00_RPII2C - Rückgabe von Fehlercode scheitert

Begonnen von Sailor, 11 März 2019, 08:12:23

Vorheriges Thema - Nächstes Thema

Sailor

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
******************************
Man wird immer besser...

klausw

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
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

Sailor

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
******************************
Man wird immer besser...