GPIO与Python对Raspberry Pi的LED控制

时间:2015-02-06 08:19:29

标签: python raspberry-pi gpio led

我正在使用连接到Raspberry Pi上的GPIO引脚的瞬时开关来控制4个LED。 我有五个按钮接线。 按下前4个按钮,根据当前状态将连接的LED的状态从打开切换为关闭或关闭为打开。 第五个按钮打开所有4个LED或根据GPIO 18的开/关状态关闭所有4个LED。 我还有一个额外的LED连接到GPIO引脚18,这根据引脚18的状态简单地打开或关闭。 该项目的想法是能够独立控制LED并具有主控制按钮。连接到引脚18的LED是一个监控LED,如果4个LED中的任何一个亮起,它应该打开,如果所有4个LED同时关闭,它应该关闭。 这都是基于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)

此代码似乎运行正常。正如您所看到的那样,它会切换引脚18的当前状态,然后将该状态应用于引脚4,17,22和27,它们是LED所连接的引脚。

我为控制各个LED而编写的代码有点复杂,看起来像这样:

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有一个版本。此版本使用引脚5作为输入来检测按钮按下,引脚4作为输出来激活LED。我想要的是这样做:

按下时(如果LED1熄灭)

- Toggle LED1 on, also toggle pin 18 on to activate the indicator light.
- Take no further action.

按下时(如果LED1亮起)

- Check if pin 17 is on or off; 
    - If pin 17 is on toggle LED1 off and take no further action. 
    - If pin 17 is off check if pin 22 is on or off; 
        - If pin 22 is on toggle LED1 off and take no further action. 
        - If pin 22 is off check if pin 27 is on or off; 
            - If pin 27 is on toggle LED1 off and take no further action. 
            - If pin 27 is off toggle LED1 off then set pin 18 to the current status of pin 4 (LED1).

然而,实际发生的是:

按下时(如果LED1熄灭)

- Turns off all of the other 3 LEDs then toggles LED1 on and toggles pin 18 on.

按下时(如果LED1熄灭)

- Turns off all LEDs and toggles pin 18 off.

我不能为我的生活弄清楚这一点。 非常感谢您的帮助。

P.S。请原谅我的无知,我昨天开始学习python并且根本没有任何编程经验。我确信它很简单,但我似乎无法解决它。

2 个答案:

答案 0 :(得分:2)

听起来你有3个逻辑块:

  1. 个别LED控制
  2. 主LED控制
  3. 监视器 - LED指示灯控制
  4. 将代码解耦为函数,让它们为checkIndividualButtoncheckMasterButtonupdateMonitorLed命名,每个逻辑块一个,并从主循环中调用它们

    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)
    

    现在你所要做的就是实现各自的功能,每个功能都做Just One Job(TM):

    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)
    

    将此功能块粘贴到主程序中的正确位置。

    免责声明:我没有测试过这个。有进一步优化和清理代码的方法,如果您愿意,很乐意引导您发表评论。

答案 1 :(得分:0)

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

最后我运行了2个python脚本,只需按一下按钮即可更改引脚状态:

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的启动时启动,它为我提供了一个可以控制LED的Web UI。

这三件事让我完全了解了我所追求的内容以及一个实时更新每个LED按钮的网络界面,基于它当前的HIGH或LOW状态。

这是一个概念验证,LED将很快被继电器取代,它将打开或关闭我家中不同房间的连接扬声器,Raspberry Pi多房间音频控制器。树莓派也将成为连接区域的音频源,具有airplay和蓝牙流媒体。