Altímetro con M5Stack y ENV sensor

Objetivos

 

  • Vamos a usar nuestro M5/ESP32 para construir un altímetro de bolsillo.
  • 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
     Sensor BMP280 DHT22Sensor BME280

     

    Jugando con M5 JSON y Arduino ESP32

     

    la última sesión construimos un altímetro con un M5Stack y un sensor BME280 cogido con cables… muy chapucero y con bastantes probabilidades de tener problemas de suelta de cables. Por eso vamos a provechar esta sesión para hacer el altímetro con un sensor Groove de M5 en lugar de elementos discretos y de paso modificamos el sensor y presentamos los módulos Groove.

    Los Groove son una familia estándar de productos para Arduino y similares que emplea un conector estándar con I2C. La virtud de estos módulos es que permiten hacer el prototyping de un modo aún más rápido que con el Arduino normal y además con un conectar estándar a prueba de niños por lo que acaba siendo ideal para pequeños proyectos rápidos o para los centros de educación de primaria, en los que se dedica más tiempo a revisar cables que a impartir la clase.

    Groove permite conectar módulos con seguridad nuestro M5 y disponer con rapidez de un prototipo funcional con conexión robusta y por eso son ideales para nuestros M5Stack porque son literalmente conectar y listo. Solo queda el programa (Que además como ya hemos comentado puede programarse en C++, micro Python o Bloques) ¿Quién da más?

    Existen infinidad de módulos Groove en el mercado, pero los de M5 han ido un paso más allá y han encapsulado una multitud de sensores y controladores / actuadores en Shields M5 y en cajitas externas con conector estándar que podemos conectar con rapidez y simplicidad a nuestro M5Stack, que van desde GPS, Controladores de motores y todos los sensores que se os ocurran:

     Sensor BMP280 DHT22  Modulo M5stack acelerometro  

    Arriba os he puesto algunos de las docenas de sensores y actuadores que M5 tiene disponibles y que quería presentaros. Puedes buscar más en la página de M5stack M5stack.com y veréis que hay de todos los tipos y colores.

    Y como muestra, resulta que tenía por aquí un sensor envelope, que incluye (Que casualidad) un DHT22 con sensor de temperatura y Humedad , pero también un BMP280 que es el que estábamos usando en los tutos últimos (Junto con su hermano mayor BME280) y que podemos usar como muestra de cómo se arma un altímetro con el M5Stack

     

    Altímetro con Envelope Sensor y M5Stack

     

    Pues nada conectamos el cablecito Groove incluido con el Envelope sensor al bus I2C que veíamos en la última sesión, operación que nos llevará como 5 segundos y ya podemos pasar a ver la programación ¿Qué te parece?

    Detalle de conexion

     

    Programando el Altímetro con M5 y Envelope Sensor

     

    Para cambiar un poco empezaremos a partir de un programa que nos proporciona M5stack como ejemplo de programación en C++ para este módulo: Envelope Sensor.

    Vamos a cambiar unas cuantas cosas, pero espero que os sirva como idea de partida. Para empezar, utiliza variantes de las librerías que hemos usado en los tutos previos (Lo que es un asco) por lo que tendremos que descargar estas variantes para no complicarnos la vida. Vamos a necesitar :

    Una vez descargadas e instaladas por el procedimiento habitual, podemos empezar a tirar líneas de código, empezando por las librerías, como siempre:

    #include <M5Stack.h>
    #include "DHT12.h"
    #include <Wire.h> //The DHT12 uses I2C comunication.
    #include "Adafruit_Sensor.h"
    #include <Adafruit_BMP280.h>

    Creamos una instancia del sensor DHT22 y otra del BMP280

    DHT12 dht12; //Preset scale CELSIUS and ID 0x5c.
    
    Adafruit_BMP280 bme;

    Recuerda que el BMP280 lee presión, altitud y Temperatura, pero no humedad, en cambio el DHT22 nos lee temperatura y humedad, con lo que podemos jugar con los dos sensores para conseguir las lecturas que deseemos. Empezamos el setup() con:

        M5.begin();
        M5.Power.begin();
        Wire.begin();

    Inicializamos el M5, La gestión de la batería y el I2C. Y pasamos a comprobar el status del BMP280:

        Serial.println(F("ENV Unit(DHT12 and BMP280) test..."));
        while (!bme.begin(0x76))
           {  Serial.println("Could not find a valid BMP280 sensor, check wiring!");
              M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!");
           }
        M5.Lcd.clear(BLACK);
        M5.Lcd.println("ENV Unit test...");

    El loop es igual de simple. Empezamos definiendo variable float para contener las lecturas que queramos, calculamos la presión de referencia como 1013 de momento y luego refinaremos el programa accediendo a Openweather:

        float tmp = dht12.readTemperature();
        float hum = dht12.readHumidity();
        float pressure = bme.readPressure();
        float altitud = bme.readAltitude(1013);
        Serial.printf("Temperatura: %2.2f*C  Humedad: %0.2f%%  Pressure: %0.2fPa\r\n", tmp, hum, pressure);

    Vamos a hora a imprimir los valores en la pantalla del M5. Definimos los colores y tamaños de los textos a imprimir:

    M5.Lcd.fillScreen(BLACK);   // Limpia la pantalla
    M5.Lcd.setCursor(0, 0);
    M5.Lcd.setTextColor(WHITE, BLACK);
    M5.Lcd.setTextSize(3);
    M5.Lcd.printf("Temp: %2.1f  \r\nHumi: %2.0f%%  \r\nPressure:%2.0fPa\r\n\n", tmp, hum, pressure);

    Y ahora aumentamos el tamaño de la letra para usar el M5Stack como altímetro (Para los que ya tenemos más años de los que nos gustaría, es mejor que se vea bien) Por ultimo un delay de 500 limita las lecturas a 2 por segundo.

    M5.Lcd.setTextSize(22);
    M5.Lcd.setTextColor(YELLOW);
    M5.Lcd.printf("%.1f m", altitud);
    delay(500);

    No me digáis que no puede ser más sencillo.

     

    Modificando la presión a nivel de mar

     

    Pues vale. Ya solo nos queda toquetear un poco el programa para que recojamos la presión de referencia a nivel de mar, como vimos en las sesiones anteriores, lo que ya es un juego de niños porque sois expertos en JSON y Openweather, por lo podríamos dejar el programa como el de más abajo. Empecemos con librería y variables varias:

    #include <M5Stack.h>
    #include "DHT12.h"
    #include <Wire.h> //The DHT12 uses I2C comunication.
    #include "Adafruit_Sensor.h"
    #include <Adafruit_BMP280.h>
    #include <HTTPClient.h>
    #include <ArduinoJson.h>

    Simplemente una lista de todas las librerías que ya hemos ido viendo. Arrancamos, ahora, las instancias de los sensores internos:

    DHT12 dht12;
    Adafruit_BMP280 bme;
    HTTPClient http;

    Aquí van los datos de la WIFI y las claves de openwheater como siempre y arrancamos el acceso HTTP.

    const char *ssid     = "Tu_SSID";
    const char *password = "contraseña";
    const String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    const String endpoint = "https://api.openweathermap.org/data/2.5/weather?q=getxo,%20ES,IN&APPID=";

    Las variables necesarias para contener los valores de las lecturas y la referencia de presión a nivel del mar:

    float temperatura, humedad, presion, altitud ;
    float SEALEVELPRESSURE_HPA = 1010 ; // Valor por defecto

    Y podemos ya empezar con el setup()

    void setup()
    {   WiFi.begin(ssid, password);
        while ( WiFi.status() != WL_CONNECTED )
          {    M5.Lcd.print ( "." );
               delay ( 500 );
          }
        M5.begin();
        M5.Power.begin();
        Wire.begin();
    
        GetJsonMeteo();
        M5.Lcd.setBrightness(10);
        Serial.println(F("ENV Unit(DHT12 and BMP280) test..."));
        while (!bme.begin(0x76))
            M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!");
            M5.Lcd.clear(BLACK);
            M5.Lcd.println("ENV Unit test...");}

    Muy parecido a los setup de los últimos tutos. La función GetJsonMeteo() es exactamente igual que siempre, pero con un ligero lavado de cara, y si has seguido los tutoriales previos no tendrás dificultad:

    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 arriba
             //long humidity = doc["main"]["humidity"];
             SEALEVELPRESSURE_HPA = presion ;  // Guardamos presion a nivel del mar
           }
         else 
             M5.Lcd.print("Error on HTTP request");
         http.end();
    }

    Tampoco creas que hay muchos cambios en el loop():

    void loop() 
    {  temperatura = dht12.readTemperature(); 
    humedad     = dht12.readHumidity(); 
    presion     = bme.readPressure()/ 100.0F ; 
    // Pasamos a Hectopascales 
    altitud     = bme.readAltitude(1013); 
    //  Serial.printf(«Temperatura: %2.2f*C  Humedad: %0.2f%%  Presion: %0.2f hPa\r\n», temperatura, humedad, presion); M5.Lcd.fillScreen(BLACK); 
    // Limpia la pantalla M5.Lcd.setCursor(0, 0); 
    M5.Lcd.setTextColor(WHITE, BLACK); 
    M5.Lcd.setTextSize(3); 
    M5.Lcd.printf(«Temp: %2.1f  \r\nHumedad: %2.0f%%  \r\nPresion:%2.0f hPa\r\n\n», temperatura, humedad, presion); M5.Lcd.setTextSize(22); 
    M5.Lcd.setTextColor(YELLOW);    
    M5.Lcd.printf(«%.1f M», altitud); delay(500); }

    M5Stack_env_sensor_nokeys

    Como ves hemos estado usando las mismas funciones con unas variaciones mínimas y lo único que he ido haciendo es mezclar dos programas. La razón es, que con mucha frecuencia alguien me envía un mensaje diciendo algo así como: “Entiendo muy bien el programa que usas para leer el sensor XXXX y también me parece claro el tutorial del actuador YYYYY, pero cuando tengo que mezclarlos no me aclaro y todo son errores de compilación. Por eso quería hacer un tuto completo mezclando un par de programas para que vierais el proceso de mezcla de programas.

    Bueno, como en todo en la vida, tenéis que ir aprendiendo poco a poco, pero no es complicado. He procurado con este ejemplo coger el programa de referencia de M5Stack para el Envelope sensor y modificarlo poco a poco para que veáis como he ido incluyendo las variable, librerías y funciones de otros programas. No es difícil, pero tienes que estar centrado y atento.

    Naturalmente a mí también me ha cascado el compilador varios errores de vuelta a empezar (¡Bueno es C++ para bromas!) pero es cuestión de leer despacio lo que te dice (Desde el principio no de abajo arriba) Cuando el compilador te da el primer error, el resto puede ser puro garbage (La palabra técnica para designar a la basura)

    • Para leer los mensajes de error del compilador, tienes que empezar desde arriba, desde la primera línea. No desde las ultimas que es lo ves en la ventana de error
    • Una vez que el compilador corta el proceso con un error, solo tiene sentido el primero, aunque después puede venir una cascada de errores sin sentido porque se ha quedado descolocado. No los hagas caso. Empieza por el primer error. .

    Lee el mensaje y aunque a veces no hay quien le entienda, si te esfuerza iras viéndole el sentido y empezarás corregir errores tú mismo y ten en cuenta que los mensajes te los envía un programa sin el menor sentido del humor.

    Espero que este pequeño ejercicio te pueda servir para que avances en tus habilidades como programador (Competencias que le llaman ahora)

    Os dejo el link a un mini video mostrando el funcionamiento del altímetro:

     

     

    IMAGEN DE MARCA