Quelle:
http://www.forum-raspberrypi.de/Thread-tutorial-standorthoehe-temperatur-und-luftdruck-mit-einem-bmp085-modul-am-rpi
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
$ 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:
$ 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.