1

I am trying to create a program which which switch an LED ON or OFF when a switch is pressed. The following is the circuit diagram

enter image description here

The python code is

import RPi.GPIO as GPIO

is_lamp_on = False
try:
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(11,GPIO.OUT)
        GPIO.setup(12,GPIO.IN,pull_up_down=GPIO.PUD_UP)
        GPIO.output(11,GPIO.LOW) #lamp is initially off
        print ('initial lamp is ', is_lamp_on)
        print ('initial input 12 is ', GPIO.input(12))
        while True:
                if GPIO.input(12)==GPIO.LOW: #button pressed down but not released yet
                        print(' button pressed but not released')
                        print ('input 12 is ', GPIO.input(12))
                        while True: #wait for button to be released
                                if GPIO.input(12)==GPIO.HIGH: #button released
                                        print(' button released, old lamp state is ',is_lamp_on)
                                        if(is_lamp_on == True): # lamp was ON when button is released
                                                GPIO.output(11,GPIO.LOW) #lamp off
                                                is_lamp_on = False;
                                                print('new lamp state before break ', is_lamp_on)
                                                break
                                        else: #lamp is not ON
                                                GPIO.output(11,GPIO.HIGH)
                                                is_lamp_on = True;
                                                print('new lamp state before break ', is_lamp_on)
                                                break
except KeyboardInterrupt:
        GPIO.cleanup()

If I do quick on/off then the LED gets on and off correctly. However, if I keep the switch pressed for longer then the LED doesn't work properly (for eg, if LED was ON then after a 2-3 second long press, the LED stays on

I found that the loop seem to execute multiple times if the switch is pressed on for longer

Pi@raspberrypi:~/kabir $ python manu_lamp_program.py 
('initial lamp is ', False)
('initial input 12 is ', 1)



---0 SHORT PRESS
 button pressed but not released
('input 12 is ', 0)
(' button released, old lamp state is ', False)
('new lamp state before break ', True)
---1 SHORT PRESS



 button pressed but not released
('input 12 is ', 0)
(' button released, old lamp state is ', True)
('new lamp state before break ', False)
-----2 LONG PRESS, the code seem to have run multiple times


 button pressed but not released
('input 12 is ', 0)
(' button released, old lamp state is ', False)
('new lamp state before break ', True)
 button pressed but not released
('input 12 is ', 0)
(' button released, old lamp state is ', True)
('new lamp state before break ', False)
What am I doing wrong?
5
  • 1
    The loops are busy spinning consuming 100% CPU. That could lead to oddities as various processes are starved. Try adding a time.sleep(0.01) in the False path of each if GPIO.input(12)
    – joan
    Aug 9, 2021 at 7:45
  • 1
    This is terrible code. Joan has already pointed out one of its deficiencies but there are others, but it is not worthwhile trying to debug. Most of us would do this in half a dozen lines. There must be thousands of examples; is there any reason you are trying to reinvent the wheel? I suggest you look at gpiozero.
    – Milliways
    Aug 9, 2021 at 8:25
  • @Milliways - yes, terrible code but that is what learning curve is all about. I'll check RPi.GPIO for the high level api but my intention is to not just call the APIs but try to understand things things work under the hood Aug 9, 2021 at 18:28
  • @joan - thanks. adding sleep worked. Happy to accept your suggestion as answer. Aug 9, 2021 at 18:29
  • @ManuChadha Good. I suggest you give your own answer explaining what you did. You can then accept your answer in a day or so.
    – joan
    Aug 9, 2021 at 19:28

1 Answer 1

0

Inspired from Joan's comment above

import RPi.GPIO as GPIO
import time

is_lamp_on = False #initial lamp state is lamp is not ON
try:
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(11,GPIO.OUT)
        GPIO.setup(12,GPIO.IN,pull_up_down=GPIO.PUD_UP)
        GPIO.output(11,GPIO.LOW) #lamp is initially off
        #print ('initial lamp is ', is_lamp_on)
        #print ('initial input 12 is ', GPIO.input(12))

        while True:
                current_pressed_state = GPIO.input(12)
                if GPIO.input(12)==GPIO.LOW: #button pressed down but not released yet
                        #print(' button pressed, will wait for release ')
                        time.sleep(0.01) #wait to see what is the state of input(12) after few milli secs
                        new_pressed_state = GPIO.input(12)
                        #print('new pressed state ',new_pressed_state)
                        if (current_pressed_state != new_pressed_state): #button released. state changed from low to high
                                #print(' button released, old lamp state is ',is_lamp_on)
                                if(is_lamp_on == True): # lamp was ON when button is released
                                        GPIO.output(11,GPIO.LOW) #lamp off
                                        is_lamp_on = False;
                                        #print('new lamp state before break ', is_lamp_on)
                                else: #lamp is not ON
                                        GPIO.output(11,GPIO.HIGH)
                                        is_lamp_on = True;
                                        #print('new lamp state before break ', is_lamp_on)
                else:
                        time.sleep(0.01) #wait before trying again
except KeyboardInterrupt:
        GPIO.cleanup()

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.