Altimetro con Arduino

Altimetro con Arduino

El presente instructivo se trata de como integrar el popular módulo BMP180 de Bosch para construir un altimetro con Arduino y/o un barómetro  con Arduino (también posee sensor de temperatura). El sensor en cuestion mide la temperatura y la presión atmosférica mediante la cual se puede calcular la altitud.

El sensor BMP180

Este sensor de Bosch viene integrado en varios tipos de modulos diferentes. Lo más importante al integrar un módulo con BMP180 es fijarse en el voltaje. Es que algunos modulos traen un regulador de voltaje integrado mientras que otros no. Si su módulo posee regulador de voltaje integrado, podrá alimentarlo dorectamente con 5V, mientras que si no lo tiene deberá ser cuidadoso y alimentarlo con 3,3V. Por favor consulte los datos técnicos de su módulo antes de conectarlo.

 

Conectaremos el módulo a nuestro Arduino UNO de la siguiente manera:

Módulo -> Arduino UNO -> Arduino Mega 2560
Vin -> 5V/3,3V -> 5V/3,3V (dependiendo del voltaje de su módulo)
GND -> GND -> GND
SDA -> A4 -> Pin 20
SCL -> A5 -> Pin 21

Acá les dejo un enlace a la hoja de datos del sensor: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMP180-DS000-121.pdf

Comunicación I2C

El sensor (módulo) se comunica por I2C lo cual es muy conveniente. La dirección que este módulo utiliza es 0x77 o 77 hexadecimal. La interacción con el sensor no es sencilla pero tampoco es terriblemente complicada. En general las operaciones de deben ser encadenadas en secuencias donde una debe ir tras la otra para realizar algunos de los cálculos más complejos como por ejemplo el de altitud.

La librería que utilizaremos será la SparkFun BMP180_Breakout que no es la manera más eficiente de interactuar con este sensor pero es una librería muy conveniente para simplificar las primeras pruebas con éste módulo.

La puede descargar desde aqui: https://github.com/sparkfun/BMP180_Breakout/archive/master.zip

Sketch del altimetro con Arduino

El Sketch es simple y es una traducción de uno de los ejemplos de la librería (al español).

// Libreria del sensor BMP180
#include <SFE_BMP180.h>

// Libreria I2C 
#include <Wire.h>

// El objeto principal que usaremos
SFE_BMP180 pressure;

// Debe proveer la altitud de su lugar en metros. http://elevationmap.net/
#define ALTITUD 588.0 
// Debe proveer la presion media a nivel del mar mas cercana a su posicion
#define PRESION_NIVEL_MAR 1014.0

void setup() {
  
  // Inicializamos Monitor Serial en 9600
  Serial.begin(9600);
  Serial.println("Inicializando...");

  // Inicializamos el sensor lo que además obtiene los valores de calibración del mismo  
  if (pressure.begin()) {
    Serial.println("Inicializacion del BMP180 exitosa!");
  }
  else {
    // Cuando obtenemos este error usualmente es un error de conexion. Revise los cables.
    Serial.println("La inicializacion del BMP180 fallo");
    while(1);
  }
}

void loop() {
  
  char status;
  double T, P, p0, a;

  Serial.println();
  Serial.print("Altitud provista: ");
  Serial.print(ALTITUD, 0);
  Serial.print(" metros, ");
  Serial.print(ALTITUD*3.28084,0);
  Serial.println(" pies");
  
  // Debe primero hacer una lectura de temperatura antes de realizar una lectura
  // de presion atmosferica. Si la lectura de temperatura es exitosa, la funcion
  // retorna el numero de milisegundos a esperar luego de la lectura.
  status = pressure.startTemperature();
  
  if (status != 0) {
    
    // Esperar a que la lectura finalice
    delay(status);

    // Leemos la termperatura de la lectura. La misma sera guardada en T
    status = pressure.getTemperature(T);
    
    if (status != 0) {
      
      // Mostramos la temperatura leida
      Serial.print("Temperatura: ");
      Serial.print(T, 2);
      Serial.print("C, ");
      Serial.print((9.0/5.0)*T+32.0,2);
      Serial.println("F");
      
      // Comenzamos la lectura de presion. El parametro provisto se denomina oversampling 
      // y provee mayor resolución. Puede ser entre 0-3 y cuanto más alto mayor la 
      // resolucion de la lectura pero tambien mayor el tiempo que llevara la misma.
      // Al igual que con la temperatura, la funcion devuelve el tiempo en ms a esperar
      // para que la lectura se complete.
      status = pressure.startPressure(3);
      
      if (status != 0) {
        
        // Esperar a que la lectura finalice
        delay(status);

        // Retrieve the completed pressure measurement:
        // Note that the measurement is stored in the variable P.
        // Note also that the function requires the previous temperature measurement (T).
        // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
        // Function returns 1 if successful, 0 if failure.

        // Obtenemos la lectura completa de presion la que sera guardada en la variable P
        // La funcion requiere la temperatura leida previamente para calcular la presion
        // (Si la temperatura es estable puede realizar varias lecturas de presion con una
        // sola lectura de temperatura.)
        status = pressure.getPressure(P, T);
        
        if (status != 0) {
          
          // Mostramos la presion leida
          Serial.print("Presion absoluta: ");
          Serial.print(P, 2);
          Serial.print(" mb, ");
          
          // El ejemplo original mostraba el resultado en inHg (pulgadas de mercurio) 
          // pero yo lo ajusté a milimetros de mercurio para este ejemplo
          // la constante para inHg es 0.0295333727
          Serial.print(P*0.750064,2);
          Serial.println(" mm Hg");

          // El sensor de presion devuelve la presion absoluta la cual varia con la
          // altitud. Para remover los efectos de la altitud use la funcion sealevel() y 
          // su altitud actual. Este numero es usualmente usado en meteorologia.
          // La altitud debe ser provista en metros. Vea la definicion de la constante
          // usada en este ejemplo y adaptela a su area.
          p0 = pressure.sealevel(P, ALTITUD); 
          Serial.print("Presion relativa (nivel del mar): ");
          Serial.print(p0,2);
          Serial.print(" mb, ");
          Serial.print(p0*0.750064,2);
          Serial.println(" mm Hg");

          // El caso inverso es el de computar una altitud que resulta de la diferencia entre
          // 2 altitudes basadas en 2 presiones atmostfericas. Debe proveer de la presion
          // recien leida asi como de la de referencia. Sirve para calcular la altura en base al 
          // suelo o en base al nivel del mar (necesitara la presion más cercana del nivel del mar.
          // En este ejemplo deberá coincidir con la suministrada originalmente (aprox.).
          a = pressure.altitude(P, PRESION_NIVEL_MAR);
          Serial.print("Altitud calculada: ");
          Serial.print(a, 0);
          Serial.print(" metros, ");
          Serial.print(a*3.28084,0);
          Serial.println(" pies");
        }
        else {
          Serial.println("Error obteniendo medicion de presion");
        }
      }
      else { 
        Serial.println("Error iniciando medicion de presion");
      }
    }
    else {
      Serial.println("Error obteniendo medicion de temperatura");
    }
  }
  else {
    Serial.println("Error iniciando medicion de temperatura");
  }

  // Pausa para repetir mediciones cada 5 minutos
  delay(5000);
}

y luego de cargarlo en su Arduino IDE y subirlo a su Arduino UNO (o Mega), debería ver also similar a lo siguiente:

Inicializando...
Inicializacion del BMP180 exitosa!

Altitud provista: 588 metros, 1929 pies
Temperatura: 27.72C, 81.90F
Presion absoluta: 945.99 mb, 709.55 mm Hg
Presion relativa (nivel del mar): 1014.75 mb, 761.13 mm Hg
Altitud calculada: 582 metros, 1909 pies

Recuerde revisar las 2 constantes que hay al principio del Sketch y ajustarlas a los valores correspondientes a su ubicación. El tiempo promedio de lectura completa (teperatura + presion) es de aprox. 53ms lo que es bastante alto. Como explica el Sketch, se puede reducir esto reteniendo el valor de temperatura y refrescándolo menos frecuentemente. En la mayoria de las aplicaciones, y en especial aquellas que requieren la lectura de presion muy seguido, podemos leer la temperatura cada 10 mins por ejemplo reduciendo significativamente el tiempo de lectura de la presion atmosférica. Una aplicación que podría beneficiarse de ésta estrategia sería un altimetro con Arduino para un dron.

 

Deja un comentario