Altímetro con M5Stack y BME280

Objetivos

 

  • Vamos a usar nuestro M5STACK ESP32 para construir un altímetro.
  • Usaremos el servicio Openweather, para tener la presión base a nivel de mar.
  • Usaremos la librería Arduino JSON para leer el documento.
  • Presentaremos los datos de altitud en pantalla.
  •  

    Material requerido.

     

    MOdelo basico Un M5Stack
     Sesnor BME280Sensor BME280  Sensor BME280

     

    Jugando con M5 JSON y Arduino ESP32

     

    En las últimas sesiones hemos ido jugando con los sensores de Bosch BMP280 y BME280 y vimos que pueden leer temperatura, presión y humedad (BME280), y además calcular la altitud en función de la presión atmosférica, a condición que los calibremos con la presión actual a nivel del mar en una zona próxima a nosotros.

    En esta nueva sesión iba a publicar las lecturas del BME280 en una pagina web, de forma similar a como hicimos antes para el sensor BMP280, pero la verdad es que la pagina de lastminuteengineers ha hecho un tutorial insuperable, que os la recomiendo, pero además simplemente copiar es de lo mas aburrido, y se me ha ocurrido que podíamos hacer un tuto un poco más original.

    Dado que el problema de calcular la altitud requiere un dato de calibración de partida, la presión a nivel de mar, ¿Porque no conseguir este dato mediante Openweather y JSON como ya vimos en un tuto anterior del M5Stack y usar esto para construir un sencillo altímetro con el M5?

    Este va a se un tuto de lo más práctico,  porque ya hemos visto todos los conceptos básicos necesarios y basta con juntarlos, pero para quien llegue de nuevo aquí, le recomiendo revisar antes los siguientes tutoriales de Prometec:

    Para el M5Stack ESP32 con JSON:

  • Openweather con JSON y M5.
  • M5 con Arduino JSON.
  •  

    Para manejar BMP / BME280:

  • SENSOR DE PRESIÓN Y TEMPERATURA BMP280
  • SERVIDOR WEB CON ESP32 Y BMP280
  • BME280: PRESION, ALTITUD,TEMPERATURA Y HUMEDAD
  •  

    Visto así, asusta un montón, pero os prometo que la cosa no es para tanto. Echad una ojeada a los tutos anteriores si os interesa el tema, porque en este tuto voy a dar los temas tratados como ya sabidos (Optimista que es uno) y así esta sesión no se eternizará. Pues nada, poneros cómodos que empezamos.

     

    I2C con M5Stack

     

    Nuestro M5 incluye un ESP32 interno y por tanto dispone de un bus I2C que podemos emplear para leer el Sensor BME280. Bastará con conectar los hilos como es debido y poco más. Como hasta ahora no habíamos hablado del I2C del M5, tendremos que empezar por comentar que se encuentra en un lateral y que por supuesto es un I2C normal y corriente.

    Su localización está aquí recuadrada en rojo con el rótulo Groove a la derecha del conector USB C, en uno de los laterales:

    Detalle de conexiones

    Fíjate, que si usas un típico cable Groove para conectarte (Aunque los Dupont normales deberían Valer) que el rojo son 5V, Negro GND, Amarillo es SDA y blanco es SCL (Clock). Aquí puedes ver la conexión que he hecho con un conector Groove y unos cables DuPont Macho – Hembra

    Sensor bme280 I2C

    Una vez que sabemos donde esta el conector I2C, conectar el sensor BME280 no tiene mas misterio y podemos hacer un pequeño programa para asegurarnos de que esta bien conectado sin mas que usar una variante del I2CScanner para el M5stack. Al ejecutarlo conexión al BME280 verás algo como esto:

    Muestra las direcciones I2C de los elementos conectados al bus

    Donde se puede apreciar que en bus I2C hay 3 cosas, en las direcciones 10,68 y 75 (Hexadecimales) , que no tengo claro que es qué, porque no lo he encontrado en la documentación, pero sabemos que hay una pantalla LCD, un lector de SD card y un audio así que por ahí andarán los tiros.

    Sabemos por lo tutoriales previos que el BME280 está en la dirección I2C 0x76 y si conectamos el sensor al I2C, aparece a la primera. Ni siquiera tienes que apagar:

    Comprobacion de conexiones al I2C

    Y una vez que tenemos el hardware debidamente conectado vamos con el programa.

     

    Altímetro con ESP32 / M5stack y Arduino

     

    Para hacer un pequeño resumen del proyecto, diremos que en principio podemos calcular la altitud en función de la presión barométrica, dado que ésta desciende a medida que ascendemos. Pero como no hay felicidad completa,  ocurre que la presión barométrica varia ampliamente no solo con la altitud, sino que también es muy sensible a la humedad ambiente y a la temperatura atmosférica.

    Recuerda que cuando ves el parte del tiempo, la presión barométrica baja indica que va a llover, porque la humedad que traen las lluvias hace disminuir la presión, y al contrario, si las altas presiónes indican que no va a llover. Por eso necesitamos calibrar la altitud con un dato como el de la presión a una altura de referencia y la forma mas sencilla es buscar la presión atmosférica a nivel de mar en una playa cerca de donde vives. En mi caso Getxo.

  • En general se calcula la altitud de un punto geográfico como la distancia de caida vertical hasta el nivel del mar.
  • Para los que quieran hilar fino: El nivel del mar no es constante a nivel mundial debido a los efectos de las mareas y de variaciones locales de la gravedad terrestre, por lo que el nivel del mar es un constructo teorico que se calcula como promedio de varios puntos.
  • Estos son mas motivos para calibrar tu sensor con un punto conocido. Recuerda que la altura como los voltios siempre se miden con relación a una referencia de base y nunca pueden ser valores absolutos. 
  •  

    Viviendo al lado del mar es fácil buscar el dato de presión de la playa más próxima, pero si vives en Madrid, lo tienes peor. En ese caso, puedes calcular la presión en tu casa y usarla como referencia. El altímetro te dará la variación de altura con respecto a ese punto ¿Vale?

    Si quieres un altímetro con respecto al mar, busca un punto próximo del que conozcas su altitud con exactitud y usas esa presión como referencia base, como hacíamos arriba. Luego solo tienes que sumarle la altura conocida a la lectura que te dé el sensor. Muy bien, Una vez aclarado esto (Espero) vamos a empezar con nuestro programa. Unas cuantas librerías:

    #include <M5Stack.h>
    #include <WiFi.h>
    #include <HTTPClient.h>
    #include <ArduinoJson.h>

    La primera es un clásico en M5, La segunda incluye el WIFI que usaremos para conectar a Openweather y por último la librería JSON nos permitirá deserializar la respuesta con los datos meteo.

    #include <Wire.h>
    
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BME280.h>

    Incluimos la librería Wire para poder usar el I2C, y por último cargamos la librería de uso del BME280 que a su vez requiere la librería Sensor.H de Adafruit. Vamos con algunas constantes y variables :

    const char *ssid     = "TU_SSID";
    const char *password = "contraseña";

    Como siempre, necesitamos que aquí pongas tus datos WIFI si quieres conectar (Y quieres o todo esto no valdrá de nada)

    const String key = "xxxxxxxxxxxxxxxxxxxxxxxx";
    
    const String endpoint = "https://api.openweathermap.org/data/2.5/weather?q=getxo,%20ES,IN&APPID=";

    En key necesitas poner tu clave (API key) de acceso a Openweather y en endpoint la cadena de búsqueda de tu punto de referencia.

  • Para ver como conseguir tu key gratuita de acceso a Openweather, revisa el tuto correspondiente que os apuntaba al principio, donde te lleva paso a paso para conseguirla.
  • Para obtener la String endpoint simplemente vete a la pagina de entrada de Openweather y busca el nombre de tu punto de referencia. Te saldrá una página en la que puedes escribir la población y luego cuando te salga la información simplemente copia la dirección web que aparece en tu navegador. 
  •  

    Por último, de momento:

    HTTPClient http;
    
    Adafruit_BME280 bme;
    float temperatura, humedad, presion, altitud ;
    
    float SEALEVELPRESSURE_HPA = 1010 ; // Valor por defecto

    Arrancamos el servicio HTTP para acceder a Openweather , creamos una instancia del sensor BME280 y definimos unas variables globales para las lecturas que saquemos del sensor y otra que albergue la presión de referencia a nivel de mar, con un valor por defecto, por si por lo que sea no podemos conectar a la WIFI.

  • Parece un buen momento para decir que puesto que no siempre tenemos conexión WIFI disponible (hasta que tengamos 5G) y dado que un altímetro se suele usar en el monte, sería interesante activar tu router WIFI en el móvil, de forma que si dispones de conexión de datos, nuestro M5 / ESP32 puede usarlo para acceder a internet.
  • Como solo necesitas acceder en el setup, es decir cuando arrancas y quieres recalibrar el altímetro, basta con activar el router WIFI en tu móvil, encender el M5 y en cuanto te dé el primer valor listo, puedes desactivar el router WIFI porque no lo necesitas más. 
  •  

    void setup()
    
    {  WiFi.begin(ssid, password);
       while ( WiFi.status() != WL_CONNECTED )
          {    M5.Lcd.print ( "." );
               delay ( 500 ); 
          }
       M5.begin();
       GetJsonMeteo();
       bme.begin(0x76);
    }

    Nos conectamos a la WIFI y vamos escribiendo puntitos hasta que tenemos éxito. Después inicializamos el M5 y llamamos a la función que lee los datos JSON de Openweather y por último arrancamos el sensor BME. Vamos con esta función final GetJsonMeteo() que hemos sacado directamente de uno de los tutoriales que recomendamos al principio, y ligeramentemodificado .

    void GetJsonMeteo()
    
    {    http.begin(endpoint + key); //construct the URL
         int httpCode = http.GET();  //send request
         if (httpCode > 0)
            { String payload = http.getString();
              DynamicJsonDocument doc(1024);
              deserializeJson(doc, payload);
              presion = doc["main"]["pressure"];  // Definida a nivel global
              SEALEVELPRESSURE_HPA = presion ;  // Guardamos presion a nivel del mar
            }
         else
              M5.Lcd.print("Error on HTTP request");
         http.end();
         delay(500);
    }

    Básicamente construimos la cadena de búsqueda con http.begin()  y mandamos un request con http.Get(). SI la respuesta es válida, recibimos la respuesta de Openweather a la string payload y deserializamos (Leemos) la respuesta de payload a un documento dinámico JSON llamado doc.

    Ahora ya podemos leer directamente el valor de la presión en nuestra localidad de referencia y se la asignamos a la variable global  SEALEVELPRESSURE_HPA para poder usarla como base de nuestra medida de altitud.

    Y finalmente en el loop()

    void loop()
    
      {  temperatura = bme.readTemperature();
         humedad = bme.readHumidity();
         presion = bme.readPressure() / 100.0F;
         altitud = bme.readAltitude(SEALEVELPRESSURE_HPA);
    
         M5.Lcd.fillScreen(BLACK);   // Limpia la pantalla
         M5.Lcd.setCursor(40, 110);
         M5.Lcd.setTextColor(BLUE);
         M5.Lcd.setTextSize(22);  
    
         M5.Lcd.printf("%.1f m", altitud);  // Solo 1 decimal, que si no baila demasiado
         Delay(500);     // para limitar a 2 lecturas / seg
    }

    Programa: BME280__JSON_NOKEYS

    Simplemente leemos los valores del sensor y los enviamos a la pantalla.

  • He dejado la temperatura, humedad, y presión aquí por si puedes usarlas para hacer un proyecto más ambicioso.
  • Por ejemplo, para usar los botones del M5 para ir rotando entre las distintas variables que nos ofrece el BME280: Temperatura, humedad y presión además de altitud. 
  •  

    Para probar el invento me he pillado el cacharrito éste y me he metido en el ascensor (Vivo en un octavo) y para mi sorpresa, el M5 con el sensor BME280, la clava. Vas viendo variar la altitud a medida que el ascensor se mueve.

    Incluso he probado a ponerlo en el suelo, en mi cintura y después levantando el brazo, y el tío nota la diferencia. ¡¡ Increíble!!. No esperaba que fuera tan sensible y aun cuando el fabricante dice que la precisión es, poco más o menos, de 1m, no esperaba que fuera tan sensible a algo tan poco tangible como la presión atmosférica.

    Da la sensación que no habrá variación por un par de pisos, pero vaya que si la hay, y el cacharro es capaz de medirla. Una sorpresa de lo más divertida que os recomiendo si tenéis niños (O si sois como niños, también Vale)

     

    IMAGEN DE MARCA

     

     

    Deja una respuesta