1. 项目概述:基于STM32的智能温度监控系统
去年夏天,我在帮朋友解决一个温室大棚的温度监控问题时,发现市面上现成的温控设备要么功能过剩价格昂贵,要么扩展性不足。于是决定用STM32开发一套低成本、可定制的温度报警系统。这个项目最吸引人的地方在于:它不仅能实现基础的温度监测和报警功能,还能通过蓝牙与手机交互,后续还能扩展物联网功能。整套方案硬件成本可以控制在百元以内,特别适合创客、电子爱好者和需要小型温控解决方案的用户。
这个系统主要由STM32单片机、温度传感器、蓝牙模块和报警装置组成。核心功能包括实时温度采集、阈值报警、蓝牙无线通信和数据存储。相比传统温控器,它的优势在于可编程性强——你可以自由修改报警逻辑、数据传输协议,甚至添加云端上传功能。下面我会从硬件选型到软件实现,详细拆解这个项目的每个环节。
2. 硬件设计与选型要点
2.1 主控芯片选择:STM32的型号博弈
STM32F103C8T6(蓝莓派)是我的首选,这款芯片有72MHz主频、64KB Flash和20KB RAM,完全能满足温度监控的需求,价格仅10元左右。它的优势在于:
- 丰富的外设:3个USART(蓝牙、调试、备用各一个)
- 充足的GPIO:驱动传感器和报警装置绰绰有余
- 低功耗特性:支持睡眠模式,适合电池供电场景
如果项目需要更复杂的处理(比如同时运行蓝牙协议栈和TCP/IP协议),可以考虑STM32F407系列。但要注意,F407的封装多为LQFP144,手工焊接难度较大,新手建议选择TSSOP20封装的F103系列。
避坑提示:小心市场上的"翻新片",特别是价格明显低于市场价的STM32。我曾遇到过一批F103,ADC基准电压漂移严重导致温度读数不准。建议通过正规渠道购买。
2.2 温度传感器对比实测
DS18B20和DHT11是最常用的两种方案,我做了组对比测试:
| 型号 | 精度 | 响应时间 | 接口类型 | 价格 | 适用场景 |
|---|---|---|---|---|---|
| DS18B20 | ±0.5℃ | 750ms | 单总线 | 5元 | 高精度测量 |
| DHT11 | ±2℃ | 2s | 单总线 | 3元 | 温湿度同时监测 |
实际使用中发现几个关键点:
- DS18B20的防水版本(探头封装在不锈钢管内)特别适合潮湿环境
- DHT11的湿度测量范围(20-90%RH)有限,不适合极端环境
- 单总线器件要注意上拉电阻(通常4.7KΩ)和线长(建议<20m)
2.3 无线通信模块选型
蓝牙模块的选择取决于具体需求:
- HC-05:经典蓝牙SPP协议,兼容绝大多数手机蓝牙串口APP,传输距离约10米(视环境而定),价格15元左右
- CC2541:BLE4.0低功耗方案,适合需要长时间电池供电的场景,但需要手机端开发专用APP
- ESP32:如果考虑后续扩展WiFi功能,可以直接用ESP32替代STM32+蓝牙方案
我的建议是:如果只是需要手机查看温度和设置阈值,HC-05是最经济的选择。接线时特别注意:
- TXD接STM32的RX引脚(如USART1的PA10)
- RXD接STM32的TX引脚(如USART1的PA9)
- 务必共地,否则会出现通信不稳定
3. 系统软件设计详解
3.1 开发环境搭建
推荐使用STM32CubeIDE(免费) + STM32CubeMX配置工具,这套组合的优势是:
- 图形化配置时钟树和外设,自动生成初始化代码
- 集成HAL库,简化开发流程
- 支持在线调试和性能分析
对于习惯Keil的用户,需要注意:
- 免费版有32KB代码限制,这个项目可能会超出
- 需要单独安装STM32支持包(DFP)
3.2 温度采集关键代码解析
以DS18B20为例,完整的温度读取流程包括:
c复制// 单总线初始化
void DS18B20_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
__HAL_RCC_GPIOx_CLK_ENABLE(); // 启用对应GPIO时钟
GPIO_InitStruct.Pin = GPIO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}
// 读取温度值(带CRC校验)
float DS18B20_ReadTemp() {
uint8_t temp[9];
if (!DS18B20_Start()) return -999; // 启动转换失败
if (!DS18B20_Read(temp, 9)) return -999; // 读取9字节(含CRC)
if (CRC8_Check(temp, 8) != temp[8]) return -998; // CRC校验失败
int16_t raw = (temp[1] << 8) | temp[0];
return raw * 0.0625; // 12位分辨率时每LSB=0.0625℃
}
经验之谈:DS18B20对时序要求严格,在调试时:
- 如果读回-85℃或+85℃,通常是总线复位失败
- 如果读数跳变剧烈,检查电源是否稳定(建议在VDD和GND间加0.1μF电容)
- 长距离传输时,适当降低总线速度(拉长延时)
3.3 蓝牙通信协议设计
推荐使用简单的ASCII协议,便于调试和APP开发,例如:
- 温度上报:
TEMP:25.6\n - 阈值设置:
SET_TH:H:30.0\n(设置高温阈值) - 报警状态:
ALARM:HIGH\n
在STM32端的处理逻辑:
c复制void USART1_IRQHandler() {
static char rx_buf[32];
static uint8_t idx = 0;
if (USART1->SR & USART_SR_RXNE) {
char c = USART1->DR;
if (c == '\n' || idx >= sizeof(rx_buf)-1) {
rx_buf[idx] = '\0';
process_command(rx_buf);
idx = 0;
} else {
rx_buf[idx++] = c;
}
}
}
4. 系统集成与调试技巧
4.1 PCB布局注意事项
-
传感器布局:
- DS18B20远离MCU和其他发热元件
- 如果使用多个传感器,建议采用星型拓扑而非菊花链
- 长距离传输时,总线加120Ω终端电阻
-
蓝牙天线处理:
- HC-05模块的陶瓷天线周围5mm内不要走线或铺铜
- 避免金属外壳完全包裹模块
- 可外接IPEX天线提升信号强度
-
电源滤波:
- 每个数字器件VCC引脚就近放置0.1μF去耦电容
- 模拟部分(如温度传感器)使用LC滤波(10μH+10μF)
4.2 低功耗优化方案
如果使用电池供电,可以通过以下措施延长续航:
- 配置STM32进入STOP模式,RTC定时唤醒(功耗可降至20μA左右)
- 温度采样间隔从1秒延长到30秒(多数温控场景足够)
- 蓝牙模块仅在需要通信时唤醒(HC-05的EN引脚可控)
- 选择低功耗LDO(如HT7333替代AMS1117)
实测数据对比:
| 工作模式 | 平均电流 | 2000mAh电池续航 |
|---|---|---|
| 全速运行 | 45mA | 约44小时 |
| 1秒唤醒一次 | 15mA | 约133小时 |
| 30秒唤醒+STOP | 0.5mA | 约4000小时 |
4.3 手机端交互方案
对于不想开发专用APP的用户,推荐以下方案:
-
蓝牙串口助手APP(如Serial Bluetooth Terminal):
- 直接发送/接收文本指令
- 支持简单的数据日志记录
-
MIT App Inventor:
- 图形化开发安卓APP
- 可设计温度曲线显示界面
- 示例代码块:
code复制当 BluetoothClient1.收到数据 设 temp_text 为 分割文本(BluetoothClient1.最后收到文本,":")的第2项 设 当前温度 为 转换文本为数字(temp_text) 在 Chart1 中添加点 (当前时间, 当前温度)
-
微信小程序+蓝牙网关:
- 通过ESP32作网关转发数据到云平台
- 小程序订阅云端数据
5. 常见问题与解决方案
5.1 温度读数不稳定
现象:温度值上下跳动超过传感器标称精度
排查步骤:
- 检查电源电压(DS18B20要求3.0-5.5V)
- 测量总线波形(正常应有明显的脉冲信号)
- 尝试降低总线速度(增加延时)
- 检查传感器封装是否接触被测介质
典型案例:某温室项目中,温度读数每隔几分钟就跳变10℃以上。最终发现是日光直射导致传感器导线温度升高,改用屏蔽线后问题解决。
5.2 蓝牙连接频繁断开
现象:手机APP显示频繁断开重连
可能原因:
- 电源噪声导致模块复位(示波器观察VCC)
- 天线受屏蔽(金属外壳或PCB铜箔遮挡)
- 波特率不匹配(HC-05默认9600,但STM32可能配置为115200)
解决方案:
c复制// 确保USART配置一致
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
5.3 系统死机或无响应
现象:工作一段时间后停止响应
诊断方法:
- 检查看门狗是否启用(建议添加独立看门狗IWDG)
- 监控堆栈使用情况(避免递归或大局部变量)
- 检查中断优先级配置(蓝牙接收中断不应阻塞系统)
配置示例:
c复制// 初始化独立看门狗(约1秒超时)
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
hiwdg.Init.Reload = 1250; // 32kHz/32*1250≈1s
HAL_IWDG_Init(&hiwdg);
// 主循环中定期喂狗
while (1) {
HAL_IWDG_Refresh(&hiwdg);
// ...其他代码
}
6. 项目扩展与进阶玩法
6.1 多节点组网方案
当需要监控多个区域时,可以考虑:
-
蓝牙Mesh组网:
- 每个节点配置为Mesh节点
- 手机通过网关节点访问整个网络
- 使用Nordic的nRF52系列芯片更佳
-
LoRa远距离传输:
- 适合数公里范围的监控
- 使用SX1276模块+STM32组合
- 注意频段合规性(中国470-510MHz)
-
有线RS485总线:
- 最稳定的工业级方案
- 需要增加MAX485电平转换芯片
- 协议建议采用Modbus RTU
6.2 云端数据可视化
通过ESP8266或SIM800模块上传数据:
-
腾讯云IoT Explorer接入:
- 使用AT指令连接MQTT
- 示例数据点:
json复制{ "temperature": 25.6, "alarm_status": 0 }
-
本地服务器存储:
- 搭建Node-RED处理数据
- Grafana生成可视化看板
- 硬件成本仅需增加一个树莓派
-
微信推送报警:
- 通过Server酱等第三方服务
- 温度超限时发送模板消息
6.3 机械结构设计建议
-
外壳3D打印:
- 壁厚建议≥2mm
- 传感器部分留出通风孔
- 安装孔位匹配标准DIN导轨
-
防水处理:
- 接口处使用硅胶密封圈
- PCB喷涂三防漆
- 按钮/指示灯选用IP67等级
-
散热考虑:
- 高温环境增加散热孔
- 避免阳光直射外壳
- 必要时添加小型散热风扇
这个项目最让我惊喜的是它的扩展潜力——从最初的简单温控器,可以演变成完整的物联网监测系统。最近我在一个农业大棚项目中,就用STM32+LoRa组网实现了16个测温点的远程监控,成本还不到商业系统的三分之一。