| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794 |
- # $Id: 51_I2C_BMP180.pm 12059 2016-08-22 21:14:59Z klauswitt $
- =head1
- 51_I2C_BMP180.pm
- =head1 SYNOPSIS
- Modul for FHEM for reading a BMP180 or BMP085 digital pressure sensor via I2C
- connected to the Raspberry Pi.
- contributed by Dirk Hoffmann 2013
- =head1 DESCRIPTION
- 51_I2C_BMP180.pm reads the air pressure of the digital pressure sensor BMP180
- or BMP085 via i2c bus connected to the Raspberry Pi.
- This module needs the HiPi Perl Modules
- see: http://raspberrypi.znix.com/hipidocs/
-
- For a simple automated installation:<br>
- wget http://raspberry.znix.com/hipifiles/hipi-install
- perl hipi-install
- Example:
- define BMP180 I2C_BMP180 /dev/i2c-0
- attr BMP180 poll_iterval 5
- attr BMP180 oversampling_settings 3
- =head1 AUTHOR - Dirk Hoffmann
- dirk@FHEM_Forum (forum.fhem.de)
- modified for use with physical I2C devices by Klaus Wittstock (klausw)
- modified to prevent division by zero when calibration data is invalid by Jens Beyer (jensb)
- =cut
- package main;
- use strict;
- use warnings;
- use Time::HiRes qw(usleep);
- use Scalar::Util qw(looks_like_number);
- use constant {
- BMP180_I2C_ADDRESS => '0x77',
- };
- ##################################################
- # Forward declarations
- #
- sub I2C_BMP180_Initialize($);
- sub I2C_BMP180_Define($$);
- sub I2C_BMP180_Attr(@);
- sub I2C_BMP180_Poll($);
- sub I2C_BMP180_Set($@);
- sub I2C_BMP180_Undef($$);
- sub I2C_BMP180_readUncompensatedTemperature($);
- sub I2C_BMP180_readUncompensatedPressure($$);
- sub I2C_BMP180_calcTrueTemperature($$);
- sub I2C_BMP180_calcTruePressure($$$);
- sub I2C_BMP180_DbLog_splitFn($);
- my $libcheck_hasHiPi = 1;
- my %sets = (
- 'readValues' => 1,
- );
- =head2 I2C_BMP180_Initialize
- Title: I2C_BMP180_Initialize
- Function: Implements the initialize function.
- Returns: -
- Args: named arguments:
- -argument1 => hash
- =cut
- sub I2C_BMP180_Initialize($) {
- my ($hash) = @_;
- eval "use HiPi::Device::I2C;";
- $libcheck_hasHiPi = 0 if($@);
-
- $hash->{DefFn} = 'I2C_BMP180_Define';
- $hash->{InitFn} = 'I2C_BMP180_Init';
- $hash->{AttrFn} = 'I2C_BMP180_Attr';
- $hash->{SetFn} = 'I2C_BMP180_Set';
- $hash->{UndefFn} = 'I2C_BMP180_Undef';
- $hash->{I2CRecFn} = 'I2C_BMP180_I2CRec';
- $hash->{AttrList} = 'IODev do_not_notify:0,1 showtime:0,1 model:BMP180,BMP085 ' .
- 'poll_interval:1,2,5,10,20,30 oversampling_settings:0,1,2,3 ' .
- 'roundPressureDecimal:0,1,2 roundTemperatureDecimal:0,1,2 ' .
- $readingFnAttributes;
- $hash->{AttrList} .= " useHiPiLib:0,1 " if( $libcheck_hasHiPi );
- $hash->{DbLog_splitFn} = "I2C_BMP180_DbLog_splitFn";
- }
- =head2 I2C_BMP180_Define
- Title: I2C_BMP180_Define
- Function: Implements the define function.
- Returns: string|undef
- Args: named arguments:
- -argument1 => hash
- -argument2 => string
- =cut
- sub I2C_BMP180_Define($$) {
- my ($hash, $def) = @_;
- my @a = split('[ \t][ \t]*', $def);
- $hash->{STATE} = 'defined';
-
- my $name = $a[0];
- my $msg = '';
- $hash->{HiPi_exists} = $libcheck_hasHiPi if($libcheck_hasHiPi);
- if (@a == 3) {
- if ($libcheck_hasHiPi) {
- $hash->{HiPi_used} = 1;
- } else {
- $msg = '$name error: HiPi library not installed';
- }
- } elsif((@a < 2)) {
- $msg = 'wrong syntax: define <name> I2C_BMP180 [devicename]';
- }
- if ($msg) {
- Log3 ($hash, 1, $msg);
- return $msg;
- }
- if ($main::init_done || $hash->{HiPi_used}) {
- eval { I2C_BMP180_Init( $hash, [ @a[ 2 .. scalar(@a) - 1 ] ] ); };
- return I2C_BMP180_Catch($@) if $@;
- }
- }
- sub I2C_BMP180_Init($$) {
- my ( $hash, $args ) = @_;
- my $name = $hash->{NAME};
- $hash->{I2C_Address} = hex(BMP180_I2C_ADDRESS);
- my $msg = '';
- # create default attributes
- if (AttrVal($name, 'poll_interval', '?') eq '?') {
- $msg = CommandAttr(undef, $name . ' poll_interval 5');
- if ($msg) {
- Log3 ($hash, 1, $msg);
- return $msg;
- }
- }
- if (AttrVal($name, 'oversampling_settings', '?') eq '?') {
- $msg = CommandAttr(undef, $name . ' oversampling_settings 3');
- if ($msg) {
- Log3 ($hash, 1, $msg);
- return $msg;
- }
- }
-
- if ($hash->{HiPi_used}) {
- my $dev = shift @$args;
- my $i2cModulesLoaded = 0;
- $i2cModulesLoaded = 1 if -e $dev;
- if ($i2cModulesLoaded) {
- $hash->{devBPM180} = HiPi::Device::I2C->new(
- devicename => $dev,
- address => hex(BMP180_I2C_ADDRESS),
- busmode => 'i2c',
- );
- } else {
- return $name . ': Error! I2C device not found: ' . $dev . '. Please check kernelmodules must loaded: i2c_bcm2708, i2c_dev';
- }
- } else {
- AssignIoPort($hash);
- }
- $hash->{STATE} = 'getCalData';
- I2C_BMP180_i2cread($hash, hex("AA"), 22);
- return undef;
- }
- sub I2C_BMP180_Catch($) {
- my $exception = shift;
- if ($exception) {
- $exception =~ /^(.*)( at.*FHEM.*)$/;
- return $1;
- }
- return undef;
- }
- =head2 I2C_BMP180_Attr
- Title: I2C_BMP180_Attr
- Function: Implements AttrFn function.
- Returns: string|undef
- Args: named arguments:
- -argument1 => array
- =cut
- sub I2C_BMP180_Attr (@) {
- my (undef, $name, $attr, $val) = @_;
- my $hash = $defs{$name};
- my $msg = '';
- if ($attr eq 'poll_interval') {
- my $pollInterval = (defined($val) && looks_like_number($val) && $val > 0) ? $val : 0;
-
- if ($val > 0) {
- RemoveInternalTimer($hash);
- InternalTimer(1, 'I2C_BMP180_Poll', $hash, 0);
- } else {
- $msg = 'Wrong poll intervall defined. poll_interval must be a number > 0';
- }
- }
- return ($msg) ? $msg : undef;
- }
- =head2 I2C_BMP180_Poll
- Title: I2C_BMP180_Poll
- Function: Start polling the sensor at interval defined in attribute
- Returns: -
- Args: named arguments:
- -argument1 => hash
- =cut
- sub I2C_BMP180_Poll($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
-
- # Read values
- I2C_BMP180_Set($hash, ($name, 'readValues'));
-
- my $pollInterval = AttrVal($hash->{NAME}, 'poll_interval', 0);
- if ($pollInterval > 0) {
- InternalTimer(gettimeofday() + ($pollInterval * 60), 'I2C_BMP180_Poll', $hash, 0);
- }
- }
- =head2 I2C_BMP180_Set
- Title: I2C_BMP180_Set
- Function: Implements SetFn function.
- Returns: string|undef
- Args: named arguments:
- -argument1 => hash: $hash hash of device
- -argument2 => array: @a argument array
- =cut
- sub I2C_BMP180_Set($@) {
- my ($hash, @a) = @_;
- my $name = $a[0];
- my $cmd = $a[1];
- if(!defined($sets{$cmd})) {
- return 'Unknown argument ' . $cmd . ', choose one of ' . join(' ', keys %sets)
- }
-
- if ($cmd eq 'readValues') {
- my $overSamplingSettings = AttrVal($hash->{NAME}, 'oversampling_settings', 3);
-
- if (defined($hash->{calibrationData}{md}) && $hash->{calibrationData}{md} != 0 && $hash->{calibrationData}{ac4} != 0) { # query sensor
- I2C_BMP180_readUncompensatedTemperature($hash);
- I2C_BMP180_readUncompensatedPressure($hash, $overSamplingSettings);
- } else { #..but get calibration variables first
- I2C_BMP180_i2cread($hash, hex("AA"), 22);
- }
- }
- }
- =head2 I2C_BMP180_Undef
- Title: I2C_BMP180_Undef
- Function: Implements UndefFn function.
- Returns: undef
- Args: named arguments:
- -argument1 => hash: $hash hash of device
- -argument2 => array: @a argument array
- =cut
- sub I2C_BMP180_Undef($$) {
- my ($hash, $arg) = @_;
- RemoveInternalTimer($hash);
- return undef;
- }
- sub I2C_BMP180_I2CRec ($$) {
- my ($hash, $clientmsg) = @_;
- my $name = $hash->{NAME};
- my $pname = undef;
- unless ($hash->{HiPi_used}) {#nicht nutzen wenn HiPi Bibliothek in Benutzung
- my $phash = $hash->{IODev};
- $pname = $phash->{NAME};
- while ( my ( $k, $v ) = each %$clientmsg ) { #erzeugen von Internals fuer alle Keys in $clientmsg die mit dem physical Namen beginnen
- $hash->{$k} = $v if $k =~ /^$pname/ ;
- }
- }
-
- if ( $clientmsg->{direction} && $clientmsg->{reg} && (
- ($pname && $clientmsg->{$pname . "_SENDSTAT"} && $clientmsg->{$pname . "_SENDSTAT"} eq "Ok")
- || $hash->{HiPi_used}) ) {
- if ( $clientmsg->{direction} eq "i2cread" && defined($clientmsg->{received}) ) {
- Log3 $hash, 5, "$name empfangen: $clientmsg->{received}";
- I2C_BMP180_GetCal ($hash, $clientmsg->{received}) if $clientmsg->{reg} == hex("AA");
- I2C_BMP180_GetTemp ($hash, $clientmsg->{received}) if $clientmsg->{reg} == hex("F6") && $clientmsg->{nbyte} == 2;
- I2C_BMP180_GetPress ($hash, $clientmsg->{received}) if $clientmsg->{reg} == hex("F6") && $clientmsg->{nbyte} == 3;
- }
- }
- }
- sub I2C_BMP180_GetCal ($$) {
- my ($hash, $rawdata) = @_;
- my @raw = split(" ",$rawdata);
- my $n = 0;
- Log3 $hash, 5, "in get cal: $rawdata";
- $hash->{calibrationData}{ac1} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{ac2} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{ac3} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{ac4} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++], 0);
- $hash->{calibrationData}{ac5} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++], 0);
- $hash->{calibrationData}{ac6} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++], 0);
- $hash->{calibrationData}{b1} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{b2} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{mb} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{mc} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{calibrationData}{md} = I2C_BMP180_GetCalVar($raw[$n++], $raw[$n++]);
- $hash->{STATE} = 'Initialized';
- return
- }
- sub I2C_BMP180_GetCalVar ($$;$) {
- my ($msb, $lsb, $returnSigned) = @_;
- $returnSigned = (!defined($returnSigned) || $returnSigned == 1) ? 1 : 0;
- my $retVal = undef;
- $retVal = $msb << 8 | $lsb;
- # check if we need return signed or unsigned int
- if ($returnSigned == 1) {
- $retVal = $retVal >> 15 ? $retVal - 2**16 : $retVal;
- }
- return $retVal;
- }
- sub I2C_BMP180_GetTemp ($$) {
- my ($hash, $rawdata) = @_;
- my @raw = split(" ",$rawdata);
- $hash->{uncompTemp} = $raw[0] << 8 | $raw[1];
- }
- sub I2C_BMP180_GetPress ($$) {
- my ($hash, $rawdata) = @_;
- my @raw = split(" ",$rawdata);
- my $overSamplingSettings = AttrVal($hash->{NAME}, 'oversampling_settings', 3);
-
- my $ut = $hash->{uncompTemp};
- delete $hash->{uncompTemp};
- return undef unless defined($hash->{calibrationData}{md}) && $hash->{calibrationData}{md} != 0 && $hash->{calibrationData}{ac4} != 0;
- my $temperature = sprintf(
- '%.' . AttrVal($hash->{NAME}, 'roundTemperatureDecimal', 1) . 'f',
- I2C_BMP180_calcTrueTemperature($hash, $ut) / 10
- );
-
- my $up = ( ( ($raw[0] << 16) | ($raw[1] << 8) | $raw[2] ) >> (8 - $overSamplingSettings) );
- my $pressure = sprintf(
- '%.' . AttrVal($hash->{NAME}, 'roundPressureDecimal', 1) . 'f',
- I2C_BMP180_calcTruePressure($hash, $up, $overSamplingSettings) / 100
- );
- my $altitude = AttrVal('global', 'altitude', 0);
-
- # simple barometric height formula
- my $pressureNN = sprintf(
- '%.' . AttrVal($hash->{NAME}, 'roundPressureDecimal', 1) . 'f',
- $pressure + ($altitude / 8.5)
- );
- readingsBeginUpdate($hash);
- readingsBulkUpdate(
- $hash,
- 'state',
- 'T: ' . $temperature . ' P: ' . $pressure . ' P-NN: ' . $pressureNN
- );
- readingsBulkUpdate($hash, 'temperature', $temperature);
- readingsBulkUpdate($hash, 'pressure', $pressure);
- readingsBulkUpdate($hash, 'pressure-nn', $pressureNN);
- #readingsBulkUpdate($hash, 'altitude', $altitude, 0);
- readingsEndUpdate($hash, 1);
- }
- =head2 I2C_BMP180_readUncompensatedTemperature
- Title: I2C_BMP180_readUncompensatedTemperature
- Function: Read the uncompensated temperature value.
- Returns: number
- Args: named arguments:
- -argument1 => hash: $hash hash of device
- =cut
- sub I2C_BMP180_readUncompensatedTemperature($) {
- my ($hash) = @_;
- # Write 0x2E into Register 0xF4. This requests a temperature reading
- I2C_BMP180_i2cwrite($hash, hex("F4"), hex("2E"));
-
- usleep(4500);
- # Read the two byte result from address 0xF6
- I2C_BMP180_i2cread($hash, hex("F6"), 2);
-
- return;
- }
- =head2 I2C_BMP180_readUncompensatedPressure
- Title: I2C_BMP180_readUncompensatedPressure
- Function: Read the uncompensated pressure value.
- Returns: number
- Args: named arguments:
- -argument1 => hash: $hash hash of device
- -argument2 => number: $overSamplingSettings
- =cut
- sub I2C_BMP180_readUncompensatedPressure($$) {
- my ($hash, $overSamplingSettings) = @_;
- # Write 0x34+($overSamplingSettings << 6) into register 0xF4
- # Request a pressure reading with oversampling setting
- my $data = hex("34") + ($overSamplingSettings << 6);
- I2C_BMP180_i2cwrite($hash, hex("F4"), $data);
-
- # Wait for conversion, delay time dependent on oversampling setting
- usleep( (2 + (3 << $overSamplingSettings)) * 1000 );
-
- # Read the three byte result from 0xF6. 0xF6 = MSB, 0xF7 = LSB and 0xF8 = XLSB
- I2C_BMP180_i2cread($hash, hex("F6"), 3);
-
- return;
- }
- sub I2C_BMP180_i2cread($$$) {
- my ($hash, $reg, $nbyte) = @_;
- if ($hash->{HiPi_used}) {
- eval {
- my @values = $hash->{devBPM180}->bus_read($reg, $nbyte);
- I2C_BMP180_I2CRec($hash, {
- direction => "i2cread",
- i2caddress => $hash->{I2C_Address},
- reg => $reg,
- nbyte => $nbyte,
- received => join (' ',@values),
- });
- };
- Log3 ($hash, 1, $hash->{NAME} . ': ' . I2C_BMP180_Catch($@)) if $@;;
- } else {
- if (defined (my $iodev = $hash->{IODev})) {
- CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
- direction => "i2cread",
- i2caddress => $hash->{I2C_Address},
- reg => $reg,
- nbyte => $nbyte
- });
- } else {
- return "no IODev assigned to '$hash->{NAME}'";
- }
- }
- }
- sub I2C_BMP180_i2cwrite($$$) {
- my ($hash, $reg, @data) = @_;
- if ($hash->{HiPi_used}) {
- eval {
- $hash->{devBPM180}->bus_write($reg, join (' ',@data));
- I2C_BMP180_I2CRec($hash, {
- direction => "i2cwrite",
- i2caddress => $hash->{I2C_Address},
- reg => $reg,
- data => join (' ',@data),
- });
- };
- Log3 ($hash, 1, $hash->{NAME} . ': ' . I2C_BMP180_Catch($@)) if $@;;
- } else {
- if (defined (my $iodev = $hash->{IODev})) {
- CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
- direction => "i2cwrite",
- i2caddress => $hash->{I2C_Address},
- reg => $reg,
- data => join (' ',@data),
- });
- } else {
- return "no IODev assigned to '$hash->{NAME}'";
- }
- }
- }
- =head2 I2C_BMP180_calcTrueTemperature
- Title: I2C_BMP180_calcTrueTemperature
- Function: Calculate temperature from given uncalibrated temperature
- Returns: number
- Args: named arguments:
- -argument1 => hash: $hash hash of device
- -argument2 => number: $ut uncalibrated temperature
- =cut
- sub I2C_BMP180_calcTrueTemperature($$) {
- my ($hash, $ut) = @_;
-
- my $x1 = ($ut - $hash->{calibrationData}{ac6}) * $hash->{calibrationData}{ac5} / 32768;
- my $x2 = ($hash->{calibrationData}{mc} * 2048) / ($x1 + $hash->{calibrationData}{md});
- $hash->{calibrationData}{b5} = $x1 + $x2;
- my $retVal = (($hash->{calibrationData}{b5} + 8) / 16);
- return $retVal;
- }
- =head2 I2C_BMP180_calcTruePressure
- Title: I2C_BMP180_calcTruePressure
- Function: Calculate the pressure from given uncalibrated pressure
- Returns: number
- Args: named arguments:
- -argument1 => hash: $hash hash of device
- -argument2 => number: $up uncalibrated pressure
- -argument3 => number: $overSamplingSettings
- =cut
- sub I2C_BMP180_calcTruePressure($$$) {
- my ($hash, $up, $overSamplingSettings) = @_;
- my $b6 = $hash->{calibrationData}{b5} - 4000;
- my $x1 = ($hash->{calibrationData}{b2} * ($b6 * $b6 / 4096)) / 2048;
- my $x2 = ($hash->{calibrationData}{ac2} * $b6) / 2048;
- my $x3 = $x1 + $x2;
- my $b3 = ((($hash->{calibrationData}{ac1} * 4 + $x3) << $overSamplingSettings) + 2) / 4;
- $x1 = $hash->{calibrationData}{ac3} * $b6 / 8192;
- $x2 = ($hash->{calibrationData}{b1} * ($b6 * $b6 / 4096)) / 65536;
- $x3 = (($x1 + $x2) + 2) / 4;
- my $b4 = $hash->{calibrationData}{ac4} * ($x3 + 32768) / 32768;
- my $b7 = ($up - $b3) * (50000 >> $overSamplingSettings);
- my $p = ($b7 < 0x80000000) ? (($b7 * 2) / $b4) : (($b7 / $b4) * 2);
-
- $x1 = ($p / 256) * ($p / 256);
- $x1 = ($x1 * 3038) / 65536;
- $x2 = (-7357 * $p) / 65536;
- $p += (($x1 + $x2 + 3791) / 16);
- return $p;
- }
- sub I2C_BMP180_DbLog_splitFn($) {
- my ($event) = @_;
- Log3 undef, 5, "in DbLog_splitFn empfangen: $event";
- my ($reading, $value, $unit) = "";
- my @parts = split(/ /,$event);
- $reading = shift @parts;
- $reading =~ tr/://d;
- $value = $parts[0];
- $unit = "\xB0C" if(lc($reading) =~ m/temp/);
- $unit = "hPa" if(lc($reading) =~ m/pres/);
- return ($reading, $value, $unit);
- }
- 1;
- =pod
- =item device
- =item summary reads pressure and temperature from an via I2C connected BMP180/BMP085
- =item summary_DE lese Druck und Temperatur eines über I2C angeschlossenen BMP180/BMP085
- =begin html
- <a name="I2C_BMP180"></a>
- <h3>I2C_BMP180</h3>
- <ul>
- <a name="I2C_BMP180"></a>
- <p>
- With this module you can read values from the digital pressure sensors BMP180 and BMP085
- via the i2c bus on Raspberry Pi.<br><br>
- <b>There are two possibilities connecting to I2C bus:</b><br>
- <ul>
- <li><b>via RPII2C module</b><br>
- The I2C messages are send through an I2C interface module like <a href="#RPII2C">RPII2C</a>, <a href="#FRM">FRM</a>
- or <a href="#NetzerI2C">NetzerI2C</a> so this device must be defined first.<br>
- <b>attribute IODev must be set</b><br><br>
- </li>
- <li><b>via HiPi library</b><br>
- Add these two lines to your <b>/etc/modules</b> file to load the I2C relevant kernel modules
- automaticly during booting your Raspberry Pi.<br>
- <code><pre>i2c-bcm2708
- i2c-dev</pre></code>
- Install HiPi perl modules:<br>
- <code><pre>wget http://raspberry.znix.com/hipifiles/hipi-install
- perl hipi-install</pre></code>
- To change the permissions of the I2C device create file:<br>
- <code><pre> /etc/udev/rules.d/98_i2c.rules</pre></code>
- with this content:<br>
- <code><pre>SUBSYSTEM=="i2c-dev", MODE="0666"</pre></code>
- <b>Reboot</b><br><br>
- To use the sensor on the second I2C bus at P5 connector
- (only for version 2 of Raspberry Pi) you must add the bold
- line of following code to your FHEM start script:
- <code><pre> case "$1" in
- 'start')
- <b>sudo hipi-i2c e 0 1</b>
- ...</pre></code>
- </li></ul>
- <p>
-
- <b>Define</b>
- <ul>
- <code>define BMP180 I2C_BMP180 [<I2C device>]</code><br><br>
- <I2C device> must not be used if you connect via RPII2C module. For HiPi it's mandatory. <br>
- <br>
- Examples:
- <pre>
- define BMP180 I2C_BMP180 /dev/i2c-0
- attr BMP180 oversampling_settings 3
- attr BMP180 poll_interval 5
- </pre>
- <pre>
- define BMP180 I2C_BMP180
- attr BMP180 IODev RPiI2CMod
- attr BMP180 oversampling_settings 3
- attr BMP180 poll_interval 5
- </pre>
- </ul>
- <a name="I2C_BMP180set"></a>
- <b>Set</b>
- <ul>
- <code>set BMP180 <readValues></code>
- <br><br>
- Reads the current temperature and pressure values from sensor.<br>
- Normaly this execute automaticly at each poll intervall. You can execute
- this manually if you want query the current values.
- <br><br>
- </ul>
- <a name="I2C_BMP180get"></a>
- <b>Get</b>
- <ul>
- N/A
- </ul>
- <br>
- <a name="I2C_BMP180attr"></a>
- <b>Attributes</b>
- <ul>
- <li>oversampling_settings<br>
- Controls the oversampling setting of the pressure measurement in the sensor.<br>
- Default: 3, valid values: 0, 1, 2, 3<br><br>
- </li>
- <li>poll_interval<br>
- Set the polling interval in minutes to query the sensor for new measured
- values.<br>
- Default: 5, valid values: 1, 2, 5, 10, 20, 30<br><br>
- </li>
- <li>roundTemperatureDecimal<br>
- Round temperature values to given decimal places.<br>
- Default: 1, valid values: 0, 1, 2<br><br>
- </li>
- <li>roundPressureDecimal<br>
- Round temperature values to given decimal places.<br>
- Default: 1, valid values: 0, 1, 2<br><br>
- </li>
- <li>altitude<br>
- if set, this altitude is used for calculating the pressure related to sea level (nautic null) NN<br><br>
- Note: this is a global attributes, e.g<br>
- <ul>
- attr global altitude 220
- </ul>
- </li>
- </ul>
- <br>
- <b>Notes</b>
- <ul>
- <li>I2C bus timing<br>
- For all sensor operations an I2C interface with blocking IO is assumed (e.g. RPII2C).
- If you use an I2C interface with non-blocking IO (e.g. FRM over ethernet) operation errors may occur,
- especially if setting the attribute oversampling_settings to a value higher than 1.
- This may be compensated depending on I2C interface used. For Firmata try setting the attribute
- i2c-config in the FRM module to a value of about 30000 microseconds.<br><br>
- </li>
- </ul>
- <br>
- </ul>
- =end html
- =begin html_DE
- <a name="I2C_BMP180"></a>
- <h3>I2C_BMP180</h3>
- <ul>
- <a name="I2C_BMP180"></a>
- <p>
- Dieses Modul ermöglicht das Auslesen der digitalen (Luft)drucksensoren
- BMP085 und BMP180 über den I2C Bus des Raspberry Pi.<br><br>
- <b>Es gibt zwei Möglichkeiten das Modul mit dem I2C Bus zu verbinden:</b><br>
- <ul>
- <li><b>Über das RPII2C Modul</b><br>
- I2C-Botschaften werden über ein I2C Interface Modul wie beispielsweise das <a href="#RPII2C">RPII2C</a>, <a href="#FRM">FRM</a>
- oder <a href="#NetzerI2C">NetzerI2C</a> gesendet. Daher muss dieses vorher definiert werden.<br>
- <b>Das Attribut IODev muss definiert sein.</b><br><br>
- </li>
- <li><b>Über die HiPi Bibliothek</b><br>
- Diese beiden Zeilen müssen in die Datei <b>/etc/modules</b> angefügt werden,
- um die Kernel Module automatisch beim Booten des Raspberry Pis zu laden.<br>
- <code><pre>i2c-bcm2708
- i2c-dev</pre></code>
- Installation des HiPi Perl Moduls:<br>
- <code><pre>wget http://raspberry.znix.com/hipifiles/hipi-install
- perl hipi-install</pre></code>
- Um die Rechte für die I2C Devices anzupassen, folgende Datei:<br>
- <code><pre> /etc/udev/rules.d/98_i2c.rules</pre></code>
- mit diesem Inhalt anlegen:<br>
- <code><pre>SUBSYSTEM=="i2c-dev", MODE="0666"</pre></code>
- <b>Reboot</b><br><br>
- Falls der Sensor am zweiten I2C Bus am Stecker P5 (nur in Version 2 des
- Raspberry Pi) verwendet werden soll, muss die fett gedruckte Zeile
- des folgenden Codes in das FHEM Start Skript aufgenommen werden:
- <code><pre> case "$1" in
- 'start')
- <b>sudo hipi-i2c e 0 1</b>
- ...</pre></code>
- </li></ul>
- <p>
-
- <b>Define</b>
- <ul>
- <code>define BMP180 <BMP180_name> <I2C_device></code><br><br>
- <I2C device> darf nicht verwendet werden, wenn der I2C Bus über das RPII2C Modul angesprochen wird. Für HiPi ist es allerdings notwendig. <br>
- <br>
- Beispiel:
- <pre>
- define BMP180 I2C_BMP180 /dev/i2c-0
- attr BMP180 oversampling_settings 3
- attr BMP180 poll_interval 5
- </pre>
- <pre>
- define BMP180 I2C_BMP180
- attr BMP180 IODev RPiI2CMod
- attr BMP180 oversampling_settings 3
- attr BMP180 poll_interval 5
- </pre>
- </ul>
- <a name="I2C_BMP180set"></a>
- <b>Set</b>
- <ul>
- <code>set BMP180 readValues</code>
- <br><br>
- Liest die aktuelle Temperatur und den Luftdruck des Sensors aus.<br>
- Dies wird automatisch nach Ablauf des definierten Intervalls ausgeführt.
- Wenn der aktuelle Wert gelesen werden soll, kann dieser Befehl auch manuell
- ausgeführt werden.
- <br><br>
- </ul>
- <a name="I2C_BMP180get"></a>
- <b>Get</b>
- <ul>
- N/A
- </ul>
- <br>
- <a name="I2C_BMP180attr"></a>
- <b>Attribute</b>
- <ul>
- <li>oversampling_settings<br>
- Steuert das Oversampling der Druckmessung im Sensor.<br>
- Default: 3, gültige Werte: 0, 1, 2, 3<br><br>
- </li>
- <li>poll_interval<br>
- Definiert das Poll Intervall in Minuten für das Auslesen einer neuen Messung.<br>
- Default: 5, gültige Werte: 1, 2, 5, 10, 20, 30<br><br>
- </li>
- <li>roundTemperatureDecimal<br>
- Rundet den Temperaturwert mit den angegebenen Nachkommastellen.<br>
- Default: 1, gültige Werte: 0, 1, 2<br><br>
- </li>
- <li>roundPressureDecimal<br>
- Rundet die Drucksensorwerte mit den angegebenen Nachkommastellen.<br>
- Default: 1, valid values: 0, 1, 2<br><br>
- </li>
- <li>altitude<br>
- Wenn dieser Wert definiert ist, wird diese Angabe zusätzlich für die Berechnung des
- Luftdrucks bezogen auf Meereshöhe (Normalnull) NN herangezogen.<br>
- Bemerkung: Dies ist ein globales Attribut.<br><br>
- <code>attr global altitude 220</code>
- </li>
- </ul>
- <br>
-
- <b>Hinweise</b>
- <ul>
- <li>I2C-Bustiming<br>
- Zur Abfrage des Sensors wird von einer I2C-Schnittstelle mit blockierendem IO-Zugriff (z.B. RPII2C) ausgegangen.
- Bei I2C-Schnittstellen, die nicht-blockierend arbeiten (z.B. FRM mit Ethernet), kann es zu Verarbeitungsfehlern kommen,
- insbesondere wenn das Attribut oversampling_settings auf einen Wert größer 1 eingestellt wird.
- Dies lässt sich je nach I2C-Schnittstelle kompensieren. Bei Firmata empfiehlt es sich,
- das Attribut i2c-config im Modul FRM auf einen Wert von ca. 30000 Mikrosekunden einzustellen.<br><br>
- </li>
- </ul>
- <br>
- </ul>
- =end html_DE
- =cut
|