Search code examples
pythonraspberry-pigpioled

Python Script - Nesting an if / else under an if inside a while True: on - Raspberry Pi


Python is my first interaction with a programming language, I started learning yesterday. I'm trying to control LEDs from physical momentary switches through a Raspberry Pi and it's GPIO pins. I have wired the switches and have a piece of code that turns each of 4 LEDs on or off. I have a 5th switch to turn on or off all 4 LEDs at once depending on the state of an unwired pin.

The code for each LED looks like this:

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.setup(4,GPIO.OUT)
GPIO.output(4,0)

GPIO.setup(18,GPIO.OUT)

GPIO.output(18,0)

while True:
    input_state = GPIO.input(10)
    if input_state == False:
         GPIO.output(4, not GPIO.input(4))
         time.sleep(0.1)
         GPIO.output(18, GPIO.input(4))
         time.sleep(0.4)

Where pin 10 is an input wired to my switch, 4 is the pin that gets turned on and powers the LED and pin 18 is a pin I use to turn on/off all LEDs at the same time with another switch. I have 4 versions of this script, 1 for each LED and just the pins used are changed.

The code to turn on/off all pins at the same time looks like this:

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)

chan_list = (4,17,22,27)

GPIO.setup(chan_list,GPIO.OUT)

GPIO.output(chan_list,0)

GPIO.setup(18,GPIO.OUT)

GPIO.output(18,0)

while True:
    input_state = GPIO.input(26)
    if input_state == False:
         chan_list = (4,17,22,27)
         GPIO.output(18, not GPIO.input(18))
         time.sleep(0.1)
         GPIO.output(chan_list, GPIO.input(18))
         time.sleep(0.4)

These codes work really well. I have them all setup to launch on startup as background processes.

I want to use pin 18 to turn on an indicator LED that turns on if any of the four LEDs are turned on and that stays on if any LEDs are turned off unless all 4 of the LEDs are turned off. This works fine using the all on/off button. The problem comes up when I use the individual LED buttons to turn off individual LEDs. In the current setup as soon as I turn off any individual LED pin 18 is turned off.

I'm trying to find a code solution to get around this issue so that pin 18 (the indicator LED) is on when any of the 4 LEDs are on and is only off if all 4 LEDs are off.

I was thinking some kind of nested series of if / else: conditions but my limited knowledge is stopping my success.

An example piece of code that I have tried is this:

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.setup(4,GPIO.OUT)
GPIO.output(4,0)

GPIO.setup(18,GPIO.OUT)
GPIO.output(18,0)


while True:
    input_state = GPIO.input(10)
    if input_state == False:
             if GPIO.output(17) == True:
                  GPIO.output(4, not GPIO.input(4))
             else:
                  if GPIO.output(22) == True:
                      GPIO.output(4, not GPIO.input(4))
                  else:
                       if GPIO.output(27) == True:
                           GPIO.output(4, not GPIO.input(4))
                       else:
                           GPIO.output(4, not GPIO.input(4))
                           time.sleep(0.1)
                           GPIO.output(18, GPIO.input(4))
                           time.sleep(0.4)

This gives an error:

Traceback (most recent call last):
  File "pin10test.py", line 20, in <module>
    if GPIO.output(17) == True:
TypeError: function takes exactly 2 arguments (1 given)

My intention is that when a button press is detected the it will go:

If pin 17 is on, toggle pin 4. If not go to next check.
If pin 22 is on, toggle pin 4. If not go to next check.
If pin 27 is on, toggle pin 4. If not go to final else:
toggle pin 4, sleep 0.1, set pin 18 to whatever pin 4 was just set to, sleep 0.4.

Then I'd adjust this piece of script into the script for each button.

This way pin 18 only changes state to off if all pins are off.

Any help in getting this script right is appreciated. Any ideas or tips on how to improve this is also appreciated.


Solution

  • input_state = GPIO.input(10)
    

    and

        if input_state == False:
    

    should be at the same level of indentation, which is exactly what the error message is saying. There is no reason to indent the second line (since the previous one doesn't open a new block, so indenting it is an error).