Good to Know Database

Raspbian Wheezy: BMP085 Digital Pressure Sensor am Raspberry Pi ansteuern


Der BMP085 Digital Pressure Sensor wird zur Messung des Luftdrucks verwendet und hat einen Messbereich von 300hPa bis 1100hPa. Neben dem Luftdruck kann mit dem Sensor auch die Umgebungstemperatur gemessen werden. Anhand des Luftdrucks kann mit der internationalen Höhenformel annähernd die Höhe über dem Meeresspiegel (NN) errechnet werden. Da der Luftdrucksensor mit einem I²C-Interface ausgestattet ist und mit einer Versorgungsspannung von 1,8V bis 3,6V betrieben wird, eignet er sich auch für den Betrieb am Raspberry Pi.

Wenn Sie bei eBay nach einem BMP085 Sensor suchen, erhalten Sie eine Liste mit vielen Angeboten aus China und Hongkong. Da die meisten Händler keine Versandkosten berechnen, können Sie einen BMP085 Digital Pressure Sensor mit der nötigen externen Beschaltung bereits als komplettes Modul für ein paar Euro erwerben. Nachteilig sind allerdings die langen Lieferzeiten welche in der Regel zwischen zwei und sechs Wochen liegen.

Die folgende Anleitung beschreibt wie Sie den BMP085 Digital Pressure Sensor an Ihren Raspberry Pi anschließen und in Betrieb nehmen. Des Weiteren wird ein Python Skript gezeigt mit welchem Sie die Temperatur und den Luftdruck messen und die Standorthöhe über NN errechnen können. Als Grundlage wurde hier das Raspbian Image vom 20.12.2013 (2013-12-20-wheezy-raspbian.zip) verwendet.

BMP085 Luftdrucksensor mit dem Raspberry Pi verbinden

Die folgenden Fotos zeigen den Luftdrucksensor BMP085 auf einer kleinen Platine mit der externen Beschaltung. Wie Sie sehen besitzt das Modul sechs Anschlüsse. Für den Betrieb am Raspberry Pi werden hiervon nur vier verwendet. Die Versorgungsspannung von 3,3V wird an den mit VCC gekennzeichneten Pin und die Masse an GND angeschlossen. Der I²C-Bus vom Raspberry Pi wird mit den Pins SDA und SCL verbunden. Auf den XCLS Pin ist der Master Clear Input (XCLR) vom BMP085 herausgeführt und der EOC Pin ist der gleichnamige Ausgang des BMP085 Sensors. Beide Anschlüsse müssen nicht beschalten werden.

BMP085 Digital Pressure Sensor - Vorderansicht  BMP085 Digital Pressure Sensor - Rückansicht

Wie bereits beschrieben sollten Sie das hier gezeigte Modul wie folgt mit Ihrem Raspberry Pi verbinden.

BMP085 Digital Pressure Sensor - Schaltplan

Weitere Informationen zum BMP085 und hilfreiche Informationen für die Programmierung finden Sie im dazugehörigen Datenblatt.

I²C-Bus des Raspberry Pi's aktivieren

Bevor Sie den I²C-Bus des Raspberry Pi's unter Raspbian verwenden können, müssen Sie diesen aktivieren. Wie dies durchgeführt wird können Sie in der Anleitung Raspbian Wheezy: I²C-Unterstützung aktivieren nachlesen.

Adresse am I²C-Bus herausfinden

Damit Sie den BMP085 Digital Pressure Sensor ansprechen können, benötigen Sie die I²C Slave Adresse des Sensors. Diese können Sie wie breits in der Anleitung Raspbian Wheezy: Teilnehmer am I²C-Bus identifizieren beschrieben mit dem Befehl i2cdetect herausfinden. Wie Sie der folgenden Ausgabe entnehmen können, besitzt in diesem Fall der BMP085 Sensor die Adresse 0x77.

pi@raspberrypi ~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77

Benötigte Python Module installieren

Als zusätzliches Python Modul wird das Paket python-smbus benötigt. Dieses enthält die Funktionalitäten für den Zugriff auf den System Management Bus (SMBus) und kann wie folgt installiert werden.

pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get install python-smbus

Messwert mit einem Python Skript abfragen

Wie bereits eingangs erwähnt, soll hier für die Messung ein Python Skript verwendet werden. Erstellen Sie daher eine neue Datei mit einem Editor.

pi@raspberrypi ~ $ vi bmp085.py

Das folgende Listing zeigt das Python Skript welches Sie in die Datei einfügen können. Wenn es notwendig sein sollte, ändern Sie die Werte der Variablen i2c_bus und i2c_addr. Die einzelnen Funktionen im Skript denke ich sollten durch die Kommentare ausreichend erläutert sein.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# Creation:    02.01.2014
# Last Update: 07.04.2015
#
# Copyright (c) 2014-2015 by Georg Kainzbauer <http://www.gtkdb.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#

# import required modules
import smbus
import time
import sys

# define I2C bus
# 0: Raspberry Pi Model B Rev 1.0
# 1: Raspberry Pi Model B Rev 2.0
i2c_bus = 1

# define I2C address of BMP085 sensor
# 0x77: typically default address
i2c_addr = 0x77


# BMP085 class
class BMP085():
  # initialize BMP085 sensor
  def __init__(self, i2c, address):
    self.i2c = i2c
    self.address = address

    # set operating mode
    # 0: ultra low power mode
    # 1: standard mode
    # 2: high resolution mode
    # 3: ultra high resolution mode
    self.mode = 3

    # Read the calibration data
    self.readCalibrationData()


  # read calibration data from BMP085 sensor
  def readCalibrationData(self):
    self.ac1 = self.readSignedWord(0xAA)
    self.ac2 = self.readSignedWord(0xAC)
    self.ac3 = self.readSignedWord(0xAE)
    self.ac4 = self.readWord(0xB0)
    self.ac5 = self.readWord(0xB2)
    self.ac6 = self.readWord(0xB4)
    self.b1 = self.readSignedWord(0xB6)
    self.b2 = self.readSignedWord(0xB8)
    self.mb = self.readSignedWord(0xBA)
    self.mc = self.readSignedWord(0xBC)
    self.md = self.readSignedWord(0xBE)


  # read word from specified register
  def readWord(self, reg):
    # read most significant byte
    msb = self.i2c.read_byte_data(self.address, reg)

    # read least significant byte
    lsb = self.i2c.read_byte_data(self.address, reg+1)

    # return calculated value
    value = (msb << 8 ) + lsb
    return value


  # read signed word from specified register
  def readSignedWord(self, reg):
    # read most significant byte
    msb = self.i2c.read_byte_data(self.address, reg)

    # read least significant byte
    lsb = self.i2c.read_byte_data(self.address, reg+1)

    # return calculated value
    if (msb > 127):
      msb = msb - 256
    value = (msb << 8 ) + lsb
    return value


  # read uncompensated temperature value
  def readRawTemperature(self):
    # write 0x2E into register 0xF4 to request temperature reading
    self.i2c.write_byte_data(self.address, 0xF4, 0x2E)

    # wait 5ms
    time.sleep(0.005)

    # read two byte result from address 0xF6
    value = self.readWord(0xF6)

    # return uncompensated temperature value
    return value


  # read uncompensated pressure value
  def readRawPreassure(self):
    # write 0x34+(BMP085_OVERSAMPLING_SETTING<<6) into register 0xF4 to request pressure reading with oversampling setting
    self.i2c.write_byte_data(self.address, 0xF4, 0x34 + (self.mode << 6))

    # wait for conversion, delay time depends on oversampling setting
    delay = (2 + (3 << self.mode)) / 1000.0
    time.sleep(delay)

    # read three byte result from address 0xF6 (0xF6 = MSB, 0xF7 = LSB, 0xF8 = XLSB)
    msb = self.i2c.read_byte_data(self.address, 0xF6)
    lsb = self.i2c.read_byte_data(self.address, 0xF7)
    xlsb = self.i2c.read_byte_data(self.address, 0xF8)

    # calculate uncompensated pressure value
    value = ((msb << 16) + (lsb << 8 ) + xlsb) >> (8 - self.mode)

    # return uncompensated pressure value
    return value


  # read compensated temperature value in degrees celcius
  def readTemperature(self):
    # read uncompensated temperature value
    ut = self.readRawTemperature()

    # calculate and return compensated temperature value
    x1 = ((ut - self.ac6) * self.ac5) >> 15
    x2 = (self.mc << 11) / (x1 + self.md)
    b5 = x1 + x2
    value = ((b5 + 8 ) >> 4) / 10.0
    return value


  # read compensated pressure value in pascal
  def readPressure(self):
    # read uncompensated temperature value
    ut = self.readRawTemperature()

    # read uncompensated pressure value
    up = self.readRawPreassure()

    # calculate compensated temperature value
    x1 = ((ut - self.ac6) * self.ac5) >> 15
    x2 = (self.mc << 11) / (x1 + self.md)
    b5 = x1 + x2

    # calculate and return compensated pressure value
    b6 = b5 - 4000
    x1 = (self.b2 * (b6 * b6) >> 12) >> 11
    x2 = (self.ac2 * b6) >> 11
    x3 = x1 + x2
    b3 = (((self.ac1 * 4 + x3) << self.mode) + 2) / 4

    x1 = (self.ac3 * b6) >> 13
    x2 = (self.b1 * ((b6 * b6) >> 12)) >> 16
    x3 = ((x1 + x2) + 2) >> 2
    b4 = (self.ac4 * (x3 + 32768)) >> 15
    b7 = (up - b3) * (50000 >> self.mode)

    if (b7 < 0x80000000):
      p = (b7 * 2) / b4
    else:
      p = (b7 / b4) *2

    x1 = (p >> 8) * (p >> 8)
    x1 = (x1 * 3038) >> 16
    x2 = (-7357 * p) >> 16

    value = p + ((x1 + x2 + 3791) >> 4)
    return value


  # read altitude in meters
  def readAltitude(self, seaLevelPressure=101325):
    # read compensated pressure value
    pressure = float(self.readPressure())

    # calculate and return altitude value
    altitude = 44330.0 * (1.0 - pow(pressure / seaLevelPressure, 0.1903))
    return altitude


# function to read and print temperature
def temperature(bmp085):
  # read temperature from BMP085 sensor
  temperature = bmp085.readTemperature()

  # print result to standard output
  print("Temperature:\t%.2f °C" % temperature)


# function to read and print pressure
def pressure(bmp085):
  # read pressure from BMP085 sensor
  pressure = bmp085.readPressure()

  # print result to standard output
  print("Pressure:\t%.2f hPa" % (pressure / 100))


# function to read and print altitude
def altitude(bmp085):
  # read pressure from BMP085 sensor and calculate altitude
  altitude = bmp085.readAltitude(101325)

  # print result to standard output
  print("Altitude:\t%.2f m" % altitude)


# main function
def main():
  # init I2C bus
  i2c = smbus.SMBus(i2c_bus)

  # init BMP085 sensor
  bmp085 = BMP085(i2c, i2c_addr)

  # read and print temperature
  temperature(bmp085)

  # read and print pressure
  pressure(bmp085)

  # read and print pressure
  altitude(bmp085)

  # quit python script
  sys.exit(0)


if __name__ == '__main__':
  main()

Nachdem Sie das Python Skript erstellt haben, ändern Sie die Rechte der Datei damit diese ausführbar wird.

pi@raspberrypi ~ $ chmod 0755 bmp085.py

Jetzt können Sie das Python Skript wie folgt aufrufen.

pi@raspberrypi ~ $ sudo ./bmp085.py
Temperature:    26.40 °C
Pressure:       970.00 hPa
Altitude:       360.96 m


Dieser Eintrag wurde am 02.01.2014 erstellt und zuletzt am 18.02.2017 bearbeitet.

Direkter Link zu dieser Seite: http://www.gtkdb.de/index_36_2473.html

[ Zur Startseite ]   [ Zur Kategorie ]


Valid XHTML 1.0 Transitional Valid CSS Valid Atom 1.0

© 2004-2018 by Georg Kainzbauer