基于Arduino与Python的DIY安防系统:传感器融合算法实战 1. 项目概述与核心思路作为一个喜欢折腾硬件和软件的老玩家我一直对如何用最少的成本实现最实用的功能感兴趣。这次分享的是一个我自己捣鼓了挺久并且已经稳定运行了小半年的DIY安防系统。它的核心目标很简单当有人经过你设定的区域比如家门口、楼梯口、或者你不想让宠物进入的房间门口时你的电脑能立刻发出警报并且把这次事件的时间、传感器读数都记录下来。市面上成熟的安防产品很多但要么太贵要么不够灵活没法按照我的想法去定制触发逻辑和报警方式。我这个方案的亮点在于“传感器融合”的思路。听起来很高大上其实原理很朴素只用单一传感器比如超声波容易误报一阵风、一只猫经过或者传感器自身偶尔的读数漂移都可能让它“神经紧张”。而所谓融合在这里我们可以理解为用软件算法给单一的硬件数据“加上一层保险”。我们不是增加更多硬件那会提高成本和复杂度而是通过Python脚本对Arduino发来的一连串超声波测距数据进行智能分析比如检查距离的连续变化模式、过滤掉瞬间的异常跳变从而更准确地判断是不是真的有人经过。整个系统的骨架是这样的一个Arduino Nano或者其他型号也行负责读取HC-SR04超声波传感器的数据一个HC-05蓝牙模块负责把数据无线发送到你的电脑电脑上运行一个Python脚本这个脚本是真正的大脑它接收数据、分析判断、发出警报比如在Mac上弹个通知在Windows上可以播放声音同时把原始数据和时间戳保存到文件里方便你事后查看。整个硬件成本不到一百块软件全部开源你可以随意修改逻辑来适应你的窗户、走廊或者储物间。2. 硬件选型、电路设计与搭建细节2.1 核心元器件解析与选型考量选择这些元件我主要基于几个原则低成本、易获取、低功耗毕竟可能要用电池供电以及足够的可靠性。主控Arduino Nano为什么是Nano相比于UnoNano体积更小更适合嵌入到最终可能放在一个小盒子里的项目中。它的核心芯片ATmega328P性能与Uno完全一致有足够的GPIO口和算力来处理超声波传感器和蓝牙通信。当然如果你手头只有Uno或Mega完全可以平替代码几乎不用改。供电注意Nano可以通过Mini-USB口供电也可以通过VIN引脚输入7-12V电压。在本项目中我们使用移动电源通过USB供电非常方便。感知核心HC-SR04超声波传感器工作原理它通过发射40kHz的超声波并接收回波根据时间差计算距离。测量范围约2cm-400cm精度对于人体检测几十厘米到几米范围完全够用。关键参数触发信号Trig需要至少10微秒的高电平然后模块会自动发射8个40kHz脉冲。回声引脚Echo会输出一个高电平脉冲其宽度与距离成正比。计算距离的公式为距离厘米 (高电平时间微秒 * 0.034) / 2。除以2是因为声音走了来回两趟。避坑点HC-SR04对供电电压比较敏感。虽然它标称5V工作但最好确保供电稳定。如果距离读数飘忽不定首先检查电源。无线桥梁HC-05蓝牙串口模块角色它本质上是一个串口转蓝牙的适配器。Arduino通过TX/RX引脚以串口协议发送数据HC-05将其转换为蓝牙信号发送给电脑反之亦然。HC-05 vs HC-06HC-05功能更强大支持主从模式切换和AT指令配置。HC-06只能作为从机。原项目提到连接名为“HC-06”的设备这可能是模块出厂默认名称或者是HC-05被配置为了从机模式。购买时确认一下即可使用上区别不大。配对密码通常默认是“1234”或“0000”。控制开关OMRON轻触开关与10kΩ电阻作用用于手动开启或关闭整个传感器系统避免在你不需要的时候误触发。电路原理这里使用的是经典的上拉电阻接法。Arduino的输入引脚通过一个10kΩ电阻连接到5V上拉同时该引脚也连接到开关的一端开关另一端接地。当开关未按下时引脚通过上拉电阻保持在高电平1当开关按下引脚直接接地变为低电平0。程序通过检测这个引脚的电平变化来判断开关状态。使用上拉电阻可以避免引脚悬空时产生不确定的杂讯。其他面包板、杜邦线、移动电源。移动电源建议选择输出稳定、容量适中的例如5000mAh可以保证系统连续工作数天。2.2 电路连接详解与实操陷阱按照电路图连接并不难但有几个细节决定了你是一次成功还是陷入调试地狱。接线清单务必对照Arduino Nano 电源5V- 面包板正极红线区域GND- 面包板负极蓝线区域移动电源USB口连接Nano的USB口供电。HC-SR04超声波传感器VCC- 面包板正极 (5V)GND- 面包板负极Trig- Arduino 数字引脚D2Echo- Arduino 数字引脚D3HC-05蓝牙模块VCC- 面包板正极 (5V)注意有些HC-05模块是3.3V逻辑电平但供电需要5V请查看模块背面说明。若为3.3V逻辑则其RX引脚不能直接接Arduino的5V TX需分压GND- 面包板负极TX- Arduino 数字引脚D0(RX)重要上传代码时必须断开此线RX- Arduino 数字引脚D1(TX)重要上传代码时必须断开此线OMRON开关与10kΩ电阻将开关跨接在面包板中间凹槽的两侧。开关一侧引脚连接至面包板负极GND。开关另一侧引脚连接至 Arduino 数字引脚D4。在 ArduinoD4引脚和面包板正极5V之间连接一个10kΩ电阻这就是上拉电阻。核心避坑指南1蓝牙模块的TX/RX连接这是新手最容易出错的地方。Arduino的D0(RX)和D1(TX)同时也是其与电脑进行串口通信用于上传程序的引脚。如果在这两个引脚连接着其他设备如HC-05的情况下尝试上传程序会产生信号冲突导致上传失败并报“avrdude: stk500_getsync()”之类的错误。正确操作流程1. 编写好Arduino代码。2.断开HC-05模块与D0、D1连接的所有线。3. 将Arduino通过USB连接电脑选择正确端口和板型上传程序。4. 上传成功后拔掉USB线先接好HC-05的线再重新插上USB线上电。这个顺序务必牢记。核心避坑指南2电源噪声与共地所有元件的GND地线必须最终连接到一起都接到面包板的负极总线形成一个共同的参考零电位点这是电路正常工作的基础。如果超声波传感器读数乱跳除了检查代码一定要确认电源正负极连接牢固且移动电源输出稳定。有条件的话可以在Arduino的5V和GND之间加一个100uF的电解电容用于滤波稳压。3. Arduino固件数据采集与串口发送Arduino端的任务很纯粹循环读取超声波传感器的距离读取开关状态然后将这些数据打包成一个格式化的字符串通过软串口发送给蓝牙模块。3.1 代码逐行解析与关键参数设置我们使用SoftwareSerial库来创建一组新的串口专门用于和HC-05通信这样就不会占用硬件串口虽然我们上传程序后也用不到硬件串口了但这是个好习惯。#include SoftwareSerial.h // 定义引脚 const int trigPin 2; const int echoPin 3; const int switchPin 4; // 创建软串口对象RX接D0, TX接D1 (对应HC-05的TX和RX) SoftwareSerial bluetooth(0, 1); // RX, TX // 定义一些变量 long duration; int distance_cm; bool lastSwitchState HIGH; // 假设初始为上拉状态开关未按下 bool systemActive false; void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(switchPin, INPUT_PULLUP); // 使用内部上拉电阻这样外部10k电阻可以省略但为了演示我们保留了外部电路。 Serial.begin(9600); // 硬件串口用于调试可选择性开启 bluetooth.begin(9600); // 蓝牙串口必须与HC-05默认波特率一致通常是9600或38400 digitalWrite(trigPin, LOW); delayMicroseconds(2); } void loop() { // 1. 读取开关状态 bool currentSwitchState digitalRead(switchPin); if (currentSwitchState LOW lastSwitchState HIGH) { // 检测到下降沿按下动作 delay(50); // 简单防抖 if (digitalRead(switchPin) LOW) { // 再次确认 systemActive !systemActive; // 切换系统状态 // 可以通过蓝牙发送状态信息例如“SYS:ON”或“SYS:OFF” if(systemActive) { bluetooth.println(SYS:ON); } else { bluetooth.println(SYS:OFF); } } } lastSwitchState currentSwitchState; // 2. 如果系统激活则进行测距 if (systemActive) { // 触发超声波传感器 digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // 读取回波脉冲时长 duration pulseIn(echoPin, HIGH, 30000); // 设置超时30ms对应约5米距离 // 计算距离厘米 if (duration 0) { distance_cm duration * 0.034 / 2; } else { distance_cm 999; // 超时或无效值用一个很大的数表示 } // 3. 通过蓝牙串口发送数据 // 格式建议”DIST:123,SW:1“ 表示距离123cm开关状态为激活(1) bluetooth.print(DIST:); bluetooth.print(distance_cm); bluetooth.print(,SYS:); bluetooth.println(systemActive ? 1 : 0); // 可选通过硬件串口打印到IDE的串口监视器用于调试 // Serial.print(Distance: ); // Serial.print(distance_cm); // Serial.println( cm); } else { // 系统未激活可以每隔一段时间发送一个休眠状态信息或者不发送 bluetooth.println(SYS:STANDBY); } // 控制采样频率避免数据过快。200ms一次比较合适。 delay(200); }关键点解析pulseIn函数与超时pulseIn(echoPin, HIGH, 30000)中的30000是超时时间微秒。如果30ms内没有收到高电平回波函数会返回0。这可以防止在传感器前方没有障碍物时程序一直卡在这里等待。根据声速30ms对应大约5米的测量距离满足大部分室内场景。数据格式我们定义了简单的数据协议如“DIST:150,SYS:1”。这样Python端可以用逗号分隔再用冒号分割键值对便于解析。统一的格式是后续稳定通信的基础。开关防抖机械开关在按下瞬间会产生快速的电压抖动可能导致程序误判为多次按下。我们采用简单的延时再检测的方法delay(50)来进行软件防抖。采样延迟delay(200)将循环周期控制在约200ms即每秒采样5次。这个频率对于检测人的行走速度足够了同时避免了数据洪流淹没蓝牙通道。3.2 上传代码与初步测试在Arduino IDE中安装SoftwareSerial库通常已内置。将上述代码复制到新项目中。务必断开Arduino Nano上连接HC-05模块TX/RX的杜邦线。选择正确的板型Arduino Nano和端口如COM3或/dev/cu.usbmodem14101。点击上传。上传成功后先关闭Arduino IDE的串口监视器如果打开了然后给Arduino断电接上HC-05的TX/RX线最后重新上电。初步测试打开Arduino IDE的串口监视器将波特率设置为9600你应该能看到每隔200ms打印出的距离信息前提是你在代码中取消了Serial.print那几行的注释。这能验证超声波传感器和基础逻辑是否工作正常。同时观察HC-05模块上的LED指示灯通常连接成功后会有规律的慢闪约每秒一次表示已进入可配对状态。4. Python大脑数据接收、融合算法与警报触发这是项目的智能核心。Python脚本需要完成几件事建立蓝牙串口连接、持续读取数据、解析数据、应用算法判断是否有人经过、触发系统通知并记录日志。4.1 环境搭建与依赖库说明原项目提到在macOS上运行在Windows上需要调整。这里我会分别说明。# 使用pip安装所需库Windows/macOS/Linux通用 pip install pyserial # 如果需要桌面通知macOS需要安装pyobjc但更推荐使用plyer库跨平台 pip install plyer # 如果需要记录日志文件可以使用Python内置的logging但这里我们按原项目思路自己写文件pyserial这是与蓝牙串口通信的核心库。它把蓝牙虚拟成的COM口当作一个普通的串口来读写。plyer一个跨平台的库可以很方便地调用操作系统的通知功能在Mac上显示通知中心提醒在Windows上显示Toast通知在Linux上显示libnotify提示。注意事项在Windows上蓝牙串口通常显示为COMx如COM6在macOS上则显示为/dev/tty.HC-05-DevB或类似名称。在Linux上可能是/dev/rfcomm0。连接前需要在系统蓝牙设置中完成配对。4.2 核心脚本解析与传感器融合逻辑实现下面是一个增强版的readingValuesV2.py脚本包含了更健壮的融合逻辑和错误处理。import serial import time from datetime import datetime import os from plyer import notification import sys class SecuritySensor: def __init__(self, port, baudrate9600, wall_distance_cm100): 初始化传感器 :param port: 串口地址如 COM6 或 /dev/tty.HC-05-DevB :param baudrate: 波特率需与Arduino设置一致 :param wall_distance_cm: 传感器到背景墙或正常静止物体的基准距离 self.port port self.baudrate baudrate self.wall_distance wall_distance_cm self.ser None self.system_active False # 数据缓存用于融合算法 self.distance_buffer [] self.buffer_size 5 # 缓存最近5次读数 # 报警状态锁防止短时间内重复报警 self.alarm_cooldown False self.cooldown_seconds 10 # 报警后冷却10秒 def connect(self): 建立蓝牙串口连接 try: self.ser serial.Serial(self.port, self.baudrate, timeout1) print(f成功连接到 {self.port}) # 清空可能存在的旧数据缓冲区 self.ser.flushInput() time.sleep(2) # 等待Arduino和模块稳定 return True except serial.SerialException as e: print(f连接失败: {e}) print(请检查1. 蓝牙是否已配对并连接。2. 端口号是否正确。3. 是否有其他程序占用了该端口。) return False def parse_data(self, line): 解析从Arduino接收到的单行数据 try: line line.decode(utf-8).strip() except UnicodeDecodeError: return None data_dict {} # 预期格式 DIST:150,SYS:1 或 SYS:ON parts line.split(,) for part in parts: if : in part: key, value part.split(:, 1) data_dict[key] value return data_dict def sensor_fusion_logic(self, current_distance): 核心融合判断逻辑。 当前实现基于滑动平均和变化趋势的简单融合。 # 1. 填充缓存 self.distance_buffer.append(current_distance) if len(self.distance_buffer) self.buffer_size: self.distance_buffer.pop(0) # 移除最旧的读数 # 如果缓存还没满不进行判断 if len(self.distance_buffer) self.buffer_size: return False # 2. 计算滑动平均值和瞬时波动 avg_distance sum(self.distance_buffer) / len(self.distance_buffer) # 计算最近一次读数与平均值的偏差 immediate_deviation abs(current_distance - avg_distance) # 3. 计算距离变化的趋势最近几次读数的变化量 # 这里简单计算缓存中第一个和最后一个的差值 trend self.distance_buffer[-1] - self.distance_buffer[0] # 4. 判断条件可调整的阈值 threshold_sudden 20 # 厘米单次读数突变的阈值 threshold_sustained 15 # 厘米持续偏离基准的阈值 trend_threshold 10 # 厘米趋势变化的阈值 # 条件A当前读数突然剧烈变化可能是快速通过 condition_a immediate_deviation threshold_sudden and current_distance self.wall_distance # 条件B平均读数持续低于背景墙距离有人停留 condition_b avg_distance (self.wall_distance - threshold_sustained) # 条件C呈现明显的持续减小趋势有人靠近 condition_c trend -trend_threshold # 满足任一条件且当前距离有效非超时值999 if current_distance ! 999 and (condition_a or condition_b or condition_c): return True return False def send_notification(self, message): 发送系统通知 try: notification.notify( title安全传感器警报, messagemessage, app_nameDIY Security System, timeout5 # 通知显示5秒 ) print(f[警报] {datetime.now().strftime(%Y-%m-%d %H:%M:%S)} - {message}) except Exception as e: print(f发送通知失败: {e}) def log_data(self, distance, status, event): 记录数据到文件 timestamp datetime.now().strftime(%Y-%m-%d %H:%M:%S) log_line f{timestamp}, DIST:{distance}, SYS:{status}, EVENT:{event}\n with open(self.log_file, a) as f: f.write(log_line) def run(self, log_file_prefixsensor_log): 主运行循环 # 创建日志目录和文件 log_dir sensor_logs os.makedirs(log_dir, exist_okTrue) timestamp datetime.now().strftime(%Y%m%d_%H%M%S) self.log_file os.path.join(log_dir, f{log_file_prefix}_{timestamp}.csv) # 写入CSV表头 with open(self.log_file, w) as f: f.write(timestamp,distance_cm,system_status,event\n) print(f日志文件已创建: {self.log_file}) if not self.connect(): sys.exit(1) print(系统启动。等待数据... (按CtrlC停止)) try: while True: if self.ser.in_waiting 0: line self.ser.readline() data self.parse_data(line) if data: # 处理系统状态 if SYS in data: if data[SYS] in [ON, 1]: if not self.system_active: self.system_active True print(系统状态激活) self.send_notification(安防系统已激活) elif data[SYS] in [OFF, 0, STANDBY]: if self.system_active: self.system_active False print(系统状态待机) self.distance_buffer [] # 清空缓存 self.send_notification(安防系统已待机) # 处理距离数据 if DIST in data and self.system_active: try: dist int(data[DIST]) # 记录原始数据 self.log_data(dist, ACTIVE) # 应用融合算法判断 if self.sensor_fusion_logic(dist): if not self.alarm_cooldown: alert_msg f检测到移动当前距离: {dist}cm self.send_notification(alert_msg) self.log_data(dist, ACTIVE, ALARM_TRIGGERED) self.alarm_cooldown True # 启动冷却计时器 def reset_cooldown(): time.sleep(self.cooldown_seconds) self.alarm_cooldown False import threading threading.Thread(targetreset_cooldown, daemonTrue).start() else: print(f[忽略] 检测到移动但在冷却期内。距离: {dist}cm) else: # 正常读数可选打印 # print(f距离: {dist}cm) pass except ValueError: pass time.sleep(0.05) # 短暂睡眠降低CPU占用 except KeyboardInterrupt: print(\n用户中断。) finally: if self.ser and self.ser.is_open: self.ser.close() print(串口连接已关闭。) if __name__ __main__: # 用户需要修改的部分 # Windows 用户在设备管理器中查看端口COMx # macOS 用户在终端输入 ls /dev/tty.* 查看 SENSOR_PORT /dev/tty.HC-05-DevB # 例如COM6 或 /dev/tty.HC-05-DevB # 测量并设置传感器到背景墙或固定障碍物的静止距离 BASE_WALL_DISTANCE_CM 120 # 单位厘米 # sensor SecuritySensor(portSENSOR_PORT, wall_distance_cmBASE_WALL_DISTANCE_CM) sensor.run()融合算法深度解读这个sensor_fusion_logic函数是实现“智能”的关键。它没有增加硬件而是通过软件算法提升了判断可靠性。数据缓存distance_buffer维护一个固定长度如5的最近距离读数列表。这相当于给系统一个“短期记忆”。滑动平均avg_distance计算缓存内数据的平均值。这能有效平滑掉单次测量可能出现的随机噪声或毛刺。瞬时偏差immediate_deviation计算最新一次读数与滑动平均值的差值。如果这个差值突然变得很大可能意味着有物体快速进入或离开探测区。变化趋势trend计算缓存中第一个和最后一个数据的差值。一个持续为负的趋势值越来越小表明物体正在持续靠近传感器。多条件触发condition_a针对快速通过。比如有人快步走过会导致某一次读数剧烈变化。condition_b针对长时间停留。比如有人站在传感器前会导致滑动平均值持续低于背景距离。condition_c针对缓慢靠近。比如有人悄悄走近距离会呈现稳定的减小趋势。 只有满足这些条件之一才判定为有效入侵触发警报。这大大降低了因传感器自身波动或小动物短暂经过引起的误报。其他重要特性报警冷却期触发一次警报后会进入10秒的冷却期期间即使再检测到移动也不会报警。这避免了人在警报区域内活动时系统“喋喋不休”地连续报警。完整的日志记录所有数据时间戳、距离、系统状态、报警事件都以CSV格式保存方便后续用Excel或Python分析优化wall_distance和判断阈值。跨平台通知使用plyer库一行代码就能实现Mac/Windows/Linux的通知。4.3 脚本运行与配置要点获取蓝牙串口号Windows配对HC-05后打开“设备管理器”在“端口COM和LPT”下找到类似“Standard Serial over Bluetooth link (COM6)”的设备记下COM号。macOS配对后打开终端输入ls /dev/tty.*你会看到类似/dev/tty.HC-05-DevB的名称。修改脚本参数打开脚本找到最后面的SENSOR_PORT和BASE_WALL_DISTANCE_CM变量根据你的实际情况修改。测量基准距离将传感器固定在最终位置前方无人的情况下运行一个简单的测试脚本读取距离取一个稳定值作为BASE_WALL_DISTANCE_CM。这是判断“有无物体”的基准线。运行脚本在终端或命令行中进入脚本所在目录执行python readingValuesV2.py。首次运行会要求输入一个记录编号原项目功能你可以按回车跳过或输入任意数字。测试在传感器前走动观察终端输出和电脑是否弹出通知。查看生成的日志文件确认数据被记录。5. 系统集成、调试与优化实战5.1 完整工作流程与部署当硬件和软件分别测试通过后就可以进行集成部署了硬件固定将面包板上的电路用热熔胶或螺丝固定在一个合适的小盒子内为超声波传感器开孔。确保传感器表面清洁无遮挡。电源管理使用移动电源供电。测试待机功耗估算续航时间。Arduino Nano和HC-05在非深度睡眠模式下电流大约在30-50mA一个10000mAh的移动电源理论上可以支持数百小时。软件自启动如果你希望电脑开机后自动运行这个监控脚本macOS可以创建一个.plist文件放入~/Library/LaunchAgents/目录。Windows可以将Python脚本的快捷方式放入“启动”文件夹。更优解使用树莓派Zero W这类微型电脑来运行Python脚本功耗更低可以完全脱离主机电脑并通过网络发送警报如Telegram消息、电子邮件这是下一步升级的方向。阈值调优这是降低误报率的关键。运行系统一段时间让人在正常活动范围内行走观察日志中的距离变化范围。然后调整Python脚本中的三个阈值threshold_sudden瞬时突变阈值通常设为10-30cm取决于人通过的速度和你希望忽略的小幅度波动。threshold_sustained持续偏离阈值通常设为5-20cm比瞬时阈值小一些用于检测缓慢移动或静止目标。trend_threshold趋势阈值通常设为5-15cm用于判断一个明确的靠近或远离趋势。buffer_size缓存大小增大缓存如到10会让系统反应更“迟钝”但更稳定减小缓存会让系统更“灵敏”但也更易受干扰。5.2 高级调试与问题排查手册即使按照步骤操作也可能会遇到问题。下面是一个系统性的排查清单问题现象可能原因排查步骤与解决方案Arduino代码上传失败1. 端口或板型选择错误。2. TX/RX引脚被占用。3. 驱动问题仅Windows。1. 确认IDE中选择的板型是Arduino Nano端口正确。2.务必在上传前断开与HC-05连接的TX/RX线。3. 尝试为Nano选择ATmega328P (Old Bootloader)。Python脚本报错[Errno 16] Resource busy或SerialException1. 蓝牙未配对/连接。2. 端口被其他程序占用。3. 端口号错误。1. 去系统蓝牙设置中确认已与HC-05或HC-06配对并连接。2. 关闭Arduino IDE的串口监视器或其他可能占用端口的软件。3. 重新检查并更正脚本中的SENSOR_PORT变量。Python脚本连接成功但收不到数据1. Arduino未供电或未运行。2. 蓝牙模块波特率不匹配。3. Arduino代码中数据格式与Python解析格式不一致。1. 检查Arduino电源指示灯是否亮起。2. 尝试修改Python和Arduino代码中的波特率为38400或115200需同时修改。3. 在Python脚本的parse_data函数里添加print(“Raw:”, line)查看原始数据格式确保与Arduino发送的格式匹配。超声波传感器读数始终为0或非常大且不变1. 接线错误Trig/Echo接反。2. 供电不足。3. 传感器损坏。1. 仔细检查Trig和Echo引脚是否接对。2. 用万用表测量传感器VCC引脚电压是否稳定在5V左右。3. 使用Arduino IDE串口监视器运行一个最简单的超声波测距例程单独测试传感器。系统频繁误报1. 基准距离wall_distance设置不准确。2. 算法阈值过于敏感。3. 环境干扰如空调风、窗帘飘动。1. 在无人环境下重新校准基准距离并留出一定余量比如减去5cm。2. 逐步提高threshold_sudden、threshold_sustained等阈值。3. 调整传感器角度避免直接对着通风口或窗户。考虑增加buffer_size。警报延迟很大1. Arduino循环中的delay过长。2. Python脚本数据处理耗时太长。1. 减少Arduino代码中loop()末尾的delay(200)比如改为100需测试稳定性。2. 优化Python代码确保主循环time.sleep很短且sensor_fusion_logic计算高效。移动电源耗电极快1. 系统未进入低功耗模式。1. 修改Arduino代码当开关关闭时让Arduino进入低功耗模式需要更复杂的编程或至少停止超声波传感器工作设置Trig为LOW和减少蓝牙发送频率。5.3 扩展思路与进阶玩法这个基础框架有巨大的可扩展性多传感器融合真正的硬件融合增加一个PIR热释电红外传感器。PIR对移动的人体热源敏感但对静止目标无效。超声波对静止目标有效但可能被非生命体触发。让Arduino同时读取两者数据只有当PIR和超声波同时触发时才判定为“人经过”这将误报率降到极低。网络化与远程警报用ESP8266或ESP32替代Arduino Nano它们自带Wi-Fi。检测到入侵后可以通过网络请求HTTP或MQTT协议将警报发送到手机App如Blynk、IFTTT、Telegram Bot或你自己的服务器。本地声光报警在Arduino端连接一个蜂鸣器和一个LED。当Python脚本判定为入侵时可以通过蓝牙反向发送一个指令如“ALARM:ON”让Arduino触发本地声光报警这样即使电脑关机或蓝牙断开也能起作用。数据可视化使用Python的matplotlib库实时绘制距离随时间变化的曲线图可以更直观地观察探测情况和调试算法阈值。机器学习优化收集大量的“有人经过”和“无人经过”时的距离序列数据使用简单的机器学习算法如Scikit-learn进行训练让系统自己学习判断模式这可能比手动设置阈值规则更有效。