11

This code does not turn the led on and off.

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

but when I print out the number in the loop it does work:

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

Any idea why that is?

3
  • 2
    see enwp.org/Heisenbug
    – cat
    Commented Jun 5, 2017 at 19:53
  • 2
    @cat Bingo, "Heisenbugs occur because common attempts to debug a program, such as inserting output statements"
    – tazboy
    Commented Jun 5, 2017 at 23:54
  • 2
    "This code does not turn the led on and off." - I beg to differ.
    – marcelm
    Commented Jun 7, 2017 at 16:32

2 Answers 2

22

Try to replace your print by a time.sleep(0.05). You may occur this strange behavior as GPIO.output is switched too quickly from HIGH to LOW to be set/detected/seen. Increase/reduce the sleep duration until the program works fine (increase) and fast enough (decrease).

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

Unroll your loop to understand what's happening here:

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

turns into:

    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]

As you can see, setting the pin low follows (near to) immediately after turning it high. In effect your LED will stay at one state for most of the time (that is, what we can perceive with the naked eye).

Fix it like this (for a 50:50 duty cycle):

for number in range(0,10):
    GPIO.output(21,GPIO.LOW)
    time.sleep(1)
    GPIO.output(21,GPIO.HIGH)
    time.sleep(1)
1
  • 2
    It may also be worth noting that the reason print() causes the original code to work is because writing to the screen is an insanely slow process and is essentially acting as the sleep(1) you suggested.
    – Jacobm001
    Commented Jun 8, 2017 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.