Interrupt-Methode Problem mit GPIO INPUT

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

    ich habe ein großes Problem bei folgendem Setting:

    Ich verwende auf einer Experimentierplatine einen 12V Gleichstrommotor, eine 12V LED und einen Taster. LED und Motor werden via 2 NPN Transistoren geschalten.
    Was ich vorhabe:
    LED und Motor sollen in einer for-Schleife ein gewisses Programm ablaufen. Währenddessen soll mir der Pi mit der "GPIO.add_event_detect - Methode" den Taster im Auge behalten und soll falls dieser betätigt wird die for-Schleife beenden und das Python-Programm beenden.
    Weil mein Motor und die LED 12 V Gleichstrom benötigen verwende ich ein externes Netzteil zur Fremdeinspeisung.

    Hier ein Foto vom Breadboard:

    Hier der Python-Programmcode:

    Nun zum eigentlichen Problem:

    Wenn ich mein Python-Programm laufen lasse, funktioniert zunächst alles einwandfrei.
    Die LED leuchtet auf, Motor läuft im vorgegebenen Zeitintervall und wenn der Taster betätigt wird, bricht die Schleife ab und das Programm wird beendet.
    Wenn ich aber zum Beispiel mit einem metallischen Gegenstand, wie einer Pinzette oder nur einem Stück Draht oder Kabel an den Minus- oder Pluspol ran gehe, bricht das Programm ab. :neutral: (Obwohl ich den Taster nicht betätigt habe, nur Kontakt mit GND oder dem Pluspol).
    Wenn ich das Programm so umschreibe, dass die Tasterstellung am Ende der for-Schleife abgefragt wird (also sequentielles Abfragen des Tasters und Programmabbruch) dann gibt es den Effekt nicht. Dann kann ich noch so oft mit einem metallischen Gegenstand an einen der beiden Pole gehen, da bricht nichts ab.
    Fazit: Ich habe dieses Phänomen nur, wenn ich die interrupt-Methode mit der Event-handler [font="Monaco, Consolas, Courier, monospace"]GPIO.add_event_detect(18, GPIO.RISING, callback=my_callback, bouncetime=200)[/font][font="Verdana"]in den Code aufnehme.[/font]
    Meine Vermutung: Ich habe das Gefühl, dass der Pi selbst auf die kleinsten Spannungsschwankungen reagiert, die ich ihm über eine Pinzette/ Kabel induziere.
    Meine Frage: Wie kann ich das Problem lösen? Gibt es eine Möglichkeit beim Pi die "Empfindlichkeit" des Inputs zu "regeln"!? :huh: Hat jemand schon mal ähnliche Erfahrungen gemacht?

    Ich hoffe ihr könnt mir da weiterhelfen!? :helpnew:

    Einmal editiert, zuletzt von LTSmash (6. Oktober 2013 um 18:02)

  • Probier mal den Eingang hardwareseitig mit einem 10kOhm Pulldown Widerstand zu bestücken.
    Unbeschaltete Eingänge am PI können jeden Zustand einnehmen.
    Betrachte mal den Status der Eingänge an einem unbeschalteten PI und du wirst sehen was ich meine.


  • Probier mal den Eingang hardwareseitig mit einem 10kOhm Pulldown Widerstand zu bestücken.
    Unbeschaltete Eingänge am PI können jeden Zustand einnehmen.
    Betrachte mal den Status der Eingänge an einem unbeschalteten PI und du wirst sehen was ich meine.

    Das habe ich auch schon ausprobiert. Allerdings ist es nach meiner Erfahrung nicht notwendig hardwareseitig einen Pulldown Widerstand zu setzen, wenn man softwareseitig einen setzt.

    Deswegen auch folgender Terminus im Code:

    Code
    pull_up_down=GPIO.PUD_DOWN

    Nichtsdestotrotz habe ich es mal auch mit einem 10kOhm Widerstand ausprobiert. Das Ergebnis ist das selbe.
    Hier im Video, was passiert. Beim Verhalten des "Funktionsaufrufes" habe ich übrigens keine Regelmäßigkeiten feststellen können.

    [youtube]92CvfKubcYA[/youtube]
    Die beiden Fenster im Video sind ein paar Millisek. Zeitversetzt. Bitte nicht wundern.

    • Offizieller Beitrag

    Da solltest du dir den bouncing wert mal für den eventhandler anschauen. Da kannst du definieren ab wieviel ms spannungsänderung der handler anspringen soll

    edit: hast du ja schon :denker: Ich hätte somit ein anderes verhalten erwartet.

    Der Unterschied zwischen Genie und Wahnsinn definiert sich im Erfolg.

    Einmal editiert, zuletzt von dbv (7. Oktober 2013 um 22:27)

  • Ich hab vergangenes Wochendende versucht mit derselben Methode wie du einen Datenlogger
    aufzubauen, der die positive Flanke am Eingang protokolliert.
    Dabei habe ich festgestellt, dass trotz bouncetime immer mehrere Ereignisse registriert wurden.
    Da ich keinen Widerstand zur Hand hatte, hab ich mir die Flankenauswertung selbst programmiert.
    Hab leider im Moment nicht richtig Zeit mal ein wenig zu testen. Würde mich nämlich auch mal
    interessieren wo da das problem liegt.


  • Da solltest du dir den bouncing wert mal für den eventhandler anschauen. Da kannst du definieren ab wieviel ms spannungsänderung der handler anspringen soll

    edit: hast du ja schon :denker: Ich hätte somit ein anderes verhalten erwartet.

    Richtig ;) Ich habe den bouncing-Wert auch schon mal verändert. Leider keine Änderung im Verhalten.

  • Moin,

    das kommt mir irgendwie bekannt vor. Bei meiner Steuerung für Garage und sonstiges Outdoorgedöns wird der Teil für die Garage über Interrupts gesteuert (öffnen, Endschalter oben + unten, Lichtschranke) trotz CAT5 Kabel und geschirmten Einbau haut es spätestens beim Einschalten von Leuchtstofflampen den Interrupt rein, egal welche Bouncetime.
    Ich habe dann der Einfachheit halber das ganze so gelöst, dass nach einem ausgelösten Interrupt der betreffende Pin mittels Routine abgefragt wird ob dieser nach z.b. 200 ms immer noch geschlossen ist. Also quasi die "Bouncetime extern abgefragt" bisher läuft das so fehlerfrei

    Programmierer und Bastler mit der Lizenz zum Löten...........


  • Moin,

    das kommt mir irgendwie bekannt vor. Bei meiner Steuerung für Garage und sonstiges Outdoorgedöns wird der Teil für die Garage über Interrupts gesteuert (öffnen, Endschalter oben + unten, Lichtschranke) trotz CAT5 Kabel und geschirmten Einbau haut es spätestens beim Einschalten von Leuchtstofflampen den Interrupt rein, egal welche Bouncetime.
    Ich habe dann der Einfachheit halber das ganze so gelöst, dass nach einem ausgelösten Interrupt der betreffende Pin mittels Routine abgefragt wird ob dieser nach z.b. 200 ms immer noch geschlossen ist. Also quasi die "Bouncetime extern abgefragt" bisher läuft das so fehlerfrei

    Aha... das heißt der Pi nimmt wohl irgendeinen elektromagnetischen Müll auf und verarbeitet den wohl als Input.

    Hast du für das externe Abfragen der Bouncetime eine Beispielskript in Python??? Das wäre super. ;)

  • # ISR
    def Interrupt_Funk(Channel):
    # Zugriff auf globale Variablen
    global geschlossen
    global offen
    global oeffnen
    global schliessen
    # global Tutwas

    # Counter um eins erhoehen und ausgeben
    print "funk gesendet"
    if geschlossen == 1:
    if(GPIO.input(Funk) == 0):
    time.sleep(0.1)
    if(GPIO.input(Funk) == 0):
    GPIO.output(Motor_auf,1)
    GPIO.output(Lichtschranke_Strom,0)
    geschlossen=0
    oeffnen = 1
    # Tutwas = 1
    print "auf gehts"
    if offen == 1:
    if(GPIO.input(Funk) == 0):
    time.sleep(0.1)
    if(GPIO.input(Funk) == 0):
    GPIO.output(Lichtschranke_Strom,1)
    GPIO.output(Motor_ab,1)
    offen = 0
    schliessen = 1
    # Tutwas = 1
    print "und runter"


    wenn Interrupt ausgelöst und der GPIO auf Masse liegt warte 100 ms und prüfe erneut. Wenn dann immer noch auf Masse führe aus....

    Programmierer und Bastler mit der Lizenz zum Löten...........


  • wenn Interrupt ausgelöst und der GPIO auf Masse liegt warte 100 ms und prüfe erneut. Wenn dann immer noch auf Masse führe aus....

    hab ich in meinem Fall auch erst mit time.sleep(...) versucht zu lösen.
    Der Nachteil der Geschichte ist halt das dein Programm dann immer schlafen geht.
    In deinem Fall sicher nicht tragisch, bei Abfrage einiger Eingänge dann aber irgendwann schon.
    Meine Lösung sieht zur Zeit so aus, dass ich bei steigender Flanke am Eingang einen Zeitstempel
    erstelle und wenn nach einer Zeit x der Pegel immer noch High ist wird dieser für gültig erklärt.
    Ist auch nur ein Fünfzeiler und die Software läuft ohne Verzögerungen weiter.

    if GPIO1 = TRUE
    if now - startzeit > 0.1
    Eingang = TRUE
    else
    startzeit = now
    Eingang = FALSE

    Einmal editiert, zuletzt von Ranta (8. Oktober 2013 um 15:36)

  • Leute, vielen Dank für die nützlichen Tipps! ;)

    Ich habe nun meine Abbruch-Funktion derart abgeändert:

    Code
    def my_callback(channel):
       if GPIO.input(18) or GPIO.input(16):
          time.sleep(0.1)
          if GPIO.input(18) or GPIO.input(16): 
             print "Abbruch 2"
             GPIO.output(15, False)
             GPIO.output(11, False)
             sys.exit(0)

    Fazit: Es funktioniert! :)

    Eine Frage habe ich noch: Wenn ich nun einen zweiten Taster aufnehme, kann ich dann in meinem Programm den Event-handler mit "GPIO.add_event_detect" einfach als zweites Kriterium mit aufnehmen? Also folgendermaßen:

    Code
    GPIO.add_event_detect(18, GPIO.RISING, callback=my_callback, bouncetime=200)
    GPIO.add_event_detect(16, GPIO.RISING, callback=my_callback, bouncetime=200)


    Oder muss das anders schreiben!?

    LG
    LTSmash

Jetzt mitmachen!

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