1. 项目背景与核心价值
去年在参与某山区水文监测项目时,我们遇到了一个棘手的问题:传统有线雨量监测设备在复杂地形中布线成本高昂,而纯无线方案又面临传输距离和功耗的平衡难题。这个开源项目正是为解决这类场景而生——它创新性地结合了Lora远距离通信和4G/WiFi数据传输的优势,打造了一套低功耗、高可靠的远程雨量监测方案。
这套系统的核心创新点在于其"双模传输"架构:
- 前端传感器节点采用Lora通信,实现半径3-5公里的数据覆盖
- 中心网关通过WiFi或4G将聚合数据上传至云平台 实测表明,在同等功耗下,这种架构比纯4G方案续航提升5-8倍,比纯Lora方案数据传输效率提高60%
2. 硬件架构深度解析
2.1 传感器节点设计要点
主控采用STM32L072CZ这颗超低功耗MCU,运行频率32MHz时功耗仅36μA/MHz。搭配RA-02型号的Lora模块(工作电流22mA@+20dBm),构成传感器端的核心组件。这里有几个关键设计细节:
电源管理特别设计了双供电回路:
- 主电路由18650锂电池(3400mAh)供电
- RTC时钟单独由CR2032纽扣电池备份
- 实测在每分钟上报1次数据的工况下,续航可达14个月
雨量检测使用翻斗式传感器,每0.2mm降雨量触发一次干簧管信号。我们在代码中做了防抖处理:
#define DEBOUNCE_TIME 50 // 消抖时间(ms) void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static uint32_t last_time = 0; if (HAL_GetTick() - last_time > DEBOUNCE_TIME) { rainfall_count++; last_time = HAL_GetTick(); } }2.2 网关设备关键配置
网关采用ESP32+SIM7600的经典组合,这里分享几个实测有效的优化技巧:
Lora天线选型:
- 推荐使用SMA接口的433MHz弹簧天线
- 安装时天线与金属外壳保持至少5cm间距
- 实测在城区环境下,当天线增益从3dBi提升到5dBi时,通信距离从1.2km增加到2.3km
4G模块配置要点:
# 查看SIM7600信号质量 AT+CSQ # 返回示例:+CSQ: 24,99 # 第一个值>10表示信号可用 # 设置APN(根据运营商调整) AT+CGDCONT=1,"IP","cmnet"3. 软件栈实现细节
3.1 低功耗策略实现
通过以下措施将传感器端平均功耗控制在45μA:
- 采用事件驱动架构,MCU平时处于STOP模式
- Lora模块仅在发送数据时唤醒
- 关键代码实现:
void enter_low_power_mode() { HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后需要重新初始化时钟 SystemClock_Config(); }3.2 数据传输协议设计
自定义的轻量级协议结构如下:
| 偏移量 | 长度 | 说明 |
|---|---|---|
| 0 | 1 | 帧头(0xAA) |
| 1 | 4 | 设备ID |
| 5 | 4 | 时间戳(Unix时间) |
| 9 | 2 | 雨量值(0.1mm精度) |
| 11 | 1 | CRC8校验 |
网关端的协议转换逻辑:
def lora_to_mqtt(raw_data): if len(raw_data) != 12: raise ValueError("Invalid packet length") device_id = int.from_bytes(raw_data[1:5], 'big') timestamp = int.from_bytes(raw_data[5:9], 'big') rainfall = int.from_bytes(raw_data[9:11], 'big') / 10.0 return { "device": f"HYD-{device_id:08X}", "time": datetime.fromtimestamp(timestamp).isoformat(), "value": rainfall }4. 部署实战经验
4.1 现场安装注意事项
传感器安装角度:
- 雨量计必须严格水平安装,使用附带的气泡水平仪校准
- 安装高度建议离地70-120cm,避免地面溅水影响
防雷措施:
- 所有户外线缆必须穿金属管接地
- 电源输入端并联TVS二极管(如SMBJ15CA)
4.2 数据质量校验方法
我们在云端部署了三级数据校验机制:
- 范围校验:单次降雨量>100mm时触发告警
- 突变校验:相邻两次数据差值>10mm时标记异常
- 关联校验:与周边站点数据做横向对比
对应的Prometheus告警规则示例:
groups: - name: rainfall.rules rules: - alert: AbnormalRainfall expr: increase(rainfall_mm[1h]) > 50 for: 10m labels: severity: warning annotations: summary: "Abnormal rainfall detected ({{ $value }}mm/h)"5. 性能优化技巧
5.1 通信距离提升方案
通过实测发现的优化点:
Lora参数组合优化:
- 带宽:125kHz(平衡距离与抗干扰)
- 扩频因子:SF9(山区用SF10)
- 编码率:4/5
天线改进方案:
- 传感器端改用PCB天线+金属反射板
- 网关端使用八木定向天线(增益8dBi)
5.2 功耗优化实测数据
不同工作模式下的电流对比:
| 模式 | 电流消耗 | 续航时间(3400mAh) |
|---|---|---|
| 持续唤醒 | 12mA | 12天 |
| 1分钟间隔 | 0.8mA | 6个月 |
| 深度睡眠+事件触发 | 45μA | 14个月 |
实现深度睡眠的关键配置:
void MX_LPM_Init(void) { __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWREx_EnableUltraLowPower(); HAL_PWREx_EnableFastWakeUp(); }6. 常见问题排查指南
根据30多个部署案例总结的典型问题:
Lora通信不稳定:
- 检查天线阻抗匹配(用VNA测量SWR应<1.5)
- 确认频点与当地无线电管理规定的兼容性
数据包丢失:
# 在网关上用这个脚本检测丢包率 import time from collections import deque packet_window = deque(maxlen=100) def check_packet_loss(new_seq): if len(packet_window) > 0: loss = new_seq - packet_window[-1] - 1 if loss > 0: print(f"Packet loss detected: {loss} packets") packet_window.append(new_seq)电源异常:
- 冬季锂电池容量下降问题:在-20℃环境下容量只剩标称值的60%
- 解决方案:改用耐低温型锂电池(如Li-SOCl2电池)
这个项目最让我惊喜的是它的适应性——通过简单修改传感器类型和协议格式,我们已经成功将其改造成用于水库水位、土壤墒情等不同场景的监测系统。最近正在试验加入太阳能充电模块,有望实现永久续航。对于想复现的朋友,建议先从单节点调试开始,逐步扩展网络规模。