通过 GPIO 和 Python 对 Raspberry Pi 的 LED 控制
LED control on Raspberry Pi by GPIO with Python
我正在使用连接到 Raspberry Pi 上的 GPIO 引脚的瞬时开关来控制 4 个 LED。
我连接了五个按钮。
按下前 4 个按钮可根据当前状态将连接的 LED 的状态从打开切换为关闭或关闭切换为打开。
第五个按钮根据 GPIO 18 的 on/off 状态打开所有 4 个 LED 或关闭所有 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 并且之前没有任何编程经验。我确定这很简单,但我似乎无法解决它。
听起来你有 3 个逻辑块:
- 独立的 LED 控制
- 主 LED 控制
- Monitor-LED指示灯控制
将代码解耦为函数,让我们将它们命名为 checkIndividualButton
、checkMasterButton
和 updateMonitorLed
,每个逻辑块一个,并从主循环中调用它们
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)
现在您所要做的就是实现单独的功能,每个功能只做一个 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)
将此函数块粘贴到主程序中的正确位置。
免责声明:我没有对此进行测试。有一些方法可以进一步优化和清理代码,如果您愿意,我们很乐意在评论中为您提供指导。
感谢@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 的网络 UI。
这 3 件事加在一起让我得到了我想要的东西,并且一个 Web 界面可以根据每个 LED 的当前高或低状态实时更新按钮。
这是一个概念验证,LED 很快将被继电器取代,继电器将打开或关闭我家不同房间中连接的扬声器组,Raspberry Pi 多房间音频控制器。 raspberry pi 也将成为连接区域的音频源,带有 airplay 和蓝牙流。
我正在使用连接到 Raspberry Pi 上的 GPIO 引脚的瞬时开关来控制 4 个 LED。 我连接了五个按钮。 按下前 4 个按钮可根据当前状态将连接的 LED 的状态从打开切换为关闭或关闭切换为打开。 第五个按钮根据 GPIO 18 的 on/off 状态打开所有 4 个 LED 或关闭所有 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 并且之前没有任何编程经验。我确定这很简单,但我似乎无法解决它。
听起来你有 3 个逻辑块:
- 独立的 LED 控制
- 主 LED 控制
- Monitor-LED指示灯控制
将代码解耦为函数,让我们将它们命名为 checkIndividualButton
、checkMasterButton
和 updateMonitorLed
,每个逻辑块一个,并从主循环中调用它们
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)
现在您所要做的就是实现单独的功能,每个功能只做一个 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)
将此函数块粘贴到主程序中的正确位置。
免责声明:我没有对此进行测试。有一些方法可以进一步优化和清理代码,如果您愿意,我们很乐意在评论中为您提供指导。
感谢@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 的网络 UI。
这 3 件事加在一起让我得到了我想要的东西,并且一个 Web 界面可以根据每个 LED 的当前高或低状态实时更新按钮。
这是一个概念验证,LED 很快将被继电器取代,继电器将打开或关闭我家不同房间中连接的扬声器组,Raspberry Pi 多房间音频控制器。 raspberry pi 也将成为连接区域的音频源,带有 airplay 和蓝牙流。