Standorthöhe, Temperatur und Luftdruck mit einem BMP085-Modul am RPi

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo zusammen,

    diesmal möchte ich Euch zeigen, wie man ein BMP085-Sensor-Modul am Raspberry Pi verwenden kann.

    Allgemeines:

    Der BMP085 ist ein Sensor von Bosch für Luftdruck und Temperatur und verfügt über eine I2C-Schnittstelle.
    Durch seine geringe Stromaufnahme und einer Betriebsspannung zwischen 1,8 und 3,6 Volt kann er direkt an den GPIOs des RPi angeschlossen werden.

    Näheres zum Sensor findet ihr im Datenblatt.

    Meiner Beobachtung nach sind derzeit zwei Varianten des Moduls im Umlauf. Eine, die ich verwende und auf das sich dieses Tutorial bezieht, bekommt ihr für kleines Geld beim Chinesen eurer Wahl ( z.B. hier )

    Außerdem bieten verschiedene deutsche Anbieter auf diversen Versteigerungsplattformen das Modul ebenfalls an. Es liegt dann preislich etwas höher als die asiatische Variante, hat aber bedeutend kürzere Lieferzeiten.

    Und dann gibt es eben noch eine zweite Version, die ich bisher nur bei saintsmart entdeckt habe.

    Der Unterschied scheint lediglich ein zusätzlicher Pin beim saintsmart-Modell zu sein und ein zusätzlicher Jumper, der sich wohl auf die Versorgungsspannung und evtl. den I2C-Bus bezieht.
    Ich habe ein solches Modul leider nicht zur Hand, und kann deshalb über die saintsmart-Variante keine fundierten Aussagen machen.
    Ich gehe aber mal davon aus, dass die Unterschiede nicht gravierend sind.

    Die Ansteuerung dieses Moduls ist Bestandteil der Adafruit Unified Sensor Library. Das hat mir sehr geholfen, weil ich in eine I2C-Falle getappt war und deshalb die Berechnungen anfangs absolut nicht stimmten.
    Diese Library ist sehr umfangreich und sehr gut beschrieben. Neben C werden wohl auch script-Sprachen unterstützt.
    Für einen einigermassen versierten script-Programmierer dürfte es kein Problem sein, durch kleinere Anpassungen diesen Sensor auch von einer script-Sprache aus anzusprechen.

    Nähere Infos dazu hier und hier.


    Anschluss und Spannungsversorgung:

    Das Modul hat sechs Anschluss-Pins: Vcc, SDA, SCL, XCLR, EOC und Gnd.
    Für meinen Test habe ich die Pins folgendermaßen über ein Breadboard verdrahtet:
    Vcc des Moduls mit Pin #1 der GPIOs
    SDA des Moduls mit Pin #3 (GPIO2, SDA) der GPIOs
    SCL des Moduls mit Pin #5 (GPIO3, SCL) der GPIOs
    XCLR des Moduls mit Pin #11 (GPIO17) der GPIOs
    EOC des Moduls mit Pin #15 (GPIO22) der GPIOs
    Gnd des Moduls mit Pin #9 der GPIOs

    Die Pins EOC und XCLR des Moduls müssen nicht angeschlossen werden und dürfen einfach offen bleiben.
    Nach Anschluss wird der Sensor mit

    Code
    $ sudo i2cdetect -y 1


    auf Adresse 0x77 angezeigt.


    Funktionsweise des Moduls:

    Zum Initialisieren des Sensors werden zunächst die Kalibrierungswerte des Sonsors gelesen. Diese Werte dürfen weder 0 noch -1 sein und dienen zur korrekten Berechnung von Luftdruck und Temperatur. Lt. Bosch hat jeder Sensor eigens für ihn eingestellte Kalibrierungsdaten.
    Anschliessend wird der entsprechende Befehl (messe Temperatur oder messe Luftdruck) in das Kommando-Register geschrieben um einen Messvorgang zu starten.
    Nach Abschluss der Messung können die entsprechenden Werte aus dem Datenregister des Sensors gelesen werden.
    Der Messvorgang kann in vier verschiedenen Modi ausgeführt werden: „ultra low power“, „standard“, „high resolution“ und „ultra high resolution“. Dabei werden intern 1, 2, 4 bzw. 8 Messungen durchgeführt. Die Messung dauert, abhängig vom Modus, dann max. zwischen 4,5 und 25,5 ms.
    Laut Datenblatt sind bis zu 128 Messzyklen im Modus „standard“ pro Sekunde möglich.
    Die vier Bit des Modus werden mit dem Befehls-Code kombiniert in das Kommando-Register geschrieben.
    Das Ende des Messvorgangs wird über einen HIGH-Level des Pins EOC (End Of Conversion) signalisiert.

    Durch einen mindestens 1 µs dauernden HIGH-Level auf dem Pin XCLR wird im Sensor ein Reset ausgelöst.

    Die beiden letztgenannten Pins dürfen allerdings lt. Datenblatt auch unbeschaltet (offen) bleiben.
    Doch dazu später noch was.


    Die Software:

    Nach einem ersten Test musste ich feststellen, dass aus meiner Sicht die wiringPi-Bibliothek hier leider nicht geeignet war.

    Mit der pigpio API funktionierte alles auf Anhieb so, wie ich mir das vorstellt habe.
    Die pigpio-Library erhaltet ihr hier und auf der Homepage des Autors von pigpio findet ihr weitere Informationen zur Library und die Beschreibung der APIs für verschiedene Sprachen.

    Bitte beachten: zum Übersetzen des Programms muss ausserdem das paket libi2c-dev installiert sein.

    Das hier als Anhang verfügbare Testprogramm ist ein einfaches C-Programm mit einigen Aufrufparametern.
    Übersetzt werden kann es mit:

    Code
    $ gcc -o bmp085 bmp085.c -I /usr/local/include -L/usr/local/lib -lpigpio -lpthread -lrt -lm

    Beim anschliessenden Aufruf von ./bmp085 stehen folgende Aufrufparameter zur Verfügung:
    -g n oder -–gpio n (--gpio=n)
    Das Programm wird im „IRQ-Modus“ gestartet. Standard ist „Wait-Modus“.

    -o x oder -–oss x (--oss=x)
    Setzen des Messmodus (Oversample-Settings). Standard ist „ultra low power“.

    -d oder –dryrun
    Testlauf

    -r oder –-reset
    Sensor reset ausführen. Hier muss zusätzlich ein GPIO mit -g angegeben werden.

    -? oder –help
    Erklärung der Aufrufoptionen

    Achtung! Aufgrund der Zugriffsbeschränkungen auf den I2C-Bus muss das Programm mit sudo aufgerufen werden (sudo ./bmp085 …).
    Das kann durch editieren der sudoers oder setzen des S-Bit umgangen werde, falls nötig. Näheres dazu bitte in den zugehörigen man-pages nachlesen.


    „IRQ-“ und „Wait-“ Modus:


    Standardmässig – also ohne den Paramter -g - wird das Programm im „Wait-Modus“ ausgeführt. Das bedeutet, dass es, abhängig vom Messmodus, eine gewisse Anzahl von ms nach Starten des Messzyklus wartet, und dann die Messdaten abholt.
    Diese Methode ist in diesem Fall vorzuziehen, da das Initialisieren des Programms und der Bibliotheken im „IRQ-Modus“ länger dauert, als der eigentliche Messvorgang.
    Auch Adafruit und Bosch warten in ihrer Software eine gewisse Zeit und holen sich anschliessend die Ergebnisse vom Sensor.
    Der zweite Vorteil des „Wait-Modus“ ist, dass der Sensor Pin EOC nicht angeschlossen werden muss (spart einen GPIO).
    Wer trotzdem mal den „IRQ-Modus“ ausprobieren will muss EOC verdrahten und als Argument der –gpio Option den entsprechenden GPIO angeben. Möglich sind die GPIOs 2, 3, 4, 17, 27, 22, 10, 9, 11, 14, 15, 18, 23, 24, 25, 8, 7 bzw. Pin-Nummern 3, 5, 7,11, 13, 15, 19, 21, 23, 8, 10, 12, 16, 18, 22, 24, 26.


    Messmethode:

    Der Mess-Modus kann über die Option –oss eingestellt werden. Gültige Werte sind hier Null bis drei. Als Standard-Wert wird 0 „ultra low power“ für einen Messzyklus angenommen. Näheres dazu steht im Datenblatt des Sensors.


    Sonstiges:

    Mit der Option -d bzw. --dryrun wird ein Testlauf durchgeführt, der keinerlei Zugriffe auf den I2C-Bus durchführt. Die Daten werden simuliert, indem in diesem Modus die Beispiel-Angaben aus dem Datenblatt verwendet werden.

    Einen Chip-Reset kann man durch Angabe der -–reset Option durchführen. Allerdings erschliesst mir der Sinn aus Sicht einer Anwendung hier nicht. Zudem muss der XCLR-Eingang des Sensors an einen der GPIOs angeschlossen werden. Dieser GPIO muss beim Aufruf mit angegeben werden ( also -–reset –-gpio=n).


    Programm-Ablauf:

    Das Programm intialisiert im „IRQ-Modus“ zunächst die pigpio-Bibliothek und setzt einen Interrupt-Handler auf einen Wechsel der Flanke des angegebenen GPIOs.
    Anschliessen werden, unabhängig vom Modus, die Kalibrierungsdaten gelesen, ein „Lese-Temperatur“-Kommando an den Sensor geschickt und nach einer kurzen Wartezeit die Werte aus dem Datenregister ausgelesen.
    Als nächsten wird der Sensor aufgefordert, eine Messung des Luftdrucks durchzuführen. Abhängig von der Messmethode „--oss“ wird im „Wait-Modus“ nun die maximale Messdauer laut Datenblatt gewartet, während im „IRQ-Modus“ so lange gewartet wird, bis der EOC-Pin des Sensors auf HIGH-Level wechselt.
    Dann werden, wieder unabhängig vom Programm-Modus aus diesen Daten die aktuelle Temperatur, der aktuelle, relative Luftdruck und die Standort-Höhe über NN berechnet und auf den Bildschirm ausgegeben.
    Achtung: der relative Luftdruck und die Standort-Höhe benötigen die Temperatur-Daten. Deshalb muss immer vor der Berechnung des Luftdrucks eine Temperaturmessung vorgenommen werden.

    Mittels der barometrischen Höhenformel könnte auch der absolute Luftdruck berechnet werden.
    Das habe ich mir aber geschenkt, weil ich den Luftdruck auf NN nur als Konstante zur Verfügung habe.


    Ich hoffe, ich habe jetzt nichts vergessen.
    Allerdings möchte ich nochmals darauf hinweisen, dass ich einige Code-Snippets von Adafruit verwendet habe, die unter BSD-Lizenz veröffentlicht sind.
    Sollte also jemand planen, meine Sourcen zu verwenden, so kann er das gerne tun, solange er damit nicht Adafruit auf die Füsse tritt (BSD-Lizenz).

    -ds


    Wer Rechtschreibfehler findet, darf sie gerne behalten, verschenken oder versteigern und wer Probleme oder Fragen zum Programm hat darf sich, wie immer, gerne melden.

  • Standorthöhe, Temperatur und Luftdruck mit einem BMP085-Modul am RPi? Schau mal ob du hier fündig wirst!

  • Vielen Dank, dass Du deinen Quelltext zur Verfügung gestellt hast! Nach dem ich einige abhängige Pakete installiert hab, läuft alles wie es soll. :)

    Ich versuche mich grad daran aus den Luftdruck-Werten Wettervorhersagen zu generieren. :D Bisher logge ich aber nur den Verlauf (wen interessiert wie das bisher aussieht drückt einfach hier).

    Vielen Dank noch mal! :)

    Einmal editiert, zuletzt von Chris1705 (12. August 2013 um 18:56)

  • Hallo Forum,
    bin neu hier und fand den Beitrag sehr interessant und die Beschreibung prima.
    Habe es dann auch gleich mal probieren wollen, bekomme aber folgende Mitteilung:

    bmp085.c:814:6: warning: conflicting types for ‘display_usage’ [enabled by default]
    bmp085.c:794:5: note: previous implicit declaration of ‘display_usage’ was here
    /tmp/ccYi37u0.o: In function `bmp085_read_value':
    bmp085.c:(.text+0x794): undefined reference to `i2c_smbus_read_word_data'
    bmp085.c:(.text+0x7bc): undefined reference to `i2c_smbus_read_byte_data'
    /tmp/ccYi37u0.o: In function `bmp085_write_value':
    bmp085.c:(.text+0x808): undefined reference to `i2c_smbus_write_byte_data'
    collect2: ld returned 1 exit status

    Kann mir jemand einen Tipp geben ?

    Gruß, ATMega8

  • Hallo Chris1705,
    danke, das hat gefehlt.
    Jetzt gibt es nur noch die Warnung:
    bmp085.c:814:6: warning: conflicting types for ‘display_usage’ [enabled by default]
    bmp085.c:794:5: note: previous implicit declaration of ‘display_usage’ was here

    Es wurde aber eine ausführbare Datei erzeugt.
    Danke.

  • Habe dazu mal eine Frage. Wie habt ihr denn den Sensor nach draußen bekommen? Oder muss ich den nicht draußen platzieren?
    Bei den 1Wire Sensoren gibt es ja sogar extra welche für den Außenbereich.

    [font="Verdana, sans-serif"]Würde nämlich gerne den Luftdruck von meinem Ort erhalten. Man kann natürlich auch die Werte von einer Wetterseite auslesen lassen. Oder jemand andere Ideen?[/font]

    Einmal editiert, zuletzt von chb1 (25. September 2013 um 11:57)


  • Habe dazu mal eine Frage. Wie habt ihr denn den Sensor nach draußen bekommen? Oder muss ich den nicht draußen platzieren?

    Du brauchst den Sensor für den Luftdruck nicht draußen platzieren. Der Luftdruck bei Dir zu Hause, sollte genau so sein wie draußen :).

    Lediglich für die Temperatur müsstest Du einen Sensor im Außenbereich platzieren. Ich habe einfach einen 1-Wire Temperatur-Sensor in einem Schrumpfschlauch eingeschlossen. Alternativ kann man sich — wie du auch schon sagtest — einen fertigen besorgen. :)

    Gruß
    Christian


  • Gibt es eine Möglichkeit den Sensor anders an zu schließen? Speziell meine ich damit Pin 11 (GPIO 17) der bei mir schon belegt ist.

    Moin agent,

    klar,


    Zitat


    XCLR des Moduls mit Pin #11 (GPIO17) der GPIOs
    EOC des Moduls mit Pin #15 (GPIO22) der GPIOs
    ...
    Die Pins EOC und XCLR des Moduls müssen nicht angeschlossen werden und dürfen einfach offen bleiben.

    Nur für SDA und SCL wüsste ich jetzt keine Alternative, von der ich behaupten kann, dass sie funktioniert.

    Notfalls das C-Programm ändern und gut ist ...

    cheers,
    -ds-

  • Hi,

    also Werte fehlen Dir keine (ist ja IIC) - EOC ist ein Pin, der einen Interrupt liefert, wenn die Messung abgeschlossen ist (Du kannst dann halt nur den Wait-Modus verwenden - ist aber erfahrungsgemäss besser) und Du kannst dem Chip keinen Reset schicken (wobei ich jetzt gar nicht sagen kann, ob und welche Auswirkungen der hätte - ich konnte da nichts feststellen).

    cheers,
    -ds-

  • Hallo, guten abend,

    mein Name ist Karsten, 45, ich bin neu hier im Forum. Seit einigen Tagen experimentiere ich mit dem Raspberry und diversen Sensoren. Nun habe ich hierher ins Forum gefunden.... :)

    Mein Interesse besteht momentan darin, wie ich die Daten vom BMP085 auf mein 16x2 Display bekomme. Da ich aber nun mit Python und der ganzen Materie um den Raspberry Pi neu bin, (ausser als Mediaplayer - das geht schon ganz gut) würde ich mich über jegliche Unterstützung freuen.

    Ich habe schon beim "Adafruit Learning System" das 16x2 schon zum Anzeigen der IP meines Wlan gebracht, auch zeigt der BMP085 Luftdruck und Temperatur am Monitor an.

    Nun möchte ich aber, dass die Daten auf dem Display angezeigt werden. Hab schon mit den Codes herumexperimentiert, klappt aber nicht. :helpnew: Kann mir da evtl. jemand von euch helfen?

    Viele Grüße
    Karsten

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!