Pretraži kod

Lekcija 96-3: Barometarski pritisak, temperatura i senzor približne nadmorske visine BMP390 s Arduinom na LCD2004

Lekcija 96-3: Barometarski pritisak, temperatura i senzor približne nadmorske visine BMP390 s Arduinom na LCD2004

BMP390 je visoko precizan barometarski senzor pritiska, temperature i približne nadmorske visine kompanije Bosch. Ovaj vodič, dio Arduino Step-by-Step kursa autora Robojax, fokusira se na to kako čitati podatke s ovog senzora i prikazati ih na velikom 20x4 (LCD2004) karakternom displeju. Ova postavka je idealna za projekte gdje trebate vidjeti sva očitanja senzora istovremeno na jednom ekranu, što je čini savršenom za stanice za praćenje okoliša, meteorološke stanice ili kao precizan visinomjer za model raketa ili dronova.

BMP380_pink-module-1

Evo nekoliko praktičnih ideja za projekte koje možete napraviti s ovom postavkom:

  • Izgradnja kućne meteorološke stanice koja prikazuje temperaturu, pritisak i nadmorsku visinu.
  • Kreiranje visokopreciznog visinomjera za model rakete ili balon na velikim visinama za praćenje uspona i spuštanja.
  • Razvoj uređaja za bilježenje podataka za staklenik ili serversku sobu gdje možete pratiti atmosferske uslove u realnom vremenu.
  • Konstrukcija uređaja za mjerenje razlike u nadmorskoj visini između spratova u zgradi, kao što je prikazano u videu.
BMP380_pink-module-4

Potreban hardver

  • Arduino Uno (ili bilo koja kompatibilna ploča)
  • BMP390 modul senzora barometarskog pritiska
  • LCD2004 (20x4) I2C LCD displej
  • Konektorske žice

Vodič za povezivanje

BMP390_arduino_wiring_2-gravity-module
BMP390_arduino_wiring_pink-1-from-sda-scl-pins
BMP390_arduino_wiring_pink-2
BMP390_LCD2004_wiring_pink

Povezivanje za ovaj projekat je jednostavno, jer i BMP390 senzor i LCD2004 koriste I2C komunikacijski protokol. To vam omogućava da povežete oba uređaja koristeći samo dvije podatkovne linije (SDA i SCL) plus napajanje i uzemljenje.

U videu, VIN pin senzora je spojen na digitalni pin (pin 12) na Arduinu. Ovo je pametan trik koji se koristi u kodu za kontrolu napajanja senzora, omogućavajući Arduinu da ga uključi ili isključi programski. SDA i SCL linije senzora spojene su na A4 i A5 pinove Arduina, respektivno.

Za LCD2004, VCC i GND pinovi su spojeni na 5V i GND pinove Arduina. Njegovi SDA i SCL pinovi su također spojeni na A4 i A5, dijeleći istu I2C magistralu sa senzorom.

Napomena o I2C adresama: Svaki I2C uređaj ima jedinstvenu adresu. LCD2004 često koristi adresu 0x27 ili 0x3F. Morate pokrenuti I2C skener skicu da biste pronašli tačnu adresu za vaš specifični LCD, kao što je prikazano u videu. BMP390 senzor također treba biti detektovan na magistrali.

 

BMP380_pink-module-2
BMP288-1

Objašnjenje koda

Ovaj odjeljak objašnjava dijelove koda koje korisnik može konfigurisati. Kompletan program je dostupan ispod članka. Kod je dizajniran da bude modularan, sa prilagođenom funkcijom za preuzimanje podataka i drugom za njihov prikaz na LCD-u.

1. Konfiguracija biblioteke i pinova

Kod počinje uključivanjem potrebnih biblioteka za BMP390 senzor i I2C LCD. Morat ćete instalirati Adafruit BMP3XX biblioteku i LiquidCrystal_I2C biblioteku koristeći Arduino Library Manager.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
#include <LiquidCrystal_I2C.h>

// Postavite LCD adresu na 0x27 ili 0x3F za displej od 20 znakova i 4 linije
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Pin za BMP390 VIN
int bmpVCCPin = 12;
  • LiquidCrystal_I2C lcd(0x27, 20, 4);: Ova linija inicijalizira LCD. Prvi parametar je I2C adresa, koju morate promijeniti da odgovara vašem LCD-u (npr. 0x3F). Drugi i treći parametar su broj kolona (20) i redova (4) za vaš LCD2004.
  • int bmpVCCPin = 12;: Ovo definira Arduino pin koji će napajati BMP390 senzor. Možete ga promijeniti na bilo koji drugi digitalni pin. Kod postavlja ovaj pin kao izlaz i postavlja ga na HIGH u setup() funkciji da bi napajao senzor sa 5V.

2. Konfiguracija jedinica prikaza

boolean fahrenheit = true;//za Celzijuse postavite na "false"
  • boolean fahrenheit = true;: Ova varijabla kontrolira jedinicu temperature koja se ispisuje na serijskom monitoru. Postavljanje na true prikazuje Fahrenheit, dok postavljanje na false prikazuje Celzijus. Kod LCD ekrana uvijek prikazuje obje jedinice.

3. Funkcija getBMP()

Ovo je moćna prilagođena funkcija koja dohvaća specifično očitanje sa senzora. Prima jedan argument tipa karakter kako bi specificirala koju vrijednost želite.

float getBMP(char type)
{
   float value;
   float temp = bmp.temperature;
   if(type =='F') {
       value = temp *9/5 + 32;//pretvori u Fahrenheit
   } else if(type =='K') {
       value = temp + 273.15;//pretvori u Kelvin
   } else if(type =='P') {
       value = bmp.pressure / 100.0F; // očitaj pritisak u hPa
   } else if(type =='A') {
       value = bmp.readAltitude(SEALEVELPRESSURE_HPA);// očitaj nadmorsku visinu
   } else {
       value = bmp.temperature;// očitaj temperaturu u Celzijusima
   }
   return value;
}

Kako koristiti: Da biste dobili specifičnu vrijednost, pozovite funkciju s odgovarajućim karakterom. Na primjer, getBMP('F') vraća temperaturu u Fahrenheitima, getBMP('P') vraća pritisak u hektopaskalima (hPa), a getBMP('A') vraća približnu nadmorsku visinu u metrima.

4. Funkcija lcdDisplay()

Ova funkcija je pomoćnik koji pojednostavljuje ispis naslova i vrijednosti na LCD ekranu na specifičnoj poziciji. Automatski upravlja pozicioniranjem kursora i simbolima jedinica (poput °C, °F, hPa, m).

void lcdDisplay(int tc, int tr, String title, int vc, int vr, float value, char symbol)
{
   lcd.setCursor (tc,tr);
   lcd.print(title);
   if(vc !=99) {
       lcd.setCursor (vc,vr);
   }
   lcd.print(value);
   // ... kod za ispis ispravnog simbola jedinice na osnovu 'symbol' ...
}

Kako koristiti: Morate navesti početni karakter (kolonu) i liniju (red) za naslov, sam tekst naslova, poziciju karaktera i linije za vrijednost, numeričku vrijednost i simbol karaktera (npr. 'C', 'F', 'p', 'm') za ispis ispravne jedinice. Vrijednost 99 za poziciju karaktera vrijednosti govori funkciji da ispiše vrijednost odmah nakon naslova.

Demonstracija projekta uživo

U videu (na 28:05), Robojax demonstrira projekt u akciji. LCD2004 ekran jasno prikazuje sva četiri ključna očitanja odjednom: temperaturu u Celzijusima, temperaturu u Fahrenheitima, pritisak u hPa i približnu nadmorsku visinu u metrima. Ovo je značajna prednost u odnosu na manji LCD1602, koji može prikazati samo dvije od ovih vrijednosti istovremeno.

Također izvodi test topline koristeći toplinski pištolj (u videu na 30:30), pokazujući kako prikazane vrijednosti temperature i nadmorske visine reagiraju trenutno na promjene u okruženju senzora, potvrđujući visoku preciznost i brzu brzinu uzorkovanja senzora.

Da bi demonstrirao funkciju nadmorske visine, Robojax nosi projekt na 25. sprat zgrade (u videu na 35:43). Senzor očitava približnu nadmorsku visinu od 57,2 metra na vrhu, u poređenju s negativnim očitanjem u prizemlju, pokazujući jasnu razliku koja odgovara visini zgrade.

Projekt za korištenje BMP390 kao termostata za upravljanje relejem pokriven je u Lekciji 96-4: Barometarski pritisak, temperatura i približni senzor nadmorske visine BMP390 s Arduinom kao termostat.

Pokretanje senzora s osnovnim kodom na serijskom monitoru pokriveno je u Lekciji 96-1: Barometarski pritisak, temperatura i približni senzor nadmorske visine BMP390 s Arduinom osnovni kod.

Prikaz podataka senzora na manjem ekranu s dvije linije pokriveno je u Lekciji 96-2: Barometarski pritisak, temperatura i približni senzor nadmorske visine BMP390 s Arduinom na LCD1602.

Povezani projekti iz ovog videa

Poglavlja

  • [00:00] Uvod u BMP390 projekt
  • [01:19] Razumijevanje BMP390 senzora i njegovih karakteristika
  • [05:45] Šema povezivanja za BMP390 s Arduino Uno
  • [10:29] Instalacija potrebnih Arduino biblioteka
  • [11:38] Objašnjenje osnovnog BMP390 koda
  • [16:54] Postavljanje LCD2004 i I2C skenera adresa
  • [20:09] Detaljno objašnjenje koda za LCD2004 ekran
  • [26:22] Demonstracija uživo sa serijskim monitorom i testom topline
  • [28:05] Demonstracija projekta na LCD2004
  • [32:12] Test nadmorske visine u stvarnom svijetu na 25. spratu

Slike

LCD2004_display-2
LCD2004_display-2
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
BMP390_LCD2004_wiring_pink
BMP390_LCD2004_wiring_pink
436-Lesson 96-3: BMP390 with LCD2004
Jezik: C++
/*
 * Lesson 96: BMP390 with LCD2004
 * with Arduino with LCD2004
Download and resource page https://robojax.com/RJT456

 * 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 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;
boolean fahrenheit = true;//for Celsius set it to "false"

#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 or 0x3F for a 20 chars and 4  line display
LiquidCrystal_I2C lcd(0x27, 20, 4);


void setup() {
    pinMode(bmpVCCPin, OUTPUT);// set pin as output
    digitalWrite(bmpVCCPin,HIGH);// always keep it high (5V) for BMB390 module
     
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Adafruit BMP388 / BMP390 test");

  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);
  // initialize the LCD, 
  lcd.begin();
  // Turn on the blacklight and print a message.
  lcd.backlight();     
  lcd.print("Robojax Video");
  lcd.setCursor (0,1); // go to start of 2nd line
  lcd.print("BMP390 Test LCD2004");
  lcd.setCursor (0,2); // go to start of 3nd line
  lcd.print("www.Robojax.com");  
  delay(4000);  
}

void loop() {
  if (! bmp.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }

    // Robojax.com BME390 Code
   lcd.clear();// clear previous values from screen  

lcdDisplay(
             // to print Celsius:
             0, // character 0 
             0, // line 0
             "Celsius: ", 

             // to print Celsius value
             12, // character undefined
             0, // line 0
             getBMP('C'),
             'C'
             );  

 lcdDisplay(
             // to print fahrenheit:
             0, // character 0 
             1, // line 2
             "Fahrenheit: ", 

             // to print Fahrenheit value
             12, // character 9
             1, // line 2
             getBMP('F'),
             'F'
             );  
 

lcdDisplay(
             // to print pressure text
             0, // character 0 
             2, // line 3
             "Pressure:", 

             // to print pressure value
             99, // character undefined
             2, // line 3
             getBMP('P'),
             'p' 
             );  
  lcdDisplay(
             // to print altitude text
             0, // character 0 
             3, // line 4
             "Aprx. Alt.:", 

             // to print Altitude value
             12, // character undefined
             3, // line 4
             getBMP('A'),
             'm' 
             );                   
        delay(4000);

     // Robojax.com BMP390 Code                                

  //take action, do something when temperature is greater than 38.0 C
  if(bmp.temperature >38.0)
  {
   digitalWrite(10, HIGH); 

   
  }else{
    digitalWrite(10, LOW);
  }
  delay(2000);
  printRobojax(false);//set to true, or false
  
}//loop ends here

/*
 * @brief returns temperature or relative humidity
 * @param "type" is character
 *     C = Celsius
 *     K = Kelvin
 *     F = Fahrenheit
 *     H = Humidity
 *     P = Pressure
 *     A = Altitude
 * @return returns one of the values above
 * Usage: to get Fahrenheit type: getBMP('F')
 * to print it on serial monitor Serial.println(getBMP('F'));
 * Written by Ahmad Shamshiri on July 13, 2019. Update 13 Jan 2022
 * at 20:56 
 * in Ajax, Ontario, Canada
 * www.Robojax.com 
 */
float getBMP(char type)
{
   // Robojax.com BMP390 Code
  float value;
    float temp = bmp.temperature;
  if(type =='F')
   {
    value = temp *9/5 + 32;//convert to Fahrenheit 
   }else if(type =='K')
   {
    value = temp + 273.15;//convert to Kelvin
   }else if(type =='P')
   {
    value = bmp.pressure / 100.0F; // read pressure
   }else if(type =='A')
   {
    value = bmp.readAltitude(SEALEVELPRESSURE_HPA);// read altitude
   }else{
    value = bmp.temperature;// read temperature
   }
   return value;
    // Robojax.com BME390 Code
}//getBME



/*
 * lcdDisplay(int tc, int tr, String title, int vc, int vr, float value)
 * displays value and title on LCD1602
 * How to use:
 * If you want to display: "Temp.: 340.45K" starting from first character
 * on second row.
 * use:
 * lcdDisplay(0, 1, "Temp.: ", 340.45,'K')
 *   
 *   'C' is degree symbol for C and F
 * tc  is character number  (0)
 * tr is row in the lcd (1)
 * title is the text (Voltage:)
 * vc value for character 
 * vr value for  row or line
 * value is the value (13.56)
 */
void lcdDisplay(int tc, int tr, String title, int vc, int vr, float value,char symbol)
{
   // Robojax.com LCD1602 for BMP390 Demo

   lcd.setCursor (tc,tr); //
   lcd.print(title);
   if(vc !=99)
   {
   lcd.setCursor (vc,vr); //
   }   
   lcd.print(value);
   if(symbol == 'C')
   {
    lcd.print((char)223);
    lcd.print('C');
   }else if(symbol == 'F')
   {
    lcd.print((char)223);
    lcd.print('F');
   }else if(symbol =='k')
   {
    lcd.print("K");
   }else if(symbol =='p')
   {
    lcd.print("hPa");
   }else if(symbol =='m')
   {
    lcd.print("m");
   }
}
 // Robojax.com LCD1602 for BMP390 Demo

/*
 * 
 * this function, if called, will print Robojax stuff
 * */
 void printRobojax( boolean doPrint)
 {
  if (doPrint){
   lcd.clear();// clear previous values from screen  
   lcd.setCursor (0,0); //set to line char 1, line 1
   lcd.print("Robojax  Tutorial"); 

   lcd.setCursor (0,1); //set to line char 1, line 2
   lcd.print("BME390 Demonstration");    

   lcd.setCursor (0,0); //set to line char 1, line 1
   lcd.print("Robojax  Tutorial"); 

   lcd.setCursor (0,2); //set to line char 1, line 3
   lcd.print("Dispaly on LCD2004");  

   lcd.setCursor (0,3); //set to line char 1, line 4
   lcd.print("www.ROBOJAX.com");
   delay(4000);     
  }     
 }

Resursi i reference

Datoteke📁

Tehnički list (pdf)