Cerca codice

Lezione 96-4: Sensore di pressione barometrica, temperatura e altitudine approssimativa BMP390 con Arduino come termostato

Lezione 96-4: Sensore di pressione barometrica, temperatura e altitudine approssimativa BMP390 con Arduino come termostato

Questo tutorial dimostra come costruire un termostato intelligente utilizzando il sensore di pressione barometrica, temperatura e altitudine approssimativa BMP390 con un Arduino. Il BMP390 è un sensore altamente preciso di Bosch in grado di misurare temperatura, pressione e calcolare l'altitudine approssimativa basandosi sulla pressione a livello del mare. In questo progetto, lo useremo per controllare un relè che può accendere e spegnere un riscaldatore o un raffreddatore in base alle soglie di temperatura, creando un sistema termostatico completamente funzionale.

BMP380_pink-module-gravitiy-1
BMP380_pink-module-1

Questo progetto ha diverse applicazioni pratiche, tra cui:

  • Creare un termostato domestico intelligente per mantenere una temperatura ambiente confortevole
  • Costruire un sistema di ventilazione per serra controllato dalla temperatura
  • Proteggere dispositivi elettronici sensibili dal surriscaldamento
  • Controllare un'incubatrice per uova o rettili
  • Monitorare e regolare la temperatura in una cantina per vini o in un magazzino
BMP380_pink-module-3-size

Hardware Richiesto

  • Arduino Uno (o scheda compatibile)
  • Modulo sensore di pressione barometrica BMP390
  • Modulo relè (per controllare il riscaldatore/raffreddatore)
  • Dispositivo riscaldatore o raffreddatore da controllare
  • Cavi jumper
  • Breadboard (opzionale)

Capire il Sensore BMP390

Il BMP390 è un sensore di pressione barometrica altamente preciso prodotto da Bosch. Il sensore vero e proprio misura solo 2mm x 2mm x 0,75mm, rendendolo estremamente compatto. La scheda breakout che utilizzerai include tutti i componenti di supporto necessari come resistori pull-up, un regolatore di tensione e un convertitore di livello logico, permettendoti di alimentarlo con 3,3V o 5V (nel video a 01:44).

Il sensore può misurare la pressione da 300 a 1250 ettopascal con una precisione assoluta di ±0,5 hPa tra 0 e 65 gradi Celsius. La sua precisione relativa è ancora migliore, pari a ±0,03 hPa, che si traduce in circa ±25 centimetri di differenza di altitudine. Il sensore presenta anche una frequenza di campionamento massima di 200 Hz, rendendolo adatto per applicazioni che richiedono letture rapide (nel video a 04:10).

Guida al Cablaggio

BMP390_arduino_wiring_pink-1-from-sda-scl-pins
BMP390_arduino_wiring_pink-2

Collegare il BMP390 al tuo Arduino è semplice utilizzando l'interfaccia I2C, che richiede solo due fili per la comunicazione dei dati oltre alle connessioni di alimentazione. Il pin VIN del sensore si collega a 5V (o 3,3V) sull'Arduino, la massa si collega a massa, SCL si collega al pin SCL (A5 su Uno) e SDA si collega al pin SDA (A4 su Uno) (nel video a 05:45).

Per il modulo relè, collegherai il suo pin di controllo al pin digitale 8 sull'Arduino, VCC a 5V e la massa a massa. Il dispositivo che vuoi controllare (riscaldatore o raffreddatore) si collega ai terminali di uscita del relè.

Una caratteristica unica di questo progetto è che il codice definisce il pin 12 come uscita di alimentazione per il modulo BMP390. Questo significa che puoi alimentare il sensore direttamente da un pin Arduino senza bisogno di una barra di alimentazione separata sulla breadboard (nel video a 08:46). Il codice imposta questo pin su HIGH nella configurazione per fornire 5V al sensore.

Installazione delle Librerie Richieste

Prima di caricare il codice, dovrai installare la libreria Adafruit BMP3XX. Apri l'IDE Arduino, vai su Sketch → Includi Libreria → Gestisci Librerie, cerca "Adafruit BMP3XX" e fai clic su Installa (nel video a 10:29). Questa libreria gestisce tutta la comunicazione a basso livello con il sensore BMP390.

Spiegazione del Codice

Il codice per questo progetto di termostato è progettato per essere altamente configurabile. Esaminiamo le principali impostazioni configurabili dall'utente all'inizio del programma.

Definizioni dei Pin

Puoi cambiare quali pin Arduino vengono utilizzati per l'alimentazione del sensore e il controllo del relè:

int bmpVCCPin = 12;//definisce il pin 12 come VCC per il sensore bmp
const int relayPin = 8;

Il bmpVCCPin fornisce 5V di alimentazione al modulo BMP390. Il relayPin controlla il modulo relè che commuta il tuo riscaldatore o raffreddatore.

BMP288-1
BMP380_pink-module-gravitiy-1

Impostazioni del Termostato

Queste costanti definiscono come si comporta il tuo termostato:

const int TEMPERATURE_UNIT = 1;//1=Celsius, 2=Fahrenheit, 3=Kelvin
const float START_TEMPERATURE = 32.0;//unità sopra
const float STOP_TEMPERATURE = 45.0;//unità sopra
const int CONTROL_TYPE = 2;// 1= riscaldatore, 2=raffreddatore
  • TEMPERATURE_UNIT: Imposta la scala di temperatura. Usa 1 per Celsius, 2 per Fahrenheit o 3 per Kelvin.
  • START_TEMPERATURE: La temperatura alla quale il relè si accende (in modalità riscaldamento) o si spegne (in modalità raffreddamento).
  • STOP_TEMPERATURE: La temperatura alla quale il relè si spegne (in modalità riscaldamento) o si accende (in modalità raffreddamento).
  • CONTROL_TYPE: Imposta a 1 per il controllo del riscaldamento (si accende quando fa freddo) o a 2 per il controllo del raffreddamento (si accende quando fa caldo).

Ad esempio, nella dimostrazione, la temperatura di avvio è impostata a 30°C e quella di arresto a 45°C, così puoi testare rapidamente il comportamento con una pistola termica. In un'applicazione reale, imposteresti questi valori più vicini tra loro, come 20°C e 23°C, per mantenere una temperatura ambiente confortevole (nel video a 30:07).

Funzioni Personalizzate

Il codice include diverse funzioni personalizzate che puoi usare e modificare:

  • loadControl(): Questa funzione implementa la logica del termostato. Confronta la temperatura attuale con le soglie START e STOP e chiama relayControl() di conseguenza. Il comportamento cambia in base al fatto che tu imposti CONTROL_TYPE a 1 (riscaldatore) o 2 (raffreddatore).
  • relayControl(int state): Questa funzione accende o spegne il relè e stampa lo stato sul monitor seriale. Passale relayON o relayOFF.
  • readValues(): Questa funzione legge il sensore e memorizza temperatura, pressione e altitudine in variabili globali. Converte automaticamente la temperatura nell'unità scelta.
  • printTemperature(): Questa funzione stampa la lettura della temperatura con il simbolo dell'unità appropriato sul monitor seriale.

Come Funziona il Termostato

La logica del termostato funziona confrontando la temperatura attuale con le soglie configurate. In modalità riscaldamento (CONTROL_TYPE = 1), quando la temperatura scende a o sotto la START_TEMPERATURE, il relè si accende per attivare il dispositivo di riscaldamento. Il riscaldatore rimane acceso finché la temperatura non sale alla STOP_TEMPERATURE, a quel punto il relè si spegne. Questo crea un effetto di isteresi che previene cicli rapidi di accensione/spegnimento (nel video a 31:04).

In modalità raffreddamento (CONTROL_TYPE = 2), la logica è invertita. Il relè si accende quando la temperatura raggiunge o supera la STOP_TEMPERATURE e si spegne quando scende di nuovo alla START_TEMPERATURE.

La dimostrazione nel video mostra questo funzionamento con una pistola termica. Quando la temperatura ha raggiunto i 45°C, il relè si è spento e la spia luminosa si è spenta. Dopo il raffreddamento a 30°C, il relè si è riattivato per riaccendere il riscaldatore (nel video a 31:53).

Dimostrazione del Progetto dal Vivo

Il video include un test pratico dell'altitudine del BMP390. Il presentatore ha portato il sensore in una località ad Ajax, Ontario, Canada, e ha misurato l'altitudine a livello del suolo vicino a un campo di pattinaggio sul ghiaccio. Il sensore inizialmente ha letto circa -15 metri, che rappresenta la differenza tra la calibrazione della pressione a livello del mare locale e l'elevazione effettiva di quel punto (nel video a 33:04).

Portando il sensore al 25° piano di un edificio vicino, la lettura è cambiata a circa 57,2 metri. La differenza di circa 72 metri tra il piano terra e il 25° piano dimostra la capacità del sensore di rilevare cambiamenti significativi di altitudine. Questo test conferma l'utilità del BMP390 per applicazioni che richiedono il monitoraggio dell'elevazione (nel video a 36:16).

La dimostrazione del termostato mostra il relè che si spegne quando la temperatura supera la soglia di arresto di 45°C, con la spia luminosa che si spegne. Dopo aver raffreddato il sensore sotto i 30°C, il relè si è riattivato, dimostrando un controllo della temperatura basato su isteresi affidabile (nel video a 31:04).

Progetti correlati da questo video

Capitoli

  • [00:00] Introduzione al progetto del sensore BMP390
  • [01:19] Comprensione delle specifiche del sensore BMP390
  • [05:45] Schema di collegamento per BMP390 con Arduino Uno
  • [10:29] Installazione della libreria Adafruit BMP3XX
  • [11:38] Spiegazione del codice per la lettura base del sensore
  • [15:51] Aggiunta del controllo del relè per il funzionamento del termostato
  • [17:30] Configurazione del display LCD (opzionale)
  • [22:52] Visualizzazione di pressione e altitudine su LCD
  • [30:07] Dimostrazione del termostato con pistola termica
  • [32:12] Test dell'altitudine al 25° piano

Immagini

BMP288-1
BMP288-1
BMP380_pink-module-4
BMP380_pink-module-4
BMP380_pink-module-3-size
BMP380_pink-module-3-size
BMP380_pink-module-2
BMP380_pink-module-2
BMP380_pink-module-1
BMP380_pink-module-1
BMP380_pink-module-gravitiy-1
BMP380_pink-module-gravitiy-1
BMP390_arduino_wiring_2-gravity-module-sda-scl-pins
BMP390_arduino_wiring_2-gravity-module-sda-scl-pins
BMP390_arduino_wiring_2-gravity-module
BMP390_arduino_wiring_2-gravity-module
BMP390_arduino_wiring_pink-1-from-sda-scl-pins
BMP390_arduino_wiring_pink-1-from-sda-scl-pins
BMP390_arduino_wiring_pink-2
BMP390_arduino_wiring_pink-2
437-Lesson 96-4: Using BMP390 as thermostat (heater or cooler)
Lingua: C++
/*
 * 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");  
}

Risorse e riferimenti

File📁

Scheda tecnica (pdf)