树莓派3B+多GPIO输入输出扩展:Python脚本优化问询
多GPIO按键监控与继电器控制扩展方案
需求说明
希望在Raspberry Pi 3B+上运行Python脚本,监控多个GPIO引脚的外部按键按下事件。当按键按下(短路至0伏)时,触发对应GPIO引脚控制Sainsmart继电器板瞬时动作,并发送告警邮件。目前已实现单输入单输出的功能,需要扩展多组GPIO输入输出,避免运行多个独立脚本。
优化后的多通道实现代码
import RPi.GPIO as GPIO import time import smtplib from email.mime.text import MIMEText # 配置参数:输入GPIO -> 对应输出GPIO、告警描述 GPIO_CONFIG = { 17: {"output_pin": 2, "alert_msg": "按键1(GPIO17)被按下,继电器(GPIO2)触发"}, 27: {"output_pin": 3, "alert_msg": "按键2(GPIO27)被按下,继电器(GPIO3)触发"}, 22: {"output_pin": 4, "alert_msg": "按键3(GPIO22)被按下,继电器(GPIO4)触发"} } # 邮件配置 EMAIL_SETTINGS = { "smtp_server": "server.com", "smtp_port": 587, "sender": "user@server.com", "password": "passwordhere", "recipients": ["recip1@domain1.com", "recip2@domain2.com"] } def send_alert_email(subject, content): """封装告警邮件发送函数""" msg = MIMEText(content, "plain", "utf-8") msg["Subject"] = "GPIO告警通知" msg["From"] = EMAIL_SETTINGS["sender"] msg["To"] = ", ".join(EMAIL_SETTINGS["recipients"]) try: smtp = smtplib.SMTP(EMAIL_SETTINGS["smtp_server"], EMAIL_SETTINGS["smtp_port"]) smtp.ehlo() smtp.starttls() smtp.login(EMAIL_SETTINGS["sender"], EMAIL_SETTINGS["password"]) smtp.sendmail(EMAIL_SETTINGS["sender"], EMAIL_SETTINGS["recipients"], msg.as_string()) smtp.quit() print("告警邮件发送成功") except Exception as e: print(f"邮件发送失败: {str(e)}") def init_gpio(): """初始化所有GPIO引脚""" GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # 配置输入引脚(上拉电阻) for input_pin in GPIO_CONFIG.keys(): GPIO.setup(input_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # 配置输出引脚,初始高电平(继电器默认断开) for config in GPIO_CONFIG.values(): output_pin = config["output_pin"] GPIO.setup(output_pin, GPIO.OUT) GPIO.output(output_pin, GPIO.HIGH) def main(): init_gpio() # 记录按键上次触发时间,用于防抖 last_trigger_time = {pin: 0 for pin in GPIO_CONFIG.keys()} DEBOUNCE_DELAY = 2 # 防抖延迟,单位秒 try: while True: current_time = time.time() for input_pin, config in GPIO_CONFIG.items(): input_state = GPIO.input(input_pin) # 按键按下(低电平),且超过防抖延迟 if input_state == False and (current_time - last_trigger_time[input_pin]) > DEBOUNCE_DELAY: output_pin = config["output_pin"] alert_msg = config["alert_msg"] print(alert_msg) # 触发继电器瞬时动作 GPIO.output(output_pin, GPIO.LOW) print(f"继电器GPIO{output_pin}触发") time.sleep(1.0) GPIO.output(output_pin, GPIO.HIGH) time.sleep(0.5) # 发送告警邮件 send_alert_email("GPIO按键触发", alert_msg) # 更新最后触发时间 last_trigger_time[input_pin] = current_time time.sleep(0.1) # 降低循环频率,减少CPU占用 except KeyboardInterrupt: print("程序终止,清理GPIO资源") GPIO.cleanup() if __name__ == "__main__": main()
关键修改说明
- 配置化管理GPIO映射:用
GPIO_CONFIG字典统一管理输入引脚、对应输出引脚和告警信息,新增通道只需在字典中添加条目,无需修改核心逻辑。 - 封装邮件发送函数:将邮件发送逻辑封装为
send_alert_email,避免重复代码,同时优化邮件格式(使用MIMEText支持中文和主题)。 - 按键防抖处理:通过记录每次触发的时间,设置
DEBOUNCE_DELAY避免按键抖动导致的重复触发。 - 结构化代码:将GPIO初始化、主循环、邮件发送拆分为独立函数,代码更易读和维护。
- 异常处理:捕获
KeyboardInterrupt(Ctrl+C),确保程序终止时正确清理GPIO资源。
内容的提问来源于stack exchange,提问作者Brian Schultz
相关产品推荐
相关产品推荐

