Czujniki cisnienia i temperatury BMP085 / BMP180
ID: 33
Kategorie: Module
Menge: 0
Position:

BMP085 i BMP180 to dwa zgodne elektrycznie czujniki ciÅ›nienia atmosferycznego i temperatury firmy Bosch.

CharakteryzujÄ… siÄ™ pomiarem ciÅ›nienia w zakresie od 300 do 1100 hPa, co daje nam możliwość okreÅ›lenia wysokoÅ›ci od +9000 do -500 metrów wzglÄ™dem poziomu morza. GÅ‚ównymi różnicami jakie wystÄ™pujÄ… pomiÄ™dzy BMP085 a BMP180 to rozmiar oraz dokÅ‚adność pomiaru w trybie wysokiej rozdzielczoÅ›ci pomiaru, w którym przewagÄ™ ma nowszy model oznaczony BMP180.

 

  BMP085 BMP180
Zakres mierzonego ciśnienia 300 - 1100 hPa
Napięcie zasilania 1.8 - 3.6 V
Pobór prÄ…du 5 µA / pomiar
Rozmiar 5.0 mm  x 5.0 mm 3.6 mm x 3.8 mm
Wysokość 1.2 mm 0.93 mm
Dokładność (tryb niskiego poboru energii) 0.06 hPa (0.5m)
Dokładność (tryb wysokiej rozdzielczości) 0.03 hPa (0.25m) 0.02 hPa (0.17m)
Temperatura pracy -40 to +85°C

PeÅ‚na karta katalogowa BMP085: http://www.jarzebski.pl/datasheets/BMP085.pdf
PeÅ‚na karta katalogowa BMP180: http://www.jarzebski.pl/datasheets/BMP180.pdf

Obliczanie wysokości na podstawie pomiaru ciśnienia atmosferycznego

ZnajÄ…c ciÅ›nienie jakie panuje na poziomie morza p0 (np.: 1013.25 hPa) oraz pomiar p, możemy okreÅ›lić aktualnÄ… wysokość, wyliczajÄ…c jÄ… z poniższego wzoru.

Zależność pomiÄ™dzy wysokoÅ›ciÄ… a ciÅ›nieniem przedstawia poniższa charakterystyka, z której wynika, że zmiana ciÅ›nienia Δp = 1 hPa odpowiada wysokoÅ›ci Δh = 8.43 m. Natomiast zmiana wysokoÅ›ci Δh = 10 m odpowiada zmianie ciÅ›nienia Δp = 1 2hPa

Połączenie z Arduino

Na rynku istnieje kilka gotowych moduÅ‚ów z czujnikami BMP085 oraz BMP180. RóżniÄ… siÄ™ one przede wszystkim poziomem napiÄ™cia zasilania, które typowo wynosi 3.3V. W przypadku posiadanych przeze mnie moduÅ‚ów IMU GY-80 oraz IMU GY-87 zasilanie może być zarówno 5V jak i 3.3V. JeÅ›li zdecydujemy siÄ™ na zasilanie 5V należy zwrócić szczególnÄ… uwagÄ™ na podÅ‚Ä…czenie do odpowiedniego 5V pinu moduÅ‚u IMU, gdyż podÅ‚Ä…czenie do pinu 3.3V może go uszkodzić.

Pin oznaczony SCL (adapter) podÅ‚Ä…czamy do pinu A5 (Arduino), natomiast pin SDA (adapter) do pinu A4 (Arduino).

Nie zapomnijmy również o masie GND.

Przykładowy program

Na szczęście w przypadku czujników BMP085 i BMP180 możemy posÅ‚użyć siÄ™ gotowÄ… bibliotekÄ… przygotowanÄ… przez Adafruithttps://github.com/adafruit/Adafruit-BMP085-Library (lub mirror BMP085.zip). BibliotekÄ™ należy rozpakować do katalogu  libraries.

  1. #include <Wire.h>
  2. #include <Adafruit_BMP085.h>
  3.  
  4. Adafruit_BMP085 bmp;
  5.  
  6. void setup()
  7. {
  8.   Serial.begin(9600);
  9.  
  10.   // Jako parametr mozemy podav dokladnosc - domyslnie 3
  11.   // 0 - niski pobór energii - najszybszy pomiar
  12.   // 1 - standardowy pomiar
  13.   // 2 - wysoka precyzja
  14.   // 3 - super wysoka precyzja - najwolniejszy pomiar
  15.   if (!bmp.begin())
  16.   {
  17.     Serial.println("Nie odnaleziono czujnika BMP085 / BMP180");
  18.     while (1) {}
  19.   }
  20. }
  21.  
  22. void loop()
  23. {
  24.     // Odczytujemy temperaturÄ™
  25.     Serial.print("Temperatura = ");
  26.     Serial.print(bmp.readTemperature());
  27.     Serial.println(" *C");
  28.      
  29.     // Odczytujemy cisnienie
  30.     Serial.print("Cisnienie = ");
  31.     Serial.print(bmp.readPressure());
  32.     Serial.println(" Pa");
  33.      
  34.  
  35.     // Obliczamy wysokosc dla domyslnego cisnienia przy pozimie morza
  36.     // p0 = 1013.25 millibar = 101325 Pascal
  37.     Serial.print("Wysokosc = ");
  38.     Serial.print(bmp.readAltitude());
  39.     Serial.println(" metrow");
  40.      
  41.     // Jesli znamy aktualne cisnienie przy poziomie morza,
  42.     // mozemy dokladniej wyliczyc wysokosc, padajac je jako parametr
  43.     Serial.print("Rzeczywista wysokosc = ");
  44.     Serial.print(bmp.readAltitude(102520));
  45.     Serial.println(" metrow");
  46.      
  47.     Serial.println();
  48.     delay(500);
  49. }

Wynik działania

Wizualizacja

Spróbujmy jeszze pokazać na wykresie poszczególne parametry za pomocÄ… processingu. W tym przypadku skorzystamy nieco z zmodyfikowanego programu dla Arduino. Wyliczymy również wysokość samodzielnie, ponieważ funkcja readAltitude() ponownie bÄ™dzie odczytywaÅ‚a ciÅ›nienie do wyliczeÅ„, które już mamy.

  1. #include <Wire.h>
  2. #include <Adafruit_BMP085.h>
  3.  
  4. Adafruit_BMP085 bmp;
  5.  
  6. float sealevelPressure;
  7.  
  8. void setup()
  9. {
  10.   Serial.begin(9600);
  11.  
  12.   if (!bmp.begin())
  13.   {
  14.     Serial.println("Nie odnaleziono czujnika BMP085 / BMP180");
  15.     while (1) {}
  16.   }
  17. }
  18.  
  19. void loop()
  20. {
  21.     // Odczytujemy temperature i cisnienie
  22.     float temp = bmp.readTemperature();
  23.     float pressure = bmp.readPressure();
  24.      
  25.     // Sami wyliczamy wysokosc
  26.     sealevelPressure = 101325;
  27.     float altitude = 44330 * (1.0 - pow(pressure / sealevelPressure, 0.1903));
  28.      
  29.     // Wyczucamy dane na port szeregowy
  30.     Serial.print("D:");
  31.     Serial.print(temp);
  32.     Serial.print(":");
  33.     Serial.print(pressure);
  34.     Serial.print(":");
  35.     Serial.print(altitude);
  36.     Serial.println();
  37. }

Program wizualizacyjny:

  1. import processing.serial.*;
  2.  
  3. Serial myPort;
  4.  
  5. boolean hasData = false;
  6.  
  7. int actualSample = 0;
  8. int maxSamples = 300;
  9. int sampleStep = 2;
  10.  
  11. float[] tempValues = new float[maxSamples+1];
  12. int minTemp = 0;
  13. int maxTemp = 0;
  14.  
  15. float[] pressureValues = new float[maxSamples+1];
  16. int minPressure = 0;
  17. int maxPressure = 0;
  18.  
  19. float[] altitudeValues = new float[maxSamples+1];
  20. int minAltitude = 0;
  21. int maxAltitude = 0;
  22.  
  23. void setup ()
  24. {
  25.   size(670, 750);        
  26.   myPort = new Serial(this, Serial.list()[0], 9600);
  27.   myPort.bufferUntil(10);
  28.   background(0);
  29. }
  30.  
  31. void drawChart(String title, float[] data, int minValue, int maxValue, int x, int y, int h, int ls, int fs)
  32. {  
  33.   strokeWeight(1);
  34.   noFill();
  35.   stroke(50,50,50);
  36.   rect(x, y, (maxSamples*sampleStep)+50, h+50);
  37.  
  38.   strokeWeight(1);
  39.   stroke(90,90,90);
  40.  
  41.   for (float t = minValue; t <= maxValue; t = t + ls)
  42.   {
  43.      float line = map(t, minValue, maxValue, 0, h);
  44.      line(x+40, y+h-line+16, x+(maxSamples*sampleStep)+40, y+h-line+16);
  45.      fill(200, 200, 200);
  46.      textSize(fs);
  47.      text(int(t), 5+x, h-line+20+y);
  48.   }
  49.  
  50.   textSize(14);
  51.   String title2 = title + " " + nf(data[actualSample-1], 0, 2);  
  52.   text(title2, ((maxSamples*sampleStep)/2)-(textWidth(title2)/2)+40, h+40+y);
  53.  
  54.   strokeWeight(2);
  55.   stroke(204, 102, 0);
  56.  
  57.   for (int i = 1; i < actualSample; i++)
  58.   {
  59.     float v0 = map(data[i-1], minValue, maxValue, 0, h);
  60.     float v1 = map(data[i], minValue, maxValue, 0, h);
  61.     line(((i-1)*sampleStep)+40+x, h-v0+16+y, (i*sampleStep)+40+x, h-v1+16+y);
  62.   }
  63. }
  64.  
  65. void draw ()
  66. {
  67.   if (!hasData) return;
  68.  
  69.   background(0);
  70.  
  71.   drawChart("Temperatura", tempValues, minTemp, maxTemp, 10, 10, 100, 1, 14);
  72.   drawChart("Cisnienie", pressureValues, minPressure, maxPressure, 10, 200, 200, 50, 10);
  73.   drawChart("Wysokosc", altitudeValues, minAltitude, maxAltitude, 10, 490, 200, 1, 12);
  74. }
  75.  
  76. void nextSample()
  77. {
  78.   if (actualSample == maxSamples)
  79.   {
  80.     float lastTemp = tempValues[maxSamples];
  81.     float lastPressure = pressureValues[maxSamples];
  82.     float lastAltitude = altitudeValues[maxSamples];
  83.       
  84.     for (int i = 1; i <= (maxSamples-1); i++)
  85.     {
  86.       tempValues[i-1] = tempValues[i];
  87.       pressureValues[i-1] = pressureValues[i];
  88.       altitudeValues[i-1] = altitudeValues[i];       
  89.     }
  90.       
  91.     tempValues[(maxSamples-1)] = lastTemp;
  92.     pressureValues[(maxSamples-1)] = lastPressure;
  93.     altitudeValues[(maxSamples-1)] = lastAltitude;
  94.   } else
  95.   {
  96.     actualSample++;
  97.   }  
  98. }
  99.  
  100. void serialEvent (Serial myPort)
  101. {
  102.   String inString = myPort.readStringUntil(10);
  103.  
  104.   if (inString != null)
  105.   {
  106.     inString = trim(inString);
  107.     String[] list = split(inString, ':');
  108.     
  109.     String testString = trim(list[0]);
  110.  
  111.     if (list.length != 4) return;
  112.     
  113.     float temp = float(list[1]);
  114.     float pressure = float(list[2]);
  115.     float altitude = float(list[3]);
  116.  
  117.     if (actualSample == 0)
  118.     {
  119.       for (int i = 0; i <= maxSamples; i++)
  120.       {
  121.         tempValues[i] = temp;
  122.         pressureValues[i] = pressure;
  123.         altitudeValues[i] = altitude;
  124.       }
  125.     }
  126.  
  127.     tempValues[actualSample] = temp;
  128.     pressureValues[actualSample] = pressure;
  129.     altitudeValues[actualSample] = altitude;
  130.  
  131.     maxTemp = floor(max(tempValues))+1;
  132.     minTemp = ceil(min(tempValues))-1;
  133.  
  134.     maxPressure = floor(max(pressureValues))+200;
  135.     minPressure = ceil(min(pressureValues))-200;
  136.     
  137.     maxAltitude = floor(max(altitudeValues))+2;
  138.     minAltitude = ceil(min(altitudeValues))-2;
  139.  
  140.     if (actualSample > 1)
  141.     {
  142.       hasData = true;
  143.     }
  144.  
  145.     nextSample();
  146.   }
  147. }

Wynik działania

O ile pomiar ciÅ›nienia jest w miarÄ™ dokÅ‚adny na potrzeby meteorologiczne, to przeliczona za jego pomocÄ… wysokość może może wahać siÄ™ w zakresie ±1 m. Warto również podkreÅ›lić fakt, że wiÄ™ksza dokÅ‚adoność pomiaru ciÅ›nienia w czujniku BMP180 rozwiÄ…zywana jest programowo, a nie sprzÄ™towo - uÅ›redniany jest 3-krotny pomiar.

Materiały dodatkowe

Biblioteka dla Arduino: http://www.jarzebski.pl/arduino/BMP085/BMP085.zip
PrzykÅ‚ady z powyższego wpisu: http://www.jarzebski.pl/arduino/BMP085/BMPxxx_examples.zip
PeÅ‚na karta katalogowa BMP085: http://www.jarzebski.pl/datasheets/BMP085.pdf
PeÅ‚na karta katalogowa BMP180: http://www.jarzebski.pl/datasheets/BMP180.pdf