基于Raspberry Pi 3的红外感应LED控制及数据管理功能实现求助
需求梳理
- 未检测到人员时,红色LED点亮,绿色LED熄灭
- 检测到人员持续3秒后,红色LED熄灭,绿色LED点亮
- 所有事件记录至树莓派本地CSV文件
- 每分钟通过邮件发送事件记录
- 将事件记录同步至Excel文件
- 继电器触点控制工作台LED
现有代码问题
- Python导入语句首字母需小写(
import而非Import),否则会触发语法错误 - Python用缩进划分代码块,不需要大括号
{},现有while循环的大括号属于语法错误 - if语句下的代码未缩进,不符合Python语法规范
- 未实现“检测到人员持续3秒”的逻辑:当前代码检测到人员后直接sleep3秒,期间不会重新验证传感器状态,易出现误触发
- 缺失CSV日志、邮件发送、Excel同步等核心功能
- 未添加GPIO清理逻辑,程序强制退出时可能导致GPIO引脚状态异常
完整实现代码
以下是满足所有需求的完整代码,包含详细注释:
import RPi.GPIO as GPIO import time import csv import smtplib from datetime import datetime from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email import encoders import threading from openpyxl import Workbook # 引脚定义(根据实际接线调整) IR_SENSOR_PIN = 7 RED_LED_PIN = 16 GREEN_LED_PIN = 18 RELAY_PIN = 22 # 全局状态变量 detected_start_time = None current_state = "无人" # 初始状态:无人 log_entries = [] # 存储待发送的日志条目 email_interval = 60 # 邮件发送间隔(秒) last_email_time = time.time() # GPIO初始化 def init_gpio(): GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(RED_LED_PIN, GPIO.OUT) GPIO.setup(GREEN_LED_PIN, GPIO.OUT) GPIO.setup(RELAY_PIN, GPIO.OUT) GPIO.setup(IR_SENSOR_PIN, GPIO.IN) # 初始状态:红灯亮,绿灯灭,继电器断开(工作台LED关闭) GPIO.output(RED_LED_PIN, GPIO.HIGH) GPIO.output(GREEN_LED_PIN, GPIO.LOW) GPIO.output(RELAY_PIN, GPIO.LOW) # 记录日志到CSV和内存 def log_event(event): timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") log_entry = [timestamp, event] # 写入本地CSV with open("detection_log.csv", "a", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(log_entry) # 添加到待发送日志列表 log_entries.append(f"{timestamp} - {event}") print(f"日志记录:{timestamp} - {event}") # 将CSV日志同步到Excel def sync_to_excel(): wb = Workbook() ws = wb.active ws.title = "人员检测日志" # 写入表头 ws.append(["时间", "事件"]) # 读取CSV内容写入Excel with open("detection_log.csv", "r", encoding="utf-8") as f: reader = csv.reader(f) for row in reader: ws.append(row) wb.save("detection_log.xlsx") log_event("日志已同步至Excel") # 发送邮件函数 def send_email(): global log_entries, last_email_time if not log_entries: return # 邮件配置(替换为你的邮箱信息) sender_email = "你的邮箱@xxx.com" receiver_email = "收件邮箱@xxx.com" password = "你的邮箱授权码" smtp_server = "smtp.xxx.com" smtp_port = 587 # 构建邮件内容 msg = MIMEMultipart() msg["From"] = sender_email msg["To"] = receiver_email msg["Subject"] = f"人员检测日志 - {datetime.now().strftime('%Y-%m-%d %H:%M')}" # 邮件正文 body = "\n".join(log_entries) msg.attach(MIMEText(body, "plain")) # 附加Excel文件 try: filename = "detection_log.xlsx" with open(filename, "rb") as attachment: part = MIMEBase("application", "octet-stream") part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header("Content-Disposition", f"attachment; filename= {filename}") msg.attach(part) except Exception as e: log_event(f"附加Excel文件失败:{str(e)}") # 发送邮件 try: server = smtplib.SMTP(smtp_server, smtp_port) server.starttls() server.login(sender_email, password) text = msg.as_string() server.sendmail(sender_email, receiver_email, text) server.quit() log_event("日志邮件已发送") except Exception as e: log_event(f"邮件发送失败:{str(e)}") # 清空待发送日志,更新最后发送时间 log_entries = [] last_email_time = time.time() # 定时任务线程:每分钟执行邮件发送和Excel同步 def scheduled_tasks(): while True: if time.time() - last_email_time >= email_interval: sync_to_excel() send_email() time.sleep(10) # 每10秒检查一次 # 主逻辑 def main(): global detected_start_time, current_state init_gpio() # 启动定时任务线程 threading.Thread(target=scheduled_tasks, daemon=True).start() # 初始化CSV文件(如果不存在则创建表头) try: with open("detection_log.csv", "r", encoding="utf-8") as f: pass except FileNotFoundError: with open("detection_log.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["时间", "事件"]) log_event("日志文件已初始化") try: while True: ir_state = GPIO.input(IR_SENSOR_PIN) # IR传感器通常是低电平检测到人员,根据你的模块调整(这里假设True为检测到人员) if ir_state: if detected_start_time is None: detected_start_time = time.time() # 检测到人员持续3秒 elif time.time() - detected_start_time >= 3 and current_state == "无人": current_state = "有人" # 切换LED和继电器状态:绿灯亮,红灯灭,继电器吸合(工作台LED开启) GPIO.output(RED_LED_PIN, GPIO.LOW) GPIO.output(GREEN_LED_PIN, GPIO.HIGH) GPIO.output(RELAY_PIN, GPIO.HIGH) log_event("检测到人员,已切换状态") else: detected_start_time = None if current_state == "有人": current_state = "无人" # 切换回初始状态:红灯亮,绿灯灭,继电器断开 GPIO.output(RED_LED_PIN, GPIO.HIGH) GPIO.output(GREEN_LED_PIN, GPIO.LOW) GPIO.output(RELAY_PIN, GPIO.LOW) log_event("人员离开,已切换状态") time.sleep(0.1) # 降低CPU占用 except KeyboardInterrupt: print("\n程序已终止") finally: GPIO.cleanup() # 清理GPIO引脚 sync_to_excel() # 最后同步一次Excel if __name__ == "__main__": main()
使用说明
- 替换代码中的邮箱配置(发件人邮箱、收件人邮箱、授权码、SMTP服务器)
- 根据实际接线调整引脚定义
- 安装依赖库:
pip install openpyxl - 运行代码:
python3 detection_system.py
内容的提问来源于stack exchange,提问作者Khaleel
相关产品推荐
相关产品推荐

