1. 项目概述
这个项目是我去年为一个农业大棚监控需求开发的完整解决方案。客户需要在手机上随时查看大棚内的温湿度、光照强度等数据,并能远程控制通风设备。经过方案对比,最终选择了STM32作为主控、ESP8266负责联网、微信小程序作为用户交互界面的技术路线。
整套系统从硬件选型到软件联调耗时约3个月,期间踩过不少坑,也积累了很多实战经验。现在我把这个项目的完整实现过程整理出来,特别会重点分享那些在官方文档里找不到的实操技巧和避坑指南。
2. 硬件架构设计
2.1 核心器件选型
主控芯片选择STM32F103C8T6主要基于三点考虑:
- 72MHz主频足够处理传感器数据
- 内置的ADC和定时器资源丰富
- 开发社区资源充足,遇到问题容易找到解决方案
ESP8266-12F作为WiFi模块有几个关键优势:
- 支持802.11 b/g/n协议
- 内置TCP/IP协议栈
- 价格仅十几元人民币
- 通过AT指令即可实现网络通信
2.2 传感器选型与接口设计
温湿度传感器选用DHT22而非DHT11,因为:
- 测量精度更高(温度±0.5℃,湿度±2%)
- 量程更宽(-40~80℃)
- 虽然贵3倍但物有所值
光照传感器采用BH1750:
- 数字输出,无需额外ADC
- 0-65535lx宽量程
- I2C接口节省IO资源
所有传感器通过3.3V供电,与STM32电平匹配。特别注意DHT22的数据线需要加上拉电阻(4.7KΩ),实测发现不加会导致数据读取失败。
3. 嵌入式软件开发
3.1 STM32程序架构
采用HAL库开发,主要模块包括:
- 传感器数据采集线程
- ESP8266通信管理线程
- 设备控制执行线程
- 系统状态监测线程
关键点在于合理配置FreeRTOS的任务优先级:
- 通信任务优先级最高(防止数据丢失)
- 控制任务次之(保证响应速度)
- 采集和监测任务优先级最低
3.2 ESP8266固件配置
使用AT固件需要特别注意:
- 上电后等待"ready"提示再发送指令
- 每条AT指令后必须添加"\r\n"
- 建议设置115200波特率(实测稳定性最佳)
网络连接流程优化:
c复制AT+CWMODE=3 // 设置STA+AP模式
AT+CWJAP="SSID","password" // 连接WiFi
AT+CIPSTART="TCP","api.xxx.com",80 // 建立TCP连接
AT+CIPMODE=1 // 开启透传模式
3.3 数据协议设计
采用自定义二进制协议而非JSON,优势在于:
- 数据包更小(平均减少60%流量)
- 解析效率更高(STM32端省去JSON解析开销)
协议格式示例:
code复制[HEAD][LEN][CMD][DATA][CRC]
0xAA 0x06 0x01 ...... 0xXX
CRC校验采用CRC-8算法,关键代码:
c复制uint8_t crc8(const uint8_t *data, uint8_t len) {
uint8_t crc = 0x00;
while(len--) {
crc ^= *data++;
for(uint8_t i=0; i<8; i++)
crc = (crc & 0x80) ? (crc<<1)^0x07 : (crc<<1);
}
return crc;
}
4. 小程序开发实战
4.1 页面布局设计
采用flex布局实现响应式界面:
xml复制<view class="container">
<view class="sensor-card" wx:for="{{sensors}}">
<text>{{item.name}}</text>
<text>{{item.value}}{{item.unit}}</text>
</view>
</view>
样式优化技巧:
css复制.sensor-card {
width: 45%;
margin: 10rpx;
box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
.sensor-card:active {
transform: scale(0.98);
}
4.2 实时数据更新方案
采用WebSocket而非HTTP轮询,优势:
- 实时性更好(延迟<100ms)
- 服务器压力小
- 耗电量更低
关键实现代码:
javascript复制const socket = wx.connectSocket({
url: 'wss://api.xxx.com/ws'
})
socket.onMessage(res => {
const data = decodeProtocol(res.data) // 解析二进制协议
this.setData({
temperature: data.temp,
humidity: data.humi
})
})
4.3 控制指令下发
采用防抖设计避免误操作:
javascript复制let timer = null
function controlDevice(cmd) {
clearTimeout(timer)
timer = setTimeout(() => {
wx.request({
url: 'https://api.xxx.com/control',
data: { command: cmd }
})
}, 300)
}
5. 云端服务搭建
5.1 服务器选型
选择腾讯云基础配置(1核2G)足够支持:
- 同时在线设备数<100台
- 日均请求量<10万次
- 数据存储需求<10GB
5.2 数据库设计
采用MySQL+Redis组合:
- MySQL存储历史数据
- Redis缓存实时数据
表结构设计示例:
sql复制CREATE TABLE sensor_data (
id BIGINT AUTO_INCREMENT,
device_id VARCHAR(32),
temp FLOAT,
humi FLOAT,
lux INT,
created_at TIMESTAMP,
PRIMARY KEY(id)
);
5.3 API接口安全
实现三重防护:
- 设备鉴权(每个设备唯一KEY)
- 请求签名(HMAC-SHA256)
- 频率限制(每分钟最多60次请求)
签名算法示例:
python复制def generate_sign(secret, params):
sorted_params = sorted(params.items())
query_str = '&'.join([f'{k}={v}' for k,v in sorted_params])
return hmac.new(secret.encode(), query_str.encode(), 'sha256').hexdigest()
6. 系统联调与优化
6.1 通信稳定性提升
遇到的典型问题及解决方案:
- WiFi频繁断开 → 启用ESP8266的自动重连功能
- 数据包丢失 → 增加重传机制(最多3次)
- 响应超时 → 调整TCP KeepAlive时间为60秒
6.2 功耗优化技巧
通过以下措施使待机电流从85mA降至12mA:
- 关闭未用外设(ADC、定时器等)
- 传感器采用间歇工作模式(每分钟唤醒一次)
- ESP8266在无数据传输时进入Light Sleep模式
关键配置代码:
c复制// 进入低功耗模式
void enter_low_power() {
HAL_ADC_DeInit(&hadc1);
__HAL_RCC_ADC1_CLK_DISABLE();
HAL_UART_DeInit(&huart2);
WiFi_sleep(LIGHT_SLEEP);
}
6.3 抗干扰设计
采取的多重防护措施:
- 所有信号线加磁珠滤波
- 电源输入端增加TVS二极管
- PCB布局严格区分模拟/数字区域
- 关键信号线做包地处理
7. 生产环境部署经验
7.1 固件批量烧录
开发了自动化烧录工具链:
- 使用ST-Link Commander批量擦除芯片
- 通过OpenOCD脚本自动烧录hex文件
- 自定义校验程序验证烧录结果
7.2 设备管理后台
实现的功能亮点:
- 设备在线状态实时监控
- 远程固件OTA升级
- 数据异常自动告警(邮件/短信)
- 历史数据可视化分析
7.3 现场调试技巧
总结的实用方法:
- 使用逻辑分析仪抓取串口数据
- 通过LED指示灯快速诊断状态
- 准备应急调试接口(SWD+串口)
- 制作便携式测试工装
8. 项目演进方向
这套系统经过半年实际运行后,我规划了以下升级路径:
- 增加LoRa组网实现多棚联动
- 引入机器学习算法预测环境变化
- 开发Android/iOS原生应用
- 支持太阳能供电方案
特别在数据处理方面,下一步准备引入时序数据库(如InfluxDB)替代MySQL,以更好地支持高频数据存储和查询。同时正在测试ESP32-C3作为下一代主控芯片,其内置WiFi/蓝牙的特性可以简化硬件设计。