2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-19 12:46:03 +00:00

modified comments

corrections in commandref

git-svn-id: https://svn.fhem.de/fhem/trunk@6209 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klauswitt 2014-07-06 21:38:39 +00:00
parent b051c575ad
commit 34b2e470d0

View File

@ -1,13 +1,9 @@
##############################################################################
# $Id$
##############################################################################
# Modul for I2C PWM Driver MCP23017
#
# define <name> I2C_MCP23017 <I2C-Adresse>
# set <name> <port> <value>
#
# contributed by Klaus Wittstock (2013) email: klauswittstock bei gmail punkt com
# Modul for I2C GPIO Extender MCP23017
#
# contributed by Klaus Wittstock (2013) email: klauswittstock bei gmail
##############################################################################
package main;
@ -17,27 +13,27 @@ use SetExtensions;
use Scalar::Util qw(looks_like_number);
my %Registers = (
'IODIRA' => 0x00, #1 = input; 0 = output (default 1)
'IODIRB' => 0x01,
'IPOLA' => 0x02, #1 inverts logic (default 0)
'IPOLB' => 0x03,
'GPINTENA' => 0x04, #1 enables the pin for interrupt-on-change (default 0)
'GPINTENB' => 0x05,
'DEFVALA' => 0x06, #The default comparison value for interrupt (opposite value will caues an interrupt) (default 0)
'DEFVALB' => 0x07,
'INTCONA' => 0x08, #If a bit is set, the corresponding I/O pin is compared against DEFVAL register. Otherwise against the previous value.
'INTCONB' => 0x09,
'IOCON' => 0x0A,
'GPPUA' => 0x0C, #100k pull up resistor for input
'GPPUB' => 0x0D,
'INTFA' => 0x0E, #shows which Pin caused the interrupt (ro)
'INTFB' => 0x0F,
'INTCAPA' => 0x10, #status from all registers at the time the interrupt occured, remain unchanged until a read of INTCAP or GPIO. (ro)
'INTCAPB' => 0x11,
'GPIOA' => 0x12, #value on the ports (r/w)
'GPIOB' => 0x13,
'OLATA' => 0x14,
'OLATB' => 0x15,
'IODIRA' => 0x00, #1 = input; 0 = output (default 1)
'IODIRB' => 0x01,
'IPOLA' => 0x02, #1 inverts logic (default 0)
'IPOLB' => 0x03,
'GPINTENA' => 0x04, #1 enables the pin for interrupt-on-change (default 0)
'GPINTENB' => 0x05,
'DEFVALA' => 0x06, #The default comparison value for interrupt (opposite value will caues an interrupt) (default 0)
'DEFVALB' => 0x07,
'INTCONA' => 0x08, #If a bit is set, the corresponding I/O pin is compared against DEFVAL register. Otherwise against the previous value.
'INTCONB' => 0x09,
'IOCON' => 0x0A,
'GPPUA' => 0x0C, #100k pull up resistor for input
'GPPUB' => 0x0D,
'INTFA' => 0x0E, #shows which Pin caused the interrupt (ro)
'INTFB' => 0x0F,
'INTCAPA' => 0x10, #status from all registers at the time the interrupt occured, remain unchanged until a read of INTCAP or GPIO. (ro)
'INTCAPB' => 0x11,
'GPIOA' => 0x12, #value on the ports (r/w)
'GPIOB' => 0x13,
'OLATA' => 0x14,
'OLATB' => 0x15,
);
my %setsP = (
@ -55,70 +51,70 @@ my %intout = (
);
###############################################################################
sub I2C_MCP23017_Initialize($) {
my ($hash) = @_;
$hash->{DefFn} = "I2C_MCP23017_Define";
$hash->{InitFn} = 'I2C_MCP23017_Init';
$hash->{UndefFn} = "I2C_MCP23017_Undefine";
$hash->{AttrFn} = "I2C_MCP23017_Attr";
$hash->{StateFn} = "I2C_MCP23017_State";
$hash->{SetFn} = "I2C_MCP23017_Set";
$hash->{GetFn} = "I2C_MCP23017_Get";
$hash->{I2CRecFn} = "I2C_MCP23017_I2CRec";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 showtime:1,0".
"poll_interval OutputPorts ".
"Pullup invert_input Interrupt OnStartup ".
my ($hash) = @_;
$hash->{DefFn} = "I2C_MCP23017_Define";
$hash->{InitFn} = 'I2C_MCP23017_Init';
$hash->{UndefFn} = "I2C_MCP23017_Undefine";
$hash->{AttrFn} = "I2C_MCP23017_Attr";
$hash->{StateFn} = "I2C_MCP23017_State";
$hash->{SetFn} = "I2C_MCP23017_Set";
$hash->{GetFn} = "I2C_MCP23017_Get";
$hash->{I2CRecFn} = "I2C_MCP23017_I2CRec";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 showtime:1,0".
"poll_interval OutputPorts ".
"Pullup invert_input Interrupt OnStartup ".
"InterruptOut:separate_active-low,separate_active-high,separate_open-drain,connected_active-low,connected_active-high,connected_open-drain ".
"$readingFnAttributes";
"$readingFnAttributes";
}
###############################################################################
sub I2C_MCP23017_Define($$) {
my ($hash, $def) = @_;
my @a = split("[ \t]+", $def);
$hash->{STATE} = 'defined';
if ($main::init_done) {
eval { I2C_MCP23017_Init( $hash, [ @a[ 2 .. scalar(@a) - 1 ] ] ); };
return I2C_MCP23017_Catch($@) if $@;
}
return undef;
if ($main::init_done) {
eval { I2C_MCP23017_Init( $hash, [ @a[ 2 .. scalar(@a) - 1 ] ] ); };
return I2C_MCP23017_Catch($@) if $@;
}
return undef;
}
###############################################################################
sub I2C_MCP23017_Init($$) { #Geraet beim anlegen/booten/nach Neuverbindung (wieder) initialisieren
my ( $hash, $args ) = @_;
if (defined $args && int(@$args) != 1) {
return "Define: Wrong syntax. Usage:\n" .
"define <name> I2C_MCP23017 <i2caddress>";
return "Define: Wrong syntax. Usage:\n" .
"define <name> I2C_MCP23017 <i2caddress>";
}
if (defined (my $address = shift @$args)) {
$hash->{I2C_Address} = $address =~ /^0.*$/ ? oct($address) : $address;
if (defined (my $address = shift @$args)) {
$hash->{I2C_Address} = $address =~ /^0.*$/ ? oct($address) : $address;
} else {
return "$hash->{NAME} I2C Address not valid";
return "$hash->{NAME} I2C Address not valid";
}
AssignIoPort($hash);
my $msg = '';
#Output level wieder setzen
my $sbyte = 0;
foreach (reverse 0..7) {
#Output level wieder setzen
my $sbyte = 0;
foreach (reverse 0..7) {
$sbyte += $setsP{ReadingsVal($hash->{NAME},"PortA".$_,"off")} << ($_); #Werte fuer PortA aus dem Reading holen
$sbyte += $setsP{ReadingsVal($hash->{NAME},"PortB".$_,"off")} << (8 + $_);
}
$msg = I2C_MCP23017_SetRegPair($hash, $sbyte, "GPIO") if $sbyte;
}
$msg = I2C_MCP23017_SetRegPair($hash, $sbyte, "GPIO") if $sbyte;
#bei Init IC neu konfigurieren
if ( defined ( my $val = AttrVal($hash->{NAME},"invert_input",undef)) ) {
if ( defined ( my $val = AttrVal($hash->{NAME},"invert_input",undef)) ) {
($msg, my $regval) = I2C_MCP23017_CheckAttr($hash, "invert_input", $val);
$msg = I2C_MCP23017_SetRegPair($hash, $regval, "IPOL") unless $msg;
}
if ( defined ( my $val = AttrVal($hash->{NAME},"OutputPorts",undef)) ) {
}
if ( defined ( my $val = AttrVal($hash->{NAME},"OutputPorts",undef)) ) {
($msg, my $regval) = I2C_MCP23017_CheckAttr($hash, "OutputPorts", $val);
$msg = I2C_MCP23017_SetRegPair($hash, ~$regval, "IODIR") unless $msg;
}
if ( defined ( my $val = AttrVal($hash->{NAME},"Pullup",undef)) ) {
}
if ( defined ( my $val = AttrVal($hash->{NAME},"Pullup",undef)) ) {
($msg, my $regval) = I2C_MCP23017_CheckAttr($hash, "Pullup", $val);
$msg = I2C_MCP23017_SetRegPair($hash, $regval, "GPPU") unless $msg;
}
if ( defined ( my $val = AttrVal($hash->{NAME},"Interrupt",undef)) ) {
}
if ( defined ( my $val = AttrVal($hash->{NAME},"Interrupt",undef)) ) {
($msg, my $regval) = I2C_MCP23017_CheckAttr($hash, "Interrupt", $val);
$msg = I2C_MCP23017_SetRegPair($hash, $regval, "GPINTEN") unless $msg;
}
}
if ( defined ( my $val = AttrVal($hash->{NAME},"InterruptOut",undef)) ) {
my $regval = 0;
$regval = $intout{$val} if defined $val;
@ -133,25 +129,25 @@ sub I2C_MCP23017_Init($$) { #Geraet beim anlegen/booten
return "no IODev assigned to '$hash->{NAME}'";
}
}
}
$hash->{STATE} = 'Initialized';
return ($msg) ? $msg : undef;
}
###############################################################################
sub I2C_MCP23017_Catch($) { #Fehlermeldung von eval formattieren
my $exception = shift;
if ($exception) {
$exception =~ /^(.*)( at.*FHEM.*)$/;
return $1;
}
return undef;
my $exception = shift;
if ($exception) {
$exception =~ /^(.*)( at.*FHEM.*)$/;
return $1;
}
return undef;
}
###############################################################################
sub I2C_MCP23017_Undefine($$) {
my ($hash, $arg) = @_;
if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) ) {
RemoveInternalTimer($hash);
}
my ($hash, $arg) = @_;
if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) ) {
RemoveInternalTimer($hash);
}
}
###############################################################################
sub I2C_MCP23017_Attr(@) {
@ -160,10 +156,10 @@ sub I2C_MCP23017_Attr(@) {
my $msg = '';
if ($command && $command eq "set" && $attr && $attr eq "IODev") {
if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $val)) {
main::AssignIoPort($hash,$val);
my @def = split (' ',$hash->{DEF});
I2C_MCP23017_Init($hash,\@def) if (defined ($hash->{IODev}));
}
main::AssignIoPort($hash,$val);
my @def = split (' ',$hash->{DEF});
I2C_MCP23017_Init($hash,\@def) if (defined ($hash->{IODev}));
}
}
if ($attr && $attr eq 'poll_interval') {
#my $pollInterval = (defined($val) && looks_like_number($val) && $val > 0) ? $val : 0;
@ -200,7 +196,7 @@ sub I2C_MCP23017_Attr(@) {
$pair[0] =~ m/^(A|B)(0|)[0-7]$/i &&
$pair[1] =~ m/^(on|off|last)$/i);
}
}
}
} elsif ($attr && $attr eq "InterruptOut") {
my $regval = 0;
if (defined $val) {
@ -221,7 +217,7 @@ sub I2C_MCP23017_Attr(@) {
return "no IODev assigned to '$hash->{NAME}'";
}
}
return ($msg) ? $msg : undef;
return ($msg) ? $msg : undef;
}
###############################################################################
sub I2C_MCP23017_State($$$$) { #reload readings at FHEM start
@ -229,7 +225,7 @@ sub I2C_MCP23017_State($$$$) { #reload readings at FHEM s
Log3 $hash, 4, "$hash->{NAME}: $sname kann auf $sval wiederhergestellt werden $tim";
if ($sname =~ m/^Port(A|B)(0|)[0-7]$/i) {
my $po = substr $sname, 4, 2; # Ax oder Bx
Log3 $hash, 5, "$hash->{NAME}: Port = $po";
Log3 $hash, 5, "$hash->{NAME}: Port = $po";
if ( index( AttrVal($hash->{NAME}, "OutputPorts", ""), $po, 0) >= 0 ) {
if ( ( my $pos = index(AttrVal($hash->{NAME},"OnStartup", ""), $po ,0) ) >=0 ) {
my $val = substr AttrVal($hash->{NAME},"OnStartup",undef), $pos + 3, 2;
@ -245,40 +241,40 @@ sub I2C_MCP23017_State($$$$) { #reload readings at FHEM s
$hash->{READINGS}{$sname}{TIME} = $tim;
}
} else {
Log3 $hash, 5, "$hash->{NAME}: $sname wird auf Altzustand: $sval gesetzt (kein Eintrag in on Startup)";
$hash->{READINGS}{$sname}{VAL} = $sval;
$hash->{READINGS}{$sname}{TIME} = $tim;
}
} else {
Log3 $hash, 5, "$hash->{NAME}: $sname wird auf Altzustand: $sval gesetzt (kein Eintrag in on Startup)";
$hash->{READINGS}{$sname}{VAL} = $sval;
$hash->{READINGS}{$sname}{TIME} = $tim;
}
} else {
Log3 $hash, 5, "$hash->{NAME}: $sname ist Eingang";
}
}
}
return undef;
return undef;
}
###############################################################################
sub I2C_MCP23017_CheckAttr {
my ($hash, $attr, $val) = @_;
my $msg = undef;
my ($regval) = 0;
if (defined $val) {
if (defined $val) {
foreach (split (/,/,$val)) {
$msg = "wrong value: $_ for \"attr $hash->{NAME} $attr\" use comma separated values from A0 - A7 and/or B0 - B7" unless ($_ =~ m/^(A|B)(0|)[0-7]$/i);
my $bank = ($_ =~ m/^A/) ? 0 : 8; # A oder B
$_ =~ tr/[a-zA-Z]//d; #Nummer aus String extrahieren
$regval |= 1 << ($_ + $bank);
$regval |= 1 << ($_ + $bank);
}
}
}
return $msg, $regval;
}
###############################################################################
sub I2C_MCP23017_SetRegPair { #set register pair for PortA/B
my ($hash, $regval, $regtype) = @_;
my %port = ();
my %port = ();
$port{A} = $regval & 0xff;
$port{B} = ( $regval >> 8 ) & 0xff;
if (defined (my $iodev = $hash->{IODev})) {
foreach my $reg (keys %port) {
if (defined (my $iodev = $hash->{IODev})) {
foreach my $reg (keys %port) {
#Log3 $hash, 1, "schreibe raus: i2cwrite|$hash->{I2C_Address}|$Registers{$regtype . $reg}|$port{$reg}|";
CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
direction => "i2cwrite",
@ -286,35 +282,35 @@ sub I2C_MCP23017_SetRegPair { #set register pair for Por
reg => $Registers{$regtype . $reg},
data => $port{$reg},
}) if (defined $hash->{I2C_Address});
}
}
} else {
return "no IODev assigned to '$hash->{NAME}'";
}
}
###############################################################################
sub I2C_MCP23017_Poll($) { #function for refresh intervall
my ($hash) = @_;
my $name = $hash->{NAME};
# Read values
I2C_MCP23017_Get($hash, $name);
my $pollInterval = AttrVal($hash->{NAME}, 'poll_interval', 0);
if ($pollInterval > 0) {
InternalTimer(gettimeofday() + ($pollInterval * 60), 'I2C_MCP23017_Poll', $hash, 0);
}
my ($hash) = @_;
my $name = $hash->{NAME};
# Read values
I2C_MCP23017_Get($hash, $name);
my $pollInterval = AttrVal($hash->{NAME}, 'poll_interval', 0);
if ($pollInterval > 0) {
InternalTimer(gettimeofday() + ($pollInterval * 60), 'I2C_MCP23017_Poll', $hash, 0);
}
}
###############################################################################
sub I2C_MCP23017_Set($@) {
my ($hash, @a) = @_;
my $name =$a[0];
my $cmd = $a[1];
my $val = $a[2];
my @outports = sort(split(/,/,AttrVal($name, "OutputPorts", "")));
unless (@a == 3) {
my ($hash, @a) = @_;
my $name =$a[0];
my $cmd = $a[1];
my $val = $a[2];
my @outports = sort(split(/,/,AttrVal($name, "OutputPorts", "")));
unless (@a == 3) {
}
}
my $msg = undef;
if ( $cmd && $cmd =~ m/^P(ort|)(A|B)((0|)[0-7])(,(P|)(ort|)(A|B)((0|)[0-7])){0,7}$/i) {
return "wrong value: $val for \"set $name $cmd\" use one of: " .
return "wrong value: $val for \"set $name $cmd\" use one of: " .
join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) )
unless(exists($setsP{$val}));
my @scmd = split(",", $cmd);
@ -336,19 +332,19 @@ sub I2C_MCP23017_Set($@) {
}
}
}
#Log3 $hash, 1, "$name: endwert: $regval";
#Log3 $hash, 1, "$name: endwert: $regval";
$msg = I2C_MCP23017_SetRegPair($hash, $regval, "GPIO") unless $msg;
} else {
my $list = "";
foreach (0..7) {
next unless ( ("A" . $_) ~~ @outports ); #Inputs überspringen
$list .= "PortA" . $_ . ":" . join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) ) . " ";
}
my $list = "";
foreach (0..7) {
next unless ( ("B" . $_) ~~ @outports ); #Inputs überspringen
next unless ( ("A" . $_) ~~ @outports ); #Inputs ueberspringen
$list .= "PortA" . $_ . ":" . join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) ) . " ";
}
foreach (0..7) {
next unless ( ("B" . $_) ~~ @outports ); #Inputs ueberspringen
$list .= "PortB" . $_ . ":" . join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) ) . " ";
}
$msg = "Unknown argument $a[1], choose one of " . $list;
}
$msg = "Unknown argument $a[1], choose one of " . $list;
}
return ($msg) ? $msg : undef;
@ -360,9 +356,9 @@ sub I2C_MCP23017_Set($@) {
# join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) )
# unless(exists($setsP{$val}));
# my $po = substr $cmd, 4, 1; # A oder B
# my $regaddr = $po eq "A" ? $Registers{GPIOA} : $Registers{GPIOB}; #Adresse für GPIO Register
# my $regaddr = $po eq "A" ? $Registers{GPIOA} : $Registers{GPIOB}; #Adresse fuer GPIO Register
# substr($cmd,0,5,"");
# return "$name error: Port$po$cmd is defined as input" unless ( ($po . $cmd) ~~ @outports ); #Prüfen ob entsprechender Port Input ist
# return "$name error: Port$po$cmd is defined as input" unless ( ($po . $cmd) ~~ @outports ); #Pruefen ob entsprechender Port Input ist
#
# my $sbyte = 0;
# foreach (reverse 0..7) {
@ -379,11 +375,11 @@ sub I2C_MCP23017_Set($@) {
# } else {
# my $list = "";
# foreach (0..7) {
# next unless ( ("A" . $_) ~~ @outports ); #Inputs überspringen
# next unless ( ("A" . $_) ~~ @outports ); #Inputs ueberspringen
# $list .= "PortA" . $_ . ":" . join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) ) . " ";
# }
# foreach (0..7) {
# next unless ( ("B" . $_) ~~ @outports ); #Inputs überspringen
# next unless ( ("B" . $_) ~~ @outports ); #Inputs ueberspringen
# $list .= "PortB" . $_ . ":" . join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) ) . " ";
# }
# return "Unknown argument $a[1], choose one of " . $list;
@ -396,38 +392,38 @@ sub I2C_MCP23017_Set($@) {
}
###############################################################################
sub I2C_MCP23017_Get($@) {
my ($hash, @a) = @_;
my $name =$a[0];
my ($hash, @a) = @_;
my $name =$a[0];
my %sendpackage = ( i2caddress => $hash->{I2C_Address}, direction => "i2cread" );
$sendpackage{reg} = 18; #startadresse zum lesen
$sendpackage{nbyte} = 2;
return "$name: no IO device defined" unless ($hash->{IODev});
my $phash = $hash->{IODev};
my $pname = $phash->{NAME};
my $pname = $phash->{NAME};
CallFn($pname, "I2CWrtFn", $phash, \%sendpackage);
}
###############################################################################
sub I2C_MCP23017_I2CRec($@) { #ueber CallFn vom physical aufgerufen
my ($hash, $clientmsg) = @_;
my $name = $hash->{NAME};
my $phash = $hash->{IODev};
my $pname = $phash->{NAME};
while ( my ( $k, $v ) = each %$clientmsg ) { #erzeugen von Internals für alle Keys in $clientmsg die mit dem physical Namen beginnen
$hash->{$k} = $v if $k =~ /^$pname/ ;
}
#hier noch überprüfen, ob Register und Daten ok
if ($clientmsg->{direction} && defined $clientmsg->{reg} && $clientmsg->{$pname . "_SENDSTAT"} && $clientmsg->{$pname . "_SENDSTAT"} eq "Ok" ) {
my $name = $hash->{NAME};
my $phash = $hash->{IODev};
my $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/ ;
}
#hier noch ueberpruefen, ob Register und Daten ok
if ($clientmsg->{direction} && defined $clientmsg->{reg} && $clientmsg->{$pname . "_SENDSTAT"} && $clientmsg->{$pname . "_SENDSTAT"} eq "Ok" ) {
if ($clientmsg->{direction} eq "i2cread" && $clientmsg->{received}) { # =~ m/^[a-f0-9]{2}$/i) {
#my @rec = @{$clientmsg->{received}}; #bei übergabe im hash als array
my @rec = split(" ",$clientmsg->{received}); #bei übergabe im als skalar
#my @rec = @{$clientmsg->{received}}; #bei uebergabe im hash als array
my @rec = split(" ",$clientmsg->{received}); #bei uebergabe im als skalar
Log3 $hash, 3, "$name: wrong amount of registers transmitted from $pname" unless (@rec == $clientmsg->{nbyte});
foreach (reverse 0..$#rec) { #reverse, damit Inputs (Register 0 und 1 als letztes geschrieben werden)
I2C_MCP23017_UpdReadings($hash, $_ + $clientmsg->{reg} , $rec[$_]);
}
readingsSingleUpdate($hash,"state", "Ok", 1);
} elsif ($clientmsg->{direction} eq "i2cwrite" && defined $clientmsg->{data}) { # =~ m/^[a-f0-9]{2}$/i) {#readings aktualisieren wenn Übertragung ok
} elsif ($clientmsg->{direction} eq "i2cwrite" && defined $clientmsg->{data}) { # =~ m/^[a-f0-9]{2}$/i) {#readings aktualisieren wenn uebertragung ok
I2C_MCP23017_UpdReadings($hash, $clientmsg->{reg} , $clientmsg->{data}) if ( ($clientmsg->{reg} == $Registers{GPIOA}) || ($clientmsg->{reg} == $Registers{GPIOB}) );
readingsSingleUpdate($hash,"state", "Ok", 1);
@ -440,7 +436,7 @@ sub I2C_MCP23017_I2CRec($@) { #ueber CallFn vom physical
(defined($clientmsg->{data}) ? " Data: " . sprintf("0x%.2X", $clientmsg->{data}) : " Data: undef").
(defined($clientmsg->{received}) ? " received: " . sprintf("0x%.2X", $clientmsg->{received}) : " received: undef");
}
} else {
} else {
readingsSingleUpdate($hash,"state", "transmission error", 1);
Log3 $hash, 3, "$name: failure in message from $pname";
Log3 $hash, 3,(defined($clientmsg->{direction}) ? "Direction: " . $clientmsg->{direction} : "Direction: undef").
@ -463,17 +459,17 @@ sub I2C_MCP23017_UpdReadings($$$) { #nach Rueckmeldung read
readingsBeginUpdate($hash);
if ($reg == $Registers{GPIOA}) {
my %rsetsP = reverse %setsP;
foreach (0..7) {
my $pval = 1 & ( $inh >> $_ );
foreach (0..7) {
my $pval = 1 & ( $inh >> $_ );
readingsBulkUpdate($hash, 'PortA'.$_ , $rsetsP{$pval})
if (ReadingsVal($name, 'PortA'.$_,"nix") ne $rsetsP{$pval}); #nur wenn Wert geändert
if (ReadingsVal($name, 'PortA'.$_,"nix") ne $rsetsP{$pval}); #nur wenn Wert geaendert
}
} elsif ($reg == $Registers{GPIOB}) {
my %rsetsP = reverse %setsP;
foreach (0..7) {
my $pval = 1 & ( $inh >> $_ );
foreach (0..7) {
my $pval = 1 & ( $inh >> $_ );
readingsBulkUpdate($hash, 'PortB'.$_ , $rsetsP{$pval})
if (ReadingsVal($name, 'PortB'.$_,"nix") ne $rsetsP{$pval}); #nur wenn Wert geändert
if (ReadingsVal($name, 'PortB'.$_,"nix") ne $rsetsP{$pval}); #nur wenn Wert geaendert
}
}
@ -492,7 +488,7 @@ sub I2C_MCP23017_UpdReadings($$$) { #nach Rueckmeldung read
Provides an interface to the MCP23017 16 channel port extender IC. On Raspberry Pi the Interrupt Pin's can be connected to an GPIO and <a href="#RPI_GPIO">RPI_GPIO</a> can be used to get the port values if an interrupt occurs.<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>
<b>attribute IODev must be set</b><br>
<a name="I2C_MCP23017Define"></a><br>
<b>Define</b>
<ul>
@ -660,7 +656,7 @@ sub I2C_MCP23017_UpdReadings($$$) { #nach Rueckmeldung read
Standard: -, g&uuml;ltige Werte: A0-A7, B0-B7<br><br>
</li>
<li>Interrupt<br>
Durch Komma getrennte Input Ports, die einen Interrupt auf IntA/B auslösen.<br>
Durch Komma getrennte Input Ports, die einen Interrupt auf IntA/B ausl&ouml;sen.<br>
Standard: -, g&uuml;ltige Werte: A0-A7, B0-B7<br><br>
</li>
<li>invert_input<br>
@ -702,4 +698,4 @@ sub I2C_MCP23017_UpdReadings($$$) { #nach Rueckmeldung read
=end html_DE
=cut
=cut