1. 项目背景与核心价值
去年在参与某农业物联网项目时,发现养殖场氨气浓度监测存在两个痛点:一是传统有线传感器部署成本高,二是WiFi覆盖在户外场景极不稳定。当时用STM32+Lora组网虽然解决了传输问题,但客户又提出需要手机远程查看数据的需求。这个开源的4G_Lora氨气监测方案恰好完美解决了这些问题,特别适合中小型养殖场、温室大棚等场景。
这个教程最硬核的部分在于实现了4G模块与云服务的TCP长连接——相比常见的HTTP轮询方式,TCP长连接既能降低功耗(4G模块不用频繁握手),又能实现实时数据推送(比如氨气超标立即告警)。下面我会结合自己趟过的坑,详细拆解从硬件选型到云端对接的全流程。
2. 硬件选型与组网架构
2.1 核心硬件清单
- 主控芯片:STM32F103C8T6(成本<15元,资源足够跑FreeRTOS)
- 4G模块:移远EC20(支持TCP/IP AT指令,实测待机电流<5mA)
- Lora模块:E22-400T30S(3km传输距离,比SX1276便宜30%)
- 氨气传感器:炜盛科技MQ137(量程5-500ppm,带温度补偿)
注意:EC20要选Mini PCIe封装的版本,比邮票孔版本方便焊接。MQ137传感器需要预热3分钟才能稳定工作。
2.2 组网拓扑设计
[氨气传感器] --(I2C)--> [STM32] --(UART_AT)--> [EC20] | [Lora模块] <--> [中继节点]这种星型+中继的混合组网模式,既保证了监测终端灵活性(Lora无线部署),又通过4G实现了广域接入。我们在猪场实测时,最远的中继节点距离网关1.2km仍能稳定回传。
3. TCP云服务对接实战
3.1 云端环境准备
推荐使用腾讯云物联网开发平台(免费版够用),关键配置步骤:
- 创建产品时选择"自定义品类"
- 数据模板中添加氨气浓度(float)、温度(int)、报警状态(bool)三个属性
- 记录产品ID(ProductID)和设备密钥(DeviceSecret)
3.2 AT指令流详解
EC20模块的完整TCP连接流程(每条指令后必须等待"OK"响应):
AT+QMTCFG="recv/mode",0,1 # 启用异步消息通知 AT+QMTOPEN=0,"iotcloud.tencentdevices.com",1883 # 连接MQTT服务器 AT+QMTCONN=0,"设备名称","ProductID;DeviceSecret" # 设备鉴权踩坑记录:EC20的MQTT指令必须严格按顺序执行,如果先发QMTCONN再发QMTOPEN必定失败。建议每条指令间隔至少500ms。
3.3 数据上传协议设计
采用腾讯云物模型标准格式,通过JSON上报数据:
// 示例:上报氨气浓度值 char payload[] = "{\"method\":\"report\",\"params\":{\"ammonia\":%.1f,\"temp\":%d}}"; sprintf(buf, payload, sensor_value, temperature); AT+QMTPUB=0,0,0,0,"$thing/up/property/ProductID/DeviceName" # 发布消息实测证明:采用QoS0级别(非持久化)时,单条消息传输平均耗时仅120ms,比HTTP短连接快3倍以上。
4. 低功耗优化技巧
4.1 心跳包策略
- 正常模式:每5分钟发送心跳(AT+QMTCONN的keepalive参数)
- 报警模式:心跳间隔缩短至30秒(需修改EC20的CFUN模式)
4.2 数据缓存机制
在STM32开辟环形缓冲区,当4G信号弱时:
- 本地存储最多50条历史数据
- 信号恢复后按时间戳顺序补传
- 添加数据有效性标志位(防止重复上传)
5. 常见问题排查手册
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| AT指令无响应 | 串口波特率不匹配 | 先用115200测试,稳定后切到9600 |
| MQTT频繁断开 | 运营商NAT超时 | 心跳间隔改为240秒以内 |
| 数据上传成功但云端缺失 | JSON格式错误 | 用在线校验工具检查转义字符 |
| Lora节点失联 | 信道冲突 | 修改扩频因子(SF)和带宽(BW) |
6. 实测性能数据
在200头规模的养猪场连续运行30天:
- 平均功耗:8.7mAh/天(2000mAh锂电池可续航7个月)
- 数据传输成功率:99.2%(补传机制生效12次)
- 氨气报警响应延迟:<3秒(从传感器触发到手机APP推送)
这个项目最让我惊喜的是EC20的稳定性——在-10℃~45℃环境下从未出现模块死机。如果要做商业化改进,建议增加NB-IoT备用链路,毕竟有些养殖场4G覆盖确实不理想。