Internet und Hostinglösungen
  • Werbung
  • Schlagwörter

Raspberry Pi BMP085 (GY-65) Temper- und Luftdrucksensor

Vorwort


Das GY-65 ist ein Board mit Bosch BMP085 Luftdrucksensor und Temperatursensor.

Hardware

GY-65 Raspberry PiGY-65 Raspberry Pi

GY-65 Raspberry Pi


Trennen Sie Ihren Rasperry Pi am besten vom Stromnetz.
Verbinden Sie nun die Anschlüsse des GY-65 mit dem Rasperry Pi:
VCC	3V3 (3,3 Volt)
SDA SDA (SerialData) I2C
SCL SCL (SerialClock) I2C
GND GND (Ground)
Technische Daten:
Druckbereich:			300 – 1100 hPa (9000 Meter über dem Meeresspiegel bis -500 m)
Versorgungsspannung: 1.8V – 3.6 V (VDDA). 1.62V – 3.6 V (VDDD)
LCC8 Paket: bleifreie keramische Carrier Package (LCC)
Geringe Leistungsaufnahme: 5 μA im Standard-Modus
Hohe Präzision: Low-Power-Modus, die Auflösung von 0.06 hPa (0,5 m)
Hohe linearen Modus: mit einer Auflösung von 0.03 hPa (0,25 m)
Reaktionszeit: 7,5 ms
Standby-Strom: 0.1 μA
Größe: 21 x 15 x 10 mm


Software


Verbinden Sie nun den Rasperry Pi mit dem Stromnetz und verbinden Sie sich am besten mit einem SSH Client um die Befehle kopieren und einfügen zu können.

I2C Schnittstelle


Öffnen Sie die config.txt im /boot Verzeichnis:
nano /boot/config.txt

Fügen Sie sofern nicht vorhanden folgende Zeilen am Ende ein:
# enable i2c interface
dtparam=i2c=on


nano /etc/modules

Fügen Sie die folgende Zeile ein
i2c-dev

Starten Sie den Raspberry Pi neu damit die I2C Schnittstelle aktiviert wird.
reboot


Prüfen Sie on die I2C Schnitstelle aktivert ist:
i2cdetect -l
i2c-0   i2c             20205000.i2c                            I2C adapter

Sollte Sie keine Ausgabe erhalten wurde die
Dieser Link ist nur für registrierte Benutzer sichtbar.
nicht aktiviert.

Ist die I2C Schnittstelle aktivert, prüfen Sie ob der GY-65 Sensor erkannt wurde:
i2cdetect -y $(ls /dev/i2c-*|cut -d '-' -f2)

     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
Sollte Sie die 77 (0x77) nicht sehen, wird der Sensor nicht erkannt. Wird der BMP085 nicht erkannt überprüfen Sie die Kabelverbindung des Sensors.

Skripte


Python


apt-get install python-dev python-smbus

Kopieren Sie die Python BMP Klasse mit:
cd /usr/src/ && git clone https://github.com/adafruit/Adafruit_Python_BMP.git
Cloning into 'Adafruit_Python_BMP'...
remote: Counting objects: 38, done.
remote: Total 38 (delta 0), reused 0 (delta 0), pack-reused 38
Unpacking objects: 100% (38/38), done.

Nach dem Download können Sie die Klasse installieren:
cd Adafruit_Python_BMP && python setup.py install
Downloading https://pypi.python.org/packages/source/s/setuptools/setuptools-3.5.1.zip
Extracting in /tmp/tmpDUfM9l
Now working in /tmp/tmpDUfM9l/setuptools-3.5.1
Building a Setuptools egg in /home/pi/Adafruit_Python_BMP
/home/pi/Adafruit_Python_BMP/setuptools-3.5.1-py2.7.egg
running install
creating Adafruit_BMP.egg-info
writing requirements to Adafruit_BMP.egg-info/requires.txt
Finished processing dependencies for Adafruit-BMP==1.5.0

Kopieren Sie die Klasse in das Skiptverzeichnis:
cp /usr/src/Adafruit_Python_BMP/Adafruit_BMP/BMP085.py /home/pi/

Erstellen Sie ein neues Skript:
nano /home/pi/temperature.py

mit dem Inhalt:
import BMP085
sensor = BMP085.BMP085()

print 'Temp = {0:0.2f} *C'.format(sensor.read_temperature())
print 'Pressure = {0:0.2f} Pa'.format(sensor.read_pressure())
print 'Altitude = {0:0.2f} m'.format(sensor.read_altitude())
print 'Sealevel Pressure = {0:0.2f} Pa'.format(sensor.read_sealevel_pressure())

Nun können Sie das Skript ausführen:
python temperature.py
Temp = 24.30 *C
Pressure = 92945.00 Pa
Altitude = 721.56 m
Sealevel Pressure = 92942.00 Pa


PHP

Zuerst sollten Sie den www-data Benutzer zu der Gruppe i2c hinzufügen, damit das PHP Skript später vom Webserver aus auf die I2C Schnittstelle zugreifen kann.
adduser www-data i2c
Füge Benutzer »www-data« der Gruppe »i2c« hinzu ...
Benutzer www-data wird zur Gruppe i2c hinzugefügt.
Fertig.

Erstellen Sie nun eine neue Datei:
nano i2c_bus.php
<?php
class i2c_bus
{
private $block = 1; // the i2c block ( 0 on first gen rpi's, 1 on subsequnet rpi's )
private $i2c_address; // the i2c bus address of the unit being communicated with ( set when instantiated )

// the i2c address of the device we're communicating with
function __construct($i2c_address)
{
$this->i2c_address = $i2c_address;
}

// register location ( eg. 0x29 )
public function read_register($register)
{
return trim(shell_exec('i2cget -y '.$this->block.' '.$this->i2c_address.' '.$register));
}

// most significant byte register location
public function read_signed_short($msb_register)
{
$msb = intval( $this->read_register( $msb_register ), 16 );
$lsb = intval( $this->read_register( $msb_register + 1 ), 16 );
$val = ( $msb << 8 ) + $lsb;
$array = unpack( 's', pack( 'v', $val ) );
return $array[1];
}

// most significant byte register location
public function read_unsigned_short($msb_register)
{
$msb = intval( $this->read_register( $msb_register ), 16 );
$lsb = intval( $this->read_register( $msb_register + 1 ), 16 );
$val = ( $msb << 8 ) + $lsb;
$array = unpack( 'S', pack( 'v', $val ) );
return $array[1];
}

// most significant byte register location
public function read_unsigned_long($msb_register)
{
$msb = intval( $this->read_register( $msb_register ), 16 );
$lsb = intval( $this->read_register( $msb_register + 1 ), 16 );
$xlsb = intval( $this->read_register( $msb_register + 2 ), 16 );
$val = ( $msb << 16 ) + ( $lsb << 8 ) + $xlsb;
$array = unpack( 'l', pack( 'V', $val ) );
return $array[1];
}

// register address ( eg. 0x29 ) and value to set at register address ( must be a decimal value, eg. 10001001 should be passed as
public function write_register($register,$value)
{
shell_exec('i2cset -y '.$this->block.' '.$this->i2c_address.' '.$register.' '.$value);
}
}
?>
nano bmp085.php
<?php
// include parent class
require_once( 'i2c_bus.php' );

class bmp085
{
// debug mode
const debug_mode = 0;
// address of this device on the i2c bus
const i2c_address = 0x77;
// operation modes
const ultra_low_power_mode = 0;
const standard_mode = 1;
const high_resolution_mode = 2;
const ultra_high_resolution_mode = 3;

// i2c connection
private $I2c;
// operating mode
private $operating_mode;
// calibration data
private $ac1;
private $ac2;
private $ac3;
private $ac4;
private $ac5;
private $ac6;
private $b1;
private $b2;
private $mb;
private $mc;
private $md;
// readings
private $ut; // uncompensated temperature
private $t; // true temperature
private $up; // uncompensated pressure
private $p; // true pressure
private $a; // altitude ( calculated using true pressure )

function __construct()
{
// instantiate i2c communication class and pass the default i2c bus address for the BMP085
$this->I2c = new i2c_bus( self::i2c_address );
// set operating mode ( don't know how to change on chip, so use default 'standard mode' )
$this->operating_mode = self::standard_mode;
// get calibration data
$this->read_calibration_data();
}

// returns an array with temperature, pressure, and altitude
/*
- temperature is in celcius ( c )
- pressure is in pascals ( Pa )
- altitude is in meters ( m )
*/
public function get_readings()
{
// get data and make calculations
$this->read_uncompensated_temperature();
$this->read_uncompensated_pressure();
$this->calculate_readings();
// return data in an array
return array(
'temperature' => $this->t,
'pressure' => $this->p,
'altitude' => $this->a
);
}

private function read_calibration_data()
{
$this->ac1 = $this->I2c->read_signed_short( 0xaa );
$this->ac2 = $this->I2c->read_signed_short( 0xac );
$this->ac3 = $this->I2c->read_signed_short( 0xae );
$this->ac4 = $this->I2c->read_unsigned_short( 0xb0 );
$this->ac5 = $this->I2c->read_unsigned_short( 0xb2 );
$this->ac6 = $this->I2c->read_unsigned_short( 0xb4 );
$this->b1 = $this->I2c->read_signed_short( 0xb6 );
$this->b2 = $this->I2c->read_signed_short( 0xb8 );
$this->mb = $this->I2c->read_signed_short( 0xba );
$this->mc = $this->I2c->read_signed_short( 0xbc );
$this->md = $this->I2c->read_signed_short( 0xbe );

if(self::debug_mode)
{
echo "\nac1: " . $this->ac1;
echo "\nac2: " . $this->ac2;
echo "\nac3: " . $this->ac3;
echo "\nac4: " . $this->ac4;
echo "\nac5: " . $this->ac5;
echo "\nac6: " . $this->ac6;
echo "\nb1: " . $this->b1;
echo "\nb2: " . $this->b2;
echo "\nmb: " . $this->mb;
echo "\nmc: " . $this->mc;
echo "\nmd: " . $this->md;
}
}
private function read_uncompensated_temperature()
{
$this->I2c->write_register( 0xf4, 0x2e );
usleep( 4500 );
$this->ut = $this->I2c->read_unsigned_short( 0xf6 );
if( self::debug_mode )
echo "\nut: " . $this->ut;
}
private function read_uncompensated_pressure()
{
$this->I2c->write_register( 0xf4, 0x34 + ( $this->operating_mode << 6 ) );
usleep( 4500 );
$this->up = $this->I2c->read_unsigned_long( 0xf6 ) >> ( 8 - $this->operating_mode );
if( self::debug_mode )
echo "\nup: " . $this->up;
}
private function calculate_readings()
{
// set to true to use datasheet sample calibration data to test math operations
if(false)
{
$this->ac1 = 408;
$this->ac2 = -72;
$this->ac3 = -14383;
$this->ac4 = 32741;
$this->ac5 = 32757;
$this->ac6 = 23153;
$this->b1 = 6190;
$this->b2 = 4;
$this->mb = -32767;
$this->mc = -8711;
$this->md = 2868;
$this->operating_mode = self::ultra_low_power_mode;
$this->ut = 27898;
$this->up = 23843;
}
// calculate true temperature
$x1 = ( $this->ut - $this->ac6 ) * $this->ac5 >> 15;
$x2 = ( $this->mc << 11 ) / ( $x1 + $this->md );
$b5 = $x1 + $x2;
$this->t = ( $b5 + 8 ) >> 4;
$this->t = $this->t * 0.1; // convert to celcius
if( self::debug_mode )
{
echo "\nx1: $x1";
echo "\nx2: $x2";
echo "\nb5: $b5";
echo "\nt: " . $this->t;
}
// calculate true pressure
$b6 = $b5 - 4000;
$x1 = ( $this->b2 * ( $b6 * $b6 ) >> 12 ) >> 11;
$x2 = ( $this->ac2 * $b6 ) >> 11;
$x3 = $x1 + $x2;
$b3 = ( ( ( $this->ac1 * 4 + $x3 ) << $this->operating_mode ) + 2 ) / 4;
if( self::debug_mode )
{
echo "\nb6: $b6";
echo "\nx1: $x1";
echo "\nx2: $x2";
echo "\nx3: $x3";
echo "\nb3: $b3";
}
$x1 = ( $this->ac3 * $b6 ) >> 13;
$x2 = ( $this->b1 * ( ( $b6 * $b6 ) >> 12 ) ) >> 16;
$x3 = ( ( $x1 + $x2 ) + 2 ) >> 2;
$b4 = ( $this->ac4 * ( $x3 + 32768 ) ) >> 15;
$b7 = ( $this->up - $b3 ) * ( 50000 >> $this->operating_mode );
if( $b7 < 0x80000000 )
$p = ( $b7 * 2 ) / $b4;
else
$p = ( $b7 / $b4 ) * 2;
if( self::debug_mode )
{
echo "\nx1: $x1";
echo "\nx2: $x2";
echo "\nx3: $x3";
echo "\nb4: $b4";
echo "\nb7: $b7";
echo "\np: $p";
}
$x1 = ( $p >> 8 ) * ( $p >> 8 );
if( self::debug_mode )
echo "\nx1: $x1";
$x1 = ( $x1 * 3038 ) >> 16;
$x2 = ( -7357 * $p ) >> 16;
$this->p = $p + ( ( $x1 + $x2 + 3791 ) >> 4 );
if( self::debug_mode )
{
echo "\nx1: $x1";
echo "\nx2: $x2";
echo "\np: " . $this->p;
}
// calculate altitude
$this->a = 44330 * ( 1 - pow( ( $this->p / 101325 ), ( 0.1903 ) ) );
if( self::debug_mode )
echo "\na: " . $this->a;
}
}
?>
nano index.php
<?php
/*----------------------------------------------------------------------+
| Copyright 2006-2016 by Kevin Buehl (kevin@buehl.biz) |
+-----------------------------------------------------------------------+
| __ __ _____________ __ __ ______________ |
| | | 2006 | | | _______ \ | | | | |___________ | |
| | | 2016 | | | | \ | | | | | | | |
| | |___ ____| | | |_______/ / | |___ ____| | ___________| | |
| |______ ____ | | _______ | |______ ____ | | ___________| |
| by | | | | \ \ Content | | | | |
| Kevin | | | |_______/ | Management | | | |___________ |
| Buehl |__| |_____________/ System |__| |______________| |
| |
| No part of this website or any of its contents may be reproduced, |
| copied, modified or adapted, without the prior written consent of |
| the author, unless otherwise indicated for stand-alone materials. |
| For more Information visit www.4b42.com. |
| This notice must be untouched at all times. |
+----------------------------------------------------------------------*/

/*----------------------------------------------------------------------+
| 201-02-01 KB created
+----------------------------------------------------------------------*/
require_once('bmp085.php');
$Bmp085 = new bmp085();
$data = $Bmp085->get_readings();
echo json_encode($data);
?>