基于Python的GPIO对覆盆子Pi的LED控制

基于Python的GPIO对覆盆子Pi的LED控制,python,raspberry-pi,gpio,led,Python,Raspberry Pi,Gpio,Led,我使用连接到Raspberry Pi上GPIO引脚的瞬时开关来控制4个LED。 我有五个按钮。 按下前4个按钮可根据当前状态将连接LED的状态从on切换到off或off切换到on。 第五个按钮根据GPIO 18的开/关状态打开或关闭所有4个LED。 我还有一个额外的LED连接到GPIO引脚18,这只是根据引脚18的状态打开或关闭。 这个项目的想法是能够独立控制LED,并有一个主控制按钮。连接到引脚18的LED是一个监控LED,如果4个LED中的任何一个点亮,则该LED应点亮;只有当所有4个LED

我使用连接到Raspberry Pi上GPIO引脚的瞬时开关来控制4个LED。 我有五个按钮。 按下前4个按钮可根据当前状态将连接LED的状态从on切换到off或off切换到on。 第五个按钮根据GPIO 18的开/关状态打开或关闭所有4个LED。 我还有一个额外的LED连接到GPIO引脚18,这只是根据引脚18的状态打开或关闭。 这个项目的想法是能够独立控制LED,并有一个主控制按钮。连接到引脚18的LED是一个监控LED,如果4个LED中的任何一个点亮,则该LED应点亮;只有当所有4个LED同时熄灭时,该LED才应熄灭。 这都是基于python脚本的,python脚本监视按钮按下并相应地执行操作

我为一次控制所有LED而编写的代码如下所示:

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)
import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

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

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

GPIO.setup(17,GPIO.OUT)

GPIO.setup(22,GPIO.OUT)

GPIO.setup(27,GPIO.OUT)

GPIO.setup(18,GPIO.OUT)

while True:
    input_state = GPIO.input(5)
    if input_state == False:
        if GPIO.output(17,0) == False:
            GPIO.output(4, not GPIO.input(4))
        elif GPIO.output(22,0) == False:
            GPIO.output(4, not GPIO.input(4))
        elif GPIO.output(27,0) == False:
            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)
该代码似乎运行正常。如您所见,它切换引脚18的当前状态,然后将该状态应用于引脚4、17、22和27,这是LED连接到的引脚

我编写的控制单个LED的代码有点复杂,它看起来如下所示:

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)
import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

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

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

GPIO.setup(17,GPIO.OUT)

GPIO.setup(22,GPIO.OUT)

GPIO.setup(27,GPIO.OUT)

GPIO.setup(18,GPIO.OUT)

while True:
    input_state = GPIO.input(5)
    if input_state == False:
        if GPIO.output(17,0) == False:
            GPIO.output(4, not GPIO.input(4))
        elif GPIO.output(22,0) == False:
            GPIO.output(4, not GPIO.input(4))
        elif GPIO.output(27,0) == False:
            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)
有4个版本的LED,每个LED有一个版本,该版本使用引脚5作为输入来检测按钮按下,引脚4作为输出来激活LED。我想做的是:

按下时(如果LED1关闭)

按下时(如果LED1打开)

然而,实际发生的是:

按下时(如果LED1关闭)

按下时(如果LED1关闭)

我一辈子都搞不清楚这件事。 非常感谢你的帮助


请原谅我的无知,我昨天开始学习python,之前根本没有编程经验。我确信这是一个简单的问题,但我似乎无法解决它。

听起来您有3个逻辑块:

  • 独立LED控制
  • 主LED控制
  • 监视器LED指示灯控制
  • 将代码解耦为函数,让我们将它们命名为
    checkIndividualButton
    checkMasterButton
    updateMonitored
    ,每个逻辑块对应一个函数,然后从主循环调用它们

    import RPi.GPIO as GPIO
    import time
    
    # our 3 functions will go here, yet to be written
    
    # setup pins here
    all_leds = [???,???,???,???]
    
    GPIO.setup blah blah blah
    
    while True:
        checkIndividualButton(button_pin=17, led_pin=4)  # assuming button wired to pin 17 controls LED on pin 4
        checkIndividualButton(????, ????) # fill this in
        checkIndividualButton(????, ????) # fill this in
        checkIndividualButton(????, ????) # fill this in
    
        checkMasterButton(master_button_pin=26, monitor_led_pin=18, all_leds) # notice reference to all_leds which we setup above
    
        updateMonitorLed(all_leds, monitor_led_pin=18)
    
    现在,您只需实现单个功能,每个功能只执行一项作业(TM):

    将此函数块粘贴到主程序的正确位置


    免责声明:我没有测试过这个。有一些方法可以进一步优化和清理代码,如果您愿意,很高兴在评论中为您提供指导。

    感谢@pbkhrv提供了非常有用的答案。 我从中学到了很多,并设法得到了一段完全符合我需要的代码

    最后,我运行了两个python脚本,其中一个在按下按钮时更改pin状态:

    import RPi.GPIO as GPIO
    import webiopi
    import time
    
    GPIO.setwarnings(False)
    
    GPIO.setmode(GPIO.BCM)
    
    chan_list = (4,17,22,27)
    
    GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(4,GPIO.OUT)
    GPIO.output(4,0)
    
    GPIO.setup(17,GPIO.OUT)
    GPIO.output(17,0)
    
    GPIO.setup(22,GPIO.OUT)
    GPIO.output(22,0)
    
    GPIO.setup(27,GPIO.OUT)
    GPIO.output(27,0)
    
    GPIO.setup(18,GPIO.OUT)
    GPIO.output(18,0)
    
    while True:
    #This portion is pin 4 control from physical switches
        if GPIO.input(5) == False:
            GPIO.output(4, not GPIO.input(4))
            time.sleep(0.3)
    
    #This portion is pin 17 control from physical switches
        if GPIO.input(6) == False:
            GPIO.output(17, not GPIO.input(17))
            time.sleep(0.3)
    
    #This portion is pin 22 control from physical switches
        if GPIO.input(19) == False:
            GPIO.output(22, not GPIO.input(22))
            time.sleep(0.3)
    
    #This portion is pin 27 control from physical switches
        if GPIO.input(13) == False:
            GPIO.output(27, not GPIO.input(27))
            time.sleep(0.3)
    
    #This portion is pins 4,17,22,27 as one control from physical switches. Toggles all on/off
    # based on the current state of pin 18.
        if GPIO.input(26) == False:
            chan_list = (4,17,22,27)
            GPIO.output(18, not GPIO.input(18))
           # time.sleep(0.01)
            GPIO.output(chan_list, GPIO.input(18))
            time.sleep(0.3)
    
    这是指示灯LED后的指示灯:

    import webiopi
    import time
    
    GPIO = webiopi.GPIO
    
    GPIO.setup(4,GPIO.OUT)
    GPIO.output(4,0)
    
    GPIO.setup(17,GPIO.OUT)
    GPIO.output(17,0)
    
    GPIO.setup(22,GPIO.OUT)
    GPIO.output(22,0)
    
    GPIO.setup(27,GPIO.OUT)
    GPIO.output(27,0)
    
    GPIO.setup(18,GPIO.OUT)
    GPIO.output(18,0)
    
    # loop function is repeatedly called by WebIOPi 
    while True:
    #Block to control pin 18 state by pin 4 state
        if (GPIO.digitalRead(4) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(4) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(17) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(22) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(27) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else: 
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    #Block to control pin 18 state by pin 17 state
        if (GPIO.digitalRead(17) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(17) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(4) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(22) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(27) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else:
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    #Block to control pin 18 state by pin 22 state
        if (GPIO.digitalRead(22) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(22) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(4) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(17) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(27) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else:
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    #Block to control pin 18 state by pin 27 state
        if (GPIO.digitalRead(27) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(27) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(4) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(17) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(22) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else:
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    这两个python脚本在raspberry pi和webiopi启动时启动,webiopi为我提供了一个可以控制LED的web UI

    这三件事结合在一起,给了我确切的目标和一个web界面,该界面根据每个LED的当前高或低状态实时更新按钮


    这是一个概念证明,LED将很快被继电器取代,继电器将打开或关闭我家不同房间的扬声器,Raspberry Pi多房间音频控制器。raspberry pi还将是连接区域的音频源,支持airplay和蓝牙流媒体播放。

    FYI,python为else if提供了一个名为
    elif
    的关键字。感谢@Hacketo,我已经用它来清理脚本了。
    def checkIndividualButton(button_pin, led_pin):
        is_pressed = GPIO.input(button_pin)
        if is_pressed:
            GPIO.output(led_pin, not GPIO.input(led_pin))
    
    def checkMasterButton(master_button_pin, monitor_led_pin, all_led_pins):
        is_pressed = GPIO.input(master_button_pin)
        if is_pressed:
            GPIO.output(monitor_led_pin, not GPIO.input(monitor_led_pin))
            time.sleep(0.1)
            GPIO.output(all_led_pins, GPIO.input(monitor_led_pin))
            time.sleep(0.4)
    
    def updateMonitorLed(all_leds_pins, monitor_led_pin):
        is_any_led_on = False
        for led_pin in all_leds_pins:
            if GPIO.input(led_pin):
                is_any_led_on = True
        GPIO.output(monitor_led_pin, is_any_led_on)
        time.sleep(0.1)
    
    import RPi.GPIO as GPIO
    import webiopi
    import time
    
    GPIO.setwarnings(False)
    
    GPIO.setmode(GPIO.BCM)
    
    chan_list = (4,17,22,27)
    
    GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    GPIO.setup(4,GPIO.OUT)
    GPIO.output(4,0)
    
    GPIO.setup(17,GPIO.OUT)
    GPIO.output(17,0)
    
    GPIO.setup(22,GPIO.OUT)
    GPIO.output(22,0)
    
    GPIO.setup(27,GPIO.OUT)
    GPIO.output(27,0)
    
    GPIO.setup(18,GPIO.OUT)
    GPIO.output(18,0)
    
    while True:
    #This portion is pin 4 control from physical switches
        if GPIO.input(5) == False:
            GPIO.output(4, not GPIO.input(4))
            time.sleep(0.3)
    
    #This portion is pin 17 control from physical switches
        if GPIO.input(6) == False:
            GPIO.output(17, not GPIO.input(17))
            time.sleep(0.3)
    
    #This portion is pin 22 control from physical switches
        if GPIO.input(19) == False:
            GPIO.output(22, not GPIO.input(22))
            time.sleep(0.3)
    
    #This portion is pin 27 control from physical switches
        if GPIO.input(13) == False:
            GPIO.output(27, not GPIO.input(27))
            time.sleep(0.3)
    
    #This portion is pins 4,17,22,27 as one control from physical switches. Toggles all on/off
    # based on the current state of pin 18.
        if GPIO.input(26) == False:
            chan_list = (4,17,22,27)
            GPIO.output(18, not GPIO.input(18))
           # time.sleep(0.01)
            GPIO.output(chan_list, GPIO.input(18))
            time.sleep(0.3)
    
    import webiopi
    import time
    
    GPIO = webiopi.GPIO
    
    GPIO.setup(4,GPIO.OUT)
    GPIO.output(4,0)
    
    GPIO.setup(17,GPIO.OUT)
    GPIO.output(17,0)
    
    GPIO.setup(22,GPIO.OUT)
    GPIO.output(22,0)
    
    GPIO.setup(27,GPIO.OUT)
    GPIO.output(27,0)
    
    GPIO.setup(18,GPIO.OUT)
    GPIO.output(18,0)
    
    # loop function is repeatedly called by WebIOPi 
    while True:
    #Block to control pin 18 state by pin 4 state
        if (GPIO.digitalRead(4) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(4) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(17) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(22) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(27) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else: 
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    #Block to control pin 18 state by pin 17 state
        if (GPIO.digitalRead(17) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(17) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(4) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(22) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(27) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else:
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    #Block to control pin 18 state by pin 22 state
        if (GPIO.digitalRead(22) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(22) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(4) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(17) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(27) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else:
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)
    
    #Block to control pin 18 state by pin 27 state
        if (GPIO.digitalRead(27) == GPIO.HIGH):
            #webiopi.sleep(0.1)
            GPIO.digitalWrite(18, GPIO.HIGH)
    
        if (GPIO.digitalRead(27) == GPIO.LOW):
            webiopi.sleep(0.01)
            if (GPIO.digitalRead(4) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(17) == GPIO.HIGH):
                webiopi.sleep(0.01)
            elif (GPIO.digitalRead(22) == GPIO.HIGH):
                webiopi.sleep(0.01)
            else:
                GPIO.digitalWrite(18, GPIO.LOW)
                webiopi.sleep(0.01)