Lección 96-4: Sensor de presión barométrica, temperatura y altitud aproximada BMP390 con Arduino como termostato
Este tutorial demuestra cómo construir un termostato inteligente utilizando el sensor BMP390 de presión barométrica, temperatura y altitud aproximada con un Arduino. El BMP390 es un sensor de alta precisión de Bosch que puede medir temperatura, presión y calcular la altitud aproximada basándose en la presión a nivel del mar. En este proyecto, lo usaremos para controlar un relé que puede encender o apagar un calentador o enfriador según los umbrales de temperatura, creando un sistema de termostato totalmente funcional.
Este proyecto tiene varias aplicaciones prácticas, incluyendo:
- Crear un termostato doméstico inteligente para mantener una temperatura ambiente confortable
- Construir un sistema de ventilación para invernaderos controlado por temperatura
- Proteger equipos electrónicos sensibles del sobrecalentamiento
- Controlar una incubadora para huevos o reptiles
- Monitorear y regular la temperatura en una bodega de vinos o sala de almacenamiento
Hardware Requerido
- Arduino Uno (o placa compatible)
- Módulo sensor de presión barométrica BMP390
- Módulo de relé (para controlar el calentador/enfriador)
- Dispositivo calentador o enfriador a controlar
- Cables de conexión
- Protoboard (opcional)
Entendiendo el Sensor BMP390
El BMP390 es un sensor de presión barométrica de alta precisión fabricado por Bosch. El sensor real mide solo 2mm x 2mm x 0.75mm, lo que lo hace increíblemente compacto. La placa de expansión que usarás incluye todos los componentes de soporte necesarios como resistencias pull-up, un regulador de voltaje y un convertidor de nivel lógico, lo que te permite alimentarlo con 3.3V o 5V (en el video en 01:44).
El sensor puede medir presión de 300 a 1250 hectopascales con una precisión absoluta de ±0.5 hPa entre 0 y 65 grados Celsius. Su precisión relativa es aún mejor, de ±0.03 hPa, lo que se traduce en aproximadamente ±25 centímetros de diferencia de altitud. El sensor también cuenta con una tasa máxima de muestreo de 200 Hz, lo que lo hace adecuado para aplicaciones que requieren lecturas rápidas (en el video en 04:10).
Guía de Conexiones
Conectar el BMP390 a tu Arduino es sencillo utilizando la interfaz I2C, que solo requiere dos cables para la comunicación de datos además de las conexiones de alimentación. El pin VIN del sensor se conecta a 5V (o 3.3V) en el Arduino, la tierra se conecta a tierra, SCL se conecta al pin SCL (A5 en Uno) y SDA se conecta al pin SDA (A4 en Uno) (en el video en 05:45).
Para el módulo de relé, conectarás su pin de control al pin digital 8 del Arduino, VCC a 5V y tierra a tierra. El dispositivo que deseas controlar (calentador o enfriador) se conecta a los terminales de salida del relé.
Una característica única de este proyecto es que el código define el pin 12 como salida de alimentación para el módulo BMP390. Esto significa que puedes alimentar el sensor directamente desde un pin del Arduino sin necesidad de una fuente de alimentación separada en la protoboard (en el video en 08:46). El código establece este pin en ALTO en la configuración para proporcionar 5V al sensor.
Instalación de las Librerías Requeridas
Antes de subir el código, necesitarás instalar la librería Adafruit BMP3XX. Abre el IDE de Arduino, ve a Sketch → Incluir Librería → Administrar Librerías, busca "Adafruit BMP3XX" y haz clic en Instalar (en el video en 10:29). Esta librería maneja toda la comunicación de bajo nivel con el sensor BMP390.
Explicación del Código
El código para este proyecto de termostato está diseñado para ser altamente configurable. Examinemos las configuraciones clave definidas por el usuario al inicio del programa.
Definiciones de Pines
Puedes cambiar qué pines del Arduino se utilizan para la alimentación del sensor y el control del relé:
int bmpVCCPin = 12;//define pin 12 as VCC for bmp sensor
const int relayPin = 8;
El bmpVCCPin proporciona alimentación de 5V al módulo BMP390. El relayPin controla el módulo de relé que conmuta tu calentador o enfriador.
Configuraciones del Termostato
Estas constantes definen cómo se comporta tu termostato:
const int TEMPERATURE_UNIT = 1;//1=Celsius, 2=Fahrenheit, 3=Kelvin
const float START_TEMPERATURE = 32.0;//unit above
const float STOP_TEMPERATURE = 45.0;//unit above
const int CONTROL_TYPE = 2;// 1= heater, 2=cooler- TEMPERATURE_UNIT: Establece la escala de temperatura. Use 1 para Celsius, 2 para Fahrenheit o 3 para Kelvin.
- START_TEMPERATURE: La temperatura a la que el relé se enciende (en modo calefactor) o se apaga (en modo enfriador).
- STOP_TEMPERATURE: La temperatura a la que el relé se apaga (en modo calefactor) o se enciende (en modo enfriador).
- CONTROL_TYPE: Configúrelo en 1 para control de calefactor (se enciende cuando hace frío) o en 2 para control de enfriador (se enciende cuando hace calor).
Por ejemplo, en la demostración, la temperatura de inicio se establece en 30°C y la de parada en 45°C para que pueda probar rápidamente el comportamiento con una pistola de calor. En una aplicación real, las establecería más cercanas, como 20°C y 23°C, para mantener una temperatura ambiente confortable (en el video en 30:07).
Funciones Personalizadas
El código incluye varias funciones personalizadas que puede usar y modificar:
- loadControl(): Esta función implementa la lógica del termostato. Compara la temperatura actual con sus umbrales de INICIO y PARADA y llama a
relayControl()en consecuencia. El comportamiento cambia según si configura CONTROL_TYPE en 1 (calefactor) o en 2 (enfriador). - relayControl(int state): Esta función enciende o apaga el relé e imprime el estado en el monitor serie. Pase
relayONorelayOFF. - readValues(): Esta función lee el sensor y almacena la temperatura, presión y altitud en variables globales. Convierte automáticamente la temperatura a la unidad elegida.
- printTemperature(): Esta función imprime la lectura de temperatura con el símbolo de unidad apropiado en el monitor serie.
Cómo Funciona el Termostato
La lógica del termostato funciona comparando la temperatura actual con sus umbrales configurados. En modo calefactor (CONTROL_TYPE = 1), cuando la temperatura baja a o por debajo de START_TEMPERATURE, el relé se enciende para activar su dispositivo de calefacción. El calefactor permanece encendido hasta que la temperatura sube a STOP_TEMPERATURE, momento en el que el relé se apaga. Esto crea un efecto de histéresis que evita ciclos rápidos de encendido/apagado (en el video en 31:04).
En modo enfriador (CONTROL_TYPE = 2), la lógica se invierte. El relé se enciende cuando la temperatura alcanza o supera STOP_TEMPERATURE, y se apaga cuando baja de nuevo a START_TEMPERATURE.
La demostración en el video muestra esto funcionando con una pistola de calor. Cuando la temperatura alcanzó 45°C, el relé se apagó y la luz indicadora se apagó. Después de enfriarse a 30°C, el relé se activó nuevamente para encender el calefactor (en el video en 31:53).
Demostración del Proyecto en Vivo
El video incluye una prueba práctica de altitud del BMP390. El presentador llevó el sensor a una ubicación en Ajax, Ontario, Canadá, y midió la altitud a nivel del suelo cerca de una pista de patinaje sobre hielo. El sensor inicialmente leyó aproximadamente -15 metros, lo que representa la diferencia entre la calibración de presión a nivel del mar local y la elevación real de ese lugar (en el video en 33:04).
Al llevar el sensor al piso 25 de un edificio cercano, la lectura cambió a aproximadamente 57.2 metros. La diferencia de unos 72 metros entre la planta baja y el piso 25 demuestra la capacidad del sensor para detectar cambios de altitud significativos. Esta prueba confirma la utilidad del BMP390 para aplicaciones que requieren monitoreo de elevación (en el video en 36:16).
La demostración del termostato muestra el relé apagándose cuando la temperatura superó el umbral de parada de 45°C, con la luz indicadora apagándose. Después de enfriar el sensor por debajo de 30°C, el relé se activó nuevamente, demostrando un control de temperatura confiable basado en histéresis (en el video en 31:04).
Proyectos relacionados de este video
- Lección 96-1: Sensor de presión barométrica, temperatura y altitud aproximada BMP390 con código básico de Arduino
- Lección 96-2: Sensor de presión barométrica, temperatura y altitud aproximada BMP390 con Arduino en LCD1602
- Lección 96-3: Sensor de presión barométrica, temperatura y altitud aproximada BMP390 con Arduino en LCD2004
Capítulos
- [00:00] Introducción al proyecto del sensor BMP390
- [01:19] Comprensión de las especificaciones del sensor BMP390
- [05:45] Diagrama de conexiones para BMP390 con Arduino Uno
- [10:29] Instalación de la biblioteca Adafruit BMP3XX
- [11:38] Explicación del código para lectura básica del sensor
- [15:51] Agregar control de relé para operación de termostato
- [17:30] Configuración de la pantalla LCD (opcional)
- [22:52] Mostrar presión y altitud en LCD
- [30:07] Demostración del termostato con pistola de calor
- [32:12] Prueba de altitud en el piso 25
Imágenes
/*
* Lesson 96: Using BMP390 as thermostat
* with Arduino using it as a Thermostat to control a heater or cooler
* Download and resource page https://robojax.com/RJT457
* Watch video instruction on YouTube: https://youtu.be/XevQYG_A5xA
*
* Code updated by Ahmad Shamshiri for Robojax.com
* on Jan 13, 2022 at 17:10 in Ajax, Ontario, Canada
This video is part of the Arduino Step by Step Course which starts here: https://youtu.be/-6qSrDUA5a8
If you found this tutorial helpful, please support me so I can continue creating content like this
and make a donation using PayPal http://robojax.com/L/?id=64
This is a library for the BMP390 temperature & pressure sensor
Designed specifically to work with the Adafruit BMP388 Breakout
----> http://www.adafruit.com/products/3966
These sensors use I2C or SPI to communicate; 2 or 4 pins are required
to interface.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing products
from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
**************************************************************************
*/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BMP3XX bmp;
int bmpVCCPin = 12;//define pin 12 as VCC for bmp sensor
// all thermostat settings
const int relayPin =8;
const int relayON = HIGH;//
const int relayOFF = LOW; //
int relayState = relayOFF;//initial state of relay
const int TEMPERATURE_UNIT =1;//1=Celsius, 2=Fahrenheit, 3=Kelvin
const float START_TEMPERATURE = 32.0;//unit above
const float STOP_TEMPERATURE = 45.0;//unit above
const int CONTROL_TYPE = 2;// 1= heater, 2=cooler
//do not change the line below
float temperature, pressure, altitude;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("Adafruit BMP388 / BMP390 test");
pinMode(bmpVCCPin, OUTPUT);// set pin as output
digitalWrite(bmpVCCPin,HIGH);// always keep it high (5V) for BMB390 module
delay(500);//wait for the bmpVCCPin to turn ON.
pinMode(relayPin, OUTPUT);//pin for relay
digitalWrite(relayPin, relayState);//change initial state of relay
if (!bmp.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire
Serial.println("Could not find a valid BMP3 sensor, check wiring!");
while (1);
}
// Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);
}
void loop() {
if (! bmp.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}
readValues();
printTemperature();
Serial.println();
loadControl();
//do extra action if temperature is greater than 89.5
if(temperature >=89.5)
{
///and your code here
}
delay(2000);//wait 2 seconds or make is less or more
}
/*
* loadControl()
* @brief controls the load based
* @param state can be either : relayON or relayOFF
* @return returns none
* Written by Ahmad Shamshiri for robojax.com
* on Jan 15, 2022 at 08:11 in Ajax, Ontario, Canada
*/
void loadControl()
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
// Serial.print("Start: ");
// Serial.print(START_TEMPERATURE);
// Serial.print(" Stop: ");
//Serial.println(STOP_TEMPERATURE);
if(CONTROL_TYPE ==1)
{
if(START_TEMPERATURE >= temperature && STOP_TEMPERATURE >=temperature)
{
relayControl(relayON);
}
if(STOP_TEMPERATURE <=temperature)
{
relayControl(relayOFF);
}
}else{
if(START_TEMPERATURE >= temperature && STOP_TEMPERATURE >=temperature)
{
relayControl(relayOFF);
}
if(STOP_TEMPERATURE <=temperature)
{
relayControl(relayON);
}
}
//Robojax.com heater/cooler with BMP390 Thermocoupler
}//loadControl()
/*
* relayControl(int state))
* @brief turns the relay ON or OFF
* @param state is "relayON" or "relayOFF" defined at the top of the code
* @return returns none
* Written by Ahmad Shamshiri for robojax.com
* on May 20, 2020 at 15:23 in Ajax, Ontario, Canada
*/
void relayControl(int state)
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
if(state ==relayON)
{
digitalWrite(relayPin, relayON);
Serial.println("Relay ON");
}else{
digitalWrite(relayPin, relayOFF);
Serial.println("Relay OFF");
}
//Robojax.com heater/cooler with BMP390 Thermocoupler
}//relayControl()
/*
* readValues()
* @brief reads the temperature based on the TEMPERATURE_UNIT
* @param average temperature
* @return returns one of the values above
* Written by Ahmad Shamshiri for robojax.com
* on Jan 15, 2022 at 08:02 in Ajax, Ontario, Canada
*/
void readValues()
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
altitude = bmp.readAltitude(SEALEVELPRESSURE_HPA);// read altitude
pressure = bmp.pressure / 100.0F; // get pressure in hecto pascal
if(TEMPERATURE_UNIT ==2)
{
temperature = bmp.temperature *9/5 + 32;//convert to Fahrenheit
}else if(TEMPERATURE_UNIT ==3)
{
temperature = bmp.temperature + 273.15;//convert to Kelvin
}else{
temperature = bmp.temperature;// return Celsius
}
//Robojax.com heater/cooler with BMP390 Thermocoupler
}// readValues()
/*
* printTemperature()
* @brief prints temperature on serial monitor
* @param character type
* @param "type" is character
* C = Celsius
* K = Kelvin
* F = Fahrenheit
* @return none
* Written by Ahmad Shamshiri for robojax.com
* on Jan 15, 2022 at 08:09 in Ajax, Ontario, Canada
* www.Robojax.com
*/
void printTemperature()
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
Serial.print(temperature);
printDegree();
if(TEMPERATURE_UNIT ==2)
{
Serial.print("F");
}else if(TEMPERATURE_UNIT ==3)
{
Serial.print("K");
}else{
Serial.print("C");
}
Serial.println();
//Robojax.com heater/cooler with BMP390 Thermocoupler
}//printTemperature()
/*
* @brief prints degree symbol on serial monitor
* @param none
* @return returns nothing
* Written by Ahmad Shamshiri on July 13, 2019
* for Robojax Tutorial Robojax.com
*/
void printDegree()
{
Serial.print("\\xC2");
Serial.print("\\xB0");
}
Cosas que podrías necesitar
-
Amazonas
-
AliExpressBMP388 High Precision Digital Atmospheric Pressure on AliExpresss.click.aliexpress.com
-
AliExpressCómpralo en AliExpress.s.click.aliexpress.com
-
BanggoodCómpralo en Banggood.banggood.com
Recursos y referencias
-
ExternoCómpralo en AliExpress.s.click.aliexpress.com
-
ExternoCómpralo en Amazon Canadáamzn.to
-
ExternoCómpralo en Amazon, EE. UU.amzn.to
-
ExternoCómpralo en Banggood.banggood.com
-
Externo
-
ExternoPágina oficial del producto BMP390 de Boschbosch-sensortec.com