1. 系统概述与设计思路

智慧农业监控系统听起来高大上,但其实就是一个能帮农民伯伯省心省力的好帮手。想象一下,你坐在家里,手机一点就能知道大棚里的温度、湿度、光照够不够,甚至还能远程给作物浇水、通风——这就是我们要做的系统。

我选择STM32作为主控芯片,主要是因为它性价比高、功耗低,还能处理多路传感器数据。ESP8266 WiFi模块负责联网,把数据传到OneNET云平台,让你在任何有网络的地方都能查看大棚情况。传感器方面,用了GY30测光照、SGP30测二氧化碳和TVOC浓度,再加上温湿度和土壤湿度传感器,基本上把作物生长的关键环境参数都覆盖了。

实际做的时候,我发现最麻烦的不是写代码,而是把这么多传感器和模块协调好。比如SGP30和GY30都是I2C设备,地址别冲突;ESP8266联网要稳定,不能动不动掉线。下面我会把这些坑都告诉你,让你少走弯路。

2. 硬件选型与连接细节

2.1 主控芯片:STM32F103C8T6

这块芯片是我用了很多年的老朋友了,48个引脚、128KB Flash、20KB RAM,对于这个项目绰绰有余。关键是它的低功耗特性很出色,适合长期运行在大棚里。

我特意用了内部RC振荡器,省掉了外部晶振,这样既能降低成本,又能进一步降低功耗。实际测试下来,整机待机电流只有1.8mA,用个充电宝都能撑好几天。

2.2 传感器选型与连接

GY30光照传感器:这款传感器直接输出数字信号,不用自己折腾AD转换,精度还能达到1勒克斯。接线时注意,VCC接3.3V,SCL和SDA分别接STM32的PB6和PB7。有个小技巧:ADDR引脚要接地,这样I2C地址才是0x23。

SGP30气体传感器:这个稍微贵点,但能同时测CO2和TVOC,还是很值的。接线和GY30类似,VCC接3.3V,SCL和SDA我接的是PB8和PB9。注意这传感器需要预热15秒才能稳定读数,编程时要加个延时。

温湿度和土壤湿度传感器:我用的是SHT20和YL-69组合。SHT20也是I2C接口,接在PB10和PB11;YL-69是模拟输出,接在PA0,需要用STM32的ADC读取。

所有传感器接好后,最好用热熔胶固定一下接头,大棚里湿度大,容易氧化。

2.3 ESP8266 WiFi模块

我用的ESP-01S模块,才8块钱一个,性价比超高。接线时注意:TX接STM32的PA3(USART2_RX),RX接PA2(USART2_TX)。别忘了给ESP8266单独供电,STM32的3.3V输出带不动它,我外接了个AMS1117稳压模块。

3. 低功耗设计实战

大棚里经常没市电,低功耗特别重要。我做了这些优化:

首先,STM32主频降到16MHz,够用就行。所有没用到的IO口都设为模拟输入模式,这样漏电流最小。

传感器不是一直读数的,我让STM32大部分时间在停止模式(Stop Mode)下睡觉,只有RTC每隔30秒唤醒它一次。实测下来,休眠时整机电流只有0.8mA,比一颗LED指示灯还省电。

ESP8266也很耗电,所以只有在要上传数据时才唤醒它。我的做法是:STM32采集完数据后,给ESP8266的EN脚一个高电平唤醒它,传完数据立即断电。

这样折腾下来,整套系统用2000mAh的锂电池能撑将近一个月,足够应付临时停电了。

4. 传感器数据采集与处理

4.1 GY30光照数据读取

GY30的使用很简单,发送测量命令后等120ms就能读数。但要注意,它有两种模式:一次性和连续。我们用一次性模式就行,更省电。

// 初始化GY30
void GY30_Init(void)
{
    I2C_WriteByte(0x23, 0x01); // 通电
    DelayMs(120);
    I2C_WriteByte(0x23, 0x07); // 连续测量模式
    DelayMs(120);
}

// 读取光照值
uint16_t GY30_ReadLight(void)
{
    uint8_t buffer[2];
    I2C_ReadBytes(0x23, buffer, 2);
    return (buffer[0] << 8) | buffer[1];
}

4.2 SGP30气体传感器读取

SGP30稍微复杂点,需要先初始化,然后每隔1秒读一次数。它还能读取序列号,用来区分多个传感器。

// SGP30初始化
uint8_t SGP30_Init(void)
{
    DelayMs(1000); // 上电延时
    if(I2C_WriteWord(0x58, 0x2003) != 0) // 获取序列号
        return 1;
    DelayMs(10);
    if(I2C_WriteWord(0x58, 0x2008) != 0) // 初始化测量
        return 2;
    return 0;
}

读出的CO2和TVOC值需要换算,SGP30库函数一般都处理好了,直接用它提供的API就行。

4.3 数据处理与滤波

传感器读数会有波动,我用了滑动平均滤波,取10次读数求平均。对于突然的异常值(比如比前后值差30%以上),直接丢弃不用。

温度湿度读数还要做单位换算,SHT20读出的原始值要套用公式转换成实际温湿度:

// SHT20温度转换
float SHT20_ConvertTemp(uint16_t raw)
{
    return -46.85 + 175.72 * (raw / 65536.0);
}

土壤湿度传感器YL-69的读数更简单,就是模拟电压值,湿度越大电压越低。我做了个映射表,把ADC读数转换成湿度百分比。

5. ESP8266与OneNET通信实现

5.1 ESP8266联网配置

ESP8266最麻烦的是AT指令,每次发送都要等回应。我写了几个基础函数:

// 发送AT指令并等待回应
uint8_t ESP8266_SendCmd(char* cmd, char* expect, uint32_t timeout)
{
    USART2_SendString(cmd);
    uint32_t start = GetTickCount();
    while(GetTickCount() - start < timeout) {
        if(USART2_RX_BUF contains expect) {
            return 0; // 成功
        }
    }
    return 1; // 超时
}

联网步骤是:先发AT测试,然后设置模式为STA,连接WiFi,最后启动TCP连接。一定要每个步骤都检查回应,否则失败了都不知道。

5.2 OneNET平台接入

OneNET用EDP协议,虽然比MQTT复杂点,但更省流量。接入流程是:先创建TCP连接,然后发连接包,认证包,最后才能上传数据。

连接包要包含产品ID和设备鉴权信息,这些在OneNET平台上创建设备时都能看到。我建议把这些配置信息写在头文件里,方便修改:

#define PRODUCT_ID "123456"
#define DEVICE_ID "my_device"
#define AUTH_INFO "my_password"

数据上传用JSON格式,OneNET平台能直接解析。我用的模板是这样的:

{
    "datastreams": [
        {
            "id": "temperature",
            "datapoints": [{"value": 25.3}]
        },
        {
            "id": "humidity", 
            "datapoints": [{"value": 60.2}]
        }
    ]
}

5.3 断线重连机制

大棚里网络不稳定,断线重连是必须的。我的做法是:每次上传数据前检查连接状态,如果断了就重新走一遍连接流程。

还加了个看门狗,如果连续3次上传失败,就重启ESP8266模块。虽然粗暴但有效,实际使用中基本没掉过线。

6. OneNET平台应用开发

6.1 数据可视化配置

OneNET最好的地方是拖拽就能做界面。我用了曲线图显示温湿度变化,表盘显示实时数值,按钮用来远程控制。

创建应用时,每个控件要绑定对应的数据流。比如温度曲线图绑定"temperature"数据流,这样数据一来自动更新。

控件属性可以设置颜色、范围、单位,调好了比专业软件还好看。我用了绿色系主题,看起来更"农业"一些。

6.2 报警功能设置

在OneNET上可以设置阈值报警,比如温度超过35度就发邮件通知。我设了这些报警规则:

  • 温度:低于10度或高于35度报警
  • 湿度:低于40%或高于90%报警
  • CO2浓度:低于200ppm或高于2000ppm报警
  • 光照强度:低于2000勒克斯报警

报警信息会推送到手机APP,点击还能直接跳转到控制界面。

6.3 远程控制实现

OneNET支持命令下发,我在平台上做了几个按钮:浇水、通风、补光。点击按钮后,命令通过EDP协议下发给STM32。

STM32收到命令后解析执行,比如收到"pump_on"就启动水泵,同时回复执行结果。这样就能实现远程手动控制。

7. 系统调试与优化

7.1 硬件调试技巧

先调通每个传感器再用代码集成。用逻辑分析仪看I2C波形最靠谱,没有的话也可以用串口打印数据。

ESP8266最容易出问题,建议先用串口调试助手测试AT指令,确定能联网后再集成到代码里。

电源一定要稳定,我在每个模块的电源脚都加了100uF电容,防止互相干扰。

7.2 软件调试方法

先写个测试程序,把所有传感器数据都打印出来,确认读数正常再往云平台传。

OneNET提供了设备模拟器,可以先用它测试数据上传,省得折腾硬件。

对于通信问题,我是在STM32端把要发送的数据也打印出来,和OneNET收到对比,很快就能找到问题。

7.3 功耗优化实战

功耗优化要一步步来。先测整机电流,然后逐个模块优化。

最大的耗电大户是ESP8266,工作电流约80mA。我的优化策略是:采集一次数据就上传,然后立即断电,这样平均电流降到5mA以下。

传感器也要断电,我用MOS管做了电源开关,不测量时彻底断电。

最后STM32本身,所有不用的外设都关闭,进入停止模式前GPIO设为模拟输入。

8. 实际应用与扩展建议

这个系统我已经在自家大棚里用了半年多,确实省心不少。早上起床先看手机,温湿度都正常就不用往大棚跑了。

有几个改进方向值得尝试:一是加个摄像头,偶尔看看作物长势;二是用太阳能供电,彻底解决供电问题;三是增加自动化规则,比如根据土壤湿度自动浇水。

对于想自己做的朋友,建议先从最简单的温湿度监测开始,慢慢增加功能。元器件尽量选常用型号,坏了也好替换。

代码架构要设计好,把传感器驱动、网络通信、业务逻辑分开,这样调试和扩展都方便。最关键是稳定第一,农业应用可经不起天天掉线。

更多推荐