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

Hier, nun endlich mein erstes Modul (das ohne die Hilfe von Rudi nicht zustande gekommen wäre) :)

Ist mittlerweile im SVN trunk committed und per update installierbar

Wenn Interesse besteht würde ich das Modul gern zum FHEM Paket hinzufügen. Was sind die Voraussetzungen dafür?

Es bietet Zugriff auf die GPIOs der Raspberrys. Sie können als Ein- und Ausgang konfiguriert werden. Wenn als Eingang genutzt, lässt sich der Pegel per poll interval abfragen oder auch bei Pegeländerung ein Interrupt auslösen, der die Readings sofort ändert.
Der Eingang lässt sich weiterhin als Toggleinput verwenden. Dabei kann ein Taster angeschlossen werden und bei jedem Tastendruck ändert sich der Pegel.

Vorbereitung: (ich habe bei mir HiPi installiert, aber die Datei "hipi-expin" sollte ausreichend sein, bitte um Rückmeldung ob es geht)
Auf GPIO Pins wird im Modul über sysfs zugegriffen. Die Dateien befinden sich unter /system/class/gpio und können nur mit root erreicht werden. Eine Möglichkeit, das zu umgehen, ist mit udev die Rechte von /system/class/gpio zu ändern:
Wenn sich bereits die HiPi Perl Bibliothek auf dem System befindet, kann auf den download von hipi-expin verzichtet werden.
jetzt sollte es möglich sein, mit normalem Nutzer auf die GPIO's zuzugreifen (um folgende Zeilen zu testen muss sich der user mit dem man testet auch in der Gruppe gpio befinden)
    echo "17" > /sys/class/gpio/export
    echo "out" > /sys/class/gpio/gpio17/direction
    echo "1" > /sys/class/gpio/gpio17/value

Wenn es keine Zugriffsfehler gibt dann ist alles Ok.

Befehlsreferenz:
Define
      define <name> RPI_GPIO <GPIO number>

      Beispiele:
            define Pin12 RPI_GPIO 18
            attr Pin12
            attr Pin12 poll_interval 5

Set
      set <name> <value>

      value ist dabei einer der folgenden Werte:

            Für GPIO der als output konfiguriert ist
                  off
                  on
                  toggle
                  Die set extensions werden auch unterstützt.

            Für GPIO der als input konfiguriert ist
                  readval

      Beispiele:
            set Pin12 off
            set Pin11,Pin12 on

Get
      get <name>

      Gibt "high" oder "low" entsprechend dem aktuellen Pinstatus zurück und schreibt den Wert auch in das reading Pinlevel

Attributes
      direction
            Setzt den GPIO auf Ein- oder Ausgang.
            Standard: input, gültige Werte: input, output

      interrupt
            kann nur gewählt werden, wenn der GPIO als Eingang konfiguriert ist
            Aktiviert Flankenerkennung für den GPIO
            bei jedem interrupt Ereignis werden die readings "Pinlevel" und "state" aktualisiert
            Zusätzlich wird bei falling und rising ein Reading "Toggle" angelegt und bei jedem dieser Ereignisse invertiert (dieses Reading wird mit dem Attribut toggletostate auf das reading "state" kopiert)
            Standard: none, gültige Werte: none, falling, rising, both

      poll_interval
            Fragt den Zustand des GPIO regelmäßig ensprechend des eingestellten Wertes in Minuten ab
            Standard: -, gültige Werte: decimal number

      toggletostate
            Funktioniert nur bei auf falling oder rising gesetztem Attribut interrupt
            Wenn auf "yes" gestellt wird bei jedem Triggerereignis das state reading invertiert
            Standard: no, gültige Werte: yes, no

      pud_resistor
            ohne Funktion


Nun testet mal schön und teilt mir eure Meinung mit 8)

Die nächste Woche bin ich im Urlaub, also nicht wundern wenn bis zum 26.11 keine Antwort kommt.

edit: Anhang gelöscht
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

betateilchen

ZitatEine Möglichkeit, das zu umgehen, ist mit udev die Rechte von /system/class/gpio zu ändern

udev heißt udev, weil es Änderungen in /dev/... vornimmt und nicht in /system/...

Was Du da vorschlägst, widerspricht nach meiner (selbstverständlich unmassgeblichen) Meinung sämtlichen allgemeingültigen Standards zum Thema "Zugriff auf Systemverzeichnisse unter Linux"
-----------------------
Mach es möglichst simpel und mach es richtig,
dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

klausw

Wenn du eine Idee hast wie man es anders machen könnte, immer her damit :D
Ich habe keine Ahnung von der Rechteverwaltung in Linux. Die udev Geschichte habe ich mir von der HiPi Bibliothek abgeschaut.
Ist es denn ein Sicherheitsproblem es so zu machen? Ich hatte es so verstanden, das bei Zugriffsversuch auf das Gpio Verzeichnis einfach nur die Rechte dieses Verzeichnisses und der Unterpfade angepasst werden.
Ist es nicht das selbe Verfahren, das du auch beim I2C Drucksensor nutzt?



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

matzefisi

#3
Hallo zusammen,

ich habe das Problem mit der Berechtigung direkt mit Udev gelöst (fhem läuft bei mir auf dem RPi):

Neue Datei anlegen (/etc/udev/rules.d/51-gpio.rules) und folgendes eintragen:
SUBSYSTEM=="subsystem", KERNEL=="gpio",  ACTION=="add", PROGRAM="/bin/sh -c 'chown -R fhem:dialout /sys%p'"
Update:
SUBSYSTEM=="subsystem", KERNEL=="gpio",  ACTION=="add", PROGRAM="/bin/sh -c 'chown -R fhem:dialout /sys/class/gpio/*'"
SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="/bin/sh -c 'chown -R fhem:dialout /sys/class/gpio/*'"


Udev neu starten:
service udev restart

Schauen ob die änderungen funktioniert haben:
ls -la /sys/class/gpio/

Allerdings werden, durch dein Modul neu angelegte Ordner, noch nicht in ihrer Berechtigung geändert: (Manueller workaround):
sudo udevadm test --action=add /class/gpio

Und jetzt zu deinem Modul:
Erstens:
Ich würde es gerne dazu benutzen um den Status eines GPIO Ports zu überwachen (high/low). Das Modul zeigt zwar den PIN Status (high/low) korrekt an, allerdings ändert sich der State nicht und es wird leider auch kein Event generiert. Daher kann ich auch nicht mit einem notify darauf reagieren.
Funktioniert doch :)

Zweitens:
Im Log wird beim DEFINE und beim Ändern eines Attributes immer die Meldung "2013.11.30 10:38:53 1: Can't open file: test, direction" angezeigt. Wahrscheinlich nicht normal oder?

Ansonsten schonmal ein großes Danke für deine Arbeit!

MfG
Matthias



klausw

Hi Matthias,

zu1(wenn auch schon erledigt :)):
Wenn du attr <name> interrupt both nutzt dann wird der state Wert sofort geändert.

zu2:
Deine Fehlermeldung kann ich bei mir nicht nachvollziehen.
Sie bedeutet, das die Datei /sys/class/gpio/gpioN/direction nicht geschrieben werden konnte.
Bei dir funktioniert es trotzdem, da diese Datei beim anlgen des GPIO standardmäßig den Inhalt "in" hat, also auf Input eingestellt ist.

Aber in diese Datei schreibe ich beim define erstmal zur Sicherheit  ein "in" für Input.
Bei attr lese ich sie auch fast immer mit aus, da ich die Attribute gegenchecken muss. (z.B. kann Interrupt nur im zusammenhang mit Input funktionieren)

Kannst du bitte die Rechte der Datei prüfen? Vermutlich klappt mit dem udev nochwas nicht.

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

matzefisi

Hi Klaus,

stimmt. Die Dateien und Unterverzeichnisse gehören immer noch dem ROOT. Da muss ich am udev noch was ändern.

MfG
Matthias

klausw

man könnte auch einfach die Dateizugriffe mit sudo machen, ich bin nicht sicher, was die beste Lösung ist
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

dennisb

Hi,

man könnte auch wiringPi nutzen: http://wiringpi.com/download-and-install/
Das dazugehörige cmd line tool "gpio" kann auch ohne root genutzt werden.


betateilchen

Zitat von: Dennis B. am 10 Dezember 2013, 22:52:17man könnte auch wiringPi nutzen:
Das dazugehörige cmd line tool "gpio" kann auch ohne root genutzt werden.

Genau deshalb habe ich diesen Weg bei der Umsetzung meines PiFace Moduls gewählt, das ja auch nix anderes macht, als GPIO zu lesen/setzen
-----------------------
Mach es möglichst simpel und mach es richtig,
dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

klausw

#9
Zitat von: Dennis B. am 10 Dezember 2013, 22:52:17
man könnte auch wiringPi nutzen: http://wiringpi.com/download-and-install/
Das dazugehörige cmd line tool "gpio" kann auch ohne root genutzt werden.

Wieso eigentlich nicht. Ich habe das mal implementiert.
Also zuerst http://wiringpi.com/download-and-install/ installieren:

sudo apt-get update
sudo apt-get upgrade
http://wiringpi.com/download-and-install/
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build


Das Attribut pud_resistor funktioniert jetzt und ich habe noch die Attribute debounce_in_ms zum entprellen von Schaltern, sowie restoreOnStartup zum wiederherstellen des Pinzustandes nach restart.




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

klausw

#10
So, ich habe auf die schnelle noch eine Zählfunktion hinzugefügt.
Wenn das Attribut interrupt auf rising oder falling steht, dann wird ein Reading namens Conter angelegt, welches bei jedem Interruptereignis eins hochzählt.
Ich werde das ganze noch konfigurierbar machen, das man den Zählwert auch im State haben kann. Und ein Multiplikator ist sicher auch nicht verkehrt.
Ideen/Wünsche sind erbeten ;)

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

klausw

#11
Die letzen Versionen hatten noch einen Fehler: Pins funktionierten generell nicht als Output wenn die HiPi Bibliothek incl. udev nicht eingerichtet sind.
Mir ist es erst jetzt aufgefallen, als ich udev entfernt habe.
Diese Version sollte jetzt ausschließlich mit WiringPi funktionieren.

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

klausw

#12
kleine Fehlerkorrektur für die SetExtension (konnte vorher bei der Nutzung als Output zum Absturz von FHEM kommen)
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

backbone10

Hi,
danke für deine Mühe und Zeit die du opferst !!

Ich würde das ganze mit einem PIFACE verwenden wollen, das krieg ich aber nich hin. Das PiFace selbst funktioniert schon (mit gpio Commands via Console)
Das FHEM hab ich auch soweit hinbekommen, nur schalten will es nicht. ich habe foldende defines gmacht :

define Pin12 RPI_GPIO 18
attr Pin12 direction output
attr Pin12 loglevel 5
     
define Pin11 RPI_GPIO 17
attr Pin11 direction output
define Pin13 RPI_GPIO 27
attr Pin13 direction output
define Pin15 RPI_GPIO 22
attr Pin15 direction output
define Pin16 RPI_GPIO 23
attr Pin16 direction output
define Pin18 RPI_GPIO 24
attr Pin18 direction output
define Pin22 RPI_GPIO 25
attr Pin22 direction output
define Pin7 RPI_GPIO 4
attr Pin7 direction output


aber nicht eine einzige LED brennt wenn ich einschalte....mit gpio readall sehe ich auch keine änderung des Zustandes

Mir ist aber auch das Mapping der physikalischen Anschlüsse des Piface zu den GPIO Ports ein Rätsel, vielleicht kann wer was dazu sagen.

Danke vorab !!!

mfg

bb10

klausw

Die Config sieht ok aus.

Hast du die neuste Modulversion installiert?
Steht im Logfile entsprechendes drin?
Du kannst auch einmal schauen wie im GPIO Verzeichnis die Rechte vergeben sind.
Das sollte so aussehen:
-rw-r--r-- 1 fhem dialout 4096 Dez 18 21:47 edge
-rw-r--r-- 1 fhem dialout 4096 Dez 18 21:47 value


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