ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

三合一智能感应灯:Arduino实现人体感应+光敏+蓝牙控制

三合一智能感应灯:Arduino实现人体感应+光敏+蓝牙控制 晚上回到家摸黑找开关这件事我忍了很久。床头灯、衣柜灯、走廊小夜灯如果都用买来的成品感应灯一个几十块不说功能还固定死了。后来我干脆用 Arduino 自己焊了一套智能小灯人体感应负责“人来亮、人走灭”光敏电阻负责“白天别乱亮”HC-06 蓝牙模块负责“想手动控制时掏出手机按一下”。三种控制方式叠在一起成本不到三十块代码我整理得很完整文章末尾直接复制就能跑。这篇文章我会把这套方案从硬件选型、接线原理、代码逻辑到调试排坑全部讲清楚零基础也能跟着做出来。我自己在测试过程中踩过不少坑比如 PIR 模块上电乱触发、光敏阈值总是调不准、蓝牙发指令没反应等等。这些问题如果不提前说明新手很可能卡住半天。所以这篇不只是“代码能用就行”的水平我会把每个关键选择背后的原因都拆开讲最后再附上完整代码和常见问题速查表。如果你正好需要一盏带“眼睛”和“耳朵”的灯这篇应该可以帮到你。1. 项目概述与方案设计1.1 为什么做“三合一”智能灯先说需求场景。我原本只想做一个衣柜感应灯开门衣柜就亮关门就灭。但实际用下来发现单纯的人体感应有个很尴尬的问题——白天打开衣柜也亮白白耗电。后来又想到加一个光线传感器让它在光线充足时不触发只在天黑或者环境光暗的情况下工作。这还不够因为有时候躺在被窝里不想动想让灯一直亮着或者直接关掉人体感应根本管不了。于是蓝牙控制也必须加进来。这三个功能放一起才算真正解决了我日常发光的全部痛点。人体感应负责自动化光敏负责节能蓝牙负责“我的灯我做主”。从技术难度来看这三个模块都是 Arduino 生态里最成熟、资料最多、价格最便宜的器件组合起来不需要太复杂的算法非常适合作为第一个自主设计的智能家居项目。如果用一句话总结方案的价值就是“两个模拟直觉的传感器 一个无线遥控器让一盏普通 LED 灯具备自动与手动的双重人格”。适合学生做课程设计也适合刚入门 Arduino 的爱好者练手更可以直接用在真实的居住环境里。1.2 硬件清单与选型思路下面是我实际用到的元器件清单没列太多可有可无的东西器件型号/规格数量参考价格用途主控板Arduino Uno 或 Nano115-30元核心逻辑处理人体感应模块HC-SR501 PIR 模块13-8元检测人体移动光敏模块光敏电阻模块带 AO 模拟输出12-5元检测环境光强蓝牙模块HC-06 从机模块18-15元接收手机指令LED白色高亮 LED 或 LED 灯带11-10元被控制的光源电阻220Ω 限流电阻、分压电阻若干几毛钱限流和电平匹配面包板/洞洞板通用12-10元搭建电路杜邦线公对公/公对母若干3元左右接线主控板我推荐 Arduino Nano 而不是 Uno。为什么因为 Nano 体积小直接插在面包板上整块电路可以做得非常紧凑适合做小夜灯、衣柜灯这类嵌入式场景。Uno 当然也没问题接线完全一致只是占地方更大。如果你手上只有 Uno那就不需要额外买板子。PIR 模块选 HC-SR501这是最普及的型号工作电压 5V输出高电平直接兼容 Arduino 数字引脚。光敏部分我强烈建议选带 AO 模拟输出的模块而不是只有 DO 数字输出的。DO 输出内部集成了一个电位器靠拧螺丝设定阈值很不方便调试而且温度漂移后阈值会跑偏。AO 输出原始电压由代码里的阈值统一判断改参数只需要改一行数字这才是可维护的做法。蓝牙模块我选 HC-06。它是纯从机模块只能被手机连接价格便宜默认波特率 9600配对密码一般是 1234 或 0000非常适合这种单向遥控场景。如果你买的是 HC-05 也没关系它兼容从机模式只是配对方式和默认波特率略有不同后面我也会提到。1.3 系统工作流程系统的整体工作逻辑很简洁我把它梳理成三条规则第一自动模式下只有“环境光足够暗”且“最近一段时间内检测到人体活动”两个条件同时满足LED 才会亮。第二人离开后灯不会立刻熄灭而是延迟一段时间默认 30 秒避免你走到门口摸黑。第三一旦手机蓝牙发送指令切到手动模式传感器就不再参与控制完全按手机指令开关灯和调亮度。这种设计的好处是自动与手动互不打架。如果你只想当普通感应灯用上电默认就是自动模式不需要任何操作。如果某天你想让灯一直亮着比如在书桌前长期伏案手机发一个 ON 指令它就进入手动常亮状态不会再因为坐久了身体静止而熄灭。人走之后再发一个 A 指令它就恢复为自动感应模式。从系统角度看核心输入有三个PIR 数字信号、光敏模拟信号、蓝牙串口命令输出只有一个PWM 调光信号。主控 Arduino 要做的就是不断轮询三个输入源再根据当前模式决定输出亮度。整个状态机不复杂但做好之后体验非常稳定。2. 电路连接与核心模块原理2.1 人体感应HC-SR501 的工作方式HC-SR501 模块的核心是一颗热释电红外传感器配合半球形的菲涅尔透镜使用。简单说一切温度高于绝对零度的物体都在持续辐射红外线人体辐射的红外线集中在 8~14 微米波段。当人从透镜前方走过时传感器敏感元上的红外能量发生快速变化模块内部比较器就会输出高电平。为什么不做成摄像头视觉识别因为成本高、功耗大而且涉及图像处理对 Arduino 这种资源紧张的主控来说太重了。PIR 模块本质上是一个“数字变化检测器”它不关心你是谁只关心眼前有没有移动的红外热源这在小夜灯场景已经完全够用。HC-SR501 背板上有两个旋钮和一组跳帽很多新手接好线以后发现行为诡异基本都是这两针跳线和两个旋钮没弄明白。一个旋钮调节灵敏度检测距离另一个旋钮调节输出高电平的保持时间。跳帽用来选择“不可重复触发”和“可重复触发”两种模式。对于这个项目我建议把跳帽拨到可重复触发模式然后把延时旋钮拧到最小。为什么因为代码里已经用millis()变量做了 30 秒的延后熄灭逻辑模块自带的延时旋钮如果调大了反而会和代码逻辑叠加导致灯亮了很久才灭。可重复触发模式下只要人还在感应范围内轻微活动模块输出就会持续保持高电平人的静默期由代码里的KEEP_ON_MS兜底配合起来体验最好。接线方面没有难点模块 VCC 接 Arduino 5VGND 接 GNDOUT 接数字引脚 D2。但要注意PIR 模块上电后会有一段约 30 到 60 秒的“自检稳定期”期间可能会随机输出高电平。如果你刚上电就看到灯闪了几下不要紧张等一分钟再看。2.2 光线感应光敏电阻模块的信号读取光敏电阻模块的原理是利用硫化镉光敏电阻的阻值随光照变化这一特性在电路里构成分压网络最终从 AO 引脚输出一个随光照变化的模拟电压。Arduino 的analogRead()会把 0~5V 的电压映射成 0~1023 的整数方便代码直接比较。这里有个很关键的坑不同厂家模块的 AO 输出方向可能相反。有的模块是光线越强电压越高有的模块是光线越强电压越低。我在调试环节会详细讲怎么用串口实测标定但接线之前心里要有个底不要默认“数值大就是亮”。我用的这块模块实测下来光线越强时 LDR 数值越小全黑环境下数值只有 20 左右晚上开台灯是 300 左右白天窗边能到 650。所以我代码里写成lightLevel LIGHT_THRESHOLD表示“暗”。接线同样简单VCC 接 5VGND 接 GNDAO 接模拟引脚 A0。注意不要接 DO原因前面说过DO 的阈值是模块上电位器定的调起来远不如改代码里的一个常量方便。安装位置也有讲究。如果你把光敏电阻放在床头灯旁边晚上打开床头灯时模块检测到“光线变亮”自动模式就会把灯关掉这就形成了负反馈循环。我的做法是把光敏电阻模块放在灯珠的反方向朝向窗外或者门口让它感知的是环境基础亮度而不是灯本身的亮度。如果安装空间受限也可以用一小块黑色热缩管遮住模块的侧面只留顶部感光孔这样能大幅抑制灯光自反馈。2.3 蓝牙控制HC-06 的接线与避坑要点HC-06 是蓝牙 2.0 从机模块最常用的接法是走串口协议手机 App 发来字符模块通过 TX、RX 引脚传给 Arduino。模块的 VCC 一般接 5VGND 共地TXD 接 Arduino 的接收引脚RXD 接 Arduino 的发送引脚。这句话说起来容易实际做的时候很多人栽在“交叉连接”这回事上——脑子一热TXD 接 TX信号就乱了。我的接线建议是使用 Arduino 的 D10 和 D11 引脚配合 SoftwareSerial 库而不是用硬件串口 D0/D1。为什么因为 D0/D1 同时承担着 USB 烧录和调试的职责如果你把蓝牙模块挂上去每次上传程序都可能被蓝牙模块干扰出现上传失败而且调试串口信息时也会混进蓝牙数据。用 D10/D11 是更稳的做法。还有一个必须注意的细节HC-06 的串口逻辑电平是 3.3V而 Arduino Uno/Nano 的 TX 输出是 5V。理论上很多模块对 5V 输入也能容忍但为了长期稳定运行最好做一个分压电阻网络。我常用的方式是在 Arduino D11发送到 HC-06 RXD 之间串联一个 2kΩ 电阻再从 HC-06 RXD 引脚接一个 1kΩ 电阻到 GND构成 3.3V 分压。HC-06 的 TX 输出本身是 3.3VArduino 能正常识别高电平不需要处理。供电方面HC-06 的 VCC 接 5V 没问题但要注意整板电流。蓝牙模块工作电流大约 40mAPIR 模块大约 50mALED 如果走 5V 引脚还要看实际功率。如果这些全走 Arduino 板载的 5V 稳压输出总电流很容易超过 200mAUSB 口还撑得住但某些劣质充电器会掉压导致蓝牙反复重启。后面我会单独讲供电建议。2.4 引脚分配总表整理一张完整的引脚接线表照着接就行HC-SR501 PIRArduinoVCC5VGNDGNDOUTD2光敏模块ArduinoVCC5VGNDGNDAOA0HC-06 蓝牙ArduinoVCC5VGNDGNDTXDD10SoftwareSerial RXRXDD11通过 2k1k 分压电路LED 灯珠/灯带Arduino正极D9PWM负极220Ω 电阻到 GND如果你用的是 Arduino Nano引脚编号完全一致。只要杜邦线按表插好烧录完代码就能跑。注意 LED 的负极一定要串限流电阻普通 5mm 灯珠工作电流 20mA 左右5V 直连不加电阻很容易烧掉。如果是大功率 LED 或灯带D9 引脚不能直接驱动得加 MOS 管或三极管这点会在供电章节展开。3. 完整代码与逻辑拆解3.1 程序状态与总体逻辑整套代码的逻辑非常直接核心是一个无限循环的loop()先读取 LDR 光敏值和 PIR 数字值再根据当前模式自动或手动决定目标亮度最后调用setOutput()写 PWM 输出。为了让代码结构清晰我拆成了几个函数setup()负责初始化引脚和串口loop()负责轮询传感器并调用业务逻辑processBluetoothCommand()负责解析手机发来的字符指令setOutput()负责实际控制 LED并做了“亮度不变就不重复写”的优化避免 PWM 输出频繁抖动。为什么要用currentBrightness这个变量做变化检测因为analogWrite()虽然很快但在低亮度下人眼能察觉到轻微闪烁而且频繁写同一个值毫无意义白白占用主循环时间。实测下来加了这个优化后 LED 亮度过渡更平滑串口调试时也不会因为中断错乱导致指令丢失。代码整体采用非阻塞写法没有用delay()做长时间等待只有上电自检闪烁时短暂延时。这样可以保证蓝牙指令在任何时刻都能被及时处理不会因为灯在闪烁而错过手机指令。3.2 自动模式和手动模式如何协作自动模式的设计重点在于“如何避免频繁开关”。裸用 PIR 的人应该都经历过这种场景走进房间灯亮了你坐下开始玩手机身体稍微一动灯又亮一下然后又灭。这是因为 PIR 检测的是红外变化静止的人体几乎没有变化信号所以人会间歇性触发。解决办法是在代码里增加一个“最后活动时间”变量lastMotionTime。每次 PIR 检测到高电平就更新一次lastMotionTime。判断是否亮灯时不看 PIR 当时是否为高而是看“距离最后一次活动过去了多久”。只要在KEEP_ON_MS默认 30 秒以内就认为有人存在。这样即使人坐下不动灯也不会立刻熄灭。手动模式的优先级更高。一旦手机发来 M、O、F 或数字亮度指令程序把autoMode设为 false进入手动控制状态。手动模式下传感器读数仍然更新但不再参与开关判断。只有收到 A 指令才会切回自动模式。这个设计避免了一个尴尬情况手机把灯调成 80% 亮度结果人一走传感器又把灯灭了那蓝牙控制就成了摆设。3.3 蓝牙指令协议设计蓝牙协议我特意做得非常简单全部使用单个字符或单个数字命令方便手机端的串口助手直接发送不需要做复杂分包处理。指令说明如下指令含义示例A 或 a切回自动模式发 A灯恢复感应M 或 m切到手动模式常亮最大亮度发 M灯全亮O 或 o手动开灯亮度设为 255发 O灯全亮F 或 f手动关灯发 F灯灭0 到 9手动设置亮度等级发 5亮度约 50%数字键的映射采用map(c - 0, 0, 9, 0, 255)也就是数字越大越亮。注意发 0 时会把灯关掉发非 0 数字时自动进入手动模式并点亮这是为了操作直觉你调亮度自然希望灯按你调的亮度亮起来。如果你希望亮度映射更细化可以把数字后面再跟两位十进制数比如发送“128”表示 50% 亮度但这会增大解析复杂度。考虑到 DIY 场景下手机端蓝牙 App 自定义按钮完全够用单字符方案最省心。3.4 完整可运行代码下面这份代码可以直接复制到 Arduino IDE选择开发板 UNO 或 Nano编译上传即可使用。#include SoftwareSerial.h #define PIR_PIN 2 // 人体感应模块输出引脚 #define LDR_PIN A0 // 光敏电阻模块模拟输出引脚 #define LED_PIN 9 // LED 控制引脚PWM #define BT_RX 10 // SoftwareSerial 接收引脚接 HC-06 TX #define BT_TX 11 // SoftwareSerial 发送引脚接 HC-06 RX SoftwareSerial btSerial(BT_RX, BT_TX); const int LIGHT_THRESHOLD 420; // 光照阈值实测后修改 const unsigned long KEEP_ON_MS 30000; // 人离开后保持亮灯时间 bool autoMode true; // 默认自动模式 bool manualForceOn false; // 手动强制开灯 int manualBrightness 255; // 手动亮度 0-255 unsigned long lastMotionTime 0; // 最后一次人体活动时间 int currentBrightness -1; // 当前实际亮度避免重复写 int lightLevel 0; // 保存光敏读数 void setup() { Serial.begin(9600); btSerial.begin(9600); pinMode(PIR_PIN, INPUT); pinMode(LED_PIN, OUTPUT); // 上电自检LED 闪 3 下确认电路和程序正常 for (int i 0; i 3; i) { analogWrite(LED_PIN, 60); delay(200); analogWrite(LED_PIN, 0); delay(200); } btSerial.println(F(SmartLight Ready)); Serial.println(F(SmartLight Ready)); } void loop() { // 读取光敏值 lightLevel analogRead(LDR_PIN); // 读取人体感应只要检测到高电平就刷新最后活动时间 if (digitalRead(PIR_PIN) HIGH) { lastMotionTime millis(); } // 自动模式环境暗 最近有人活动 开灯否则关灯 if (autoMode) { bool darkEnough (lightLevel LIGHT_THRESHOLD); bool someoneHere (millis() - lastMotionTime KEEP_ON_MS); if (darkEnough someoneHere) { setOutput(255); } else { setOutput(0); } } else { // 手动模式完全受控于手机指令 if (manualForceOn) { setOutput(manualBrightness); } else { setOutput(0); } } // 处理手机蓝牙指令 processBluetoothCommand(); // 每秒输出一次调试信息到串口监视器 static unsigned long lastDebug 0; if (millis() - lastDebug 1000) { lastDebug millis(); Serial.print(F(LDR:)); Serial.print(lightLevel); Serial.print(F( PIR:)); Serial.print(digitalRead(PIR_PIN)); Serial.print(F( Mode:)); Serial.println(autoMode ? A : M); } } void processBluetoothCommand() { while (btSerial.available()) { char c btSerial.read(); if (c A || c a) { autoMode true; btSerial.println(F(Auto Mode)); } else if (c M || c m) { autoMode false; manualForceOn true; manualBrightness 255; btSerial.println(F(Manual Mode)); } else if (c O || c o) { autoMode false; manualForceOn true; manualBrightness 255; btSerial.println(F(ON)); } else if (c F || c f) { manualForceOn false; manualBrightness 0; btSerial.println(F(OFF)); } else if (c 0 c 9) { autoMode false; manualForceOn (c ! 0); manualBrightness map(c - 0, 0, 9, 0, 255); btSerial.print(F(Brightness:)); btSerial.println(manualBrightness); } } } void setOutput(int brightness) { if (brightness ! currentBrightness) { currentBrightness brightness; analogWrite(LED_PIN, brightness); } }这段代码我已经在 Uno 和 Nano 上都跑过硬件型号一样复制粘贴即可。唯一需要你根据实际情况修改的大概率是LIGHT_THRESHOLD这个光敏阈值下文会讲怎么标定。3.5 手机连接调试步骤代码烧录完成后打开手机蓝牙搜索附近设备找到名字类似 HC-06 的蓝牙设备配对密码输入 1234 或 0000。然后在应用商店下载一个蓝牙串口助手我用的是 Android 上常见的 “Serial Bluetooth Terminal”iOS 上可以用 “LightBlue” 或者自带测试功能的蓝牙调试 App。打开 App连接 HC-06波特率务必选择 9600。之后界面会变成一个类似串口助手的输入框发送 A、M、O、F 或者数字 0 到 9观察 LED 变化。如果发送后没有反应大概率是接线时把 TX 和 RX 接反了或者没有共地。还有一个非常容易忽略的问题某些手机系统在蓝牙配对成功后会自动占用“音频类”蓝牙通道需要在开发者选项里选用“仅传输文件”或让 HC-06 以 SPP 串口模式工作否则串口数据无法通过。建议把常用的指令做成 App 里的自定义按钮比如“自动模式”“手动开灯”“手动关灯”“亮度30%”“亮度80%”。这样以后用起来就不需要每次敲字符按一下按钮就行。手机端的输入框如果自带“发送新行”选项建议关掉避免发送命令后面带一个换行符\n导致 Arduino 端解析出多余字符。4. 调试过程与常见问题4.1 第一步上电自检与串口观察组装完成后先不要急着盖上外壳通上电看一遍自检流程。如果 LED 连续闪了 3 下说明程序烧录正常、LED 电路正常。如果完全没亮优先检查 LED 的正负极是不是接反以及 D9 引脚上有没有输出 PWM 波形。紧接着打开 Arduino IDE 的串口监视器波特率选 9600。正常情况下每秒会输出一行LDR:xxx PIR:x Mode:A这样的调试信息。先看 LDR 数值白天应该比较高用手遮住光敏电阻再松开数值应该明显变化。再看 PIR 数值在模块面前走动数值应从 0 变 1停止走动后一段时间会恢复 0。如果串口监视器里什么都没有第一件事检查 USB 端口是否选对第二件事确认代码里SoftwareSerial用的引脚没有和 USB 冲突。还有一个小技巧如果 PIR 数值一直为 1 不归零通常不是模块坏了而是模块还没过自检稳定期。等一分钟再看或者断电重启一次。我调试时还遇到过光敏读数一直为 0 或者一直为 1023 的情况这通常是 AO 引脚接错位置或者模块 5V 供电没接好。用万用表量一下模块 VCC 和 GND 之间的电压确认是 5V 左右再检查 AO 线的杜邦线是否插紧。4.2 如何标定光敏阈值LIGHT_THRESHOLD这个参数是整个项目里最需要“因地制宜”的地方。我一开始随意设了 500结果晚上开了台灯之后 LDR 值还在 450 左右灯反而不亮了。后来我把阈值改成 300情况好了很多。我的标定方法是先保持代码不动打开串口监视器记录几个关键场景下的 LDR 值。白天不拉窗帘的时候是多少阴天是多少晚上开灯是多少晚上关灯全黑又是多少。记录 20 组数据后取“白天最低值”和“晚上开灯最高值”的中间偏暗位置作为阈值。比如我实测到的数据白天窗外 600 到 800阴天室内 400 左右晚上开台灯 250 到 350晚上关灯全黑 10 到 30。那我阈值取 300 左右比较合理低于 300 视为暗高于 300 视为亮。如果某些角落光敏数值波动很大可以适当加一点滞回逻辑即在程序里分别设置“亮转暗阈值”和“暗转亮阈值”中间留出缓冲带不过我实际用下来单阈值够用就没有增加复杂度。有几个细节会干扰标定光敏电阻模块附近如果有大功率热源或强红外光也会影响读数湿度大时光敏电阻表面可能结露导致数值漂移。另外手机上蓝牙控制亮度时只是调 PWM不影响环境光所以不会干扰 LDR 判断。4.3 PIR 旋钮调节心得HC-SR501 背板的两个旋钮外观看起来一模一样但作用完全不同。一个标着“灵敏度”或“距离”C负责调节检测距离顺时针旋转可增大感应范围另一个标着“延时”R负责调节输出高电平保持时间。不同批次模块丝印位置可能有差异所以调节前最好查一下你手上模块的说明书。我的建议是先把灵敏度旋钮拧到中间位置延时旋钮拧到最小一般是最左边。然后上电测试人从 3 米外慢慢靠近看模块输出变化。如果太灵敏动不动就误触发就往逆时针方向减小灵敏度。如果人走到很近才感应到就往顺时针方向增大。延时旋钮不要调太大原因前面说过代码里已经用KEEP_ON_MS做了 30 秒保持。如果你把模块延时也调到很大就会出现“人已经走了一分钟灯还亮着”的现象看起来像逻辑错误其实是硬件延时叠加造成的。把这个旋钮拧到最小让模块尽早释放控制权给代码。还有一个我踩过的坑PIR 模块正对空调出风口或暖气片时热气流会让模块误认为“有人”导致灯半夜自己亮。安装时要避免这类热源直射。如果家里有宠物小动物体温也会触发 PIR这只能通过调整安装角度缓解。4.4 常见问题速查表把实际开发中最高频的问题整理成一张表遇到问题可以先来这里查现象可能原因解决办法灯一直亮不灭PIR 灵敏度太高、延时旋钮过大、代码 KEEP_ON_MS 太长减小灵敏度延时旋钮拧到最小按需求缩短 KEEP_ON_MS白天也亮灯LIGHT_THRESHOLD 设置过高、光敏探头被遮挡串口实测 LDR 值重新标定阈值调整探头位置人坐着不动灯灭PIR 只感应红外变化静止人体难以触发调整安装角度让感应区覆盖门口或过道或增加雷达模块手机搜不到 HC-06模块没供电、TX/RX 接反、蓝牙被占用检查 VCC/GND断电重启模块确认配对密码是 1234/0000手机发指令没反应TX/RX 接反、未共地、波特率不一致按引脚表交叉连接确认共地波特率统一 9600上传程序失败板型或端口没选对、D0/D1 被占用拔掉蓝牙模块 RX 线重新选择板型和端口LED 亮度上不去或闪电源电流不足、PWM 驱动能力不够用独立电源供电加 MOS 管或三极管驱动大功率 LED刚上电灯乱闪PIR 处于自检稳定期等待 30-60 秒属于正常现象如果你用的是 HC-05 而不是 HC-06配对密码和默认波特率会不同常见是 38400 或 9600名字更多样。遇到搜不到或连不上时先查你手里模块的具体型号说明书不要盯着 HC-06 的配置死磕。4.5 供电与长期运行建议这个小灯如果只驱动一枚 5mm LED整机电流不到 200mA用 USB 口供电绰绰有余。但如果你想把它做成真正能长期稳定运行的床头夜灯或者衣柜灯有几个供电细节值得注意。第一Arduino Uno/Nano 板载 5V 稳压器能提供的电流有限。Nano 使用 AMS1117 稳压芯片最大输出电流大约 800mA但实际还要扣除主控和各个模块消耗。如果 LED 灯带功率比较大建议给灯带单独接一个 5V 电源Arduino 只负责控制信号LED 的负极接 MOS 管MOS 管栅极接 D9 引脚这样大电流不走主控板。第二蓝牙模块对电压波动比较敏感。如果供电电压低于 3.6VHC-06 可能直接黑屏断电表现为灯正常但手机搜不到蓝牙。遇到这种情况不要怀疑程序先用万用表量模块 VCC 引脚电压。USB 线如果太长或者质量差压降也会导致电压不够换根短线测试往往就好了。第三长期插电使用建议在 5V 电源两端并联一个 100 到 220 微法的电解电容。PIR 模块内部有继电器逻辑触发瞬间电流会有小波动电容能吸收这些波动避免蓝牙模块误重启。电容极性不能接反长脚是正极。一些个人操作体会实际做这个项目时我前后改了三个版本。第一版只做了 PIRLDR没有蓝牙每次调阈值都要拧电位器麻烦到崩溃第二版加上了蓝牙但把模块接到了 D0/D1上传程序时反复失败折腾了很久第三版才改成现在这套 SoftwareSerial 方案稳定下来之后一次性跑了两周没出问题。最后再分享一个调试技巧强烈建议在调逻辑时把KEEP_ON_MS临时改成 5000也就是 5 秒。这样每次测试“人走灯灭”不用等半分钟逻辑确认无误后再改回 30000。我因为没做这一步每次测试都要干等着灯灭浪费了不少时间。如果你也想做这个项目建议先把所有模块放在面包板上测试一周确定无误再焊接成最终成品这样后续改动成本最低。
返回列表