Loop funktioniert nur, wenn ich 'print' verwende.

11

Dieser Code schaltet die LED nicht ein und aus.

import  RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT)
for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
GPIO.cleanup()

aber wenn ich die Zahl in der Schleife ausdrucke, funktioniert es:

import  RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT)
for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    print(number)
GPIO.cleanup()

Irgendeine Idee warum das so ist?

Tazboy
quelle
1
siehe enwp.org/Heisenbug
Katze
2
@cat Bingo, "Heisenbugs treten auf, weil häufige Versuche, ein Programm zu debuggen, wie das Einfügen von Ausgabeanweisungen"
Tazboy
1
"Dieser Code schaltet die LED nicht ein und aus." - Ich bin anderer Ansicht.
Marcelm

Antworten:

22

Versuchen Sie, Ihre printdurch eine zu ersetzen time.sleep(0.05). Dieses seltsame Verhalten kann auftreten, wenn der GPIO-Ausgang zu schnell von HOCH auf NIEDRIG umgeschaltet wird, um eingestellt / erkannt / gesehen zu werden. Erhöhen / verringern Sie die Schlafdauer, bis das Programm einwandfrei funktioniert (erhöhen) und schnell genug (verringern).

import  RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(21,GPIO.OUT)
for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    time.sleep(0.05)
GPIO.cleanup()
Technico.top
quelle
Ja. Das macht Sinn.
Tazboy
51

Rollen Sie Ihre Schleife ab, um zu verstehen, was hier passiert:

for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)

verwandelt sich in:

    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    # [and so on]

Wie Sie sehen können, folgt das Einstellen des Stifts unmittelbar nach dem Hochdrehen (in der Nähe von). Tatsächlich bleibt Ihre LED die meiste Zeit in einem Zustand (dh was wir mit bloßem Auge wahrnehmen können).

Beheben Sie dies wie folgt (für einen Arbeitszyklus von 50:50):

for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    time.sleep(1)
Ghanima
quelle
Beeindruckend. Das scheint jetzt so offensichtlich. Danke, dass du es mir gezeigt hast.
Tazboy
4
Dies sollte die akzeptierte Antwort sein. Es erklärt tatsächlich, was passiert ist
2
Es kann auch erwähnenswert sein, dass der Grund dafür, print()dass der ursprüngliche Code funktioniert, darin besteht, dass das Schreiben auf den Bildschirm ein wahnsinnig langsamer Prozess ist und im Wesentlichen so funktioniert, wie sleep(1)Sie es vorgeschlagen haben.
Jacobm001
Obwohl diese Antwort es besser macht, sie aufzuschlüsseln, habe ich die andere Antwort gewählt, weil es die erste schriftliche Lösung für mein Problem war. Die Gesamtabstimmung bestimmt die bessere Antwort.
Tazboy
1
@tazboy Sie müssen sich nicht gezwungen fühlen, eine bestimmte Entscheidung bezüglich der "akzeptierten Antwort" zu
treffen