Code bleibt hängen?

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo liebes Forum

    Hardware + Programmiersprache:

    Raspberry Pi 4 (auf dem Raspberry Pi Zero soll es später auch laufen) / Sprache: Python

    Ziel des Codes:

    Es soll ein Bild im Fullscreen geöffnet werden. Sobald ein Taster (GPIO 11) betätigt wird (dieser bleibt nach dem Betätigen auf 1), soll das Bild geschlossen und stattdessen ein Video in Endlosschleife laufen. Aktuell habe ich noch eine LED am GPIO Pin 13 angeschlossen, welche sich bei Tastendruck auch einschaltet.

    Aktueller Stand:

    Auf Tastendruck leuchtete das LED und auch das Video wurde gestartet. Die while Schleife funktioniert also grundsätzlich. Den Loop für das Video habe ich noch nicht integriert.

    Dann habe ich den Code mit diesen 3 Zeilen ergänzt, um die nächste Funktion zu ergänzen (Bild zu Beginn öffnen):

    import os

    os.system('mirage -f /home/pi/Desktop/Blackscreen.png')

    os.system('pkill mirage')

    Seither wird zwar das Bild direkt am Anfang im Fullscreen geöffnet, jedoch passiert gar nichts, sobald ich den Taster drücke:

    Die LED leuchtet nicht, das Video startet nicht und das Bild bleibt im Fullscreen geöffnet.

    Wo habe ich einen Fehler eingebaut, dass das Drücken des Tasters nichts mehr bewirkt?

    Hier mein gesamter Code (import subprocess und time sind noch von früheren Versuchen drin):

    Fehlermeldung, falls die etwas damit zu tun hat:

    /usr/lib/python2.7/dist-packages/mirage.py:1864: GtkWarning: _gdk_drawable_get_source_drawable: a ssertion 'GDK_IS_DRAWABLE (drawable)' failed

    pix = gtk.gdk.pixmap_create_from_data(None, pix_data, 1, 1, 1, color, color)

    Ich bin noch Anfänger in dem Gebiet und konnte den Fehler im Code nicht finden.

    Könnt ihr mir bitte helfen? Vielen Dank! :helpnew:

  • Hallo Geckolicious,

    was passiert wenn Du den Befehl system (der als veraltet gilt) ergänzt mit

    Code
    &

    ???

    In Deiner Version wird das Ende des Programms abgewartet, das Du mit system gestartet hast. Dann bringt ein Killen danach nichts.

    Mit dem & wird das Programm im Hintergrund gestartet.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (6. April 2020 um 14:36)

  • Es gibt einen Grund, warum man os.system nicht mehr benutzen soll. Fuer sowas nimmt man subprocess.Popen. Damit erreicht man zwei Ziele:

    - der Aufruf ist asynchron, dein Programm laeuft also weiter.

    - die Rueckgabe ist ein Popen-Objekt, mit dem du dann weiter hantieren kannst. zB `kill` aufrufen, damit ein Programm beendet wird.

    Doch eigentlich ist dein Vorgehen eh suboptimal - den omxplayer andauernd zu starten und wieder zu stoppen kostet nur wertvolle Zeit. Stattdessen benutzt man zB dieses Projekt https://github.com/willprice/python-omxplayer-wrapper um den Player *einmal* zu starten, und dann fernzusteuern.

    Und statt das Bild ebenfalls per externem Programm darzustellen, macht man das besser mit pygame, bringt das in den Full-Screen, und laesst es das Bild darstellen. Der omx-player sollte sich dann eigentlich darueber legen, und bei stop der Wiedergabe wieder das Bild sichtbar sein. Alternativ erstellt man eine kurze Endlos-Video-Sequenz des Bildes & laesst die vom omxplayer in einer Endlosschleife darstellen, bis eben der eigentlich Film dran ist.

    • Offizieller Beitrag

    Und verwende besser gpiozero statt RPi.GPIO, das ist aktueller und einfacher umsetzbar. Wie das damit funktioniert steht hier: https://gpiozero.readthedocs.io/en/stable/reci…-controlled-led

    Und für einen Admin, dessen Namen ich jetzt nicht schreibe. :lol: Python 2 ist EOL, wird also nicht mehr weiter entwickelt oder upgedatet. Aktuell verwendet man Python 3.

  • Hallo zusammen

    Danke für eure schnelle Antworten!

    was pasdiert wenn Du den Befehl system (der als vetaltet gilt) ergänzt mit

    Code
    &

    Das hat funktioniert, danke! Dank dir habe ich jetzt auch verstanden, weshalb mein Code "hängen geblieben" ist.

    @__deets__ und hyle: Stimmt, ich habe auch gemerkt, dass mein Code nicht so optimal läuft (etwas längere Reaktionszeit).

    Ich versuche gerne eure Ideen umzusetzen. Melde mich wieder, sobald ich Den neuen Code zusammenhabe und testen konnte.

    Bis später :)

  • Hallo,

    wobei das mit dem `&`im gegebenen Fall ein Würg-Around ist und keine Lösung. Die Lösung ist das bereits vorgeschlagene `subprocess`.

    Und wenn du schon beim korrigieren bis: Python 2 ist seit dem 1.1.2020 ohne Support durch die Python-Entwickler -> nutze Python 3. Der gezeigte Code sollte eigentlich 1:1 auch unter Python 3 laufen, du muss also nur die Shebang ändern.

    `if` und `while` sind Statements in Python, keine Funktionen -> da muss keine Klammer hinter.

    Gruß, noisefloor

  • Hallo zusammen

    Hier ein Zwischenupdate:

    In die von euch genannten Themen (gpiozero, pygame und subprocess) lese ich mich aktuell noch ein. Den neuen Code habe ich also nocht nicht ready, wollte aber unterdessen wenigstens schonmal meinen "Plan B Code" etwas aufbessern:

    Danke euch noch für den Tipp mit dem Python 3. Mir ist nicht aufgefallen, dass ich Python 2 genutzt habe.

    In der Zwischenzeit habe ich also auf Python 3 gewechselt und den Code noch etwas angepasst:

    Mit diesem Code dauerte es mit Python 2 etwa 1 Sekunde nach dem Betätigen des Tasters, bis das Video startete.

    Mit Python 3 braucht er jetzt 3 Sekunden. Sollte Python 3 nicht etwas schneller sein?

    Doch eigentlich ist dein Vorgehen eh suboptimal - den omxplayer andauernd zu starten und wieder zu stoppen kostet nur wertvolle Zeit. Stattdessen benutzt man zB dieses Projekt https://github.com/willprice/python-omxplayer-wrapper um den Player *einmal* zu starten, und dann fernzusteuern.

    Stimmt, den omxplayer-wrapper wollte ich ursprünglich auch nutzen, konnte ihn aber nicht installieren. Deshalb habe ich dann auf meine Lösung zurückgegriffen...

    Falls jemand mitlesen sollte, der das gleiche Problem hat: Unterdessen konnte ich den omxplayer-wrapper doch installieren:

    Wenn ich den ersten Befehl aus der Doku eingab:

    Code
    sudo apt-get update && sudo apt-get install -y libdbus-1{,-dev}

    Erschien die Meldung:

    "E: Paket libdbus-1 kann nicht gefunden werden."

    Anstelle des oben genannten Befehls habe ich dann diesen genommen:

    Code
    sudo apt install libdbus-glib-1-dev dbus libdbus-1-dev

    Dieser hat funktioniert und danach konnte ich den omxplayer-wrapper installieren.

    So. Ich halte euch auf dem Laufenden, sobald ich eure Inputs (gpiozero, pygame und subprocess) in einem neuen Code zusammegebracht habe. :) Danke viel Mals für eure bisherige Hilfe! Lieber Gruss, Geckolicious

  • Python3 ist zwar milde schneller als 2, das sollte aber keine Auswirkungen hier haben, und das du das beobachtet hast halte ich nicht fuer systematisch reproduzierbar. os.system ist ein Systemaufruf, an dem Python im Grunde so gut wie nicht beteiligt ist, und der sich auch zwischen Versionen nicht geandert hat.

    • Offizieller Beitrag

    Zum Verständnis hier mal aus der Hüfte

    Ist natürlich ungetestet, also keine Gewähr und man verzeihe mir, dass alles auf Modulebene steht! Mit pygame habe ich wenig Erfahrung, deshalb lass ich das mal besser weg.

  • Zum Verständnis hier mal aus der Hüfte

    Ist natürlich ungetestet, also keine Gewähr und man verzeihe mir, dass alles auf Modulebene steht! Mit pygame habe ich wenig Erfahrung, deshalb lass ich das mal besser weg.

    Wow, danke hyle!!

    Hab mal alles eingegeben und getestet -> das Bild wir geöffnet, aber der Tastendruck wird anscheinend nicht erkannt. Zumindest passiert nichts, wenn ich den Taster drücke.

    Werde mich morgen an die Fehlersuche machen.

    Danke dir nochmals viel mals, für den vorbereiteten Code!

    • Offizieller Beitrag

    Vermutlich verwendest Du einen Pulldown-Widerstand oder der Taster ist gegen 3V3 geschaltet, womit kein Event erkannt wird.

    Ergänze mal in Zeile 9 pull_up=False, also das diese so aussieht:

    Python
    button = Button("BOARD11",pull_up=False)

    Eine Fehlermeldung bekommst Du nicht oder?

    • Offizieller Beitrag

    Ich hab doch mal getestet, allerding mit dem Bildbetrachter FEH statt Mirage und eine kleine Pause eingebaut, damit man den Übergang zwischen Bild und Video nicht sieht. Vielleicht kannst Du Dir da ja was abkucken. Zumindest funktioniert das bei mir so.

    Wie geschrieben solltest Du allerdings auch Pullup- oder Pulldown-Widerstände beachten. Bei mir sind externe Pullups verbaut, deshalb muss ich das nicht extra bei Buttons angeben und bei gpiozero ist Pullup der Standardwert, also werden damit die internen Pullups aktiviert. D.h. falls Du Pulldown verwendest oder der Taster mit 3V3 und GPIO verbunden ist, dann siehe vorherigen Beitrag #11!

  • Ich hab doch mal getestet, allerding mit dem Bildbetrachter FEH statt Mirage und eine kleine Pause eingebaut, damit man den Übergang zwischen Bild und Video nicht sieht. Vielleicht kannst Du Dir da ja was abkucken. Zumindest funktioniert das bei mir so.

    Wie geschrieben solltest Du allerdings auch Pullup- oder Pulldown-Widerstände beachten. Bei mir sind externe Pullups verbaut, deshalb muss ich das nicht extra bei Buttons angeben und bei gpiozero ist Pullup der Standardwert, also werden damit die internen Pullups aktiviert. D.h. falls Du Pulldown verwendest oder der Taster mit 3V3 und GPIO verbunden ist, dann siehe vorherigen Beitrag #11!

    Hallo zusammen

    Update:

    Leider bin ich doch noch nicht dazu gekommen, mich selber mit der Fehlersuche intensiv zu beschäftigen.

    Umso erleichterter bin ich darum, dass deine hyle letzten beiden Einträge dann funktioniert haben! :bravo2:

    Habe deinen oben zitierten Code so übernommen (inklusive feh). Zusätzlich habe ich diesen Codeteil von dir integriert:

    Ergänze mal in Zeile 9 pull_up=False, also das diese so aussieht:

    Python
    button = Button("BOARD11",pull_up=False)

    Dies funktioniert nun auch bei mir! Vielen Dank! Ich hätte bestimmt ewig gebraucht, um auf den Input mit dem Pullup zu kommen. Danke für deine umfangreiche Unterstützung!

    Sobald der Taster betätigt wird, dauert es etwa 2 Sekunden bis das Video startet. Ich nehme an, dass dies nicht beschleunigt werden kann?

  • Doch, wenn man den OMXPlayer via DBUS fernsteuert. Damit kann man an eine bestimmte Position springen, da warten, und die Wiedergabe dann loslaufen lassen.

    • Offizieller Beitrag

    Geckolicious Übrigens nur am Rande. Wenn Du feh weiterlaufen lässt (Zeile 18 welässt oder auskommentierst), dann kannst Du das Video nach dessen Ende durch Tasterdrücken wieder starten.

    @__deets__ Hatte ich auch getestet und funktioniert auch gut mit player definieren und gleich darauf pausieren und dann in der Funktion starten. Aber ein bisschen Spaß beim Lernen soll Geckolicious ja auch haben. Wobei das eigentlich fast in Klartext in der Doku steht. ;)

  • @__deets__ hyle Jaa weiss, da gibt es noch viel zu Lernen für mich :)

    Werde zuerst ein paar andere Aufgaben abarbeiten, die zum gleichen Projekt gehören. Werde mich dann in ein paar Tagen nochmals mit dem Code befassen. Und vorallem die Doku besser studieren... :^^:

    Gebe euch dann nochmals ein Update. Bis dahin: Liebe Grüsse und schöne Ostern

Jetzt mitmachen!

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