Interrupt aufruf langsamer als if Abfrage

  • Habe mit einem B+ das Problem, dass eine interrupt abfrage langsamer abgefragt wird als eine Routine im Hauptprogramm.

    100ms Pulse wird von GPIO4 erkannt.
    Abfragen ob er wirklich 100ms lang ist.
    Wenn 100ms lang dann wird ein Wert addiert.

    Anfang des Programms:
    #!/usr/bin/python
    import RPi.GPIO as GPIO
    import time
    import sys, os

    GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
    GPIO.setwarnings (False)
    GPIO.setup((4),GPIO.IN, pull_up_down=GPIO.PUD_UP) # Münzprüfer Pulse 0,5


    Folgende Routine Hauptprogramm funktioniert.
    -------
    while True:
    if GPIO.input(4) == True:
    Sta = time.time()
    while GPIO.input(4) == True:
    En = time.time()
           
    Diff = En-Sta
    if Diff > 0.9:
    A = A + B
    ------

    wenn ich das jetzt als Interrupt laufen lasse ist schon die Abfrage
    while GPIO.input(4) == False:
    nicht mehr aktuell. GPIO4 ist schon wieder True
    Hier die Interrupt Routine

    -------
    def summe(self):
    Sta = time.time()
    while GPIO.input(4) == True:
    En = time.time()
    else:
    Diff = En-Sta
    if Diff > 0.9:
    A = A + B

    GPIO.add_event_detect(4, GPIO.RISING, callback=summe, bouncetime = 30)

    while True:
    time.sleep(0.0001)
    -------


    Hat jemand eine Idee wie ich per interrupt einen 100 ms langen Puls abfragen kann ?
    Ich muß insgesamt 5 GPIO#s abfragen und um "verschlucker zu vermeiden ist eine Interrupt Abfrage notwendig
    Danke für konstruktive Hilfe.
    Detkor

  • Das Problem könnte deine Lösung "keep script running" sein -> die while am Ende, um zu verhindern dass das Script nach Abarbeitung der Zeilen eben beendet wird. Der von dir gewählte sleep ist viel zu niedrig und verursacht enorm hohe CPU Last. Setz den sleep ruhig höher, da der Interrupt sowieso in einem separaten Thread läuft.

    Bei eigenen Tests ist ein Interrupt sehr schnell. Du hast bei dir aber auch eine bouncetime von 30ms eingestellt -> in dieser Zeit wird ein erneuter Flankenwechsel ignoriert.. ist dir das bewusst?
    Die while in deiner Callback könnte aber auch stören, da das den 'Thread' solange pausiert.. Eben so lange bis wieder ein Flankenwechsel stattfindet (von RISING auf FALLING).
    Evtl. wäre es besser den Interrupt von GPIO.RISING auf GPIO.BOTH zu ändern und dann in der Callback den Flankenwechsel zu prüfen bzw aus der Callback auszulagern? Siehe dazu FAQ Bereich hier im Forum -> Linksammlung -> Interrupt

    GPIO.setup((4) ... sieht aber auch komisch aus. Wieso schreibst du das in Klammern? :s


    PS: Bitte das vollständige Script in CODE posten.

  • Hi,
    das wird so, wie Du das angehst, vermutlich niemals richtig funktionieren ... schon gr nicht mit mehreren Pins.
    Es ist ein absolutes no-go in einer Interrupt-Routine auf irgendwas zu warten.
    ISRs sind so kurz wie möglich zu halten. sleeps() sowie ähnliche Konstrukte sind dort schlicht fehl am Platz.
    -> Hier auf Wikipedia <- mal ein paar Grundinfos dazu ...

    Ich würde da für jeden GPIO Pin eine raise- und eine fall- Variable anlegen, und nur die in der ISR setzen. Im Hauptprogramm kannst Du dann die Differenz ermitteln.

    cu,
    -ds-

Jetzt mitmachen!

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