domingo, 23 de octubre de 2022

Presión, temperatura y humedad, con BMP180 y DHT22

 

En una de las entradas de este blog, Presión y temperatura con LCD Keypad Shield y BMP180, interesaba añadir un sensor más que pudiera registrar la humedad relativa (Hr). 

La humedad del ambiente tiene una gran relevancia en nuestra vida cotidiana, ya que repercute en el confort, en la salud, y en la duración o conservación de alimentos, por ejemplo.

La cantidad de vapor de agua que está presente en el ambiente determina el grado de humedad presente en el mismo. El sensor DHT22 nos brinda la temperatura y la humedad relativa del ambiente.

La Humedad Relativa (HR) es la cantidad de vapor de agua que reside en un ambiente en relación a la cantidad de vapor de agua que podría contener como máximo a una temperatura determinada. 

Las conexiones con el LCD Keypad Shield de Arduino son como muestra el siguiente esquema:

Necesitamos tener instaladas las librerías siguientes:

Para el LCD Keypad Shield:

Para el DHT22 y el BMP180 las siguientes:

Para usar el BMP180 precisamos bajar la librería sparkfun/BMP180 desde GitHub: BMP180_Breakout_Arduino_Library

El archivo .zip lo guardamos, por ejemplo, en Descargas, y luego lo instalamos en Programa -> Incluir librería -> Añadir blblioteca .zip...


Seleccionamos luego el archivo, y después hacemos clic en Abrir


Las encontramos escribiendo su nombre en el buscador del gestor de librerías.

El código a utilizar como .ino es el siguiente (Copiar y pegar):


/* V10 Mike Grusin, SparkFun Electronics 10/24/2013
V1.1.2 Updates for Arduino 1.6.4 5/2015
Versión con display de Nacho 2022, beerware. Gracias Mike, te debo una cerveza, cuando quieras en mi ciudad, Ourense, Spain
*/

// Your sketch must #include this library, and the Wire library.
// (Wire is a standard library included with Arduino.):

#include <SFE_BMP180.h>
#include <Wire.h>
#include <DHT.h>
int dhtPin = 2;
#define DHTTYPE DHT22 // Para el DHT 22
DHT dht(dhtPin, DHTTYPE);
// Display LCD Keypadshield Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Carácter especial de grado en binario en display con caracter de 40 puntos , 8 verticales y 5 horizontales
byte gradoC[8] = {
0b00111,
0b00101,
0b00111,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};

int tecla = 0; // Variables de control del teclado
int caso;

// You will need to create an SFE_BMP180 object, here called "pressure":

SFE_BMP180 pressure;

#define ALTITUDE 145.0 // Altitud en metros sobre el nivel del mar de la ciudad de Ourense España

void setup()
{
dht.begin();
pinMode(10,OUTPUT); // Control del display
digitalWrite(10, HIGH); // Enciendo por defecto el display
lcd.createChar(1, gradoC); // Creamos caracter grado centigrado y lo guardamos en 1

lcd.begin(16, 2); // Inicializar el LCD
lcd.setCursor(0,0);
if (pressure.begin())
lcd.print("Inicio OK BMP180");
else
{
// Oops, something went wrong, this is usually a connection problem,
// see the comments at the top of this sketch for the proper connections.
lcd.setCursor(0,0);
lcd.print("BMP180 fallo/n/n");
while(1); // Pausa para siempre. Pause forever.
}
lcd.setCursor(0,1);
lcd.print("OU ES Alt.:"); // Altitud de Ourense (Orense), España
lcd.print(ALTITUDE,0);
lcd.print(" m");
delay(5000);
caso = 5;

}


void loop()
{
char status;
double T,P,p0,a; //Coma flotante de doble precision. 4 bytes

// Las lecturas las obtendremos cada segundo aproximádamente
// Si queremos la presión compensada a nivel del mar, como se muestra en los partes meteoreológicos,
// necesitamos conocer la altura sobre la cual se mide la presión.
// Para ello se usa en este programa una constante llamada ALTITUDE, que tiene la altura de mic ciudad
// sobre el nivel del mar: Ourense, España: 145 msnm

tecla = analogRead(0); // Selección de tecla
if (tecla <= 45) caso = 3; // Tecla derecha
if ((tecla <= 200) & (tecla > 50)) caso = 1; // Tecla Arriba
if ((tecla <= 350) & (tecla > 200)) caso = 2; // Tecla Abajo
if ((tecla <= 500) & (tecla > 350)) caso = 5; // Scroll en el display
if ((tecla <= 850) & (tecla >500)) caso = 4; // Tecla de menú
delay(100);
switch (caso){
case 1:
lcd.setCursor(0,1);
lcd.print(" Apago Display ");
delay(1000);
caso = 5;
digitalWrite(10, LOW);
break;

case 2:

digitalWrite(10, HIGH);
lcd.setCursor(0,1);
lcd.print("Enciendo Display");
delay(1000);
caso = 5;
break;

case 3: // Temperatura en grados Fahrenheit
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);

// Hay que tener en cuenta que la medicion se almacena en la variable T
// La funcion devuelve 1 si tiene exito, y si falla 0

status = pressure.getTemperature(T);
if (status != 0)
{
// Print out the measurement:
lcd.setCursor(0,0);
lcd.print(" ");
//lcd.print(T,2);
lcd.print((9.0/5.0)*T+32.0,2);
lcd.print(" ");
lcd.write(1); // escribimos grado
lcd.print("F ");
}
break;

case 4: // Preion en mmHg
status = pressure.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
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.

status = pressure.getPressure(P,T);
if (status != 0)
{

// The pressure sensor returns abolute pressure, which varies with altitude.
// To remove the effects of altitude, use the sealevel function and your current altitude.
// This number is commonly used in weather reports.
// Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
// Result: p0 = sea-level compensated pressure in mb (hPa)

p0 = pressure.sealevel(P,ALTITUDE); // we're at 145 meters (Ourense, Spain)
lcd.setCursor(0,1);
lcd.print(" ");
//lcd.print(p0,2);
lcd.print(p0*0.0295333727*25.4,2);
lcd.print(" mmHg "); // 750 mmHg es igual a 1000 hPa
}
}
break;
case 5:
lcd.setCursor(16,0);
float humidity = dht.readHumidity();
lcd.print(" Humedad: ");
lcd.print((int)humidity);
lcd.print("% ");
lcd.setCursor(16,1);
lcd.print(" Cotidiana Place"); // Imprime un título en la primera línea del display
// scroll 16 posiciones (longitud de string) a la izquierda
// para mover con lo siguiente hacia la izquierda
for (int posiConta = 0; posiConta < 16; posiConta++) {
// scroll hacia la izquierda
lcd.scrollDisplayLeft();
// espera un bit:
delay(50);
}
delay(5000);
lcd.clear();
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);

// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.

status = pressure.getTemperature(T);
if (status != 0)
{
// Print out the measurement:
lcd.setCursor(0,0);
lcd.print(" ");
lcd.print(T,2);
lcd.print(" ");
lcd.write(1); // escribimos grado
lcd.print("C ");
}
}
caso = 0;
default:
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);

// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.

status = pressure.getTemperature(T);
if (status != 0)
{
// Print out the measurement:
lcd.setCursor(0,0);
lcd.print(" ");
lcd.print(T,2);
lcd.print(" ");
lcd.write(1); // escribimos grado
lcd.print("C ");
status = pressure.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);

status = pressure.getPressure(P,T);
if (status != 0)
{
p0 = pressure.sealevel(P,ALTITUDE); // we're at 145 meters (Ourense, Spain)
lcd.setCursor(0,1);
lcd.print(" ");
lcd.print(p0,2);
lcd.print(" hPa "); // 1 hPa es igual a 1 mbar
}
else lcd.print("error r.p.m\n"); //Gestión de errores
}
else lcd.print("error s.p.m\n");
}
else lcd.print("error r.t.m.\n");
}
else lcd.print("error s.t.m.\n");

delay(1000); // Pausa durante 1 segundos.

}
} // Fin de switch case


} // Fin de programa



Fueron corregidas algunas líneas de código, además de implementar el nuevo para usar ambos sensores.

Espero que les guste y le saquen partido. Gracias.


No hay comentarios:

Publicar un comentario