Pętla nie działa, chyba że użyję „print”


11

Ten kod nie włącza ani nie wyłącza diody LED.

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()

ale kiedy wydrukuję liczbę w pętli, działa:

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()

Masz pomysł, dlaczego tak jest?



2
@cat Bingo, „Heisenbugs występują, ponieważ typowe próby debugowania programu, takie jak wstawianie instrukcji wyjściowych”
tazboy

1
„Ten kod nie włącza i nie wyłącza diody LED”. - Pozwolę sobie być innego zdania.
marcelm

Odpowiedzi:


22

Spróbuj zastąpić swój printprzez time.sleep(0.05). Może wystąpić takie dziwne zachowanie, ponieważ GPIO.output jest zbyt szybko przełączane z WYSOKIEGO na NISKI, aby go ustawić / wykryć / zobaczyć. Zwiększ / zmniejsz czas trwania snu, aż program będzie działał poprawnie (zwiększ) i wystarczająco szybko (zmniejsz).

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()

Tak. To ma sens.
tazboy

51

Rozwiń pętlę, aby zrozumieć, co się tutaj dzieje:

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

zamienia się w:

    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]

Jak widać, ustawienie niskiego pinu następuje (blisko) natychmiast po jego podniesieniu. W efekcie Twoja dioda LED pozostanie w jednym stanie przez większość czasu (czyli to, co możemy zobaczyć gołym okiem).

Napraw to w następujący sposób (dla cyklu pracy 50:50):

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

Łał. To wydaje się teraz takie oczywiste. Dzięki za pokazanie mi.
tazboy

4
To powinna być zaakceptowana odpowiedź. To właściwie wyjaśnia, co się stało

2
Warto również zauważyć, że powodem, dla print()którego oryginalny kod działa, jest to, że pisanie na ekranie jest niezwykle powolnym procesem i zasadniczo działa tak, jak sleep(1)sugerowałeś.
Jacobm001

Chociaż ta odpowiedź lepiej się rozbija, wybrałem inną odpowiedź, ponieważ było to pierwsze pisemne rozwiązanie mojego problemu. Ogólne głosowanie określi lepszą odpowiedź.
tazboy

1
@tazboy nie musisz czuć się zmuszany do jakiegokolwiek konkretnego wyboru dotyczącego „zaakceptowanej odpowiedzi”
Ghanima
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.