Python-Code ignoriert Bewegungsmelder und läuft dauerhaft in Endlos-Schleife

  • Hallo zusammen,

    ich hoffe, ihr könnt mir helfen einen Fehler zu finden, da ich ziemlich auf dem Schlauch stehe.

    Vielleicht ein paar einleitende Worte:

    Es handelt sich um einen Code auf einem Raspberry Pi 3b, der verschiedene Aktionen ausführen soll, nachdem ein Bewegungsmelder (HC-SR501) eine Bewegung erkannt hat (siehe hierzu auch anhängendes Bild).

    Nach Durchlauf des Programms soll die nächste Auslösung – unabhängig davon, ob zwischenzeitlich Bewegungen erkannt wurden oder nicht – erst nach einer Pause von 180 Sekunden möglich sein.

    Problem aktuell ist, dass das Programm in Dauerschleife läuft und der Bewegungsmelder quasi gar nicht berücksichtigt wird.

    Bevor ich alles an seinen Bestimmungsort eingebaut habe, wurde das ganze erfolgreich außerhalb getestet. Deshalb verstehe ich auch nicht, warum das jetzt nicht mehr funktioniert.

    In der Testphase hatte ich bereits das gekaufte NoName-Netzteil (3A) für den Pi gegen ein Original-Netzteil mit 2,5A ausgetauscht, da ich eine „Low Voltage“-Meldung bekam, nachdem ich den miniamp angeschlossen hatte.

    Den Bewegungsmelder habe ich durch andere kleine Programme getestet und somit festgestellt, dass dieser in Ordnung ist. Gegenüber dem finalen Einbauort (ca. 70cm Kabel dazwischen) habe ich den BWM auch mal direkt am Pi angeschlossen.

    Ansonsten habe ich auch schon mal den miniamp (VCC und GND) vom Pi abgeklemmt bzw. mit einer separaten Stromversorgung versehen (VCC und GND; allerdings kam dann kein Ton mehr raus).

    Des Weiteren hab ich auch mal den Lüfter abgeklemmt und dafür dort den Bewegungsmelder angeschlossen.

    Die Verkabelung wurde ebenfalls geprüft.

    Alles hat leider nichts bewirkt. Das Programm läuft weiterhin in Dauerschleife.

    Ich vermute daher, dass der Fehler doch irgendwo im nachfolgenden Code liegt.

    Oder es gibt irgendwelche anderen Störeinflüsse.

    Ich würde mich freuen, wenn ihr euch das Konstrukt mal ansehen und mir bei der Suche des Fehlers behilflich sein könntet.

    Bin für jeden Tipp dankbar.

    Grüße

    PeerT

    Raspberry_Verschaltung.pdf

  • Python-Code ignoriert Bewegungsmelder und läuft dauerhaft in Endlos-Schleife? Schau mal ob du hier fündig wirst!

  • Hallo,

    den Code habe ich nur am Handy überflogen. Du machst folgendes, du schickst dein Programm 180Sekunden schlafen und wenn es dsmit fertig ist, wiederholst du das und so geht es immer weiter, weil du die Dauerschleife nicht verlässt.

    Wenn du willst das nach einer Erkennung eine gewisse Zeit nichts passiert, dann musst du die Zeit messen und entsprechend die Reaktion so lange ignorieren.

    Sorry Codebeispiele sind mir am Handy zu aufwändig.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • PeerT Der Kommentar ``# 180 Sekunden kein erneutes Auslösen ermöglichen`` ist schlicht falsch. Nichts an diesem `sleep()` verhindert irgend etwas, Du hast da nur den *Hauptthread* schlafen gelegt, und das hat genau 0 Einfluss auf die Behandlung des Bewegungsmelders, die in einem eigenen Thread passiert.

    Man würde sich bei der Auslösung einfach merken wann die letzte Auslösung der Aktion war, oder vielleicht besser wann die nächste Auslösung ist, und bis dahin die Signale vom Bewegungsmelder einfach ignorieren. Um das sauber zu lösen würde man sich eine Klasse schreiben, denn man muss sich ja Zustand über Aufrufe hinweg merken.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • OK,

    also, das time.sleep(180) kommt schon mal weg.

    Wie schreibt man nun eine Klasse, um sich die Zustände zu merken?

    Welche Routine wendet man da an?

    Kann dies der Grund dafür sein, dass das Programm in Dauerschleife läuft?

    Schlafen legt sich da leider gar nichts. Zumindest sehe ich das nicht beim Ablauf.

  • Wenn ich auf "Run" klicke startet das Programm, läuft wie gewünscht durch und beginnt dann direkt - ohne irgendeine Unterbrechung - wieder von vorne.

    Und zwar ohne, dass der Bewegungsmelder irgendwie aktiviert wurde.

    Als wenn irgendjemand ständig vor dem BWM herumlaufen würde, um die Aktion zu sehen.

    Dies ist aber nicht der Fall.

  • Nein fast.

    Die Prints kommen so:

    Das Programm wurde gestartet

    Bewegung erkannt

    Nebeln

    Sargdeckel öffnet sich

    Sargdeckel schließt sich

    Bewegung erkannt

    Nebeln

    Sargdeckel öffnet sich

    Sargdeckel schließt sich

    Bewegung erkannt

    Nebeln

    Sargdeckel öffnet sich

    Sargdeckel schließt sich

    ...

    Ohne irgendwelche Unterbrechungen oder das der BWM ausgelöst werden müsste. Die Relais schalten alle einwandfrei. Nach drei Durchgängen stehe ich in der Garage so weit im Nebel, dass man meinen könnte es brennt oder ich bin in einer Disco. 8)

    Ich breche das Programm dann immer ab mit STRG-C oder Klick auf "Stop".

  • Hallo,

    wie in den meisten Fällen ist es denke ich auch hier besser/leichter gpiozero zu verwenden anstannt Rpi.GPIO.

    Hier ein einfaches Codebeispiel:

    https://gpiozero.readthedocs.io/en/stable/reci…l#motion-sensor

    und hier die ausführliche Dokumentation mit den verschiedenen möglichen Parametern und Methoden:

    https://gpiozero.readthedocs.io/en/stable/api_…ensor-d-sun-pir

    Reicht dir das als Anhaltspunkt, wenn nicht kannst du gerne nachfragen

  • Moin Hofei,

    unabhängig davon, dass ich nicht mehr die Zeit habe, mich in gpiozero einzuarbeiten und dazu wahrscheinlich auch noch Änderungen am Raspberry vornehmen muss: warum sollte dies das Problem lösen, dass das Programm sich ständig wiederholt?

    Sicherlich kann man sich darüber zu einem späteren Zeitpunkt (nach Halloween) Gedanken machen, da der Pi 3b für diese mickrige Aufgabe eh völlig "over-the-top" ist. Ich hatte ihn halt hier rumliegen und wollte mir nicht noch neue Mikrocontroller zulegen.

  • PeerT Der Kommentar ``# 180 Sekunden kein erneutes Auslösen ermöglichen`` ist schlicht falsch. Nichts an diesem `sleep()` verhindert irgend etwas, Du hast da nur den *Hauptthread* schlafen gelegt, und das hat genau 0 Einfluss auf die Behandlung des Bewegungsmelders, die in einem eigenen Thread passiert.

    Man würde sich bei der Auslösung einfach merken wann die letzte Auslösung der Aktion war, oder vielleicht besser wann die nächste Auslösung ist, und bis dahin die Signale vom Bewegungsmelder einfach ignorieren. Um das sauber zu lösen würde man sich eine Klasse schreiben, denn man muss sich ja Zustand über Aufrufe hinweg merken.

    Hallo zusammen,

    erst mal vielen Dank für Eure Kommentare und Denkanstöße.

    Ich habe zu dem Thema mal gegoogelt, aber leider keine Ansätze gefunden, wie ich das mit den Signalen des BWM (Zeit messen, Reaktionen ignorieren, etc.) oder eine Klasse schreiben lösen könnte.

    Könnt Ihr mir vielleicht noch ein paar Ansätze geben, wonach ich suchen muss?

  • Teste doch mal nur den PIR-Sensor:

  • Warum sich das Programm wiederholt, hat __blackjack__ schon beantwortet.

    Das sleep() verhindert keinen Callbackaufruf.

    Als kleiner Test:

    Die 60 Sekunden sind erst in Zeile 21 abgelaufen, dennoch wurde bei jedem Tastendruck während des sleeps die Funktion aufgerufen und somit das Hello ausgegeben.

  • @ fred0815

    Ich kann das Programm heute Nachmittag gerne einmal testen.

    Jedoch habe ich bereits mehrere einfache Programme aus der Planungsphase (LED-Stripe einschalten, Sound-Datei abspielen, etc.) getestet, die alle einen einwandfreien Bewegungsmelder attestierten.

    Was mir jetzt so auf die Schnelle auffällt ist, dass im Code ein "import sleep" steht.

    Ist das zwingend notwendig?

    Diesen Eintrag habe ich nämlich nicht.

  • @ Hofei

    Ich habe es (hoffentlich) schon verstanden, dass die sleep-Zeile keinen Callback verhindert.

    Deswegen hatte ich ja darauf geantwortet, dass ich diese Zeile dann wohl auch entfernen kann.

    Das Programm soll sich aber nicht ständig von alleine wiederholen, sondern erst wieder, wenn der BWM eine neue Bewegung erkannt hat.

    Und auch erst dann, wenn zwischen einem vollständigen Programm-Durchlauf (Sargdeckel ist wieder zu) und dem erneuten Auslösen eine Wartezeit von x Minuten (hier drei) vergangen ist.

Jetzt mitmachen!

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