Taster mit Python steuern.

  • Ich möchte ja auch Python Script damit starten. Das kann ich ja auch mit 'subproces' machen.

    Das haben wir doch schon behandelt... Man startet kein Python Script aus einem anderen Python Script. Bitte lass von diesem Irrwitz ab.

    Ich hoffe du hast nur ein Verständnissproblem...

    Du brauchst ein Python Script um eine Tasterbetätigung zu erfassen und eine entsprechende Reaktion zu programmieren. Nicht zwangsweise Python, geht auch mit anderen Programmiersprachen aber das sprengt jetzt den Rahmen.

    Woher soll der Computer sonst wissen was es mit dem Input eines GPIO's machen soll?

    Man erstellt also eine Scriptdatei, definiert einen bestimmten GPIO als Eingang, definiert was bei Betätigung passieren soll und verkabelt diesen speziellen GPIO auch entsprechend.

    Eine Re-/Aktion kann sein eine LED zu schalten. Ein mal Taster betätigen = LED an. Erneute Betätigung = LED aus. Das stellt erst mal kein Problem dar.

    Deine Aktion soll es nun aber sein eine VLC Instanz zu starten, etwas abzuspielen und bei einem erneuten betätigen des Tasters VLC auch wieder zu beenden?

    Bitte nicht direkt mit subprocess anfangen... Das ist eine faule und "ich wills nicht verstehen"-Vorgehensweise.

    Bitte schildere uns genau was du vor hast, möglichst viele Details nennen, sonst wird es auch für uns Mühsam...

  • Hier nochmal mein aktueller Code der funktioniert:

    Ich möchte einen VLC stream von meiner PI Cam starten, das mache ich bereits schon mit den Sript:

    Code
    command = cvlc v4l2:///dev/video0 --v4l2-width 1280 --v4l2-height 720 --v4l2-fps 49 --v4l2-chroma h264 --sout '#standard{access=http,mux=ts,dst=0.0.0.0:12345}'
    
    subprocess.Popen( command, shell=True, stdout=subprocess.PIPE)

    Das funktioniert, das bette ich dann in den Script ein, da wo jetzt die LED ist.

    Ich bin noch ein relativer Anfänger.

    Ich bin nicht darauf aus alles vorgeschrieben zu bekommen, denn man lernt am besten, wenn man es selbst schreibt, aber bin für jeden Ratschlag dankbar.

  • Ich bin nicht darauf aus alles vorgeschrieben zu bekommen, denn man lernt am besten, wenn man es selbst schreibt, aber bin für jeden Ratschlag dankbar.

    Gut, dann Schritt für Schritt..

    Als erste Verbesserung würde ich vorschlagen deine Schleife auf Basis eines Flags umzusetzen. Aktuell müssen nämlich zwangsweise 3 Sekunden zwischen den Tasterbetätigungen vergehen, das is nich so schön. Sind dann zwar mehr Codezeilen aber sieht IMHO besser aus.

    ..da gibts glaub ich auch eine Methode über gpiozero um das zu regeln..

    Als nächstest solltest du das in ein richtiges Schema setzen - wie eine Python Datei aufgebaut sein sollte:

    Und dann baust Du mal bitte deinen vlc Befehl in diese eine Scriptdatei mit ein.

  • @meigrafd

    Kannst du mir mal das Sript mit eigenen Worten erklären?

    Weil 'state' ist ja 'False', Aber was macht dann das 'False = False'?

    Ich weiß das 'False' FALSCH bedeutet und 'True' WAHR. Aber ich kann mir das Sript irgendwie nicht erklären.

    Und die Zeile:

    Code
    if __name__ == '__main__':

    bedeutet, dass es die Definition ausführen soll?!

  • state ist ja nur eine Variable die man definiert und dessen Wert festlegt.

    Dh vor der Schleife legen wir den Wert auf False fest, weil angenommen werden kann dass die LED dann noch aus ist. Dann wird die Schleife so lange blockiert bis button betätigt wird und dann wird der Wert von state überprüft: Ist der Wert True, die LED also eingeschaltet, wird die LED wieder ausgeschaltet und der Wert von state auf False gesetzt. Ist state aber False (else) wird die LED eingeschaltet und der Wert von state auf True gesetzt.


    Wie ich oben bereits erwähnte, kann man auch den aktuellen Zustand eines GPIO's abfragen, sprich ob der er HIGH (1) oder LOW (0) gesetzt ist.

    Auf deinen Code bezogen wäre das: led.is_active oder led.value

    Dabei spielt es keine Rolle ob der Pin über die aktive Script-Instanz geschaltet wurde oder von einem anderen Script.

    Beispiel:

    Python
    import gpiozero
    led = gpiozero.LED(27)
    led.value

    Würde zunächst False ausgeben.

    Öffnet man dann aber eine weiteres Terminal, geht in die interaktive-Python-Konsole und führt dort das aus:

    Python
    from RPi import GPIO
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(27, GPIO.OUT)
    GPIO.output(27, GPIO.HIGH)

    ...öffnet dann wieder die erste Konsole und führt erneut led.value aus wird einem True angezeigt. Zauberei :angel:

    Diesen Umstand kannst du dir also auch zu Nutze machen und auf eine selbst festgelegte Variable verzichten:

    ...was es mit '__main__' auf sich hat recherchierst du bitte selbst ;)

  • Der Korrektheit halber sollte bzw. muss man anstelle von while 1: oder while "hallo_welt" oder sonstigen Unfug while True: schreiben.

    Auch sollte sicherheitshalber dafür gesorgt werden, dass nach Beenden (was hier sowieso Fehlermeldungen erzeugen wird) die Pins wieder geschlossen werden. Äquivalent zu pigpio via cancel() oder RPi.GPIO cleanup()

    Auch sollte in der Hauptfunktion (im obigen Fall noch nicht schlimm) so wenig wie möglich stehen. In der Regel nur noch Funktionsaufrufe etc. In Anbetracht, dass du ja mit VLC operieren willst empfehle ich dir jetzt schon, Funktionen zu schreiben, welche aber nur eine Aufgabe abarbeiten...

    Hier mal ein Beispiel, ausgehend von meigrafd Version, welche echt gut ist (Ueberprüfung led.value)

  • Ich hab jetzt mal mein mjpg streamer zum starten und beenden gebracht.

    Es funktioniert auch so wie es soll, aber ich denke Profihaft ist das wohl noch nicht.

    bootsmann

    Was hat "led.value" zu bedeuten?

    Heißt das, wenn das LED aus ist (also value 0) soll es in value 1 (LED an) springen?.

  • Versuche möglichst Codezeilen nicht zu wiederholen. Dh. zB. eine Lösung mit nur 1x button.wait_for_press() wäre besser.

    killall zu verwenden ist auch nicht optimal, da würde ich lieber gezielt den vom Script gestarteten Prozess sauber beenden, anstatt einfach "alle" zwanghaft zu töten.

    Hinzu kommt dass durch shell=True eine weitere Shell gestartet wird, wodurch dann subprocess.Popen().pid nicht die ProcessID des Programms sondern der Shell beinhalten würde - also ein selbstgemachtes Problem.

    Also erster Schritt wäre shell=True weg zu lassen. Bedingt dadurch muss command dann anders geschrieben werden, nämlich in Form einer List, was sich mithilfe des shlex Modules und davon der split Methode aber einfach bewerkstelligen lässt.

    Zweiter Schritt wäre die Rückgabe von subprocess.Popen() in eine Variable zu setzen sodass man darauf später zugreifen und gezielt den Prozess beenden kann. Hierbei gibt es (wie immer) unterschiedliche Möglichkeiten: https://docs.python.org/2/library/subp…l#popen-objects

    Beispiel:

  • meigrafd

    Erkläre mir mal bitte den Sinn von stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1.

    Es wird ja hier nicht mit dem Prozess mjpg_streamer kommuniziert.

    Darum macht meiner Meinung nach eine `PIPE` keinen Sinn, weil der Inhalt 1:1 durchgereicht wird.

    Wenn stdout=PIPE angegeben wird, dann wird eine Verbindung zu dem stdout-Stream des Kind-Prozesses geöffnet.... (darum verstehe ich den Sinn nicht, lass mich aber gerne aufklären)

    Normalerweise verwendet man terminate() anstelle von kill().

    matze1

    Ich schrieb ja nicht zum Spass, dass man nicht alles in die Hauptfunktion stecken sollte. Auf Modulebene haben nur Konstanten, Klassen und/oder Funktionen zu stehen.

  • Es gibt kein von mir gewollten Sinn - habe das vom TE übernommen weil ich annahm er würde mit der Ausgabe noch irgendwas machen wollen...

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!