Auf Interrupt reagieren

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

    ich versuche verzweifelt nach einer Möglichkeit, mittels Interrupt eine Variable zu setzen

    Folgenden nicht funktionierenden Code habe ich: :helpnew:

    Folgendes soll passieren:
    Wenn am Pin17 ein Signal anliegt, soll eine Variable gesetzt werden.
    Wurde 60 Sek. kein Signal am Pin17 empfangen, soll das Programm fortgesetzt werden.
    Löse ich den Interrupt aus, wird die Variable auch richtig angezeigt.

    Sobald ich #b=b-1 aktiviere, kommt es zum Fehler.

    Ich habe viel nachgelesen und habe auch gefunden, dass es so nicht funktioniert. Leider habe ich keine Ahnung, wie ich das Problem lösen kann.
    Gibt es eine Möglichkeit, der Interrupt-Routine eine 2. Variable zu übergeben?
    Ich habe es selbst leider nicht geschafft.
    Für eine Hilfe zur Lösung meines Problems wäre ich dankbar.

    MfG LK61

  • Hallo,

    da es hier keine Antwort für mich gibt, habe ich eine etwas unkonventionelle Lösung gewählt.

    Hintergrund meines Anliegens war es, eine Videoaufzeichnung, welche durch einen Schaltvorgang an einem GPIO ausgelöst wird, zu starten.
    Der Auslöser ist ein PIR. Aufgezeichnet sollte nur bei Bewegung und zur Sicherheit noch etwas länger. Die Aufzeichnung soll so lange statt finden, wie der PIR Bewegungen detektiert. (Also retriggerbar sein) Die Nachlaufzeit habe ich mit Y 20 Sekunden gewählt und ist frei änderbar.

    Hier mal meine Lösung mittels Interrupt-Routine.
    Ich poste nur einen Auszug des Scriptes. Die ganze Geschichte. Plattenplatz-Überprüfung und ggf. Löschen alter Dateien habe ich der Übersicht wegen weggelassen.

    Cial LK61

  • Moin,
    und geht es nun?

    ich kann dir bei php nicht helfen, aber eine Abfrage wie du sie machst, gibt normal ein Ergebnis zurück. Und dieses Ergebnis kann man doch einem INT zuweisen.

    Gruss DG8BR

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

  • ich kann dir bei php nicht helfen, aber eine Abfrage wie du sie machst, gibt normal ein Ergebnis zurück.

    Wo steht hier etwas von PHP :s Du bist der erste der Hier etwas von wegen PHP schreibt


    Und für den TE:

    Dein allein stehendes 'return' ist überflüssig und dort fehl am Platz. Bitte lies dich diesbezüglich noch mal ein wann und wofür man return verwendet.
    Aber auch der von dir gewählte 'Lösungsweg' ist der falsche. Du ignorierst leider völlig was es mit Interrupt überhaupt aufsich hat und nutzt dieses Feature falsch.
    Wie es richtig(er) geht findest du hier:
    Python script GPIO event pushbullet notification Picam
    Bild per raspistill in Python
    https://www.forum-raspberrypi.de/Thread-python-…48763#pid148763
    Zeitraffer start und stop

    Quelle -> Forumsuche nach: picamera pir

  • Hi,

    das Return ist in der Tat überflüssig. Eine Antwort auf die eigentliche Frage hast Du aber nicht zufällig?

    In Deinem Thread packst Du ein Sleep in einen Interrupt. Das ist meiner Meinung nach auch nicht die eleganteste Lösung.


  • In Deinem Thread packst Du ein Sleep in einen Interrupt. Das ist meiner Meinung nach auch nicht die eleganteste Lösung.

    In welchem der 4 Threads siehst du ein Sleep in der Interrupt Funktion :huh: Glaub du fehlinterpretierst da etwas...
    In der Interrupt Funktion steht nirgends ein sleep - höchsten dort wo das Script daran gehindert wird sich zu beenden - aber selbst das beschrieb ich nur in einem Thread um den dortigen TE nicht zu überfordern bzw nicht auf ein Schlag zu viel an seinem Ursprünglichen Script zu ändern... Ich nutze eigentlich nur noch 'signal.pause()'

    Zu deinem Anliegen aus Beitrag#1:

    Anstatt global würd ich ein Dictionary nutzen, das ist sowas wie ein Array.
    Und wenn der Interrupt ausgelöst wurde kannst du einen Timer starten, der dann nach Ablauf eine Prüfung durchführt.
    Siehe dazu:
    Mehrere GPIO`s mit Ausschaltverzögerung nutzen
    Taster, Funktion, Schleife beenden,

  • Hi,
    das Programm läuft nun seit 2 Tagen fehlerfrei. Der Code ist simpel und die Abfrage über GPIO ist vielleicht für Python-Programmierer nicht schick. Dennoch ist diese Lösung in meinem Fall ausreichend.
    Vielen Dank für Eure Unterstützung.

    Ciao LK61

    Hi,

    ich noch mal - der Tipp mit dem Threading ist gut. Ich denke, ich werde das Script noch mal umschreiben. :cool:
    (Schon damit ich irgendwann zur Python-Gemeinde gehöre)

    :thumbs1:

    Ciao LK61

    Einmal editiert, zuletzt von LK61 (20. April 2015 um 11:00)

  • Moin,
    kaum schreibt man was falsches...und es wird geholfen...

    Danke

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

  • @Maigraft,

    Hi,
    ich habe meinen Code mit Threading angepasst und ganz schnell wieder verworfen.
    Mein Script, (das ganze - ich postete nur den Interrupt-Auszug) läuft einwandfrei.
    Warum ein funktionierendes Programm, welches fehlerfrei läuft und auch in 10 Jahren noch seinen Dienst verrichten wird, der falsche weg sein soll, entzieht sich meiner Logik.

    Was ein Interrupt ist, ist mir natürlich klar. Warum Phyton alles anders macht, als andere große Programmiersprachen, ist mir noch schleierhaft. selbst mit Assembler oder Bascom wird ein Interrupt besser gehandelt als Python das kann. In jeder Hochprache gibt es globale Variablen. Richtig eingesetzt sind sie eine feine Sache. Vielleicht begreife ich es ja noch.

    Wenn Du jetzt deinen Lösungsweg in einem .NET, C oder VB-Forum posten würdest, bekämst Du sicher ebenso abwertende Antworten.

    Das soll jetzt keineswegs überheblich oder beleidigend rüber kommen und postet jetzt nicht alle auf einmal wie gut doch Phoenix ist und wie unvollkommen die anderen Sprachen sind.

    Ciao LK61

  • Das was du ankreidest ist freilich auch in Python möglich.
    Allerdings handhabst du den Interrupt halt irgendwie komisch... Dieses ganze x und y Gedöns ist überflüssig sofern man erst mal versteht wie es mit Python funktioniert :fies: Python macht das auch nicht anders als andere Sprachen, nur ist selbstverständlich der Aufbau und vor allem die Syntax je nach Programmiersprache eine andere.
    (mal davon abgesehen das x und y wirklich professionelle Variablen Namen sind)

    Leider sprichst du aber auch in Rätseln was das 'Aufzeichnen' betrifft - du erwähnst mit keiner Silbe womit oder was du aufzeichnest - dementsprechend können wir dazu auch nichts weiter sagen - Hellsehen bzw Gedankenlesen ist ein Mythos.

    Analysieren wir also mal dein Script und versuchen zu verstehen was da passiert:
    (die ersten 7 Zeilen lass ich bewusst weg)

    In der main() initialisierst du einen Interrupt Handler der beim Flankenwechsel von LOW auf HIGH reagiert und falls diese auslöst wird der TMP pin auf HIGH gestellt.
    Dann kommt eine while Schleife welche erst den Zustand des TMP pins ausliest und falls dieser auf HIGH steht wird TMP wieder auf LOW gestellt sowie y auf 21.
    Unabhängig von x wird dann geprüft ob y größer 0 ist und falls ja wird der Wert um 1 reduziert. Wenn anschließend y auf 1 steht wird ein print ausgegeben und der Ablauf für eine Sekunde blockiert bevor die Schleife von vorne anfängt.. Also insg 20 Sekunden bevor die "Ende der Videoaufzeichnung" Ausgabe kommt.
    (y wird btw innerhalb der Schleife erst nach 2 Durchläufen nach der Aufzeichnung auf 0 gesetzt, was auch seltsam is...)

    Betrachtet man also diesen Ablauf, stellt sich zumindest wir sofort die Frage wo denn dort überhaupt eine Aufnahme stattfindet? :s
    TMP scheint damit jedenfalls nichts zu tun zu haben da dieser Pin ja bereits früher ausgeschaltet wird, quasi sofort. Könnte also nur eine LED sein? kA, seh ich nicht...

    Diese ganze x und y Geschichte könnte man wie gesagt auch weg lassen. Entzieht sich mir eh wieso du das so löst aber nun von Assembler, .NET oder VB sprichst - programmierst du dort auch auf diese Art und Weise? :denker:
    Als einziger Grund, wieso du das auf diese Art und Weise umgesetzt hast, fällt mir eigentlich nur ein das du verhindern willst dass sich das Script beendet. Denn das täte es ohne die while. Aber dafür gibts auch schönere Lösungen die ich dir oben verlinkt hatte...

    Das obige Konstrukt könnte also auch wie folgt aussehen und dennoch ca. das gleiche bewirken:
    (wie gesagt: kA was TMP sein soll - Stichwort professionelle Variablen Namen)

    Mit threading.Timer könntest du jedenfalls auch sehr elegant einen Pin nach 20 Sek aus schalten.... Aber mehr kann ich hierzu jetzt nicht sagen, da ich wie gesagt weder weiß Womit aufgezeichnet wird noch wofür TMP steht... groß artig rum raten und mir nen Wolf texten möcht ich nicht - hab auch besseres zu tun als meine Glaskugel zu streicheln.

  • ANMERKUNG:

    Die Interpretation des Codes durch Maigraft ist schlechthin Quatsch. Es sollte eigentlich nicht schwer sein, den Code zu verstehen. Er ist dazu viel zu simpel. Wer zweifelt, sollte den Code mal kopieren und bei sich selbst laufen lassen. Einfach am GPIO17 einen Schalter anschließen...

    Gruß LK61

  • lol - und das nachdem wir darüber sogar via PN getextet haben :-/

    Du verstehst weiterhin nicht worauf ich hinaus wollte, worüber ich sowohl hier als auch via PN viel drüber geschrieben habe. Obwohl ich via PN kein Support gebe, und dir das auch sagte, hab ich es trotzdem versucht... Musste mir von dir dann aber herablassend wiederholt anhören wieso ich deinen Code denn nicht verstehen würde (und den Satz den du hier nun gepostet hast) - dabei könnte ich dir das ebenfalls vorwerfen, aber hab ich das?

    Du gibst selbst zu von Python keine Ahnung zu haben - siehst dich aber dennoch in der Lage meine Verbesserungsvorschläge als Quatsch abzustempeln...

    Wer seine GPIO's tatsächlich nutzen möchte, wird mit Deinem Code kein Spass haben - denn du vergewaltigst einen GPIO um einen Counter (y) zurück zu setzen. Solch eine Vorgehensweise ist unprofessionell - egal ob es funktioniert.
    Der TMP pin wird von dir nicht wirklich genutzt - du verwendest das nur um in einer anderen Funktion den Interrupt abzufragen... Entschuldige aber *kopf meets tisch*


    Bevor hier aber 'irgend wer anderes' solch ein Fail nach macht, hier Dein Code nur professioneller und wie ich mehrmals versucht hab Dir zu erklären:

    [code=php]
    #!/usr/bin/env python
    #
    # (c) by meigrafd
    #
    from __future__ import print_function
    import time
    import RPi.GPIO as IO

    PIR_Kontakt=17

    IO.setmode(IO.BCM)
    IO.setup(PIR_Kontakt, IO.IN)
    dictionary = {}
    dictionary['motion'] = False
    dictionary['counter'] = 0

    def INT_PIR(channel):
    dictionary['motion'] = True

    def main():
    print('Programmstart')
    IO.add_event_detect(PIR_Kontakt, IO.RISING, callback=INT_PIR, bouncetime=100)
    while True:
    if dictionary['motion'] == True:
    dictionary['motion'] = False
    if dictionary['counter'] == 0:
    print('Beginn der Videoaufzeichnung')
    dictionary['counter'] = 21
    if dictionary['counter'] > 0:
    dictionary['counter'] -= 1
    if dictionary['counter'] == 1:
    print('Ende der Videoaufzeichnung')
    time.sleep(1)

    if __name__ == '__main__':
    try:
    main()
    except (KeyboardInterrupt, SystemExit):
    GPIO.cleanup()
    [/php]


    PS: Ich untersage dir diesen Code für deine X Kunden zu verwenden! Der Zug ist dank deines letzten Posts nun abgefahren!

    • Offizieller Beitrag

    Ich finds meigrafds interpretation recht sinnig. Selbst in anderen Sprachen gibts andere Syntaktische Möglichkeiten um ein 20sek. Video aufzunehmen. Dein x,y macht die Sache nur schwer lesbar, die anderen Schwachpunkte hat meigrafd ja recht ausführlich dargelegt

    Der Unterschied zwischen Genie und Wahnsinn definiert sich im Erfolg.

  • Hallo,

    ich möchte das ganze jetzt zum Abschluß bringen.
    Erst mal danke für die Antworten.
    Wie ich jetzt ein Ereignis aus dem Interupt raus bekomme, nämlich über ein Dictionary, das war die Antwort, die ich hören wollte.

    @maigraft. Das war nicht herablassend. Du schriebst: Ich weiß immer noch nicht, was TMP macht.

    Den Quatsch bezog ich auf den von dir geposteten Code. Ich habe ihn nämlich laufen lassen. Du auch?

    Wenn Du meinen Code getestet hättest, hättest Du gemerkt, dass er funktioniert.


    Schaue Dir deinen Code mal genau an. Mein X macht nichts anderes, als Dein Dictionary ('motion') und Y nichts anderes als Dein Dictionary('counter')

    Dass ich von Python wenig Ahnung habe, ist korrekt. Dafür aber in einigen anderen Sprachen.
    Und genau so hätte ich es in .NET o.ä. gemacht. Dort sind Hilfsvariablen keine Schande.
    Ich danke Dir auf alle Fälle für die Zeit und die Mühe.
    Da meine Schaltung samt Code funktioniert, werde ich erst mal nichts dran rum basteln.

    Übrigens - der Satz von Dir: programmierst du dort auch auf diese Art und Weise? war der nicht herablassend und beleidigend?

    Wie willst Du mir verbieten, deinen Code zu verwenden? =(

    dbv Genau das ist ja das Problem. Es ging nie darum eine 20-sekündige Videoaufnahme zu machen. Die Videoaufnahme kann auch schon mal 30 Minuten (+20Sek) sein.

    Ciao und schönen Sonntag noch - LK61

  • ich habe never bezweifelt das dein code funktionieren würde... wo steht das?

    ich hab jegendlich angekreidet wofür du TMP verwendest. das was du damit machst, wozu du es missbrauchst, ist quatsch - egal in welcher programmiersprache.


    Dictionary schrieb ich dir bereits hier in Beitrag#6 und dann auch noch mal via PN, da hattest du aber besseres zu tun als darauf zu achten, nämlich herablassend zu bemängeln wieso ich immer noch nicht den doch eigentlich super simplen code verstehen könne, aber du der schon jahrzente X zufriedene kunden hätte, wüsste schließlich was er tue ....

    du _brauchst_ den TMP GPIO nicht.
    genau darauf wollte ich hinaus. auch hatte ich mit "globalen variablen" ('global') eine weitere möglichkeit angekrazt die du aber auch nicht beachtet hast - für dich waren ja leider nur meine ersten 9 wörter dieser PN interessant: Ich versteh immer noch nicht wozu TMP gebraucht wird. aber deine allgemeine art kommt mir herablassend vor, nicht nur ein satz. das spiegelt die gesamte konversation mit dir wieder.
    beachte mal den satz wort für wort und ohne da irgendwas rein zu interpretieren, gerade der letzte teil: wozu tmp gebraucht wird. der TMP GPIO erfüllt bei dir keinerlei zweck. da ist nichts angeschlossen oder sonst was. aber das macht kein sinn ... man nimmt sich doch nicht irgendeinen I/O den man dann beschaltet. was ist wenn einer deiner kunden ausgerechnet diesen I/O für etwas anderes nutzen möchte?


    und ich verbiete es nicht sondern untersage es. wenn das einer deiner kunden irgendwann mal lesen würde, und dann sieht das Du meinen Code an ihn als den deinen verkauft hast, tja, den rest kannste dir denken.


    PS: das einzige was ich oben am code gerade in der main() geändert habe ist dein x und y durch dictionary zu ersetzen sowie alles mit TMP raus zu werfen. siehst du das nicht? ich hatte da nicht vor eine andere möglichkeit zu offerieren.

Jetzt mitmachen!

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