Python Programm nicht beenden

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo,

    Ich habe gerade ein kleines Verständnisproblem, und zwar habe ich am PI einen button an GND und GPIO 17 angeklemmt und hätte gerne ein Programm, das etwas macht sobald ich diesen drücke.

    Geht ja mit rpi.gpio und interrupts ganz gut, hab das nach diesem Tutorial gemacht:
    http://raspi.tv/2013/how-to-us…pi-and-rpi-gpio

    Das Problem ist nur, nachdem ich den Knopf drücke beendet sich das Programm und wartet nicht darauf, dass der Knopf wieder gedrückt wird.

    Wie kann ich das Problem denn lösen?

    Vielen Dank!

    Einmal editiert, zuletzt von vupibi (16. Juli 2014 um 05:14)

  • Hast du in deinem Programm auch eine Endlosschleife eingebaut? ;)

    • Offizieller Beitrag

    Hast du in deinem Programm auch eine Endlosschleife eingebaut? ;)

    Nein, hat er hoffentlich nicht. Sonst brauch er ja keine interupts ;) bzw. wenn er endlos in ner schleife rumeiert kann auch die zustände auch in jedem durchlauf abfragen. hast du dir auch mal die 2. Seite angeschaut? Das coole ist eigentlich die callback function. Aber Fragen wir doch mal anders. Was willst du erreichen? grade Anfänger für Anfänger halte ich interupts für (noch) zu schwere Kost und der Weg von xerion21 dein Ziel.

  • Wie startest du das Script denn?

    Erscheinen irgendwelche Meldungen wenn du es manuell über die Konsole gestartet hast und den Taster drückst?

    Bitte zeig uns dein vollständiges Script, exakt so wie du es verwendest - bitte poste das innerhalb von CODE! (sehr wichtig!)


    Aber wie dbv bereits schrieb vermute auch ich das er die 2.Seite des Artikels nicht beachtet/gesehen hat und somit nichts vom callback weiß --> "Click here for the next article (part 2)"

  • Das Script, welches Du verwendest ist nur ein Beispiel für die Nutzung des Interrupts. Es ist gewollt, dass es nach dem betätigen des Schalters beendet wird.


    Erstmal solltest Du unbedingt an den GPIO noch einen Pullup anschließen, um eine eindeutige abfallende Flanke zu bekommen. Pullups bzw. Pulldowns (intern oder extern) sind Pflicht. Das nur nebenbei.
    Hier muß also wohl oder übel eine Schleife her, die jedoch gut Programmiert, das System kaum belastet. Hier ein schönes Beispiel von Adafruit. Das "geheimnis" ist, das ganze in eine Funktion main() zu legen und die dann abhängig vom Event laufen zu lassen. Ich hab die Kommentare mal auf Englisch gelassen, wenn Ihr wollt kann ich die auch eindeutschen.

    • Offizieller Beitrag

    Warum sollte main() auch nur irgendeinen Einfluss darauf haben. Das ganze würde auch ohne Main() exakt so funktionieren. Sprich, den ganzen codeblock einen tab nach links (und def main(): entfernen). die Endlosschleife, welche die LED blinken lässt, hält das Script am laufen und somit können die Interrupts auch ausgewertet werden.

  • Das wäre möglich, trotzdem hat sich (nicht nur) bei Python die Nutzung einer main() unter professionellen Programmierern durchgesetzt. Und wenn ich was zeige, dann zeige ich es richtig. Alles andere ist Spagettiprogrammierung, die durchaus auch funktionieren kann, aber irgendwann undurchsichtig wird. Die Verwendung der main()ist auch der erste Ansatz zur objektorientierten Programmierung. Ich weiß, dass es viele Möglichkeiten gibt, also sollte dies hier kein Anlass sein über verschiedene Programmierstile zu streiten.

    • Offizieller Beitrag
    Zitat

    Das "geheimnis" ist, das ganze in eine Funktion main() zu legen und die dann abhängig vom Event laufen zu lassen.


    Das hast du geschrieben (zur Erinnerung)...wir diskutieren nicht über Programmierstile...aber diese aussage ist falsch....die Verwendung von Main() hat keinen Einfluss auf die Endloslauffähigkeit des Codes...die while Schleife schon

  • Na ich weiß nicht dbv, schau Dir den Code mal richtig an. Die while-Schleife sorgt nur für das Blinken der LED. Da schießt Du etwas schnell. Das wichtige an dem Script ist der Aufruf der main() mit

    Code
    if __name__=="__main__":
        main()


    Es wäre schön, wenn Ihr jemandem mit über 30 Jahren Programmiererfahrung einfach mal glaubt. Wobei :auslachen: "Alter schützt vor Torheit nicht", oder?

    Übrigens sorgt erst der Aufruf der main() für ein wirkliches Eventhandling. Das hat nichts mit einer banalen while-Schleife zu tun.

  • Die Funktion muss nicht zwangsläufig main() heißen. Aber gehen wir mal logisch ran.
    Wenn ich eine Schleife (while, for ... next) nehme und dort einen Event abfrage, wo bitte spare ich da Ressourcen? Dann kann ich doch gleich den Status des GPIO's in der Schleife abfragen, oder? Teile ich dem Interpreter aber mit: reagiere erst wieder, wenn sich ein Event ereignet, hält die ganze Interpretermaschienerie die Füße still und interpretiert nur das was zeitlich gerade anliegt. Im Beispiel die Schleife für das Blinken der LED. Erst wenn ich die Taste drücke hopst er da hin, wo was passiert. Ist vielleicht etwas populärwissenschaftlich ausgedrückt, aber es sollen ja auch alle verstehen. Ist die main() nicht da, kann es sein, dass das Pythonmodul in c geschrieben ist und das Eventhandling dort abläuft, dann folgt das allerdings nicht der mvc-Regel (model-view-controll) oder aber und das ist häufiger als man denkt, der Programmierer weiß nicht, was Eventhandling ist und glaubt es in eine Schleife setzen zu müssen. Vielleicht hast Du ja ein Beispiel ohne main(), dann könnte ich da mal raufschauen.

    Kurzer Zusatz: Eventhandling muss vom BS und vom Interpreter unterstützt werden. Sonst könnte das nicht funktionieren. Das BS erkennt einen Event und leitet den an den Interpreter weiter der dann reagiert. Es gibt heute noch Sprachen, die können das nicht.

  • Das man keinen Performance-Unterschied bemerkt ist noch LANGE kein Grund dafür den guten Stil seinzulassen.
    Ich bin kein Python-Kenner, aber es ist in Scriptsprachen normalerweise kein guter Stil die main wegzulassen, weil das schnell dazu führt, dass man "irgendwo zwischendrin" code schreibt, bzw man nicht deutlich erkennt wo der tatsächlich ausgeführte Code anfängt, gescheige denn in einer längeren Datei danach suchen kann.

  • Das stimmt, aber es ging um die richtige Nutzung des Eventhandlings, nicht um die Performance. Und warum soll ich was falsches zeigen. Ausserdem wäre es Spagettiprogrammierung.

    Da war Horroreyes schneller. Danke für die Bestätigung. Ich dachte schon es hat keiner Erbarmen mit mir :bravo2:

  • Hui, da hab ich aber was losgetreten :D

    Erst mal vielen, vielen Dank für eure Antworten!!
    Ich habe mal ein bisschen weiter gemacht und mich mal an dem orientiert was raspiprojekt schrieb. Das mit der main() Methode und der while Schleife habe ich soweit verstanden :)

    Mal ein paar Worte zu dem Programm:
    Es gibt fürs erste 2 LEDs, die erste blinkt (conf_led_system) (liegt innerhalb der main() in der while Schleife) und zeigt, dass das Programm läuft.
    Die zweite (conf_led_ok) soll einmal beim start blinken und dann immer wenn ich einen Schalter drücke, oder eine Aktion anläuft.
    Das klappt auch schon ganz supi.

    Dann gibt es zwei Schalter, die mal ein Relais steuern sollen. Der erste (motor_stop) macht das Relais zu, und der zweite (motor_hoch) es wieder auf.

    Jetzt habe ich aber folgendes Problem:
    Nachdem ich das add_event_detect für den zweiten Button hinzugefügt hatte, habe ich trotz timestamp (fast) immer eine doppelte Ausführung der Funktion. Wieso?
    Generell hätte ich es gerne so, dass wenn man den button gedrückt hält er beim loslassen NIE nochmal auslöst, unabhängig davon wie lange ich ihn gedrückt halte. Wie Löse ich das Problem denn am besten?

    Passt der Code soweit? Ich komme eigentlich aus der Webumgebung (PHP, JS und co.) und bin mit python noch nicht so bewandert. Ist aber schon toll, so ganz ohne dämliche Semikolons :P

    Einmal editiert, zuletzt von vupibi (16. Juli 2014 um 19:05)

Jetzt mitmachen!

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