Der BMP085 Sensor wird von Bosch Sensortec nicht mehr hergestellt, dafür gibt es jetzt den neuen BMP180. Er ist deutlich kleiner geworden. Die technischen Daten sind aber größtenteils gleich. Ich habe nur Zusatzinformation im neuen Datenblatt gefunden die sich auf die relative Luftdruckmessung bezieht, die war im BMP085 Datenblatt nicht enthalten.
Der Grössenvergleich.
Der Aufbau
Ich verwende hier folgende Anschlüsse:
Arduino > BMP180 Platine
3,3V > VCC
GND > GND
A5 > SCL
A4 > SDA
Der absolute Luftdruck wird mit einem max. Fehler -4 bis +2 hPa (typisch -1 hPa) gemessen, was einem Höhenunterschied von ca. 8m entspricht.
Der relative Luftdruck wird mit einem Fehler von +-0,12 hPa angegeben, was einem Höhenunterschied von ca. 1 m entspricht. Relative Messungen beziehen sich immer auf die vorherigen Messungen. Wenn der Luftdruck einmal abgeglichen ist, z.B. mit einer lokalen Wetterstation, ist die Höhenmessung mit 1m Genauigkeit möglich.
Die Software
Die Software kann 1:1 vom BMP085 übernommen werden. Ich habe nur die Namen der Funktionen geändert. Ansonsten ist alles gleich und läuft auf Anhieb.
// BMP180 Luftdruck und Temperatur Sensor // // Matthias Busse 20.6.2014 Version 1.0 #include < Wire.h> // Einstellungen für den BMP180 #define I2C_ADDRESS 0x77 const unsigned char oversampling_setting = 3; //oversamplig: 0 ungenau (13ms) ... 3 genau (34ms) const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 }; int ac1, ac2, ac3, b1, b2, mb, mc, md; unsigned int ac4, ac5, ac6; int temp = 20, temp_mittel=200; long druck = 1013, druck_mittel=101300; float temp_offset=0.0, druck_offset=1.0; // Korrekturwerte int mitteln=5; void setup() { Serial.begin(38400); Serial.println("BMP180 Temperatur und Luftdruck auslesen."); Wire.begin(); bmp180_get_cal_data(); bmp180_read_temperature_and_pressure(&temp_mittel,&druck_mittel); // erstmal Mittelwerte lesen } void loop() { bmp180_read_temperature_and_pressure(&temp, &druck); // dauert ca. 34ms temp_mittel = ((temp_mittel * (mitteln-1)) + temp) / mitteln; druck_mittel = ((druck_mittel * (mitteln-1)) + druck) / mitteln; Serial.print("Temp.: "); Serial.print(((float)temp_mittel/10.0)+temp_offset, 1); Serial.print(" Druck: "); Serial.println(((float)druck_mittel/100.0)+druck_offset, 2); // delay(1000); // ms } void bmp180_read_temperature_and_pressure(int* temp, long* druck) { int ut= bmp180_read_ut(); long up = bmp180_read_up(); long x1, x2, x3, b3, b5, b6, p; unsigned long b4, b7; x1 = ((long)ut - ac6) * ac5 >> 15; //Temperatur berechnen x2 = ((long) mc << 11) / (x1 + md); b5 = x1 + x2; *temp = (b5 + 8) >> 4; b6 = b5 - 4000; //Druck berechnen x1 = (b2 * (b6 * b6 >> 12)) >> 11; x2 = ac2 * b6 >> 11; x3 = x1 + x2; if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) << 1; if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2); if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 1; if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) >> 2; x1 = ac3 * b6 >> 13; x2 = (b1 * (b6 * b6 >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15; b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting); p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2; x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; *druck = p + ((x1 + x2 + 3791) >> 4); } unsigned int bmp180_read_ut() { write_register(0xf4,0x2e); delay(5); //mehr als 4.5 ms return read_int_register(0xf6); } void bmp180_get_cal_data() { ac1 = read_int_register(0xAA); ac2 = read_int_register(0xAC); ac3 = read_int_register(0xAE); ac4 = read_int_register(0xB0); ac5 = read_int_register(0xB2); ac6 = read_int_register(0xB4); b1 = read_int_register(0xB6); b2 = read_int_register(0xB8); mb = read_int_register(0xBA); mc = read_int_register(0xBC); md = read_int_register(0xBE); } long bmp180_read_up() { write_register(0xf4,0x34+(oversampling_setting<<6)); delay(pressure_waittime[oversampling_setting]); unsigned char msb, lsb, xlsb; Wire.beginTransmission(I2C_ADDRESS); Wire.write(0xf6); Wire.endTransmission(); Wire.requestFrom(I2C_ADDRESS, 3); while(!Wire.available()) {} // warten msb = Wire.read(); while(!Wire.available()) {} // warten lsb |= Wire.read(); while(!Wire.available()) {} // warten xlsb |= Wire.read(); return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting); } void write_register(unsigned char r, unsigned char v) { Wire.beginTransmission(I2C_ADDRESS); Wire.write(r); Wire.write(v); Wire.endTransmission(); } char read_register(unsigned char r) { unsigned char v; Wire.beginTransmission(I2C_ADDRESS); Wire.write(r); Wire.endTransmission(); Wire.requestFrom(I2C_ADDRESS, 1); while(!Wire.available()) {} // warten v = Wire.read(); return v; } int read_int_register(unsigned char r) { unsigned char msb, lsb; Wire.beginTransmission(I2C_ADDRESS); Wire.write(r); Wire.endTransmission(); Wire.requestFrom(I2C_ADDRESS, 2); while(!Wire.available()) {} // warten msb = Wire.read(); while(!Wire.available()) {} // warten lsb = Wire.read(); return (((int)msb<<8) | ((int)lsb)); }
Die Ausgabe
Vorherige Beiträge:
– Luftdruck und Temperatur als NMEA 0183 Datensatz ausgeben
– Der Luftdruck und Temperatur Sensor BMP085 am Arduino Uno.
von Matthias Busse
Pingback: Barometer Display mit 1h / 3h Differenz und Temperatur Ausgabe. Mit dem 5110 Display, BMP-180, Uno | Shelvin – Elektronik ausprobiert und erläutert
Pingback: Grafische PC Ausgabe der Arduino Daten mit Processing | Shelvin – Elektronik ausprobiert und erläutert
in der Funktion „bmp180_read_temperature_and_pressure“ ist ein kleiner Fehler.
Bei Temperaturen >34°C wird die Temp negativ. Und die Berechnung des Drucks ist dann falsch.
Als Behebung kann der Datentyp der Variablen „ut“ von int auf long geändert werden:
<> long ut= bmp180_read_ut();
Vielen Dank für den tollen Bericht. Es hat alles gut funktioniert, aber es ist etwas kompliziert. Diese Anleitung ist auch nicht so schlecht: http://www.aeq-web.com/bmp085-180-arduino/?ref=ws
Hallo,
super was Sie da machen mit dem Arduino.
Frage: Für ein eigenes Projekt möchte ich einen BME280 einsetzen.
Liegt da evtl. ein passender Sketch in der Schublade?
Schönen Tag wünscht Wilhelm Freitag