Modul für RPi GPIO Zugriff mit Interrupt Funktion für Input

Begonnen von klausw, 15 November 2013, 14:28:41

Vorheriges Thema - Nächstes Thema

klausw

Das auslesen über state ist sowieso mist -> wenn es kein statefile vorhanden ist dann wird es auch nciht ausgelöst
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

Ralli

#151
Zitat von: klausw am 07 November 2014, 12:16:12
schaue gleich mal rein...
funktionierte denn meine Version nicht?
Jein - nicht so, wie gewünscht bzw. nicht mit den jetzt eingebauten Möglichkeiten.

Zitat
Jein, der Counter und der Toggle sollten wiederhergestellt werden.
Und wenn toggletostate gesetzt ist, dann natürlich auch state (soll schließlich eine Tasterfunktion nachbilden)
Das habe ich auch so gelassen.

Zitat
restoreOnStartup hat du, vermute ich, falsch verstanden:

  • no -> kein wiederherstellen
  • off -> auf off wiederherstellen
  • on -> auf on wiederherstellen
  • last -> auf letzten wert
  • yes ist ein Überbleibsel aus Kompatibilitätsgründen (werde ich jetzt entfernen)
Nein, hab ich schon richtig verstanden, kann man aber m.M. nicht so auf GPIOs anwenden, die auf Input konfiguriert sind, da das einfach nicht "passt". Für einen Input bekommen die Einstellmöglichkeiten einfach andere Bedeutungen.

Zitat
Für Input sollte generell der Status am Pin hergezogen werden (ausser bei toggletostate)
Genau.

Zitat
die Events können beim FHEM sStart nicht geladen werden, da zur Ladzeit des Pins das dazugehörige notify noch nicht geladen ist. Daher läuft es ins leere. Der Timer verschiebt es einfach.
Ok!

Zitat
Das auslesen über state ist sowieso mist -> wenn es kein statefile vorhanden ist dann wird es auch nciht ausgelöst
Richtig! Das ist noch ein Manko.

Edit:
Ich habe aber noch eine andere Idee.

Die Funktion RPI_GPIO_State wird ja nach meinem Verständnis nur aufgerufen, wenn mittels Statefile die gespeicherten Readings/Stati zurückgeschrieben werden müssen.

Dann müsste eigentlich bei einem Input nur der zu setzende Wert mit dem tatsächlichen Pinlevel verglichen werden. Und nur wenn der abweicht, wird ein RPI_GPIO_Poll getimert.

So wie angehangen - ist aber noch nicht getestet!
Gruß,
Ralli

Proxmox 8.4 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.4 dev, virtualisierte RaspberryMatic (3.81.5.20250527) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.4.1) und HMW-GW, FRITZBOX 7490 (07.59), FBDECT, Siri und Alexa

klausw

Das ist aber immer noch das gleiche Problem.
Wenn im Statefile keine state Variable für den Input existiert, dann wird die Stateroutine auch nicht aufgerufen.
Obwohl dann ist es halt so.
Ich könnte den Timer auch ins define verlegen. Allerdings trifft der Timer dann auch für Outputs zu. Das wiederum hat den NAchteil, das die Timestamp geändert wird. Diese sollte aber den letzten Schaltzeitpunkt zeigen.
Fazit, ich werde es in der Stateroutine lassen.
Was die restoreOnStartup Attribute betrifft, werde ich sie bei inputs ausschießlich für toggle verwenden.

Was ich noch nicht verstanden habe, wieso Du bei den Inputs einmal ein event auslösen möchtest und einmal nicht.

Es nur auszulösen, wenn gespeicherter Wert und reeller Wert unterschiedlich sind finde ich da sinnvoller.
(was das Dein Problem? Also das immer getriggert wurde, auch wenn sich der Wert nicht geändert hat?)
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

Ralli

Ganz einfach:

Für mich ist es am sinnvollsten, wenn ein Event nur ausgelöst wird, wenn auch tatsächlich (in der Downzeit) eine Statusänderung stattgefunden hat.

Ich habe ein notify oder doif auf xy:open bzw. xy:off sitzen. Wenn das zur Laufzeit von fhem ausgelöst wurde, braucht es nicht neu ausgelöst werden, wenn dann fhem weg war und wieder kommt.

Ansonsten waren die in meiner ersten Version eingebauten Möglichkeiten eben nur Möglichkeiten für diejenigen, die warum auch immer so etwas brauchen. Denkbar: Normalerweise werden zur Laufzeit von fhem diverse Dinge über die Inputs getriggert. Wenn fhem nun down geht und wieder kommt und in der Zwischenzeit sich an den Inputs was getan hat, kann es ja sein, dass nicht jeder auf jeden Fall dann auch noch eine Aktion auslösen lassen möchte - während der Laufzeit von fhem aber sehr wohl.
Gruß,
Ralli

Proxmox 8.4 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.4 dev, virtualisierte RaspberryMatic (3.81.5.20250527) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.4.1) und HMW-GW, FRITZBOX 7490 (07.59), FBDECT, Siri und Alexa

klausw

Soo, folgende Version übernimmt die Pinwerte. Wenn Pinwerte mit denen aus dem Statefile nicht übereinstimmen dann wird ein Timer gestartet um ein notify auslösen zu können. Sonst werden nur die Werte übernommen.
Das ganze funktioniert immer, wenn restoreOnStartup nicht "no" ist.
Schau mal obs so passt für dich

Lösche bitte Deine alten Modulvorschläge, die irritieren nur :)
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

Ralli

Hallo Klaus,

das wird langsam ;) . Aber ich glaube, er hat im letzten elsif vor dem Vergleich und im letzten else den alten Wert nicht in $sval?
Gruß,
Ralli

Proxmox 8.4 Cluster mit HP ED800G2i7, Intel NUC11TNHi7+NUC7i5BNH, virtualisiertes fhem 6.4 dev, virtualisierte RaspberryMatic (3.81.5.20250527) mit HB-RF-ETH 1.3.0 / RPI-RF-MOD, HM-LAN-GW (1.4.1) und HMW-GW, FRITZBOX 7490 (07.59), FBDECT, Siri und Alexa

klausw

Zitat von: Ralli am 07 November 2014, 18:11:53
Hallo Klaus,

das wird langsam ;) . Aber ich glaube, er hat im letzten elsif vor dem Vergleich und im letzten else den alten Wert nicht in $sval?
sollte schon, $sval wird vorher nicht neu geschrieben
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

fnord

Hi zusammen,

ich betreibe FHEM auf einem BBB mit Debian und habe mir dafür das Relay Cape von Logic Supply geholt. Das steuere ich mit RPI_GPIO (und Wiring Pi) an, was für die Eingänge auch gut klappt. Die beiden Relais reagieren aber nicht - das geht nur, wenn ich nach dem FHEM-Start die Direction manuell setze:

echo out > /sys/class/gpio/gpio65/direction

Beim Start geschieht nämlich merkwürdiges (das Device heißt GPIO_Relay1):


2014.11.06 22:00:07 5: GPIO_Relay1, in fileaccess: value 1
2014.11.06 22:00:07 5: GPIO_Relay1, in fileaccess: direction high
2014.11.06 22:00:07 4: GPIO_Relay1: direction ueber gpio utility einstellen
2014.11.06 22:00:07 4: GPIO_Relay1: direction gesetzt auf low
2014.11.06 22:00:07 4: OUTPUT GPIO_Relay1: STATE wiederhergestellt auf off


Und auf der Konsole lese ich derweil:

export: Invalid mode: low. Should be in or out


Soweit ich den Code verstanden habe, wird tatsächlich versucht, als Direction "low" bzw. zu setzen, wo IMHO "out" korrekt wäre (Funktion RPI_GPIO_fileaccess, Zeile 493):


$dir = ($args[1] == $lev ? "high" : "low")


Wenn ich das entsprechend ändere, läuft die Relais-Ansteuerung wunderbar - und ja: die Eingänge funktionieren dann auch noch  ;)


$dir = ($args[1] == $lev ? "in" : "out")


Ich frage mich also, ob die genannte Zeile nicht einen Fehler enthält, den ich in diesem Fall gern korrigiert hätte. Falls ich das Modul irgendwie falsch benutze, dann sorry. Bis auf direction=output hatte ich allerdings keine besonderen Einstellungen vorgenommen.

Und bevor ich es vergesse: Das ist ein für mich sehr nützliches und (ansonsten  ;)) toll funktionierendes Modul, vielen Dank dafür!


Gruß

fnord

klausw

Zitat von: fnord am 07 November 2014, 23:27:08
...
Und auf der Konsole lese ich derweil:

export: Invalid mode: low. Should be in or out


Soweit ich den Code verstanden habe, wird tatsächlich versucht, als Direction "low" bzw. zu setzen, wo IMHO "out" korrekt wäre (Funktion RPI_GPIO_fileaccess, Zeile 493):


Du hast es richtig verstanden. Es wird als direction "low" gesetzt. Ein schreiben von low in direction führt dazu, das der Pin als Output gesetzt wird und gleichzeitig auf Low (das soll kurzzeitiges schalten beim booten unterbinden ... für die Details musst Du mal diesen Tread ein Stück zurückverfolgen)
Jetzt scheint Dein Kernel dies nicht zu unterstützen.
Die Frage ist nun, ob Du eine exotische Distribution verwendest, oder ob es beim BBB generell nicht unterstützt wird. Versuche das doch mal herauszufinden  :)
Da ich nur ein paar Pi's habe kann ich dazu nix sagen.
Notfalls müsste ich da noch ein attribut einbauen...wenn das überhaupt so einfach geht.
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

fnord

Danke für die prompte Rückmeldung! Also soetwas wie

echo high > /sys/class/gpio/gpio65/direction

funktioniert hier (Debian wie gesagt) durchaus. Wenn ich es (wiederum) richtig verstehe, wird doch aber an der Stelle das gpio-Tool von Wiring Pi verwendet. Ich rate mal:

gpio export 65 low

...denn das liefert genau die zitierte Fehlermeldung auf der Konsole. Könnte es so sein?


Gruß

fnord

klausw

Zitat von: fnord am 08 November 2014, 00:57:56
Danke für die prompte Rückmeldung! Also soetwas wie

echo high > /sys/class/gpio/gpio65/direction

funktioniert hier (Debian wie gesagt) durchaus. Wenn ich es (wiederum) richtig verstehe, wird doch aber an der Stelle das gpio-Tool von Wiring Pi verwendet. Ich rate mal:

gpio export 65 low

...denn das liefert genau die zitierte Fehlermeldung auf der Konsole. Könnte es so sein?
Ah, das Debain habe ich überlesen.

Wenn ich mit den Quellcode anschaue, kann das durchaus passieren. Das muss ich noch anpassen.
Aber es sollte trotzdem gehen. Das passiert nur, wenn der fhem user keine Schreibrechte auf die GPIOs hat.
Gibt es bei Dir eine gruppe namens gpio? und ist fhem Mitglied der selben?
Was zeigt "ls -l" im gpio65 Verzeichnis an?
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

fnord

Die Dateien für die Pins sind bei mir für den FHEM-Benutzer nicht schreibbar. Ich fand es wenig elegant, in die /etc/rc.local noch diverse Initialisierungen zu stopfen. Wiring Pi kann das ja sehr fein selbst erledigen. Wenn ich FHEM die Schreibrechte gebe, dann funktioniert es auch - in diesem Fall wird wohl der else-Zweig der Bedingung ab Zeile 511 genommen:


if ($fname eq "direction" && (not -w $file)) { #wenn direction und diese nicht schreibbar mit gpio utility versuchen
    ...
} else {
    my $fh = IO::File->new("> $file");
    ...


Ich glaube, ich verstehe jetzt auch das Problem besser: In Zeile 496 wird ja RPI_GPIO_fileaccess rekursiv aufgerufen, um vor dem eigentlichen Setting zunächst die Direction zu setzen:

RPI_GPIO_fileaccess($hash, "direction", $dir);

$dir ist dabei "high" oder "low". Dieser Aufruf läuft bis zur o.g. Zeile 511, um dann entweder das gpio-Tool aufzurufen (if) oder den Pin direkt zu setzen (else, Zeilen 520ff). Das direkte Setzen mit high/low funktioniert (wie oben beschrieben), der gpio-Aufruf mit high/low aber eben nicht, wie in meinem letzten Posting geschildert! Mein Vorschlag: Zeile 513

RPI_GPIO_exuexpin($hash, $value);

ändern in

RPI_GPIO_exuexpin($hash, $value eq "high" ? "in" : "out");

Damit klappt es (bei mir) auch wenn die Pin-Rechte fehlen.


Gruß

fnord

klausw

Zitat von: fnord am 08 November 2014, 22:44:48
RPI_GPIO_exuexpin($hash, $value eq "high" ? "in" : "out");

Damit klappt es (bei mir) auch wenn die Pin-Rechte fehlen.

was ist dann, wenn der Pin auf low gesetzt werden soll?

ich schlage vor:
$dir = "out" if ( $dir eq ("high" || "low") );
in Zeile 540 einfügen.
Teste das bitte mal.
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

fnord

Zitat$dir = "out" if ( $dir eq ("high" || "low") );

Das klappt leider nicht. Meine Perl-Kenntnisse sind ziemlich rudimentär, aber die Zeile bedeutet doch: "Wenn $dir 'high' oder 'low' enthält, dann setze es auf 'out'", korrekt? Was ich aber erreichen wollte war: "Wenn $dir 'high' enthält, dann setze es auf 'in', wenn es ansonsten "low" enthält, dann setze es auf 'out'". Ich denke, wir sind uns schon einig, und an Deinem Vorschlag erkenne ich, dass Du die Lösung gern in RPI_GPIO_exuexpin hättest. Mein Gegenvorschlag:

sub RPI_GPIO_exuexpin($$) { #export, unexport and direction Pin via GPIO utility
my ($hash, $dir) = @_;
my $sw;
if ($dir eq "unexport") {
$sw = $dir;
$dir = "";
} else {
$sw = "export";

if ($dir eq "high") {
$dir = "in";
} elsif ($dir eq "low") {
$dir = "out";
}

$dir = " ".$dir;
}
if ( defined(my $ret = RPI_GPIO_CHECK_GPIO_UTIL($gpioprg)) ) {
Log3 $hash, 1, "$hash->{NAME}: " . $ret;
} else {
my $exp = $gpioprg.' '.$sw.' '.$hash->{RPI_pin}.$dir;
$exp = `$exp`;
}
}


Das if-elsif habe ich eingefügt, Anfänger-style ;). Funktioniert hier sowohl für Ein- wie Ausgänge. Was hältst Du davon?


Gruß

fnord

klausw

was ich will, ist eventuelle Fehler ausbügeln  8)

Was Du vorschlägst macht für mich keinen Sinn.
Die Routine RPI_GPIO_exuexpin wird entweder für einen Input mit "in" und für einen Output mit "out" aufgerufen.
Zusätzlich halt noch über die State Funktion beim booten (was bei wiringpi nicht funktioniert) mit "high" oder "low" für einen Output.
Mit $dir = "out" if ( $dir eq ("high" || "low") ); sollte das glattgezogen sein.
Jedenfalls bedeutet sowohl "high" als auch "low" einen output
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