diff --git a/FHEM/00_RPII2C.pm b/FHEM/00_RPII2C.pm index 3ecd3d584..a1e71ce1e 100644 --- a/FHEM/00_RPII2C.pm +++ b/FHEM/00_RPII2C.pm @@ -30,45 +30,44 @@ my $libcheck_SMBus = 1; my $check_ioctl_ph = 1; sub RPII2C_Initialize($) { - my ($hash) = @_; - - eval "use Device::SMBus;"; - $libcheck_SMBus = 0 if($@); - eval {require "sys/ioctl.ph"}; - $check_ioctl_ph = 0 if($@); + my ($hash) = @_; + eval "use Device::SMBus;"; + $libcheck_SMBus = 0 if($@); + eval {require "sys/ioctl.ph"}; + $check_ioctl_ph = 0 if($@); # Provider $hash->{Clients} = join (':',@clients); - #$hash->{WriteFn} = "RPII2C_Write"; #wird vom client per IOWrite($@) aufgerufen - $hash->{I2CWrtFn} = "RPII2C_Write"; #zum testen als alternative fuer IOWrite + #$hash->{WriteFn} = "RPII2C_Write"; #wird vom client per IOWrite($@) aufgerufen + $hash->{I2CWrtFn} = "RPII2C_Write"; #zum testen als alternative fuer IOWrite # Normal devices - $hash->{DefFn} = "RPII2C_Define"; - $hash->{UndefFn} = "RPII2C_Undef"; - $hash->{GetFn} = "RPII2C_Get"; - $hash->{SetFn} = "RPII2C_Set"; - $hash->{AttrFn} = "RPII2C_Attr"; + $hash->{DefFn} = "RPII2C_Define"; + $hash->{UndefFn} = "RPII2C_Undef"; + $hash->{GetFn} = "RPII2C_Get"; + $hash->{SetFn} = "RPII2C_Set"; + $hash->{AttrFn} = "RPII2C_Attr"; $hash->{NotifyFn} = "RPII2C_Notify"; - $hash->{AttrList}= "do_not_notify:1,0 ignore:1,0 showtime:1,0 " . - "$readingFnAttributes"; + $hash->{AttrList}= "do_not_notify:1,0 ignore:1,0 showtime:1,0 " . + "$readingFnAttributes"; $hash->{AttrList} .= " useHWLib:IOCTL,SMBus " if( $libcheck_SMBus && $check_ioctl_ph); $hash->{AttrList} .= " swap_i2c0:off,on"; } ##################################### sub RPII2C_Define($$) { # - my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); - unless(@a == 3) { - my $msg = "wrong syntax: define RPII2C <0|1>"; - Log3 undef, 2, $msg; - return $msg; - } + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + unless(@a == 3) { + my $msg = "wrong syntax: define RPII2C <0|1>"; + Log3 undef, 2, $msg; + return $msg; + } $hash->{SMBus_exists} = $libcheck_SMBus if($libcheck_SMBus); $hash->{ioctl_ph_exists} = $check_ioctl_ph if($check_ioctl_ph); my $name = $a[0]; - my $dev = $a[2]; + my $dev = $a[2]; if ($check_ioctl_ph) { $hash->{hwfn} = \&RPII2C_HWACCESS_ioctl; @@ -78,53 +77,53 @@ sub RPII2C_Define($$) { # return $name . ": Error! no library for Hardware access installed"; } my $device = "/dev/i2c-".$dev; - if ( RPII2C_CHECK_GPIO_DEVICE($device) ) { - Log3 $hash, 1, "file $device not accessible try to use gpio utility to fix it"; + if ( RPII2C_CHECK_I2C_DEVICE($device) ) { + Log3 $hash, 3, "$hash->{NAME}: file $device not accessible try to use gpio utility to fix it"; if ( defined(my $ret = RPII2C_CHECK_GPIO_UTIL($gpioprg)) ) { - Log3 $hash, 1, $ret if $ret; + Log3 $hash, 1, "$hash->{NAME}: " . $ret if $ret; } else { #I2C Devices mit gpio utility fuer FHEM User lesbar machen my $exp = $gpioprg.' load i2c'; $exp = `$exp`; } - } + } $hash->{NOTIFYDEV} = "global"; - #$hash->{Clients} = $clientsI2C; - #$hash->{MatchList} = \%matchListI2C; + #$hash->{Clients} = $clientsI2C; + #$hash->{MatchList} = \%matchListI2C; - if($dev eq "none") { - Log3 $name, 1, "$name device is none, commands will be echoed only"; - $attr{$name}{dummy} = 1; - return undef; - } - my $check = RPII2C_CHECK_GPIO_DEVICE($device); - return $name . $check if $check; + if($dev eq "none") { + Log3 $name, 1, "$name device is none, commands will be echoed only"; + $attr{$name}{dummy} = 1; + return undef; + } + my $check = RPII2C_CHECK_I2C_DEVICE($device); + return $name . $check if $check; $hash->{DeviceName} = $device; $hash->{STATE} = "initialized"; - return undef; + return undef; } ##################################### sub RPII2C_Notify { # - my ($hash,$dev) = @_; - my $name = $hash->{NAME}; - my $type = $hash->{TYPE}; - if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) { - RPII2C_forall_clients($hash,\&RPII2C_Init_Client,undef);; - } elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) { - } + my ($hash,$dev) = @_; + my $name = $hash->{NAME}; + my $type = $hash->{TYPE}; + if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) { + RPII2C_forall_clients($hash,\&RPII2C_Init_Client,undef);; + } elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) { + } } ##################################### sub RPII2C_forall_clients($$$) { # - my ($hash,$fn,$args) = @_; - foreach my $d ( sort keys %main::defs ) { - if ( defined( $main::defs{$d} ) - && defined( $main::defs{$d}{IODev} ) - && $main::defs{$d}{IODev} == $hash ) { - &$fn($main::defs{$d},$args); - } - } - return undef; + my ($hash,$fn,$args) = @_; + foreach my $d ( sort keys %main::defs ) { + if ( defined( $main::defs{$d} ) + && defined( $main::defs{$d}{IODev} ) + && $main::defs{$d}{IODev} == $hash ) { + &$fn($main::defs{$d},$args); + } + } + return undef; } ##################################### sub RPII2C_Init_Client($@) { # @@ -142,19 +141,19 @@ sub RPII2C_Init_Client($@) { # } ##################################### sub RPII2C_Undef($$) { # - my ($hash, $arg) = @_; - my $name = $hash->{NAME}; + my ($hash, $arg) = @_; + my $name = $hash->{NAME}; - foreach my $d (sort keys %defs) { - if(defined($defs{$d}) && - defined($defs{$d}{IODev}) && - $defs{$d}{IODev} == $hash) - { - Log3 $name, 3, "deleting port for $d"; - delete $defs{$d}{IODev}; - } - } - return undef; + foreach my $d (sort keys %defs) { + if(defined($defs{$d}) && + defined($defs{$d}{IODev}) && + $defs{$d}{IODev} == $hash) + { + Log3 $name, 3, "deleting port for $d"; + delete $defs{$d}{IODev}; + } + } + return undef; } ##################################### sub RPII2C_Attr(@){ @@ -170,20 +169,20 @@ sub RPII2C_Attr(@){ } ##################################### sub RPII2C_Set($@) { #writeBlock noch nicht fertig - my ($hash, @a) = @_; - my $name = shift @a; - my $type = shift @a; + my ($hash, @a) = @_; + my $name = shift @a; + my $type = shift @a; my @sets = ('writeByte', 'writeByteReg', 'writeBlock'); #, 'writeNBlock'); - return "Unknown argument $type, choose one of " . join(" ", @sets) if @a < 2; + return "Unknown argument $type, choose one of " . join(" ", @sets) if @a < 2; foreach (@a) { #Hexwerte pruefen und in Dezimalwerte wandeln return "$name: $_ is no 1byte hexadecimal value" if $_ !~ /^(0x|)[0-9A-F]{1,2}$/xi ; $_ = hex; } - my $i2ca = shift @a; + my $i2ca = shift @a; return "$name: I2C Address not valid" unless ($i2ca > 3 && $i2ca < 128); #pruefe auf Hexzahl zwischen 4 und 7F - my $i2chash = { i2caddress => $i2ca, direction => "i2cwrite" }; + my $i2chash = { i2caddress => $i2ca, direction => "i2cwrite" }; my ($reg, $nbyte, $data) = undef; if ($type eq "writeByte") { $data = join(" ", @a); @@ -218,15 +217,15 @@ sub RPII2C_Set($@) { #writeBlock noch nicht fertig } ##################################### fertig? sub RPII2C_Get($@) { # - my ($hash, @a) = @_; - my $nargs = int(@a); - my $name = $hash->{NAME}; - my @gets = ('read'); - unless ( exists($a[1]) && $a[1] ne "?" && grep {/^$a[1]$/} @gets ) { + my ($hash, @a) = @_; + my $nargs = int(@a); + my $name = $hash->{NAME}; + my @gets = ('read'); + unless ( exists($a[1]) && $a[1] ne "?" && grep {/^$a[1]$/} @gets ) { return "Unknown argument $a[1], choose one of " . join(" ", @gets); - } + } if ($a[1] eq "read") { - return "use: \"get $name $a[1] [ []]\"" if(@a < 3); + return "use: \"get $name $a[1] [ []]\"" if(@a < 3); return "$name: I2C Address not valid" unless ( $a[2] =~ /^(0x|)([0-7]|)[0-9A-F]$/xi); return "$name register address must be a hexvalue" if (defined($a[3]) && $a[3] !~ /^(0x|)[0-9A-F]{1,4}$/xi); return "$name number of bytes must be decimal value" if (defined($a[4]) && $a[4] !~ /^[0-9]{1,2}$/); @@ -234,41 +233,41 @@ sub RPII2C_Get($@) { # $i2chash->{reg} = hex($a[3]) if defined($a[3]); #startadresse zum lesen $i2chash->{nbyte} = $a[4] if defined($a[4]); #Log3 $hash, 1, "Reg: ". $i2chash->{reg}; - #my $status = RPII2C_HWACCESS_ioctl($hash, $i2chash); + #my $status = RPII2C_HWACCESS_ioctl($hash, $i2chash); my $status = &{$hash->{hwfn}}($hash, $i2chash); #my $received = join(" ", @{$i2chash->{received}}); #als Array my $received = $i2chash->{received}; #als Scalar undef $i2chash; #Hash loeschen return (defined($received) ? "received : " . $received ." | " : "" ) . " transmission: $status"; } - return undef; + return undef; } ##################################### sub RPII2C_Write($$) { #wird vom Client aufgerufen - my ($hash, $clientmsg) = @_; + my ($hash, $clientmsg) = @_; my $name = $hash->{NAME}; my $ankommen = "$name: vom client empfangen"; - foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; } + foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; } Log3 $hash, 5, $ankommen; if ( $clientmsg->{direction} && $clientmsg->{i2caddress} ) { $clientmsg->{$name . "_" . "SENDSTAT"} = &{$hash->{hwfn}}($hash, $clientmsg); - #$clientmsg->{$name . "_" . "SENDSTAT"} = RPII2C_HWACCESS($hash, $clientmsg); + #$clientmsg->{$name . "_" . "SENDSTAT"} = RPII2C_HWACCESS($hash, $clientmsg); } foreach my $d ( sort keys %main::defs ) { #zur Botschaft passenden Clienten ermitteln geht auf Client: I2CRecFn - #Log3 $hash, 1, "d: $d". ($main::defs{$d}{IODev}? ", IODev: $main::defs{$d}{IODev}":"") . ($main::defs{$d}{I2C_Address} ? ", I2C: $main::defs{$d}{I2C_Address}":"") . ($clientmsg->{i2caddress} ? " CI2C: $clientmsg->{i2caddress}" : ""); - if ( defined( $main::defs{$d} ) + #Log3 $hash, 1, "d: $d". ($main::defs{$d}{IODev}? ", IODev: $main::defs{$d}{IODev}":"") . ($main::defs{$d}{I2C_Address} ? ", I2C: $main::defs{$d}{I2C_Address}":"") . ($clientmsg->{i2caddress} ? " CI2C: $clientmsg->{i2caddress}" : ""); + if ( defined( $main::defs{$d} ) && defined( $main::defs{$d}{IODev} ) && $main::defs{$d}{IODev} == $hash && defined( $main::defs{$d}{I2C_Address} ) && defined($clientmsg->{i2caddress}) - && $main::defs{$d}{I2C_Address} eq $clientmsg->{i2caddress} ) { - my $chash = $main::defs{$d}; + && $main::defs{$d}{I2C_Address} eq $clientmsg->{i2caddress} ) { + my $chash = $main::defs{$d}; Log3 $hash, 5, "$name ->Client gefunden: $d". ($main::defs{$d}{I2C_Address} ? ", I2Caddress: $main::defs{$d}{I2C_Address}":"") . ($clientmsg->{data} ? " Data: $clientmsg->{data}" : ""); - CallFn($d, "I2CRecFn", $chash, $clientmsg); + CallFn($d, "I2CRecFn", $chash, $clientmsg); undef $clientmsg #Hash loeschen nachdem Daten verteilt wurden - } + } } - return undef; + return undef; } ##################################### #FRM_forall_clients($$$) @@ -285,10 +284,9 @@ sub RPII2C_Write($$) { #wird vom Client aufgerufen #} ##################################### -sub RPII2C_CHECK_GPIO_DEVICE { +sub RPII2C_CHECK_I2C_DEVICE { my ($dev) = @_; - my $ret = undef; - #unless (defined($hash->{gpio_util_exists})) { + my $ret = undef; if(-e $dev) { if(-r $dev) { unless(-w $dev) { @@ -305,8 +303,7 @@ sub RPII2C_CHECK_GPIO_DEVICE { sub RPII2C_CHECK_GPIO_UTIL { my ($gpioprg) = @_; - my $ret = undef; - #unless (defined($hash->{gpio_util_exists})) { + my $ret = undef; if(-e $gpioprg) { if(-x $gpioprg) { unless(-u $gpioprg) { @@ -336,13 +333,13 @@ sub RPII2C_SWAPI2C0 { system "$gpioprg -g mode 1 ALT0"; } } else { - Log3 $hash, 1, $ret if $ret; + Log3 $hash, 1, $hash->{NAME} . ": " . $ret if $ret; } return } sub RPII2C_HWACCESS($$) { - my ($hash, $clientmsg) = @_; + my ($hash, $clientmsg) = @_; my $status = "error"; my $inh = undef; Log3 $hash, 5, "$hash->{NAME}: HWaccess I2CAddr: " . sprintf("0x%.2X", $clientmsg->{i2caddress}); @@ -369,23 +366,23 @@ sub RPII2C_HWACCESS($$) { # } #hier Mehrfachbeschreibung eines Registers noch entfernen und dafuer Bereich mit Registeroperationen beschreiben } elsif (defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #Register beschreiben - my @data = split(" ", $clientmsg->{data}); - foreach (@data) { + my @data = split(" ", $clientmsg->{data}); + foreach (@data) { $inh = $dev->writeByteData($clientmsg->{reg},$_); Log3 $hash, 5, "$hash->{NAME}; Register ".sprintf("0x%.2X", $clientmsg->{reg})." schreiben - Inhalt: " .sprintf("0x%.2X",$_) . " Returnvar.: $inh"; last if $inh != 0; $status = "Ok" if $inh == 0; } } elsif (defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #Byte(s) schreiben - my @data = split(" ", $clientmsg->{data}); - foreach (@data) { + my @data = split(" ", $clientmsg->{data}); + foreach (@data) { $inh = $dev->writeByte($_); Log3 $hash, 5, "$hash->{NAME} Byte schreiben; Inh: " . $_ . " Returnvar.: $inh"; last if $inh != 0; $status = "Ok" if $inh == 0; } } elsif (defined($clientmsg->{reg}) && $clientmsg->{direction} eq "i2cread") { #Register lesen - my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1; + my $nbyte = defined($clientmsg->{nbyte}) ? $clientmsg->{nbyte} : 1; my $rmsg = ""; for (my $n = 0; $n < $nbyte; $n++) { $inh = $dev->readByteData($clientmsg->{reg} + $n ); @@ -426,14 +423,14 @@ sub RPII2C_HWACCESS_ioctl($$) { my ($fh, $msg) = undef; my $ankommen = "$hash->{NAME}: vom client empfangen"; - foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; } + foreach my $av (keys %{$clientmsg}) { $ankommen .= "|" . $av . ": " . $clientmsg->{$av}; } Log3 $hash, 5, $ankommen; my $i2caddr = hex(sprintf "%x", $clientmsg->{i2caddress}); if ( sysopen(my $fh, $hash->{DeviceName}, O_RDWR) != 1) { #Datei oeffnen - Log3 $hash, 1, "$hash->{NAME}: HWaccess sysopen failure: $!" + Log3 $hash, 3, "$hash->{NAME}: HWaccess sysopen failure: $!" } elsif( not defined( ioctl($fh,$I2C_SLAVE,$i2caddr) ) ) { #I2C Adresse per ioctl setzen - Log3 $hash, 1, "$hash->{NAME}: HWaccess (0x".unpack( "H2",pack "C", $clientmsg->{i2caddress}).") ioctl failure: $!" + Log3 $hash, 3, "$hash->{NAME}: HWaccess (0x".unpack( "H2",pack "C", $clientmsg->{i2caddress}).") ioctl failure: $!" } elsif (defined($clientmsg->{nbyte}) && defined($clientmsg->{reg}) && defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cblockwrite") { #Registerblock beschreiben my $data = chr($clientmsg->{reg}); foreach (split(" ", $clientmsg->{data})) { @@ -441,24 +438,24 @@ sub RPII2C_HWACCESS_ioctl($$) { } my $retval = syswrite($fh, $data, length($data)); unless (defined($retval) && $retval == length($data)) { - Log3 $hash, 1, "$hash->{NAME}: HWaccess blockweise nach 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, Reg: 0x". unpack( "H2",pack "C", $clientmsg->{reg}) . " Inh: $clientmsg->{data}, laenge: ".length($data)."| -> syswrite failure: $!"; + Log3 $hash, 3, "$hash->{NAME}: HWaccess blockweise nach 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, Reg: 0x". unpack( "H2",pack "C", $clientmsg->{reg}) . " Inh: $clientmsg->{data}, laenge: ".length($data)."| -> syswrite failure: $!"; } else { $status = "Ok"; Log3 $hash, 5, "$hash->{NAME}: HWaccess block schreiben, Reg: 0x". unpack( "H2",pack "C", $clientmsg->{reg}) . " Inh(dec):|$clientmsg->{data}|, laenge: |".length($data)."|"; } #(my $datah = $data) =~ s/(.|\n)/sprintf("%.2X ",ord($1))/eg; - #Log3 $hash, 1, "$hash->{NAME}: HWaccess block schreiben data:|$clientmsg->{data}|, laenge: |".length($data)."|"; + #Log3 $hash, 1, "$hash->{NAME}: HWaccess block schreiben data:|$clientmsg->{data}|, laenge: |".length($data)."|"; #$status = "Ok" if $resulw == length($data); } elsif (defined($clientmsg->{data}) && $clientmsg->{direction} eq "i2cwrite") { #byteweise beschreiben - my $reg = undef; + my $reg = undef; $reg = $clientmsg->{reg} if (defined($clientmsg->{reg})); $status = "Ok"; foreach (split(" ", $clientmsg->{data})) { my $data = (defined($reg) ? chr($reg++) : "") . chr($_); my $retval = syswrite($fh, $data, length($data)); unless (defined($retval) && $retval == length($data)) { - Log3 $hash, 1, "$hash->{NAME}: HWaccess byteweise nach 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, ". (defined($reg) ? "Reg: 0x". unpack( "H2",pack "C", ($reg - 1)) . " " : "")."Inh: 0x" . unpack( "H2",pack "C", $_) .", laenge: ".length($data)."| -> syswrite failure: $!"; + Log3 $hash, 3, "$hash->{NAME}: HWaccess byteweise nach 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." schreiben, ". (defined($reg) ? "Reg: 0x". unpack( "H2",pack "C", ($reg - 1)) . " " : "")."Inh: 0x" . unpack( "H2",pack "C", $_) .", laenge: ".length($data)."| -> syswrite failure: $!"; $status = "error"; last; } @@ -472,14 +469,14 @@ sub RPII2C_HWACCESS_ioctl($$) { Log3 $hash, 5, "$hash->{NAME}: HWaccess byteweise lesen setze Registerpointer auf " . ($clientmsg->{reg} + $n); my $retval = syswrite($fh, chr($clientmsg->{reg} + $n), 1); unless (defined($retval) && $retval == 1) { - Log3 $hash, 1, "$hash->{NAME}: HWaccess byteweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg} + $n)) : "") . " -> syswrite failure: $!" if $!; + Log3 $hash, 3, "$hash->{NAME}: HWaccess byteweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg} + $n)) : "") . " -> syswrite failure: $!" if $!; last; } } my $buf = undef; my $retval = sysread($fh, $buf, 1); unless (defined($retval) && $retval == 1) { - Log3 $hash, 1, "$hash->{NAME}: HWaccess byteweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg} + $n)) : "") . " -> sysread failure: $!" if $!; + Log3 $hash, 3, "$hash->{NAME}: HWaccess byteweise von 0x".unpack( "H2",pack "C", $clientmsg->{i2caddress})." lesen,". (defined($clientmsg->{reg}) ? " Reg: 0x". unpack( "H2",pack "C", ($clientmsg->{reg} + $n)) : "") . " -> sysread failure: $!" if $!; last; } $rmsg .= ord($buf); @@ -508,43 +505,45 @@ sub RPII2C_HWACCESS_ioctl($$) { preliminary:
  • - Access rights for /dev/i2c-* devices + load I2C kernel modules:
    + open /etc/modules
    +
      sudo nano /etc/modules

    + add these lines
    +
      + i2c-dev
      + i2c-bcm2708
      +
    +

  • + +
  • Choose one of the three follwing methodes do grant access to /dev/i2c-* for FHEM user:
    • - Add following lines into /etc/init.d/fhem before perl fhem.pl line in start or into /etc/rc.local:
      + sudo apt-get install i2c-tools
      + sudo adduser fhem i2c
      + sudo reboot

      +

    • +
    • + Add following lines into /etc/init.d/fhem before perl fhem.pl line in start or into /etc/rc.local:
      sudo chown fhem /dev/i2c-*
      sudo chgrp dialout /dev/i2c-*
      sudo chmod +t /dev/i2c-*
      sudo chmod 660 /dev/i2c-*
      -
    • -
    • - Alternatively for Raspberry Pi you can install the gpio utility from WiringPi library change access rights of I2C-Interface
      +

    • +
    • + Alternatively for Raspberry Pi you can install the gpio utility from WiringPi library change access rights of I2C-Interface
      WiringPi installation is described here: RPI_GPIO.
      gpio utility will be automaticly used, if installed.
      -
    • + Important: to use I2C-0 at P5 connector you must use attribute swap_i2c0.
      +
    -
  • +
  • - installation of i2c dependencies:
    - sudo apt-get install libi2c-dev i2c-tools build-essential
    -
  • -
  • - load I2C kernel modules:
    - open /etc/modules
    - sudo nano /etc/modules
    - add theese lines
    - - i2c-dev
    - i2c-bcm2708
    -
    -
  • -
  • - Optional, access via IOCTL will be used if Device::SMBus is not present.
    + Optional: access via IOCTL will be used if Device::SMBus is not present.
    To access the I2C-Bus via the Device::SMBus module, following steps are necessary:
    - sudo apt-get install libmoose-perl
    - sudo cpan Device::SMBus

    +
      sudo apt-get install libmoose-perl
      + sudo cpan Device::SMBus


@@ -559,15 +558,15 @@ sub RPII2C_HWACCESS_ioctl($$) {
  • Write one byte (or more bytes sequentially) directly to an I2C device (for devices that have only one register to write):
    - set <name> writeByte <I2C Address> <value>

    + set <name> writeByte <I2C Address> <value>

  • Write n-bytes to an register range (as an series of single register write operations), beginning at the specified register:
    - set <name> writeByteReg <I2C Address> <Register Address> <value>

    + set <name> writeByteReg <I2C Address> <Register Address> <value>

  • Write n-bytes to an register range (as an block write operation), beginning at the specified register:
    - set <name> writeBlock <I2C Address> <Register Address> <value>

    + set <name> writeBlock <I2C Address> <Register Address> <value>


  • Examples:
      @@ -628,55 +627,57 @@ sub RPII2C_HWACCESS_ioctl($$) {

      RPII2C

        - Ermöglicht den Zugriff auf die I2C Schnittstellen des Raspberry Pi über logische Module. Register von I2C IC's können auch direkt gelesen und geschrieben werden.

        + Ermöglicht den Zugriff auf die I2C Schnittstellen des Raspberry Pi, BBB, Cubie über logische Module. Register von I2C IC's können auch direkt gelesen und geschrieben werden.

        Dieses Modul funktioniert grunsätzlich auf allen Linux Systemen, die /dev/i2c-x bereitstellen.

        Vorbereitung:
        • + I2C Kernelmodule laden:
          + modules Datei öffnen
          +
            sudo nano /etc/modules

          + folgendes einfügen
          +
            + i2c-dev
            + i2c-bcm2708
            +
          +

        • +
        • Eine der folgenden drei Möglichkeiten wählen um dem FHEM User Zugriff auf /dev/i2c-* zu geben:
          • - Folgende Zeilen müssen der Datei /etc/init.d/fhem vor perl fhem.pl in start hinzu, oder in die Datei /etc/rc.local eingefügt werden:
            + + sudo apt-get install i2c-tools
            + sudo adduser fhem i2c

            +

          • +
          • + Folgende Zeilen entweder in die Datei /etc/init.d/fhem vor perl fhem.pl in start, oder in die Datei /etc/rc.local eingefügen:
            sudo chown fhem /dev/i2c-*
            sudo chgrp dialout /dev/i2c-*
            sudo chmod +t /dev/i2c-*
            sudo chmod 660 /dev/i2c-*
            -
          • -
          • - Für das Raspberry Pi kann alternativ das gpio Utility der WiringPi Bibliothek benutzt werden um FHEM Schreibrechte auf die I2C Schnittstelle zu bekommen.
            +

          • +
          • + Für das Raspberry Pi kann alternativ das gpio Utility der WiringPi Bibliothek benutzt werden um FHEM Schreibrechte auf die I2C Schnittstelle zu bekommen.
            WiringPi Installation ist hier beschrieben: RPI_GPIO
            Das gpio Utility wird, wenn vorhanden, automatisch verwendet
            -
          • + Wichtig: um den I2C-0 am P5 Stecker des Raspberry nutzen zu können muss das Attribut swap_i2c0 verwendet werden.
            +
          -
        • +
        • - Installation der I2C Abhängigkeiten:
          - sudo apt-get install libi2c-dev i2c-tools build-essential
          -
        • -
        • - I2C Kernelmodule laden:
          - modules Datei öffnen
          - sudo nano /etc/modules
          - folgendes einfügen
          - - i2c-dev
          - i2c-bcm2708
          -
          -
        • -
        • - Optional, Hardwarezugriff via IOCTL wird standardmäßig genutzt, wenn Device::SMBus nicht installiert ist
          + Optional: Hardwarezugriff via IOCTL wird standardmäßig genutzt, wenn Device::SMBus nicht installiert ist
          Soll der Hardwarezugriff über das Perl Modul Device::SMBus erfolgen sind diese Schritte notwendig:
          - sudo apt-get install libmoose-perl
          - sudo cpan Device::SMBus

          +
            sudo apt-get install libmoose-perl
            + sudo cpan Device::SMBus


        Define
          define <name> RPII2C <I2C Bus Number>
          - Die <I2C Bus Number> ist die Nummer des I2C Bus an den die I2C IC's angeschlossen werden (0 oder 1)

          + Die <I2C Bus Number> ist die Nummer des I2C Bus an den die I2C IC's angeschlossen werden

        @@ -684,15 +685,15 @@ sub RPII2C_HWACCESS_ioctl($$) {
        • Schreibe ein Byte (oder auch mehrere nacheinander) direkt auf ein I2C device (manche I2C Module sind so einfach, das es nicht einmal mehrere Register gibt):
          - set <name> writeByte <I2C Address> <value>

          + set <name> writeByte <I2C Address> <value>

        • Schreibe n-bytes auf einen Registerbereich (als Folge von Einzelbefehlen), beginnend mit dem angegebenen Register:
          - set <name> writeByteReg <I2C Address> <Register Address> <value>

          + set <name> writeByteReg <I2C Address> <Register Address> <value>

        • Schreibe n-bytes auf einen Registerbereich (als Blockoperation), beginnend mit dem angegebenen Register:
          - set <name> writeBlock <I2C Address> <Register Address> <value>

          + set <name> writeBlock <I2C Address> <Register Address> <value>


        • Beispiele: