Parallel 10 sec. Video-Aufnahme und 2 sec. GPIO 25 on

  • Hallo zusammen,


    ausgelöst durch Bewegungsmelder soll 2 Sekunden lang GPIO 25 aktiviert und gleichzeitig ein 10 sekündiges Video aufgenommen werden.

    Anders ausgedrückt, die durch GPIO 25 on verursachte Reaktion soll von Anfang an gefilmt werden.

    Zur Bewegungsmelder-Videoaufnahme die mit großartiger Unterstützung von

    hervorragend funzt habe ich die Funktion wasserwerfer hinzugefügt. Leider beginnt das Video erst danach.

    Code
    def wasserwerfer():
        ww.on()
        time.sleep(2)
        ww.off()
    
    def record_video(camera, date_time):
    .


    Kann man mit Python die Videoaufnahme parallel zum wasserwerfer starten?


    Viele Grüße

    Ich Bins

  • Ich bin leider kein Python Spezialist. Hast Du mal versucht den Code zu verstehen? Die beiden Codefetzen hier bringen wenig - aber auf den Code im verlinkten Beitrag kann man etwas anfangen. Das Problem ist, dass sowohl Dein Wasserwerfer als auch die Aufnahme warten und deshalb kannst Du nichts gleichzeitig machen. Ich würde vorschlagen, die Aufnahme zu teilen, dann kannst Du den Ablauf wie folgt machen: Aufnahme Start > Wasserwerfer (dauert zwei Sekunden > Aufnahme warten (dauert noch 8 Sekunden > Aufnahme Stopp.

    ...wenn Software nicht so hard-ware ;) ...

    Freue mich über jeden like :thumbup:

  • Ich versuche das mal basierend auf Deinen Code hin zu kriegen:

    Übrigens, am Code ist mir einiges aufgefallen, das mir "nicht so" gefällt. Da ich aber in Python auch nicht erfahren bin, mache ich hier keine Verbesserungsvorschläge bzw. versuche es zu verbessern. Da können ggf. andere hier deutlich professioneller helfen.

    Mir geht es darum Dir einen möglichen Lösungsweg aufzuzeigen.

    ...wenn Software nicht so hard-ware ;) ...

    Freue mich über jeden like :thumbup:

  • Hier mit Simulationscode in einer Klasse:


    Dann nochmal ohne Simulation und Kommentare. Ist aber ungetestet. Möglicherweise kommt es noch irgendwo zu Fehlern.

    Am besten auch mal in der Dokumentation zu Python nachlesen, was die einzelnen Funktionen, Klassen und Methoden machen.

  • Vielen Dank Euch beiden,


    habt Ihr noch einen Tip für mich?

    Ich versuche schon ein paar Minuten vergeblich Thonny Code in die Windows-Zwischablage zu kopieren.

    Auf den Pi greife ich aus Win10 über VNC zu und verwende Thonny zum Experimentieren mit Euren Beispielen.

    Manchmal gelingt es problemlos in beide Richtungen den Inhalt der Zwischenablage auszutauschen und jetzt gerade

    in Richtung Windows erhalte ich zuvor gespeichertes oder nur Fragmente.

  • Hallo VeryPrivat,


    wenn ich Deinen Vorschlag in den bestehenden Code (ohne Pir, IR, h264 > mp4 ) einbaue wirft der Werfer Wasser aber ich erhalte


    Fertig für nächste Bewegungserkennung.

    Bewegung erkannt

    Traceback (most recent call last):

    File "/home/user/Probe.py", line 43, in <module>

    main()

    File "/home/user/Probe.py", line 39, in main

    record_video_wait()

    File "/home/user/Probe.py", line 24, in record_video_wait

    camera.wait_recording(RECORDING_TIME)

    NameError: name 'camera' is not defined

  • Der gepostete Code passt mit den Zeilennummern nicht zum Traceback.

    Bei record_video_start wird das camera objekt übergeben, aber bei den Funktionen record_video_wait und record_video_stop wird es nicht übergeben. Alles, was man in einer Funktion zuweist, ist auf Modulebene nicht erreichbar.


    camera ist in main() instanziiert worden und auch nur dort gültig, es seiden es werden Funktionen innerhalb main aufgerufen und das camera Objekt der jeweiligen Funktion übergeben. Man könnte camera auch auf Modulebene definieren. Ich habe dafür eine Klasse verwendet, um alles später in einem Objekt zu haben. Das geht mit Klassen einfacher, da man neben den Methoden auch Attribute definieren kann und die Methoden auf die Attribute der Klasse zugreifen können. Wenn man mit Funktionen arbeitet und global verhindern will, muss die jeweiligen Objekte den Funktionen auch übergeben. Das kann dann auch über mehrere Funktionen hinweg geschehen.



    Das müsste funktionieren. Code ist ungetestet.


    Edited 2 times, last by DeaD_EyE: ww -> aktor Button zu main() hinzugefügt. ​AKTOR_TIME eingeführt ().

  • Hallo,


    DeaD_EyE du hast geschrieben:

    Code
    ww = LED(25)
    ww.wait_for_press()

    Das sollte eher ein Button sein?


    Der Threadersteller hat ja zu Beginn des Themas auf meine Codebeispiele hingewiesen. Ich habe bewusst beim Funktionsaufruf 'camera' übergeben, damit nicht alles wild durcheinander irgendwo auf Modulebene definiert wird. Aber eventuell ist das am Anfang auch schwer zu verstehen, ich habe dazu zum Beispiel auch lange gebraucht :sleepy:


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Das sollte eher ein Button sein?

    Ich find Elektroporn geil. Also kann man auch mal mit LEDs kuscheln.


    Der Button ist noch nicht einmal importiert worden. Hach, ich weiß, woran es lag.

    Das Tool isort sortiert die Imports nach __future__, imports der python-stdlib, imports von fremden modulen, imports aus eigenem Code.

    Zuerst kommt immer alles mit import, dann from ... import ...

    Gleichzeitig werden alle Imports entfernt, die nicht genutzt werden. Deswegen ist dort auch kein Button, weil ich ihn nie benutzt habe.


    Werde ich mal korrigieren. Aber ich brauche erst 10 Kaffee um wach zu werden.

    Ich habe bewusst beim Funktionsaufruf 'camera' übergeben, damit nicht alles wild durcheinander irgendwo auf Modulebene definiert wird.

    War ja auch richtig. zeigt aber auch das man schon bei sehr wenig Code viel mitschleppen muss. Ob man eine Klasse oder viele Funktionen nutzt, ist oftmals eine Entscheidung zwischen vielen Funktionen auf Modulebene, oder halt einer Klasse, an der alles dran hängt, was man braucht. Besser ist es natürlich noch, wenn Teile logisch von einander getrennt sind. Wasserwerfer, Sensor, Video. Da es aber so wenig Funktionalität hat, kann man das auch in einer Klasse zusammenfassen und am Ende hat man trotzdem nur ganz wenig Methoden.


    Das Problem ist immer, dass Anfänger mit Klassen so ihre Probleme haben.

  • Hallo DeaD_EyE,


    nach Deinem letzten Beispiel in das ich die PIR Abfrage anstelle des LED-Button noch integrierte scheint es jetzt mit nachfolgendem Code zu funktionieren. Leider, warum auch immer, erhöhte sich dadurch die Fehlerhäufigkeit der PIR. Wenn ich mit FileZilla über WLan die Videos auf meinen Win10 PC übertrage lösen die PIR aus. Weil die PIR sehr störungsanfällig sind verwende ich bereits zwei von den Teilen.

    Seltsamerweise verhalten sich die PIR mit der Version von Dennis89 (unten) nicht so empfindlich.


    Hier die von DeaD_EyE abgewandelte Variante von VeryPrivat.


    Version von Dennis89, mit dem Nachteil, dass erst nach dem Wasserwerfer das Video beginnt.

    Meine Versuche in die Version ganz oben noch die Funktionen

    Code
            change_video_format(video_file)
            h264_entfernen(video_file)

    von Dennis89 zu integrieren scheiterten bisher.

  • Version von Dennis89, mit dem Nachteil, dass erst nach dem Wasserwerfer das Video beginnt.

    Ungetestet:


    Viel Erfolg

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Beim MotionSensor kann man die queue_len und den threshold angeben.

    Wenn man das nicht angibt, wird die queue_len auf 1 gesetzt und damit die queue deaktiviert.

    Bei besonders empfindlichen PIR-Sensoren sollte man zuerst diesen Ganzzahlwert erhöhen.

    Code
        motion_sensor1 = MotionSensor(23, queue_len=10)
        motion_sensor2 = MotionSensor(24, queue_len=10)   

    Mit dieser Einstellung müssen beide Sensoren eine Sekunde lang (sample_rate=10) neue Werte bekommen, die im Durchschnitt größer als der threshold sind. Der threshold ist Standardmäßig 0.5. Die sample_rate ist Standardmäßig 10.


    Wenn du die Empfindlichkeit durch die queue_len herabsetzt, kann es sein, dass die Konstruktion nicht mehr funktioniert:

    Code
    motion_sensor1.wait_for_motion() and motion_sensor2.wait_for_motion()

    Da Resultat nicht verwendet wird, kann man das auch so schreiben:

    Code
    motion_sensor1.wait_for_motion()
    motion_sensor2.wait_for_motion()

    Wenn die Sensoren nun viel unempfindlicher eingestellt sind, kann es z.B. vorkommen, dass motion_sensor1 auslöst, dann 2 Stunden gar nichts passiert und danach motion_sensor2 auslöst. Mit dieser Abfrage ist nicht garantiert, dass beide Sensoren gleichzeitig ausgelöst haben.


    Probiert erst mal die andere queue_len aus.

  • Hallo Dennis,


    habe Deine neue watercannon-Version getestet und erhalte


    und zusätzlich werden in die Konsole 5 Seiten Importing AVC-H264: | | (01/100) geschrieben. Kann man diese Ausgabe irgendwie unterdrücken?

    Fehlermeldung.pdf

  • Oh da habe ich eine Klammer vergessen, teste mal:

    Thread(target=start_watercannon, args=[water_led]).start()



    Zu den restlichen Ausgaben kann ich dir mangels Erfahrung leider nichts sagen.



    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Damit läufts. :bravo2: Weil ich in meiner Bude keine Überschwemmung gebrauchen kann habe ich am Relaiskontakt meinen Multimeter (als Durchgangsprüfer) angestöpselt. Dieser piepst zwei mal. Das Piepsen kann aber leider nicht im Video sehen, hören ebenso wenig.

    Jetzt werde ich den Katzenschreck wieder am Ort des Geschehens positionieren und bin auf das Ergebnis gespannt. Dort ist es jedoch nicht so einfach die PIR auszulösen und ich muss zum Testen eine mit warmen Wasser gefüllte Flasche von meinem Balkon in den PIR-Erfassungsbereich baumeln lassen.

  • Hallo DeaD_EyE,


    das ist ja interessant, dass man auf diese Weise die Einstellungen der PIR ändern kann.

    Nur weiß ich nicht so recht welche Code-Schnipsel ich verwenden sollte.


    Ich habe es jetzt mit

    Code
    def main():
        motion_sensor1 = MotionSensor(23, queue_len=10)
        motion_sensor2 = MotionSensor(24, queue_len=10) 
        while True:
            print("Fertig für nächste Bewegungserkennung.")
            motion_sensor1.wait_for_motion()
            motion_sensor2.wait_for_motion()

    getestet. Meintest Du es so?

  • Hallo Dennis,


    der letzte Katzenschreck-Einsatz mit Deiner neuen Version war erfolgreich.

    Leider ist der Wasserverbrauch durch die zweimalige Aktivierung des Wasserwerfers durch

    water_led.blink(on_time=1, off_time=0.5, n=2) relativ hoch und der Behälter wegen der Fehlalarme zu schnell.

    Ich gehe davon aus, dass mit , n=1 nur einmal das Kommando "Wasser marsch" ausgegeben wird und sleep(2) nicht nötig ist.

    Code
    def start_watercannon(water_led):
        print("Wasserwerfer an")
        water_led.blink(on_time=1, off_time=0.5, n=1)
        # sleep(2)
        print("Wasserwerfer aus")

    Ist das richtig oder bin ich auf dem Weg der Holzes?

  • Ich gehe davon aus, dass mit , n=1 nur einmal das Kommando "Wasser marsch" ausgegeben wird

    'n' ist die Anzahl, wie oft geblinkt wird, siehe hier.

    Das 'sleep' habe ich einfach aus deinem oder sonst einem vorherigen Code übernommen.


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?