GPIO mit Python innerhalb einer gewissen Zeit abfragen (z.B.: 1 Sekunden)

  • Sehr geehrte aktive Forums-Mitglieder.
    Lange Zeit betrachte ich nun schon diese Forum und ihr wart schon das eine oder ander Mal eine Hilfe für mich dafür herzlich :danke_ATDE: .
    Es war mir bis jetzt leider unmöglich mal eine Antowrt zu posten da ihr immer schneller (oder besser) als ich wart.
    Nun heute wende ich mich an euch, mit der Bitte um :helpnew:
    Falls das Thema am falschen Ort platziert wurde enschuldige ich mich.


    Mein PI erledigt diverse Aufgaben unter anderem steuert er mein WLAN-Router und meine "alte" Stereoanlage (ein / aus).
    Das Einschalten ist über ein Funkrelais gelöst das ein PIN (PIN 16 -> GPIO23) auf High setzt.

    Leider kommt es ab und zu vor, das es ein "false_positiv" gibt > soll heissen mitten in der Nacht wird mein WLAN und die Stereoanlage eingeschaltet - uncool :@

    Meine Idee dazu ist mein bestehendes Python-Script so zu erweitern das nach einem ersten HIGH geprüft wird, ob innerhalt einer gewissen Zeit (1 Sekunde) der selbe Pin ein zweites Mal HIGH geschaltet wurde. Falls Ja -> schalte WLAN und Stereoanlage ein, falls nein gehe wieder Return und warte (theoretisch unendlich lange bis der Pin HIGH geschaltet wird, dann beginnt das spiel von vorne. (soweit ich das verstehe ist das eine art Rekursion wobei das keine Rolle spielt, da komme ich shcon wieder weiter.

    Somit benötige ich "nur" den Code zum prüfen ob der Pin innerhalb einer gewissen Zeit (1 Sekunde) mind 1mal HIGH war.

    Anbei noch mein Script (abgeschrieben - da ich aktuell kein Netzwerkzugriff auf den PI habe)
    ------------
    import RPi.GPIO as GPIO
    import subprocess
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

    def func1():
    try:
    GPIO.wait_for_edge(23, GPIO.FALLING)
    subprocess.call("/home/pi/eingang.sh")
    except KeyboardInterrupt:
    GPIO.cleanup()
    GPIO.cleanup()
    return

    print "Eingangsüberwachung aktiv"
    func1()
    --------------

    Für euere Bemühungen bedanke ich mich bereits im voraus.

    Freundliche Grüsse
    Dani

    Einmal editiert, zuletzt von dll-live (14. April 2017 um 15:52)

  • GPIO mit Python innerhalb einer gewissen Zeit abfragen (z.B.: 1 Sekunden)? Schau mal ob du hier fündig wirst!

  • Hallo Dani,

    einfacher wäre es, die Zeitspanne zwischen zwei Ereignissen GPIO-Ereignissen zu prüfen. Ist diese z.B. kleiner als 100 ms, dann kann man davomn ausgehen, dass da jemand etwas gedrückt hat. Du musst also nur die aktuelle Zeit bei jedem Ereignis in einer Variablen ablegen.

    Kannst Du Störsignale ausschließen? Üblicherweise fängt man die mit einem Pull-Up- oder Pull-Down-Widerstand ab. Ohne solche Widerstände fungiert die (lange) Leitung als Antenne, wodurch dann auch mal HIGH-Pegel entstehen, d.h. ein Pegel von > 1,3 V.

    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.

  • Sali Andreas.

    Die "Zeit-Messung" ist kein wirkliche Option, da ich sonst beim nächsten wirklichen Schalten drei HIGH's brauche (erste HIGH messung starten - ( lange Warten) zweites HIGH -> auswerten zu lange wieder vorne beginnen -> drittes HIGH messung starten - 4 HIGH auswerten OK -> schalten. Das ist ein HIGH zu viel ich muss es maximal mit 2 HIGH machen.

    und Nein die Störsignale kann ich leider nicht zu hundert Prozent ausschliessen. Das meine Leitung als Antenne taugt vermuttei ch ehner weniger denn die ist max 30 cm lang.

    Hoffe, das weitere Ideen kommen, das mit dem Interrupt in einer gewissen Zeit wäre auch für andere Sachen eine coole Methode.

    Gruss Dani

  • Hallo Dani,

    schaue Dir doch mal die Schaltung in diesem Thread an.

    Da passiert prinzipiell das Gleiche - nur dass bei einem Taster-Ereignis in Abhängigkeit der Dauer des Gedrückthaltens der Raspberry Pi heruntergefahren oder neu gebootet wird. Dieses Programm ist bei allen meinen Raspberry Pi aktiv. Und bislang gab es keinen einzigen unbeabsichtigten Shutdown oder Reset.

    Genau diese Technik (Hardware, Software) verhindert, dass Prell-Ereignisse oder Störsignale zu ungewünschten Aktionen führen - eigentlich das, was Du haben möchtest.


    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.

  • Sali Andreas.

    Ich habe dien Thread mal quer gelesen - coole Sachen.
    Diesen Ansatz kann ich jedoch hier nicht verwenden. denn dies ist der glieche wie in deinem ersten Post (Zeitmessung zwischen 2 Ereignissen). Das geht leider nicht auf....
    Ich versuch das nochmals zu beschreiben:

    Situation a)
    1) Signal kommt (Zeit 0)
    2) "kurze" Wartezeit (0.5 Sekunden)
    3) Signal kommt
    ==> PI soll schalten

    Situation b)
    1) Signal kommt (Zeit 0)
    2) "lange" Wartezeit (5 Stunden)
    3) Signal kommt
    ==> Pi schaltet nicht da warte zeit zu lange
    4) "kurze" Warte Zeit (0.5) Sekunden
    5) Signal kommt
    ==> PI sollte jetzt schalten

    Situation a lässt sich mit der Zeitmessung (deinem Thread) perfekt abfangen - da geb ich dir zu 100 % Recht
    Sitation b läst sich leider nicht abfangen
    Mein Problem es können beiden Sitationen auftreten und ich will / muss diese entsprechend Abfangen.

    Gruss Dani

  • Hallo Dani,

    ich glaube, Du bist auf dem falschen Dampfer. Dein Fall b) tritt doch gar nicht auf.

    Situation b)
    1) Signal kommt (Zeit 0)
    2) "lange" Wartezeit (5 Stunden) ==> ohne jegliche Relevanz, da nach Ablauf der erlaubten Zeitspanne das erste Signal verworfen wird, weil offensichtlich irrtümlich zustande gekommen - der Rest entspricht dann der Situation 1, auf die alles Weitere zurückgeführt werden kann. Deswegen ist es entscheidend, die Zeit jedes Ereignisses zu ermitteln.
    3) Signal kommt
    ==> Pi schaltet nicht da warte zeit zu lange
    4) "kurze" Warte Zeit (0.5) Sekunden
    5) Signal kommt
    ==> PI sollte jetzt schalten

    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 (14. April 2017 um 22:42)

  • Hallo Andreas.

    Wie schaff ich es dass nach einer definierten Zeit wieder von vorne begonnen wird? :helpnew:
    Denn genau da klemmpt es bei mir und ich renn gegen die Wand. :wallbash:

    wenn du mir das aufziegen kannst, bin ich Happy :danke_ATDE: und mein Oster fest ist gerettet.

    Gruss Dani

  • Hallo Dani,


    Wie schaff ich es dass nach einer definierten Zeit wieder von vorne begonnen wird? :helpnew:
    Denn genau da klemmpt es bei mir und ich renn gegen die Wand. :wallbash:

    wenn du mir das aufziegen kannst, bin ich Happy :danke_ATDE: und mein Oster fest ist gerettet.


    Ist doch eigentlich recht einfach:
    Das erste Ereignis erkennst Du ==> Du ermittelst die aktuelle Uhrzeit.
    Danach dödelt Dein Programm in der "Hauptereignisschleife". Dort wird außer einem Delay / Sleep nicht wirklich viel passieren. Dort fragst Du ab, ob die Differenz zwischen der aktuellen Zeit und der erfassten Zeit größer als DEINE Vorgabe ist. Ist sie das irgendwann, wird die erfasste Zeit gelöscht. Somit braucht dieser Vergleich auch nur dann gemacht zu werden, wenn die Variable der erfassten Zeit einen Inhalt aufweist.

    Ist die Differenz zu klein, wird es das gleiche Ereignis sein. Dann beibt die erfasste Zeit erhalten.

    Schau Dir mal den Quellcode zu dem verlinkten Beitrag genauer an. Da steht eigentlich genau drin, wie man sowas programmieren kann.

    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 (14. April 2017 um 22:51)

  • Sali Andreas.

    Im Moment gibt es zwei Optionen:

    a) ich seh den Wald vor lauter Bäumen nicht oder
    b) Meine Beschreibung ist noch nicht verständlich genug

    Da ich auf b setze, verusche ich es nochmals mit anderen worten!

    Szenario:
    Der Pi dümelt vor sich hin und wartet darauf das am Eingang ein HIGH kommt. Nach x Zeiteinheiten wurde ein HIGH erkannt. Jetzt hat der Benutzer/die Eingange eine vordefinierte Zeit ( z.B.: max 1 Sekunde) Zeit dem Pi nochmals ein HIGH zu schicken - ist das erfolgt Ausgang schalten falls nicht zurück auf Anfang. (Warten bis ein HIGH erkannt wird.
    Wichtig das HIGH selber dauern jeweils nur ganz Kurz (deshalb wird mit Interrupt gearbeitet).

    Frage:
    Wie schaff ich es ein Interrupt auf einer gewissen Zeit (z.B.: Innerhalb 1 Sekunde) abzufragen (anders Ausgedrückt - wie weiss ich das innerhlab einer Sekunde ein Interrupt kam oder nicht?

    Andreas: Dir danke ich schon mal jetzt für deine Geduld und das Verständnis mit mir.
    Gruss Dani
    Gruss Dani

  • Hallo Dani,

    schaue Dir mal folgende Tabelle an:


    Schnackelt's jetzt?

    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 (14. April 2017 um 23:30)

  • Hallo Andreas

    Leider nein :wallbash: :wallbash: :wallbash:

    Es ist folgendes:

    Zeit (in Sekunden) | Signal am Eingang | Aktion (angegeben Schrittlänge normalerweise 0.1 Sekunden)
    0.0 | LOW | warten auf HIGH gefolgt von sofortigem LOW
    0.1 | LOW | warten auf HIGH gefolgt von sofortigem LOW
    0.2 | HIGH | HIGH ist da ( :thumbs1: )
    0.21 | LOW | änderung auf low (von HIGH erkannt)==> ab jetzt muss irgend wann innerhalb der nächsten Sekunde nochmals ein HIGH kommen - dann wir geschaltet sonst nicht
    0.3 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    0.4 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    0.5 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    0.6 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    0.7 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    0.8 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    0.9 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    1.0 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    1.1 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    1.2 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW ==> ist ausgeblieben daher wieder von vorne beginnen
    1.3 | LOW | warten auf HIGH gefolgt von sofortigem LOW

    1.4 | HIGH | HIGH ist da ( :thumbs1: )
    1.41 | LOW | änderung auf low (von HIGH erkannt)==> ab jetzt muss irgend wann innerhalb der nächsten Sekunde nochmals ein HIGH kommen - dann wir geschaltet sonst nicht
    1.5 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    1.6 | LOW | warten auf (erneuetes) HIGH gefolgt von sofortigem LOW
    1.7 | HIGH | erneutes HIGH ist da ( :thumbs1: )
    1.71 | LOW | änderung auf low (von HIGH erkannt)==> ist innerhalb der Sekunde :bravo2: :bravo2: :bravo2:
    egal was jetzt kommt, entweder sofort schalten oder warten bis Zeit durch ist und dann schalten.

    ist mein Problem jetzt verständlicher?

    Gruss Dani

    Einmal editiert, zuletzt von dll-live (14. April 2017 um 23:42)

  • Hallo Linusg


    Also ich hab's geschnallt :lol:

    Nur das noch nicht:

    Wie jetzt, komplett zufällig oder was?! Kannst du das ^ noch mal genauer sagen als "egal was kommt entweder oder"?

    LG

    Damit meine ich, dass es mir nun egal ist, wie es weiter geht
    entweder wird der Ausgang direkt nach 1.71 geschaltet
    oder ob die restliche Zeit (die Restzeit der Sekunde) zuerst noch gewartet wird.

    ist dies nun auch noch klar geworden?

    Gruss Dani

  • Hallo Dani,


    Hallo Andreas

    Leider nein :wallbash: :wallbash: :wallbash:

    Ich geb's auf. Hier Code in der Programmiersprache Icon.


    Code-Deutung:

    Zeile 1: Einbinden meiner GPIO-Library
    Zeile 3: Definition eines Pins für Eingabe
    Zeile 4: Definition eines Pins für Ausgabe
    Zeile 6: Programmeintrittspunkt
    Zeile 7: Einleitung einer Endlosschleife (geht bis Zeile 14)
    Zeile 8: Abfrage, ob auf dem GPIO-Eingang ein HIGH-Pegel anliegt) Wenn ja, dann passiert folgendes
    Zeile 9: Falls die Variable [font="Courier New"]zeit[/font] gesetzt ist (ist hier noch nicht der Fall) und kleiner 1000 ist, würde der GPIO-Ausgang auf HIGH gesetzt werden
    Zeile 10: Falls [font="Courier New"]zeit[/font] noch ungesetzt ist, wird die Variable [font="Courier New"]zeit[/font] auf die aktuelle Uhrzeit gesetzt.
    Zeile 11: Ende der Abfrage zu Zeile 8
    Zeile 12: Wenn seit Setzen der Variable [font="Courier New"]zeit[/font] mehr als eine Sekunde vergangen ist, dann wird die Variable [font="Courier New"]zeit[/font] wieder auf ungesetzt zurückgesetzt.
    Zeile 13: 5 ms verzögern
    Zeile 14: Ender der Endlosschleife
    Zeile 15: Programmende (wird nie erreicht)

    Somit wird der GPIO-Ausgang nur dann gesetzt, wenn innerhalb einer Sekunde zwei HIGH-Ereignisse aufgetreten sind. Alle anderen Fälle ergeben sich hier erst gar nicht, weil nach dem ersten HIGH-Pegel kein zweiter innerhalb einer Sekunde erkannt wird oder weil die Variable [font="Courier New"]zeit[/font] wieder zurückgesetzt wird und Warterei und Zählerei von Vorne beginnen.

    Übertrage diesen Algorithmus nach Python und nutze Interrupts zur Erfassung von GPIO-Ereignissen.


    Beste Grüße

    Andreas

    EDIT: Ach, linusg ist ja auch hier... ;)

    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 (15. April 2017 um 00:22)

  • Ja, legen wir einfach mal fest, dass sofort geschaltet wird (bei 1.7 nicht 2.0). :lol:
    Das sollte nicht schwer sein, aber bevor ich was (ungetestet!) zusammenbastle, welche GPIO Bibliothek nimmst du? Python mit RPi.GPIO? gpiozero? pigpio?

    EDIT: Und ja, es war mal wieder einer schneller und hat auch noch kompletten Code abgeliefert ;)
    Kannst du so viel Python um das zu übertragen?

    LG

  • Hallo Dani,


    oder ob die restliche Zeit (die Restzeit der Sekunde) zuerst noch gewartet wird.


    Wozu sollte jetzt noch gewartet werden? Es ist doch klar, dass der Ausgang jetzt auf HIGH gesetzt werden soll...

    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 (15. April 2017 um 00:17)

  • Zitat


    Wozu sollte jetzt noch gewartet werden?

    Ganz meine Rede! Aber vielleicht hat es sich ja schon erledigt, der OT kann ja deinen (genau beschriebenen :thumbs1: ) Code als Basis nehmen und was schönes mit Interrupts zaubern.


    Also gut, ich übersetz' dann mal... hab ja grad' sonst nichts zu tun :)
    -> Pythoncode folgt.


    EDIT: Ach, linusg ist ja auch hier... ;)

    Tja, einfach aus dem Nichts aufgetaucht und nichtmal Hallo gesagt :^^:

    LG

  • Sali

    Andreas:
    Ja, das Schalten kann sofort erfolgen, ob dies möglich ist, weiss ich nicht.
    Da ich mit dieser Verzögerung leben kann, ist es für mich auch ok, wenn es die "Restzeit" noch abwartet.

    Linusg: Besten Dank!

    Gruss Dani

    Einmal editiert, zuletzt von dll-live (15. April 2017 um 00:26)

  • Hallo Dani,


    Ja, das Schalten kann sofort erfolgen, ob dies möglich ist, weiss ich nicht.


    Möglich ist alles. Code ist geduldig. Programmieren kann man (fast) alles, was man in einem Algorithmus widerspruchsfrei unter Berücksichtigung aller denkbaren Fälle beschreiben kann.

    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.

Jetzt mitmachen!

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