智能农业不是噱头

提起智慧农业,很多人第一反应是"又是PPT技术"。但实际上,农业物联网是落地最实在的领域之一。原因很简单:农业生产天然需要环境数据——温湿度、土壤水分、光照、CO2浓度。这些数据靠人工去量不现实,靠传感器自动采集才是唯一方案。

这篇文章拆解一套从传感器到云平台到手机APP的完整方案,不讲概念只讲实现。

整体架构

[传感器节点] --LoRa--> [网关] --4G--> [云平台] --HTTP--> [手机APP/小程序]
    |
[电池供电,户外部署]

为什么用LoRa而不是WiFi或蓝牙?

  • WiFi功耗大,户外没有电源,电池撑不住
  • 蓝牙距离太短,农田面积大
  • LoRa传输距离2-5公里,穿透性好,功耗低,一节电池跑半年

传感器节点设计

硬件清单

器件 型号 价格 用途
MCU STM32L432 8元 低功耗主控
LoRa模组 SX1278 15元 远距离通信
温湿度 SHT30 6元 空气温湿度
土壤水分 电容式传感器 12元 土壤含水量
光照 BH1750 3元 光照强度
电池 18650 3.7V/3000mAh 10元 电源
太阳能板 5V/1W 8元 辅助充电
PCB+外壳 - 15元 -
总计 ~77元

一个节点77元,一亩地放3-5个节点,硬件成本200-400元。

低功耗设计

STM32L432的STOP模式功耗约1.2uA。轮询策略:

  • 每10分钟采集一次传感器数据
  • 采集完成→LoRa发送→进入STOP模式
  • RTC定时唤醒
// 采集和上报流程
void loop() {
    // 1. 唤醒,初始化传感器
    sht30_init();
    soil_sensor_init();
    bh1750_init();
    
    // 2. 采集数据
    float temp = sht30_read_temp();
    float humi = sht30_read_humi();
    float soil = soil_read();
    uint16_t lux = bh1750_read();
    
    // 3. 构建数据包
    uint8_t packet[16];
    pack_data(packet, temp, humi, soil, lux);
    
    // 4. LoRa发送
    lora_send(packet, 16);
    
    // 5. 关闭传感器电源
    sensor_power_off();
    
    // 6. 进入STOP模式,10分钟后唤醒
    HAL_RTCEx_SetWakeUpTimer(&hrtc, 600, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
    
    // 唤醒后重新初始化时钟
    SystemClock_Config();
}

实测功耗:

  • 采集+发送:约40mA,持续2秒
  • STOP模式:1.2uA,持续598秒
  • 平均功耗:(40mA2 + 0.0012mA598) / 600 = 0.134mA

3000mAh电池理论续航:3000 / 0.134 = 22388小时 ≈ 932天

加上太阳能板辅助充电,基本不需要维护。实际部署中考虑温度影响和电池老化,保守估计续航1年以上。

LoRa通信

节点端发送

// lora_node.c
#include "sx1278.h"

#define NODE_ID    0x01
#define GATEWAY_ID 0x00

void lora_send_data(float temp, float humi, float soil, uint16_t lux) {
    uint8_t packet[16];
    
    packet[0] = GATEWAY_ID;  // 目标地址(网关)
    packet[1] = NODE_ID;     // 源地址
    packet[2] = 0x01;        // 数据类型:传感器数据
    
    // 浮点转int16(x100)
    int16_t temp_i = (int16_t)(temp * 100);
    int16_t humi_i = (int16_t)(humi * 100);
    int16_t soil_i = (int16_t)(soil * 100);
    
    memcpy(&packet[3], &temp_i, 2);
    memcpy(&packet[5], &humi_i, 2);
    memcpy(&packet[7], &soil_i, 2);
    memcpy(&packet[9], &lux, 2);
    
    // CRC校验
    uint16_t crc = crc16(packet, 11);
    memcpy(&packet[11], &crc, 2);
    
    SX1278_Send(packet, 13);
}

网关端接收

网关用ESP32 + SX1278,收到LoRa数据后通过4G转发到云平台:

# gateway.py - ESP32 MicroPython
from sx127x import SX1278
import urequests, time

lora = SX1278(spi_id=1, pin_ss=5, pin_dio0=4)
lora.init(freq=433, bw=125, sf=12, cr=8, sync=0x34)

MQTT_TOPIC = "farm/sensor/{}/data"
CLOUD_API = "http://your-server/api/sensor/data"

while True:
    if lora.received():
        packet = lora.read()
        if len(packet) >= 13:
            node_id = packet[1]
            temp = int.from_bytes(packet[3:5], 'little') / 100.0
            humi = int.from_bytes(packet[5:7], 'little') / 100.0
            soil = int.from_bytes(packet[7:9], 'little') / 100.0
            lux = int.from_bytes(packet[9:11], 'little')
            
            # 转发到云平台
            data = {
                "node_id": node_id,
                "temp": temp,
                "humi": humi,
                "soil": soil,
                "lux": lux,
                "ts": int(time.time())
            }
            try:
                urequests.post(CLOUD_API, json=data, timeout=10)
            except:
                # 网络断了,存本地
                cache.append(data)
    
    # 定时补传缓存
    if cache and network_ok:
        for item in cache:
            try:
                urequests.post(CLOUD_API, json=item, timeout=10)
                cache.remove(item)
            except:
                break
    
    time.sleep(0.1)

云平台

云平台用FastBee或ThingsBoard都可以。这里以自建PHP后端为例:

数据接收接口

<?php
// api/sensor/data.php
header('Content-Type: application/json');

$data = json_decode(file_get_contents('php://input'), true);
if (!$data) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid data']);
    exit;
}

// 存入数据库
$pdo = new PDO('mysql:host=localhost;dbname=farm_iot', 'root', 'password');
$stmt = $pdo->prepare("
    INSERT INTO sensor_data (node_id, temperature, humidity, soil_moisture, light, timestamp)
    VALUES (:node_id, :temp, :humi, :soil, :lux, FROM_UNIXTIME(:ts))
");
$stmt->execute($data);

// 检查告警规则
check_alerts($data);

echo json_encode(['status' => 'ok']);

告警规则

function check_alerts($data) {
    // 温度告警
    if ($data['temp'] > 35 || $data['temp'] < 5) {
        send_alert($data['node_id'], '温度异常', $data['temp']);
    }
    
    // 土壤干旱
    if ($data['soil'] < 20) {
        send_alert($data['node_id'], '土壤干旱', $data['soil']);
    }
}

function send_alert($node_id, $type, $value) {
    // 存入告警表
    // 推送微信/短信通知
    $msg = "节点{$node_id} {$type}: {$value}";
    // 调用推送接口...
}

手机端

用微信小程序最省事,不需要下载APP:

// pages/index/index.js
Page({
  data: {
    nodes: []
  },
  
  onLoad() {
    this.loadData()
    setInterval(() => this.loadData(), 30000)
  },
  
  loadData() {
    wx.request({
      url: 'https://your-server/api/sensor/latest',
      success: (res) => {
        this.setData({ nodes: res.data })
      }
    })
  }
})

界面就一个列表,每个节点显示温湿度、土壤水分、光照,颜色标记异常值。30秒刷新一次。

实际部署经验

虎王科技在河北某农场部署的方案:

指标 数值
面积 50亩(蔬菜大棚)
传感器节点 20个
网关 1个(大棚中心位置)
通信距离 最远节点400米
数据完整率 97.5%(2.5%丢包,主要是LoRa干扰)
节点续航 平均8个月(冬季太阳能效率低)
月流量 约30MB(4G网关)
总硬件成本 ~2000元

农民最关心的数据是土壤水分。系统上线后,浇水决策从"凭经验"变成"看数据",用水量减少约20%。

踩坑记录

坑1:LoRa同频干扰

多个节点同时发送会冲突。解决:给每个节点加随机延迟(0-2秒),错开发送时间。

坑2:土壤传感器腐蚀

电容式土壤传感器插在土里,3个月后探头腐蚀。解决:选镀金探头的型号,或者用覆膜式传感器。

坑3:大棚内LoRa信号衰减

蔬菜大棚的金属骨架和塑料膜会削弱LoRa信号。实测穿透2个大棚后信号衰减约10dB。解决:网关放在大棚外面,或者每个大棚放一个中继节点。

总结

智能农业物联网方案的核心链路:传感器→MCU→LoRa→网关→4G→云平台→小程序。每个环节的技术选型都直接影响成本和可靠性。

关键原则:

  • 节点越省电越好(STOP模式+太阳能)
  • 通信越简单越好(LoRa+CRC,不要搞复杂协议)
  • 平台越轻量越好(PHP+MySQL够用,不要过度设计)

虎王科技在农业物联网方向有完整方案和落地经验,欢迎交流合作。


沧州虎王科技,专注物联网软硬件开发、通信设备、嵌入式系统与设备管理平台。

更多推荐