1. 从一个真实需求说起:独居老人监护到底难在哪
我接触过好几个做智能养老方向的项目,大部分最后都卡在同一个地方:不是技术做不出来,而是做出来的东西没人愿意用。摄像头方案老人觉得被监视,穿戴设备老人嫌麻烦不充电,纯传感器方案又经常误报。这个基于STM32的智能独居老人养老环境和监护系统,是我认为在成本和实用性之间平衡得比较合理的一个方案,也是很多电子类专业毕业设计会选的方向。
先说清楚这个项目到底做什么。它的核心逻辑是:用STM32作为主控,采集房间内的环境数据(温湿度、烟雾、光照等)和人体活动状态(通过红外、毫米波或超声波等方式判断老人是否在活动),数据通过无线模块上传到云平台,家属或社区人员通过手机或网页就能看到老人的实时状态。一旦出现异常——比如长时间没有活动、温度过高、检测到烟雾——系统会主动推送告警。
适合谁看这篇内容?如果你是电子、自动化、物联网相关专业的学生,正在做毕业设计或课程设计,这篇可以直接当参考;如果你是刚入行的嵌入式工程师,想找一个完整的STM32+云平台的项目练手,也合适;哪怕你只是家里有独居老人,想自己动手做一个简易监护装置,这里面的选型思路和踩坑经验同样能用上。
我见过太多人一上来就纠结"用哪个云平台""要不要上RTOS",结果硬件还没搭起来就卡了半个月。所以这篇我打算按实际做项目的顺序来讲:先想清楚需求边界,再定硬件方案,然后才是软件和云平台,最后是调试阶段那些让人抓狂的问题。每一步我都会说清楚为什么这么选,以及我当时踩过什么坑。
2. 需求拆解:别急着画原理图,先把这几个问题想明白
2.1 监护系统到底要监测什么,不监测什么
很多人做这个项目的第一反应是"功能越多越好",温湿度、烟雾、跌倒检测、心率、血氧全往上堆。我劝你先冷静。每加一个传感器,就多一路电源、多一份布线、多一个调试变量,最后很可能什么都做了一半。
从实际需求出发,独居老人监护最核心的就三件事:
- 环境安全:温度是否过高或过低、有没有烟雾(火灾隐患)、燃气是否泄漏。这三项直接关系到生命安全,优先级最高。
- 活动状态:老人今天有没有正常活动。如果连续几个小时没有任何活动信号,大概率出了问题。这是"独居"场景最独特的价值点。
- 异常告警:上面任何一项超出阈值,要能及时通知到人。注意是"通知到人",不是"记录在数据库里",这是很多方案的通病。
至于心率、血氧这类生理指标,说实话,用非接触方式测准很难,接触式老人又不愿意戴。我的建议是:毕设或练手项目先把上面三项做扎实,生理监测作为扩展方向提一下就行,别硬做。
2.2 为什么选STM32而不是ESP32或树莓派
这是被问得最多的问题。我直接给结论:如果你要交一份有"嵌入式"含量的作业或作品,STM32更合适;如果你只想快速跑通功能,ESP32更省事。
STM32的优势在于:外设资源丰富(多路ADC、多个定时器、多种通信接口),适合接各种传感器;生态成熟,资料多,遇到问题好查;用标准库或HAL库开发,能体现你对底层寄存器和外设配置的理解,这在答辩或面试时是加分项。缺点是本身不带WiFi,需要外挂无线模块。
ESP32自带WiFi和蓝牙,开发快,但"太方便"反而让很多人说不清楚底层原理。树莓派算力强,但功耗高、成本高,而且严格说它是Linux单板机,不算单片机。
这个项目选STM32,我建议用STM32F103C8T6(也就是常说的"最小系统板")作为入门,资源够用、价格便宜、资料最多。如果要做带屏幕显示的版本,可以上STM32F103ZET6或者F407系列,Flash和RAM更宽裕。
2.3 云平台选型:为什么我最后选了巴法云这类轻量MQTT平台
云平台这块,热词里出现了"stm32 巴法云",说明很多人走的是这条路。我实际对比过几种方案:
| 方案 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| 巴法云等MQTT平台 | 接入简单,有现成APP,免费额度够用 | 功能相对固定,定制性弱 | 毕设、快速验证 |
| 自建MQTT服务器 | 完全可控,数据自己掌握 | 需要服务器和运维,成本高 | 有服务器资源、要求数据私有 |
| 阿里云/腾讯云IoT | 功能全,稳定 | 配置复杂,学习曲线陡 | 商业项目 |
| 直接HTTP上报 | 最简单 | 实时性差,功耗高 | 低频数据采集 |
对于这个项目,我推荐MQTT协议+轻量云平台的组合。MQTT是发布/订阅模型,设备只管往主题(Topic)发消息,手机端订阅对应主题就能收到,天然适合这种"设备上报+远程查看"的场景。而且MQTT报文小,对STM32这种资源有限的设备很友好。
注意:选云平台时一定要确认它支持标准MQTT协议,并且有免费额度。有些平台看着免费,实际限制设备数或消息条数,做项目前先看清楚。
3. 硬件方案:从原理图到元件清单的完整思路
3.1 主控与最小系统:那些容易忽略的细节
STM32最小系统看着简单,但有几个地方新手特别容易翻车。
供电部分:STM32F103的工作电压是2.0V~3.6V,典型3.3V。如果你用5V的USB供电,必须经过LDO稳压到3.3V。热词里出现的"5v转3.3v稳压电路原理图"就是这个环节。常用的芯片是AMS1117-3.3,但要注意它的压差和散热——输入5V输出3.3V时,压差1.7V,如果电流到500mA,功耗就是0.85W,芯片会发烫。所以输入输出都要加滤波电容,一般输入加10uF,输出加10uF和0.1uF。
晶振:外部高速晶振用8MHz,配合内部PLL倍频到72MHz。晶振旁边那两个负载电容(一般20pF左右)不能省,否则可能不起振。我遇到过一块板子死活下载不了程序,查了半天是晶振虚焊。
复位电路:10K上拉电阻加0.1uF电容,再加一个复位按键。这个电路简单但不能省,否则调试时想手动复位都做不到。
BOOT配置:BOOT0和BOOT1引脚决定启动模式。正常运行时BOOT0接低电平(从Flash启动)。如果你要用串口下载程序,需要把BOOT0拉高再上电。很多人第一次用串口下载失败,就是忘了改这个跳线。
下载调试接口:建议引出SWD接口(SWDIO、SWCLK、GND、3.3V四根线),用ST-Link下载调试最方便。热词里"vscode 搭建stm32开发环境及j-link下载环境"说明也有人用J-Link,原理一样,都是SWD协议。
3.2 传感器选型:DHT11够用吗,人体检测用什么
温湿度:DHT11是最常见的选择,便宜、单总线接口、驱动简单。但它的精度一般(温度±2℃,湿度±5%),而且采样频率不能太高(最快1秒一次)。如果要求高一点,可以用DHT22或SHT30。对于养老监护场景,DHT11完全够用,因为你要的是"温度是否异常"这个判断,不是精确测量。
DHT11的接线要注意:数据线需要接一个4.7K~10K的上拉电阻。热词里"dht11原理图嘉立创画图"说明很多人用嘉立创画板,记得把这个上拉电阻画上,我见过有人漏了,数据死活读不出来。
烟雾检测:用MQ-2气体传感器,能检测烟雾、液化气、甲烷等。它的输出是模拟电压,接STM32的ADC引脚。注意MQ-2需要预热,刚上电时读数不准,要等20秒左右稳定。另外它有个可调电位器用来调灵敏度,调试时用打火机的气体(不点火)靠近就能测试。
人体活动检测:这是这个项目的关键。常见方案有三种:
- HC-SR501红外模块:便宜,输出高低电平,检测到人体移动就输出高电平。缺点是只能检测"移动",老人坐着不动就检测不到,而且受环境温度影响大。
- 微波雷达模块:能检测微小动作甚至呼吸,但价格贵一些,调试复杂。
- 超声波模块:热词里"stm32超声波测距"很热,但超声波测距是用来测距离的,用在人体检测上需要额外逻辑判断,不太直接。
我的建议:用红外模块做主要检测,配合"超时未活动"的逻辑判断。具体做法是:红外模块输出接STM32的外部中断或定时器输入捕获,每次检测到活动就刷新一个计时器。如果计时器超过设定时间(比如2小时)没有刷新,就判定为"长时间无活动",触发告警。这个逻辑简单可靠,比追求高精度传感器实用得多。
3.3 无线通信与显示:ESP8266和ILI9341的搭配
无线模块:ESP8266(比如ESP-01S)是最经济的选择,通过AT指令和STM32串口通信,能连WiFi并支持MQTT。接线就四根:VCC、GND、TX、RX。注意ESP8266是3.3V供电,而且瞬时电流可能到300mA,所以电源要能供得上,最好单独加个电容。
热词里"stm32使用ili9341读id是a1a1"说明有人用ILI9341屏幕。这个屏幕是SPI接口的TFT彩屏,240x320分辨率,用来显示温湿度、活动状态、告警信息很直观。读ID返回0xA1A1说明通信正常,如果读出来是0x0000或0xFFFF,一般是接线问题或SPI配置不对。
显示内容设计:屏幕上不用显示太多,我建议分三块:顶部显示当前温湿度和时间,中间显示活动状态(正常/异常),底部显示最近一次告警信息。字体用16x16或24x24就够了,太大占Flash。
3.4 元件清单与成本估算
把上面的选型整理成清单,方便你直接采购:
| 元件 | 型号 | 数量 | 参考单价 | 备注 |
|---|---|---|---|---|
| 主控 | STM32F103C8T6最小系统板 | 1 | 15元 | 核心板 |
| 温湿度 | DHT11 | 1 | 5元 | 含上拉电阻 |
| 烟雾 | MQ-2模块 | 1 | 8元 | 需预热 |
| 人体红外 | HC-SR501 | 1 | 6元 | 可调延时 |
| 无线 | ESP-01S | 1 | 10元 | 需3.3V供电 |
| 显示 | ILI9341 2.4寸 | 1 | 25元 | SPI接口 |
| 稳压 | AMS1117-3.3 | 2 | 1元 | 主控和无线各一路 |
| 蜂鸣器 | 有源蜂鸣器 | 1 | 2元 | 本地告警 |
| 按键 | 轻触按键 | 3 | 0.5元 | 设置用 |
| 其他 | 电阻电容排针等 | - | 10元 | 杂项 |
整套下来大概80~100元,成本控制得不错。如果去掉显示屏,能省25元,但显示功能对调试帮助很大,建议保留。
4. 软件架构:从裸机到云端的完整链路
4.1 主程序框架:为什么我用前后台而不是RTOS
很多人一上来就想上FreeRTOS,觉得"高级"。但对于这个项目,我建议先用前后台架构(主循环+中断),原因有三:一是任务不多,主要就是采集、显示、通信三件事;二是RTOS会增加调试复杂度,任务优先级、栈大小、互斥锁都是坑;三是毕设答辩时,前后台架构你更容易讲清楚每一行代码在干什么。
主循环的结构大概是这样:
int main(void) { HAL_Init(); SystemClock_Config(); // 72MHz MX_GPIO_Init(); MX_USART1_UART_Init(); // 调试串口 MX_USART2_UART_Init(); // ESP8266 MX_ADC1_Init(); // MQ-2 MX_SPI1_Init(); // ILI9341 MX_TIM2_Init(); // 活动检测计时 DHT11_Init(); LCD_Init(); ESP8266_Init(); while (1) { DHT11_Read(&temp, &humi); // 读温湿度 smoke_val = ADC_GetValue(); // 读烟雾 activity_check(); // 检查活动状态 LCD_Refresh(); // 刷新显示 cloud_upload(); // 上传云端 HAL_Delay(1000); // 1秒周期 } }关键点:用定时器中断做活动检测的计时,不要在主循环里用HAL_Delay累加,因为主循环里其他操作会占用时间,导致计时不准。
4.2 DHT11驱动:时序是唯一的难点
DHT11是单总线协议,全靠时序。它的一次通信过程是:主机拉低至少18ms发起始信号,然后释放,DHT11响应拉低80us再拉高80us,之后开始传40位数据(8位湿度整数+8位湿度小数+8位温度整数+8位温度小数+8位校验和)。
难点在于微秒级延时。HAL库的HAL_Delay是毫秒级,不够用。解决办法是用定时器做微秒延时,或者用简单的循环延时(需要根据主频计算)。我一般用定时器,准确且不占用CPU。
// 微秒延时示例(基于72MHz) void delay_us(uint32_t us) { uint32_t start = TIM3->CNT; while ((TIM3->CNT - start) < us); }读数据时,每一位的判定是:先等50us低电平结束,然后看高电平持续多久——26~28us表示0,70us表示1。这个判定窗口比较窄,所以延时函数一定要准。
踩坑提醒:DHT11对时序很敏感,如果读出来全是0或全是1,先检查延时是否准确,再检查上拉电阻是否接好。另外两次读取之间至少间隔1秒,太频繁会读失败。
4.3 ESP8266的AT指令与MQTT接入
ESP8266通过AT指令控制,流程是:复位→设置WiFi模式→连接路由器→连接MQTT服务器→订阅/发布主题。
连接WiFi的AT指令序列:
AT+RST // 复位 AT+CWMODE=1 // Station模式 AT+CWJAP="SSID","密码" // 连接WiFi AT+CIPMUX=0 // 单连接 AT+CIPSTART="TCP","mqtt服务器地址",1883 // 连接MQTT连上MQTT后,需要发送MQTT连接报文。这里有个坑:MQTT报文是二进制格式,不能直接用AT+CIPSEND发字符串。解决办法有两种:一是用AT+CIPSEND发送十六进制数据(需要ESP8266固件支持),二是自己拼装MQTT报文然后按字节发送。
我推荐第二种,虽然麻烦但可控。MQTT的CONNECT报文格式是固定的,你可以提前算好字节,用数组存起来发送。发布消息时,把温湿度数据拼进payload,注意长度字段要算对。
// MQTT CONNECT报文示例(简化) uint8_t mqtt_connect[] = { 0x10, 0x1A, // 固定头 0x00, 0x04, 'M','Q','T','T', // 协议名 0x04, // 协议级别 0x02, // 连接标志 0x00, 0x3C, // 心跳60秒 0x00, 0x06, 'c','l','i','e','n','t', // 客户端ID // ... 用户名密码 };如果觉得手拼报文太麻烦,也可以用现成的MQTT库(比如MQTTClient),但要注意STM32的RAM有限,库不能太大。
4.4 云平台数据流与告警逻辑
数据上传后,云平台那边要配置好主题(Topic)。一般分两个主题:一个用于上报数据(比如device/upload),一个用于下发命令(比如device/cmd)。手机端APP订阅上报主题,就能实时看到数据。
告警逻辑我建议放在STM32端判断,而不是云端。原因很简单:如果网络断了,云端判断就失效了,但本地判断还能触发蜂鸣器告警。具体逻辑:
- 温度超过35℃或低于5℃ → 告警
- 烟雾值超过阈值 → 告警
- 连续2小时无活动 → 告警
告警时,STM32做两件事:一是本地蜂鸣器响,二是通过MQTT发一条告警消息到云端。云端再推送到手机。
经验:告警阈值不要写死在代码里,做成可以通过按键或云端命令修改的变量。因为不同季节、不同老人,合适的阈值不一样。我一开始写死了30℃,结果夏天天天误报。
5. 调试阶段:那些让人抓狂的真实问题
5.1 程序下载失败:从BOOT引脚查到电源
下载失败是新手遇到的第一道坎。我按排查顺序列一下:
- 检查BOOT0:用SWD下载时BOOT0接低电平。如果之前用串口下载改成了高电平,忘了改回来,就会下载失败。
- 检查供电:用ST-Link下载时,如果目标板没独立供电,要确认ST-Link的3.3V能带得动。有些板子功耗大,ST-Link供电不足,需要外接电源。
- 检查SWD接线:SWDIO和SWCLK不能接反,GND必须共地。
- 检查复位:有些板子复位电路有问题,需要手动按复位键再点下载。
- 检查芯片是否被锁:如果之前设置了读保护,需要用ST-Link Utility解锁。
热词里"由于找不到msvcp140.dll无法继续执行代码"是电脑端软件的问题,一般是缺少Visual C++运行库,装一个VC++ Redistributable就行,和STM32本身无关。
5.2 串口乱码:波特率、时钟、编码三重排查
串口打印乱码,按这个顺序查:
- 波特率:两边必须一致,常用115200。如果一边115200一边9600,出来的就是乱码。
- 时钟配置:如果SystemClock配置错了,实际波特率会和设定值不符。比如你以为是72MHz,实际是8MHz,那波特率就差了9倍。
- 编码格式:热词里"stm32 gbk转utf8"就是这个坑。STM32默认发的是GBK编码的中文,如果串口助手用UTF-8显示,中文就是乱码。解决办法是在串口助手里切换编码,或者代码里把中文转成UTF-8再发。
我一般调试时先只发英文和数字,确认通信正常后再处理中文。
5.3 传感器读数异常:从电源和时序入手
DHT11读失败:前面说过,先查延时和上拉电阻。还有一个容易忽略的点——供电电压。DHT11工作电压3.3V~5.5V,如果你用3.3V供电,数据线的高电平也是3.3V,STM32能识别。但如果DHT11用5V供电,数据线高电平是5V,长期可能损坏STM32引脚。所以要么都用3.3V,要么加电平转换。
MQ-2读数漂移:MQ-2是模拟传感器,读数受电源波动影响大。如果ADC读数跳动厉害,可以在电源脚加个大电容(100uF),软件上做滑动平均滤波。
红外模块误触发:HC-SR501对环境温度敏感,夏天容易误触发。可以调它的延时和灵敏度电位器,或者软件上做"连续多次检测到才判定有效"的逻辑。
5.4 云平台连接不稳定:心跳与重连机制
ESP8266连MQTT,最常见的问题是断线后不自动重连。解决办法是加一个心跳检测:每隔一段时间(比如30秒)检查连接状态,如果断了就重新走一遍连接流程。
另外,MQTT本身有Keep Alive机制,CONNECT报文里设置的心跳时间(比如60秒),如果这个时间内没有数据交互,服务器会认为客户端离线。所以要么定期发PING报文,要么保证有数据上报。
// 简单的重连逻辑 if (mqtt_status != CONNECTED) { ESP8266_ConnectWiFi(); MQTT_Connect(); MQTT_Subscribe(); mqtt_status = CONNECTED; }踩坑提醒:重连时不要频繁重试,否则可能被服务器封IP。我一般设置重试间隔5秒,连续失败10次就等1分钟再试。
6. 从能跑到好用:几个提升项目质量的方向
6.1 低功耗设计:让设备能长期稳定运行
如果这个设备要长期放在老人家里,功耗就得考虑。STM32F103在72MHz全速运行时电流大概30~50mA,加上ESP8266(峰值300mA)和传感器,整体功耗不低。
优化思路:让STM32在不需要采集时进入睡眠模式。比如每10秒唤醒一次采集数据,采集完就睡。ESP8266也可以在不发送数据时断开连接或进入休眠。这样平均电流能降到几毫安,用电池也能撑几天。
不过要注意,睡眠模式下定时器和中断的配置会变复杂,调试难度增加。建议先把功能跑通,再考虑低功耗优化。
6.2 数据本地缓存:断网时数据不丢
网络不可能永远稳定。如果断网期间的数据直接丢了,家属看到的就是"数据空白",容易引起恐慌。解决办法是在STM32上加一块EEPROM或Flash,断网时把数据存起来,联网后补传。
STM32F103内部有Flash,可以划出一块区域做数据存储。但要注意Flash擦写次数有限(约1万次),不能频繁写。可以攒够一批数据再写一次。
6.3 开题报告怎么写才不空洞
热词里"c语言大作业开题报告"说明很多人需要写开题。我见过太多开题报告全是"随着社会老龄化加剧……"这种套话。我的建议是:开题报告的核心是"你要解决什么问题"和"你打算怎么解决"。
具体结构可以这样:背景(独居老人监护的现实需求,用数据说话)→ 现有方案的不足(摄像头侵犯隐私、穿戴设备不便)→ 你的方案(STM32+传感器+云平台,低成本、非侵入)→ 技术路线(硬件选型、软件架构、云平台)→ 预期成果(能实现哪些功能)→ 进度安排。
关键是技术路线部分要具体,别写"采用先进的物联网技术"这种空话,要写"采用STM32F103作为主控,通过DHT11采集温湿度,通过MQTT协议上传至云平台"。
6.4 原理图绘制与PCB布局的实用建议
如果你要把这个项目做成PCB(而不是用模块拼接),有几个点要注意:
- 电源分区:数字部分和模拟部分(MQ-2的模拟输出)要分开布局,地线最后单点汇聚,减少干扰。
- 无线模块位置:ESP8266的天线区域要远离金属和电池,否则信号差。最好放在板子边缘,天线朝外。
- 晶振走线:晶振尽量靠近STM32,走线短且包地,减少干扰。
- 丝印标注:每个接口都标清楚引脚定义,调试时能省很多事。
用嘉立创EDA或Altium Designer都行,嘉立创有免费的打板额度,适合学生。
7. 我在这个项目里踩过的几个真实坑
第一个坑是ESP8266供电不足。一开始我用STM32板子上的3.3V给ESP8266供电,结果一发送数据就重启。后来查资料才知道ESP8266发送瞬间电流能到300mA,板载LDO带不动。解决办法是单独用一个AMS1117给ESP8266供电,输入输出都加大电容。
第二个坑是MQTT主题名写错。云平台上的主题名是区分大小写的,我代码里写的是device/upload,平台上配的是Device/Upload,结果数据发出去了但手机端收不到。查了一晚上才发现是大小写问题。所以主题名一定要复制粘贴,别手打。
第三个坑是DHT11和红外模块互相干扰。这两个模块离得太近时,DHT11的时序会受影响,读数偶尔出错。后来我把它们物理隔开,问题就没了。这也提醒我,模块布局不只是电气问题,还有物理干扰。
第四个坑是告警太频繁。一开始阈值设得太敏感,温度波动1℃就告警,结果一天推送几十条,家属直接关掉了通知。后来改成"超过阈值持续5分钟才告警",并且加了告警间隔限制(同一类型告警10分钟内只发一次),体验就好多了。
这些坑,文档里不会写,只有真正动手做才会遇到。但正是这些细节,决定了一个项目是"能演示"还是"能实用"。
最后分享一个调试小技巧:在代码里加一个"调试模式"开关。调试模式下,所有传感器数据、通信状态都通过串口打印出来,方便定位问题;正常模式下只打印关键信息,减少干扰。这个开关用宏定义控制,编译时决定,不占运行资源。我靠这个习惯,省下了大量排查时间。