Ein herzerfrischendes Moin Moin ans Forum vorweg!
Hallo klausw
Ich erweitere gerade ein eigenes Modul auf Basis deines 00_RPII2C.pm.
Das klappt auch so weit so gut..
Ich habe eine "_Read" und eine "_I2CRec" - Funktion und wenn ich im Read
CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
direction => "i2cread",
i2caddress => 105,
reg => 0,
nbyte => 50
});
eingebe, gibt er mir auch ganz brav folgendes durch die "_I2CRec"-Funktion im Log-File aus:
clientmsg : $VAR1 = {
'nbyte' => 50,
'reg' => 0,
'myRpiI2C_SENDSTAT' => 'Ok',
'direction' => 'i2cread',
'received' => '1 0 0 0 0 0 0 0 96 3 16 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 49 50 0 0 0 1 0 25 203 65 80 53 0 255 255 255 255 255 255 255 255 255 255 ',
'i2caddress' => 105
};
Wenn ich allerdings absichtlich eine falsche (nicht existente) Adresse eingebe:
CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
direction => "i2cread",
i2caddress => 101,
reg => 0,
nbyte => 50
});
Dann wird die "_I2CRec"-Funktion nicht aufgerufen.
Ich hätte erwartet, dass
clientmsg : $VAR1 = {
'myRpiI2C_SENDSTAT' => 'regerror',
ausgegeben wird.
Wenn ich beispielsweise ein
CallFn($iodev->{NAME}, "I2CWrtFn", $iodev, {
direction => "i2cread",
i2caddress => 105,
reg => 0,
nbyte => 255
});
eingebe, wird mir ein
clientmsg : $VAR1 = {
'nbyte' => 255,
'reg' => 0,
'myRpiI2C_SENDSTAT' => 'error',
'direction' => 'i2cread',
'i2caddress' => 105
};
ausgegeben. An dieser Stelle wird mir wenigstens ein Fehlercode in die "_I2CRec"-Funktion übergeben.
Warum ich allerdings nicht mehr als 99 der 255 möglichen Register auslesen kann, ist mir ebenfalls ein Rätsel.
Ist das ein Bug oder erwarte ich die Fehlermeldung an einer falschen Stelle?
Gruss
Sailor
Moin Sailor,
fangen wir mit der zweiten Frage an:
Das ist vermutlich eine Hardwarebeschränkung. Ich gebe die Daten direkt an ioctl weiter.
Bei der Rückgabe prüfe ich, ob die Anzahl der Bytes zu den angeforderten passt.
Es gibt kommen also entweder gar keine Daten von der Hardware oder zu wenige.
Es würde helfen den Lesevorgang aufzuteilen.
Benötigst du denn den kompletten Bereich?
Alternativ könntest du $clientmsg->{direction} = "i2cbyteread" verwenden. In diesem Fall werden die Bytes einzeln abgeholt.
Das verdreifacht allerdings den Traffic auf dem I2C Bus.
Nun zur ersten Frage:
Im Fehlerfall sollte auf jeden Fall etwas zurück kommen.
Hier ein Beispiel am PCF8574 Modul (es hängt natürlich kein entsprechender Baustein dran):
Internals:
CFGFN
DEF 0x33
FUUID 5c8776a9-f33f-6e82-cbdd-abf9ae7ea8378406
I2C_Address 51
IODev RPiI2C
NAME test
NR 1578
RPiI2C_SENDSTAT error
STATE Initialized
TYPE I2C_PCF8574
helper:
InputPorts 0
InvrtPorts 0
Attributes:
IODev RPiI2C
in der _i2cRec hast du folgendes drin?:
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/ ;
}
Dann sollte auf jeden Fall das Internal .*_SENDSTAT erzeugt werden.
Notfalls mal schauen, was RPII2C im Verbose 5 macht.
Grüße
Klaus
Hallo Klaus
Zitat von: klausw am 12 März 2019, 10:28:51
Im Fehlerfall sollte auf jeden Fall etwas zurück kommen.
Jetzt kommt auch was.
Was ich beim übereifrigen Ausmisten leider auch gelöscht hatte, war die folgende Zeile in der "_Read" - Funktion (letzte Zeile):
sub UpsPico_Read($$$$) {
my ($hash, $addr, $reg, $nbytes) = @_;
my $name = $hash->{NAME};
### Set I2C address in hash
$hash->{I2C_Address} = $addr;
Ich muss nämlich in dem Programm bis zu 8 I2C - Adressen mit jeweils bis zu 19 Registern auslesen können.
Das bedeutet ich muss der Read-Funktion immer I2C-Adresse, Register-Start-Adresse (0x00) und Anzahl der zu lesenden Register angeben.
Jetzt kommt auch bei einer "toten" Adresse der heiss erwartete
client message : $VAR1 = {
'i2caddress' => 90,
'reg' => 0,
'myRpiI2C_SENDSTAT' => 'regerror',
'direction' => 'i2cread',
'nbyte' => 50
};
Komisch, kaum macht man es richtig, funktioniert es! ;D
Gruss
Sailor