Seite 1 von 1
GPIO lesen
Verfasst: Mittwoch 10. Juni 2020, 14:51
von Knollo
Guten Tag allerseits, ich versuche den Zustand der GPIO's zu lesen:
Code: Alles auswählen
import os
status = os.system("gpio read 26")
print(type(status))
if(status == 1):
print("LED ein")
else:
print("LED aus")
erzeugt die Ausgabe:
bei ausgeschalteter LED und
bei eingschalteter LED. Irgendwie gelingt es nicht auf die 1 zuzugreifen. Wo liegt der Fehler?
Danke für jede Hilfe -
Stefan
Re: GPIO lesen
Verfasst: Mittwoch 10. Juni 2020, 15:10
von __deets__
Autsch. Verzeih, aber das ist wirklich nicht schoen, was du da treibst.
Das Ursprungsproblem besteht darin, dass du den schon lange nicht mehr empfohlenen os.system call benutzt. Und der hat einen andere Semantik, als du das glaubst: nur weil ein Programm 0 oder 1 ausgibt, heisst das nicht, das die Ausgabe dann auch magisch als Rueckgabewert von os.system auftaucht. Das ist der sogenannte Returncode, also die Art wie Linux kommuniziert, dass der Prozess ok beendet wurde. Und der ist immer 0 wenn alles glatt ging.
Aber selbst wenn du das umgehen wuerdest (mit subprocess.run zb) - das ist wirklich ganz extrem von hinten durch die Brust ins Auge. Es gibt einen ganzen Zoo von Bibliotheken, mitttels derer man auf dem PI Pins einliest, und das schneller, zuverlaessiger und eleganter als mit einem solchen Prozessaufruf.
Mein Tipp: installier dir erstmal gpiozero, und benutz das.
Re: GPIO lesen
Verfasst: Mittwoch 10. Juni 2020, 20:45
von Knollo
Mh, das Problem eines Unverständigen ist das er das Ganze nicht überblick und trotzdem versucht einzusteigen.
Code: Alles auswählen
import subprocess
import shlex
cmd = "gpio read 26"
args = shlex.split(cmd)
process = subprocess.run(args, stdout=subprocess.PIPE)
output = process.stdout
print(type(output))
print(output[0])
zst = output[0]
if (zst == 48):
print("aus")
else:
print("an")
ist die jetzige Lösung, vermutlich trotzdem noch nicht elegant

gpiozero ist installiert, aber mangels fundierter englischkentnisse schwierig einzusteigen:
https://gpiozero.readthedocs.io/en/stable/faq.html
ich will mich hier nicht als Kloppie outen, sondern nur eine Lösung für das Problem suchen die ich verstehe..
Danke
Stefan
Re: GPIO lesen
Verfasst: Mittwoch 10. Juni 2020, 21:20
von __blackjack__
@Knollo: Das `shlex`-Modul ist nicht wirklich nötig. Warum schreibst Du da die Liste nicht einfach selbst hin?
Das was Du `process` nennst ist kein Prozess, das ist das Ergebnis eines Prozesses der bereits beendet ist.
Der Bytewert 48 ist mehr als undurchsichtig, den muss man entweder erklären, oder das nicht mit magischen Zahlen schreiben. Und was zum Henker bedeutet `zst`?
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import subprocess
def main():
gpio_result = subprocess.run(
["gpio", "read", "26"], stdout=subprocess.PIPE
)
if int(gpio_result.stdout):
print("an")
else:
print("aus")
if __name__ == "__main__":
main()
Aber das ist wie gesagt der falsche Weg das so zu machen. Selbst ein Modul das die generische GPIO-Schnittstelle des Kernels verwendet, wäre besser als *das*.
Insbesondere bei der gezeigten Funktionalität hat das keinen Vorteil gegenüber eines einfachen Shell-Skripts (ungetestet):
Code: Alles auswählen
#!/bin/sh
if gpio read 26 > /dev/null; then
echo 'an'
else
echo 'aus'
fi
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 12:53
von Knollo
Code: Alles auswählen
from gpiozero import LED
led=LED(12)
while True:
led.on()
print(led.is_active)
#'True'
time.sleep(1)
led.off()
print(led.is_active)
#'False'
time.sleep(1)
Danke, sieht jetzt so hoffentlich besser aus:-)?
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 14:13
von __blackjack__
@Knollo: Grundsätzlich ja. Wobei das ja jetzt etwas anderes macht als das Programm im ersten Beitrag. Und da ist hoffentlich eine LED angeschlossen, sonst ist es natürlich irreführend die `LED`-Klasse zu verwenden und das Objekt `led` zu nennen.
Das läuft so aber nicht ohne `time` auch zu importieren. Und eine She-Bang-Zeile könnte man dem bei der Gelegenheit auch verpassen, damit man das als Programm ausführen kann.
Die Kommentare sind ein bisschen irreführend, denn in Python beziehen sich Kommentare die alleine stehen auf die nachfolgenden Code-Zeilen. Da der Kommentar jeweils kurz ist und damit die Zeilenlänge nicht ausufert, würde ich die beiden hinter den jeweiligen `print()`-Aufruf schreiben.
Eingerückt wird mit vier Leerzeichen pro Ebene. Keine Tabulatorzeichen. Die machen nur Probleme.
Dann noch das ganze in eine Hauptfunktion die nur aufgerufen wird wenn man das als Programm aufruft, und es ist vollständig.
Code: Alles auswählen
#!/usr/bin/env python3
import time
from gpiozero import LED
def main():
led = LED(12)
while True:
led.on()
print(led.is_active) # → True
time.sleep(1)
led.off()
print(led.is_active) # → False
time.sleep(1)
if __name__ == "__main__":
main()
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 14:47
von Knollo
Aha, danke - im Gesamtprojekt handelt es sich um eine Gartenbewässerung mit 6 Kreisläufen.
Auf dem Raspi-Server liegt ein php Seite mit 6 Textinput, 6 Button - "Ein" und 6 Butto -"Aus". In den Textinputform erfolgt die Eingaber der maximalen Bewässerungsdauer. Per PHP wird das Pythonsript mit Parameterübergabe($_POST) aufgerufen.
An irgendeiner Stelle soll der Zustand aller 6 Ventile geprüft werden und falls offen, dann geschlossen werden. Am Ende steht alles in einer Funktion in Form einer Schleife . Diese durchläuft ein Array mit den angeschlossenen Pins und prüft den Zustand.Bis zu dem Punkt läuft jetzt alles perfekt.
Als nächsten Schritt soll in die Webseite noch ein Timer per Javascript eingebaut werden. Das gilt es noch zu basteln.
Danke für die konstruktive Hilfe
Stefan
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 14:50
von sparrow
Ich würde den Sprachenbruch ja direkt vermeiden und die Webanwendung in Python schreiben.
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 15:23
von Knollo
Hallo, Problem ist das die PHP-Seite erst nach Ablauf des php-Scriptes neu aufgerufen wird. Also, wenn der sleep() 30 Minuten läuft erfolgt anschließend die neue Webseite und der clientseitige Einbau des Timers ist somit nicht mehr sinnvoll.
Oder???
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 15:32
von Sirius3
Daher ist es ja nicht sinnvoll, mit PHP zu arbeiten, und statt dessen alles in Python zu lösen. Dann kann auch im Hintergrund etwas abgefragt werden und unabhängig davon Webseiten ausgeliefert werden.
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 15:41
von Knollo
??? wie kann per Javascript ein Pythonsript aufgerufen und die Variablen übergeben werden, hab ich wiedermal was verpasst???
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 15:43
von __deets__
Nein, aber das kannst du auch mit PHP nicht. Was du kannst ist einen Webserver von JavaScript aus ansprechen, und den kannst du auch in Python schreiben, und damit gleichzeitig deine Bewaesserung steuern.
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 17:39
von Knollo
__deets__ hat geschrieben: Donnerstag 11. Juni 2020, 15:43
Nein, aber das kannst du auch mit PHP nicht. Was du kannst ist einen Webserver von JavaScript aus ansprechen
...ist Ajax das Stichwort?
und bzgl. php > Python:
Code: Alles auswählen
<?php
var_dump($_POST);
if ($_POST["GPIO"] == "GPIO") {
echo "GPIO schalten";
shell_exec("python3 gpio.py");
}
?>
...läuft so wie es soll, wobei die Möglichkeit alles in Python zu schreiben mir wirklich lieber wäre. Nun da gibt es wieder was zu tun :

Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 17:47
von __deets__
Mit der Wasserpumpenzange die Felgenmuttern lösen läuft auch “wie es soll”. Ist trotzdem nicht optimal. AJAX ist ein Stichwort. Aber heutzutage sind eher websockets angesagt.
Re: GPIO lesen
Verfasst: Donnerstag 11. Juni 2020, 18:13
von Knollo