拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Arduino智能家居安防系统:从超声波测距到舵机联动的完整实践

简介基于Arduino的智能家居安防系统源码包面向计算机类毕业设计、课程作业提供一套可直接运行的前后端结合完整方案解决从硬件数据获取到页面展示的联动问题适合学习嵌入式硬件接入、Web端交互和系统集成的在校学生。该源码包以Vue构建监控界面通过JavaScript完成业务逻辑与Arduino数据请求配合JSON配置、HTML页面和PNG素材构成轻量资源整体仅135KB、共28个文件便于快速下载与二次开发PNG可用于界面图标与展示素材JSON和配置文件则帮助梳理运行参数。压缩包目录结构清晰src下包含components、views、router、requests等模块另有server.js服务端入口、package.json依赖清单和README说明有助于理解前端路由、接口封装以及服务启动等关键流程。已有293人学习下载无论是毕设初期搭建项目骨架还是课程作业中实现报警展示、状态刷新等功能都能从中获得实用参考。1. Arduino 智能家居安防系统从毕设选题到可演示原型半夜阳台传来动静卧室里的人和手机同时收到报警推送——这个基于 Arduino 的智能家居安防系统在毕设答辩现场 10 秒内就能复现。整套代码由 Arduino 下位机、Node.js 中间层和 Vue 管理端三部分组成硬件成本控制在 200 元以内用 USB 线连接电脑即可演示。它不像纯软件毕设那样需要大量数据支撑也不像纯硬件课题那样依赖焊接功底对课程作业和毕业设计来说都是性价比极高的选题。这套方案覆盖了智能家居安防系统设计中最核心的入侵检测、异常报警和远程监控三个环节能直接支撑答辩演示和说明书撰写。2. 系统架构与硬件选型Arduino 主控、传感器与执行器的配合2.1 四层架构决定开发顺序拿到源码包先别急着编译。项目文件里的src/App.vue、server.js、views和components已经暗示了它是「下位机 中间层 前端」的三段式结构。我在做 Arduino 智能家居项目时习惯把整套系统拆成四个层次感知层负责采集环境状态主要是人体红外PIR、超声波测距和火焰传感器决策层由 Arduino 主控板承担读取传感器原始值后按阈值判断是否触发告警执行层包含舵机、蜂鸣器和指示灯响应布防、撤防与报警动作交互层则是 Node.js 中间服务加 Vue 页面把串口数据转换成浏览器里能看的实时曲线和状态卡片。这样拆完以后每一层都可以单独测试。写毕业设计说明书时系统架构图直接照这个分层画答辩老师一看就知道不是临时拼凑的。更重要的是这种分层方式决定了你的开发顺序先打通传感器到 Arduino 的数据链路再调执行器最后做联调每一步都有明确的验证标准。2.2 主控板怎么选Uno 还是 Nano网上大量教程默认的板型是 Arduino Uno R3这个选择在毕设场景下是合理的。Uno 引脚完整、自带 USB 转串口芯片插上电脑就能烧录调试Nano 虽然体积小、价格略低但有的版本供电设计比较吃紧。带一个 SG90 舵机加两三个传感器时Uno 的 5V 引脚直接对外供电压力不大Nano 最好额外接电源。我建议毕设首选 Uno理由有三个一是加装传感器扩展板后接线空间充裕答辩现场不容易因为碰到杜邦线导致接触不良二是 5V 输出能力更强舵机瞬态抽流不那么容易把板子复位三是几乎所有仿真平台——包括后面第 5 章要说的 Wokwi——默认都是 Uno 模型代码可以直接搬过去做兜底演示。2.3 传感器与执行器的选型清单模块推荐型号作用成本参考人体红外HC-SR501检测移动人体触发入侵告警8 元超声波HC-SR04测距判断门窗开合作为红外失效的兜底5 元舵机SG90联动模拟锁窗或带动摄像头转动9 元蜂鸣器有源蜂鸣器 5V现场声光报警3 元指示灯LED 220Ω 电阻显示布防/撤防状态忽略火焰传感器数字量输出型厨房明火检测判据可选6 元这套选型正好覆盖了「arduino 超声波」「arduino 控制舵机」这两类高频检索场景。HC-SR501 负责第一层入侵判断HC-SR04 负责第二层距离验证火焰传感器作为可选的第三路输入组合起来就是一个完整的安防逻辑链条而不是单点报警。2.4 引脚分配先画表再接线我见过太多同学代码写好了接线却乱成一团最后对照原理图查半天。正确做法是先把引脚分配表定下来代码里用宏定义引用而不是到处裸写数字。功能模块Arduino 引脚说明PIR 输出D2数字输入HIGH 表示有人超声波 TrigD9输出触发脉冲超声波 EchoD10输入回波脉宽舵机信号D5PWM 输出有源蜂鸣器D7数字输出布防 LEDD13板载 LED 即可火焰传感器D3低电平触发这样分配的核心理由是避开 D0/D1 串口引脚同时把 PIR 这类中断敏感型输入放在支持外部中断的 D2 上方便后续扩展为中断触发模式。超声波模块放 D9/D10因为这两个引脚挨着接线时不会交叉绕线。舵机用 D5是因为 SG90 对 PWM 频率要求宽松Arduino 默认的 490Hz 完全够用。3. Arduino 端逻辑实现PIR 触发、超声波测距与舵机联动3.1 状态机简化安防逻辑下位机程序不建议一上来就上 RTOS 或复杂框架一个大循环加枚举状态就能把安防逻辑讲清楚而且答辩时容易解释。我定义四个状态DISARMED撤防、ARMED布防、TRIGGERED可疑触发、ALERT报警。enum SystemState { DISARMED, ARMED, TRIGGERED, ALERT }; SystemState state DISARMED;主循环里每个周期都检查 PIR 输入只要处于布防态且检测到人体就进入TRIGGERED此时连续三帧超声波距离小于 20cm或者火焰传感器输出低电平就升级为ALERT执行舵机闭锁和蜂鸣器报警。撤防只接受来自串口的指令Web 端下发{cmd:disarm}即可回到DISARMED。这样状态转换关系画在一页 PPT 上就能说清楚代码里不会出现七八层if嵌套。3.2 PIR 消抖与超声波中位值滤波3.2.1 PIR 三次采样消抖HC-SR501 上电后有 30 秒左右的稳定期之后输出逻辑其实很简单难点在消抖。默认输出高电平时长由背面电位器控制最长可能达到 10 秒窗帘被风吹动都可能误报。常见做法是连续采样三次间隔 50ms三读全为 HIGH 才认为有人进入。const int pirPin 2; const int pirSampleInterval 50; bool readPirStable() { int highCount 0; for (int i 0; i 3; i) { if (digitalRead(pirPin) HIGH) highCount; delay(pirSampleInterval); } return highCount 3; }这段代码的逻辑是「三次采样取多数」比单次读取可靠得多。50ms 的间隔不会漏掉有效信号因为 SR501 的最小高电平保持时间也在秒级。如果传感器安装在高人流区域可以把采样次数提高到 5 次或者把灵敏度电位器逆时针调低一档。3.2.2 HC-SR04 手写测距与中位值滤波超声波模块在热词里被反复提及这里我不用NewPing库直接写时序好处是你能在答辩时准确说出「中位值滤波如何消除飞点」。const int trigPin 9; const int echoPin 10; float readDistanceCm() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration pulseIn(echoPin, HIGH, 30000UL); return duration * 0.017; // 声速 340m/s → (340/2) mm/ms 换算 } float filteredDistance() { float readings[3] {0, 0, 0}; for (int i 0; i 3; i) { readings[i] readDistanceCm(); delay(30); } // 冒泡排序取中位 for (int i 0; i 2; i) { for (int j i 1; j 3; j) { if (readings[j] readings[i]) { float tmp readings[i]; readings[i] readings[j]; readings[j] tmp; } } } return readings[1]; }pulseIn的第三个参数 30000 是超时上限单位微秒对应最大检测距离约 5 米。返回值乘以 0.017 是因为距离 声速 × 时长 / 2340m/s 除以 2 再换算到厘米就是每微秒约 0.017cm。30ms的采样间隔是为了避免超声波余振干扰下一帧数据。中位值滤波能有效剔除超声波的毛刺飞点比算术平均更抗异常值。3.3 舵机联动锁窗与复位系统进入ALERT时舵机需要转动到指定角度模拟锁窗动作。SG90 的 PWM 周期是 20ms0.5ms 脉冲对应 0 度2.5ms 对应 180 度Servo库封装了角度到占空比的换算。#include Servo.h Servo lockServo; const int servoPin 5; const int unlockAngle 10; const int lockAngle 120; void setup() { lockServo.attach(servoPin); lockServo.write(unlockAngle); } void lockWindow() { for (int angle unlockAngle; angle lockAngle; angle 2) { lockServo.write(angle); delay(15); } }这里write传入的是角度库内部自动换算成 PWM 占空比。循环里每次加 2 度、延时 15ms是为了让舵机平滑转动。如果直接一步跳到 120 度SG90 启动瞬间电流过大可能导致 Arduino 复位。这也是热词里「arduino 在 5v 端口接电容」的典型应用场景——舵机电源和主板共用时在 5V 与 GND 之间加一个 470uF 电解电容能有效吸收瞬态电流。3.4 串口 JSON 上抛Arduino 端每隔 500ms 向串口输出一行 JSON便于 Node.js 端按行解析。我使用ArduinoJson库字段包括距离、PIR 状态、系统状态和火焰检测值。#include ArduinoJson.h void publishState() { StaticJsonDocument256 doc; doc[distance] filteredDistance(); doc[pir] digitalRead(pirPin); doc[state] (int)state; doc[flame] digitalRead(flamePin); serializeJson(doc, Serial); Serial.println(); }StaticJsonDocument256预分配 256 字节内存足够容纳这四个字段。serializeJson后紧跟一个换行符是为了让接收端用 ReadlineParser 按行拆分。测试时你可以先打开串口监视器确认输出格式但联调时必须关掉否则 COM 口被占用server.js无法打开。提示串口波特率统一设置为 9600Arduino 端Serial.begin(9600)与 Node.js 端baudRate: 9600必须严格一致。4. Web 端与串口通信Vue Node.js 实现远程监控与告警4.1 server.js 中间层架构server.js是整个系统的桥梁承担串口数据读取、指令下发和前端推送三件事。我常用的技术栈是serialport读串口、socket.io做 WebSocket 推送外加express提供 REST 接口。核心代码不长却解决了最关键的实时性问题。const { SerialPort } require(serialport); const { ReadlineParser } require(serialport/parser-readline); const express require(express); const http require(http); const { Server } require(socket.io); const app express(); const server http.createServer(app); const io new Server(server, { cors: { origin: * } }); const serialPort new SerialPort({ path: COM3, baudRate: 9600, }); const parser serialPort.pipe(new ReadlineParser({ delimiter: \n })); parser.on(data, (line) { try { const data JSON.parse(line); io.emit(telemetry, data); } catch (e) { // 忽略非 JSON 行 } }); app.post(/api/arm, (req, res) { serialPort.write({cmd:arm}\n); res.json({ ok: true }); }); server.listen(3000, () console.log(listening on 3000));ReadlineParser按换行符把 Arduino 上拋的数据拆成完整 JSON 字符串JSON.parse解析后通过io.emit(telemetry, data)推送给所有已连接的浏览器页面。/api/arm和/api/disarm路由负责写入控制指令这样前端按钮点击后指令通过串口到达 Arduino形成完整闭环。联调时最容易踩的坑是串口号Windows 下通常是COM3或COM4macOS 下则是/dev/tty.usbmodem*。建议启动时先打印可用串口列表再让用户选择而不是硬编码。4.2 Vue 前端组件与实时更新前端目录里的src/views放页面路由src/components放可复用组件src/requests封装 axios 请求。Home.vue作为主页面展示系统状态、距离雷达图和布防/撤防按钮。实时数据通过 socket.io-client 订阅。import { ref, onMounted, onUnmounted } from vue; import { io } from socket.io-client; const socket io(http://localhost:3000); const distance ref(0); const stateText ref(撤防); const stateMap [撤防, 布防, 触发, 报警]; socket.on(telemetry, (data) { distance.value data.distance; stateText.value stateMap[data.state] || 未知; }); onUnmounted(() socket.close());这里用了 Vue 3 组合式 APIref创建响应式变量socket.on订阅后后端每推送一条数据页面上的距离数字和状态文案就自动更新不需要手动刷新。如果源码用的是 Vue 2写法会变成this.socket.on但订阅关系是一致的。毕设答辩时老师问「前后端如何通信」你只需要回答HTTP 负责指令下发WebSocket 负责数据上行二者分工明确。4.3 本地联调顺序与检查点完整的联调顺序我建议按以下步骤走烧录 Arduino 代码打开串口监视器确认 JSON 每 500ms 输出一行关闭串口监视器在项目根目录执行npm install然后node server.js另开终端运行npm run serve启动 Vue 开发服务器浏览器访问页面先用手遮挡 PIR 传感器确认页面状态变为「触发」再按下「布防」按钮观察舵机是否转动到锁定角度。npm install阶段最容易出问题的是serialport原生模块编译失败。我的建议是使用 Node.js 14 到 18 的 LTS 版本避免用刚发布的最新奇数版本如果仍失败可以尝试npm rebuild或者检查 Python 编译环境是否完整。5. 答辩演示与避坑串口占位、供电和仿真兜底5.1 串口被占用是最常见的现场事故答辩现场翻车率最高的场景就是 Arduino IDE 的串口监视器还开着server.js启动时直接报Error: File not found或打不开端口。三个检查点IDE 串口监视器必须关闭拔插 USB 后要重新确认server.js里的path是否变化USB 转串口驱动未安装时端口可能显示为未知设备。我习惯写个小工具在启动时列出所有可用串口至少能快速定位问题。5.2 供电不稳导致舵机抽搐SG90 堵转电流接近 500mAUSB 口供电扛不住时现象是舵机一转Arduino 就复位Web 端看到数据断流。对策是给舵机单独接 5V 2A 电源三线共地信号线接 D5。如果共用电源则在 5V 与 GND 之间接 470uF 电解电容。这个问题在「arduino 在 5v 端口接电容」这类热词里反复出现属于典型的毕设硬件坑。5.3 PIR 误触发调整HC-SR501 背面有两个电位器左边调灵敏度右边调输出延时。在室内演示时把灵敏度调低一档逆时针延时调到最短约 3 秒人站在传感器正前方 2 米处走动触发最稳定。如果仍有误触发把传感器朝地面斜下方安装减少对空调风口或窗外移动物体的误判。5.4 Wokwi 仿真平台兜底演示如果答辩前硬件临时出问题Wokwi 仿真平台可以兜底。它支持 Arduino Uno 在线仿真超声波模块能直接模拟距离变化连 PIR 都可以用按钮等效触发。把 Arduino 代码贴进去虚拟串口配合本地的server.jsWeb 页面依旧能收到实时数据整个演示流程不中断。唯一的坑是 Wokwi 里虚拟串口映射到本机的方式与真实串口不同需要按平台提示选择桥接地址端口参数跟着改就行。这套兜底方案对远程课程作业展示同样适用至少能保证系统逻辑完整呈现。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门