STM32智慧农业项目全流程:从传感器采集到ESP8266+MQTT上云

发布时间:2026/9/29 3:44:46
STM32智慧农业项目全流程:从传感器采集到ESP8266+MQTT上云 每年到了十一二月到次年春天这段时间来问我STM32的智慧农业项目怎么做的人就明显多起来——大部分是物联网专业的学生手里攥着一个毕设选题时间只剩三四个月心里没底。这个题目的好处在于它把嵌入式开发、传感器采集、物联网联网、云端可视化这几件事全串到了一起认真做完一套下来能写进简历的东西远比基于单片机的简易温度计要多。麻烦也在这儿模块一多任何一个环节出问题都能让整个系统趴窝。这篇我按自己经手和帮人调试过的若干版实际情况把基于STM32的智慧农业项目从选型、写代码、联网、踩坑排查一直到学习路线和文档材料结构一条线讲透源码工程也会给出可以直接照着搭的骨架。1. 先想清楚这套系统最终长什么样1.1 智慧农业项目的最小可用闭环很多人一上来就打开淘宝搜智慧农业套件看到几十个传感器就懵了。先把闭环想清楚再谈器件。一个能在答辩现场站得住脚的智慧农业系统本质上是三件事的循环感知—决策—执行。感知是采数据土壤湿度、空气温湿度、光照强度条件允许再加个二氧化碳浓度或者水位。决策是判断土壤湿度低于阈值就浇水温度超过上限就通风或开风扇光照不足就补光。执行是动作继电器吸合带动水泵、风扇、补光灯同时把状态回传给屏幕和云端。这条链子跑通就是最小可用闭环。答辩老师最看重的往往不是你堆了多少传感器而是这个闭环的逻辑是否自洽阈值怎么定的采集多久一次执行之后有没有反馈确认。提示先做加法再做减法。一开始功能列全然后在时间预算里砍到 3 到 4 个采集量 2 个执行动作这个规模刚好能在三周内调通剩下的时间留给联网和文档。1.2 别被智慧两个字吓到拆成三层就好理解把整套系统横向切成三层后面所有工作都能挂到这棵树上脑子就不会乱。层级职责典型器件/技术感知执行层采集物理量、驱动负载土壤湿度、DHT22、BH1750、继电器、水泵主控决策层数据滤波、阈值判断、状态机STM32F103、裸机或FreeRTOS联网应用层数据上云、远程控制、可视化ESP8266/ESP32、MQTT、物联网云平台分层的好处是排故时能快速定位数据不对先怀疑感知层逻辑不对看主控数据上不去查联网层。我见过太多人把三层搅在一起调试最后连到底是传感器坏了还是串口发错了都分不清。1.3 功能清单和取舍原则给一份我在实际项目里常用的目标功能清单你可以按时间和能力打钩必做土壤湿度采集 自动/手动浇水、空气温湿度显示、OLED 本地显示、按键设置阈值。加分光照采集 补光、数据上云 手机端查看、历史曲线、超限报警。炫技时间充裕再碰摄像头、太阳能供电、多节点组网。取舍原则只有一条凡是不能在答辩现场稳定演示三遍的功能一律砍掉。演示翻车一次前面做得再好也会打折扣。2. 主控选型的真相为什么STM32依然是稳妥解2.1 STM32、ESP32、Arduino 三条路线的实测对比这几年 ESP32 很火很多同学纠结要不要直接上 ESP32 省掉联网模块。我的判断是看你的培养方案和答辩侧重。三条路线的差异我列一下维度STM32F103ESP32Arduino UNO主频72MHz240MHz 双核16MHz联网需外挂模块板载 WiFi/蓝牙需外挂模块外设丰富度高多ADC/定时器/USART高低学习曲线较陡中等平缓毕设专业感高中低如果你的专业方向偏嵌入式、课程里讲过 STM32那就用 STM32。它对 GPIO、ADC、定时器、串口这些底层外设的掌控感是毕设答辩里能讲出深度的地方——比如你能说清 ADC 的采样时间怎么设、DMA 怎么搬运数据、定时器中断多久触发一次。这些细节用 Arduino 很难讲出层次。ESP32 适合想省事又要联网的同学但很多老师会觉得它偏应用、不够底层。折中方案是 STM32 主控 ESP8266 联网既有底层可讲又满足物联网属性也是这个选题最主流的组合。2.2 具体型号怎么选C8T6 还是 RCT6型号上别纠结太久给几条实用建议STM32F103C8T6蓝板最便宜、资料最多、够用。64KB Flash、20KB RAM跑这套系统绰绰有余。缺点是引脚少IO 紧张时要规划。STM32F103RCT6 / ZET6引脚多、Flash 大适合要接 LCD 彩屏或多个传感器的情况正点原子/野火的板子多用这个。STM32F407性能强、有 FPU但对这个项目属于杀鸡用牛刀价格和复杂度都上去了不推荐作为首选。一个坑C8T6 的 ADC 通道和某些定时器通道会跟复用引脚冲突如果你的传感器多画板或接线前一定先画一张引脚分配表把每个外设占用的引脚、是否复用冲突列清楚能省掉大量返工。2.3 外设资源够不够动手前先算一笔账以 C8T6 为例假设我们要接土壤湿度ADC1_CH0、DHT22一个普通 GPIO、BH1750I2C1、OLEDI2C1 共用、ESP8266USART2、按键3 个 GPIO、继电器2 个 GPIO。算下来ADC 用 1 路I2C 一组总线挂两个从机没问题USART 占用一组GPIO 用了不到 10 个。资源完全够。真正容易忽略的是定时器你需要一个定时器做周期采样比如 1 秒一次一个定时器给 DHT22 做微秒级延时一个给串口超时判断用。STM32F103 有 4 个通用定时器加 2 个高级定时器够分。但如果同时要 PWM 调光、要输入捕获测频率就得重新规划。动手前把每个定时器干什么写下来比边写边抢要省心得多。3. 传感器与执行器选型从土壤湿度到水泵继电器3.1 土壤湿度传感器电阻式和电容式到底差在哪新手最常见的坑就在这。市面上两种电阻式两根探针那种YL-69便宜但探针是裸露金属通电后会电解腐蚀用几周读数就飘还容易受土壤盐分影响。作为演示用可以长期用不推荐。电容式v1.2 那种表面有阻焊层不直接接触土壤电解质抗腐蚀读数更稳价格贵一点点。做毕设我强烈建议用电容式。接口上有模拟量输出和数字量输出两种。数字量输出DO是靠电位器调阈值的比较器精度差只适合湿/干二值判断。要做连续的湿度百分比必须用模拟量AO接 STM32 的 ADC。这一点很多人踩过接了 DO 口发现只能出 0 和 1还以为是程序问题。标定方法我一般这么做把探针完全插进干燥的土里记一个 ADC 值记为 dry插进浇透水的土里记一个 wet然后线性映射// 假设 dry2800, wet120012位ADC数值越小越湿视具体模块而定 uint8_t soil_percent(uint16_t adc) { int32_t p (int32_t)(2800 - adc) * 100 / (2800 - 1200); if (p 0) p 0; if (p 100) p 100; return (uint8_t)p; }不同批次的模块这两个端点值差很多务必自己实测别抄网上的数。3.2 温湿度传感器的取舍DHT11 便宜但精度低湿度 ±5%、温度 ±2℃DHT22AM2302精度好很多。两者都是单总线时序DHT22 对时序要求更严格。如果你对精度没底、又怕单总线调不通可以考虑 SHT30 或 AHT20走 I2C协议简单稳定性价比现在也很高。DHT 系列最大的问题是时序敏感读的时候要关中断否则一次中断就能把时序打乱返回全 0 或校验错。我一般把读取函数里的中断临时关掉读完再开并对失败做重试连续失败三次再报错不要一失败就报警容易误报。3.3 光照、CO2、水位这些加分项光照BH1750 走 I2C直接出 lux 数值比光敏电阻省事精度也够。CO2MH-Z19 走串口价格偏高做加分项可以注意它需要预热。水位超声波 HC-SR04 测水箱液位记得加温度补偿否则夏天冬天差挺多。这些都不必全上选一到两个和你的应用场景强相关的即可。比如做温室补光光照就是必做做鱼菜共生水位和溶氧才有意义。功能和场景要能对上话答辩时才讲得圆。3.4 执行器继电器、水泵、补光灯执行侧核心是继电器。选型看两点线圈电压5V 最常见和触点容量水泵启动瞬间电流大选 10A 触点更稳。驱动上单片机的 IO 直接驱动继电器线圈是带不动的必须加驱动。常见方案三极管S8050 续流二极管最省成本。光耦隔离模块抗干扰好推荐。ULN2003 这类达林顿阵列一个芯片驱动多路IO 不够时特别香。注意继电器线圈断电瞬间会产生反向电动势续流二极管不能省否则这个尖峰可能直接把三极管甚至单片机 IO 打坏。水泵建议用小功率的直流水泵5V/12V别上 220V 交流水泵——实验室环境里安全风险大答辩老师也不建议。补光用 LED 灯带配合 MOSFET 做 PWM 调光比继电器开关更有智慧农业的味道。3.5 供电最容易被忽视的重灾区一整套系统同时工作时的电流STM32 约 50mAESP8266 峰值能到 300mA继电器吸合约 70mA水泵 12V 那边几百 mA。如果全用 USB 或开发板上的 3.3V 供电水泵一动电压就塌单片机复位。正确做法是分开供电单片机和控制逻辑一路 3.3V/5V水泵和继电器驱动一路两路共地。用一块 12V 电源经 DC-DC 降压给逻辑部分12V 直接给水泵。这个问题我在第 6 节会展开讲因为它是莫名其妙的复位最常见的元凶。4. 代码怎么写才不乱驱动分层与工程结构4.1 目录结构先定下来裸机项目最容易写成一个 main.c 塞八百行。我建议从第一天就按层分目录Project/ ├── Core/ // 启动文件、main.c、中断 ├── Drivers/ │ ├── bsp_gpio.c │ ├── bsp_adc.c │ ├── bsp_usart.c │ ├── bsp_i2c.c │ └── bsp_timer.c ├── Devices/ │ ├── dht22.c │ ├── soil.c │ ├── bh1750.c │ └── oled.c ├── App/ │ ├── app_sensor.c // 采集与滤波 │ ├── app_ctrl.c // 决策与执行 │ └── app_mqtt.c // 联网 └── Middlewares/ └── cJSON/ // 拼 JSON 用这样分的好处Devices层只关心怎么从传感器拿数App层只关心拿到数做什么。换传感器只改 Devices不动逻辑改策略只动 App不动底层。4.2 驱动层用 HAL 还是寄存器HAL 库开发快CubeMX 生成一堆初始化代码适合赶时间的中等项目寄存器版更能体现功底但调试慢。我的建议是主控初始化用 CubeMX 生成 HAL关键外设比如 ADC 采样、串口中断、DHT 时序直接操作寄存器或写裸机函数这样既不慢又能在答辩里讲出底层细节。比如读取 DHT22 这种微秒级时序用 HAL 的HAL_Delay根本不行得自己写基于DWT或SysTick的微秒延时// 基于 DWT 的微秒延时Cortex-M3/M4 可用 void delay_us(uint32_t us) { uint32_t start DWT-CYCCNT; uint32_t ticks us * (SystemCoreClock / 1000000); while ((DWT-CYCCNT - start) ticks); }用 DWT 之前别忘了在初始化里使能先开DEMCR的 TRCENA再清DWT-CYCCNT最后置CTRL的 CYCCNTENA。4.3 定时器与任务调度别用 delay 卡死新手最爱在 main 循环里一堆HAL_Delay(1000)结果按键不灵、串口收不全。正确做法是用一个 1ms 的 SysTick 或定时器中断做一个软件时基主循环里比较时间戳触发任务static uint32_t last_sensor 0; void loop(void) { if (tick_now() - last_sensor 1000) { last_sensor tick_now(); app_sensor_poll(); // 每秒采一次 } app_ctrl_poll(); // 高频轮询做按键和状态机 app_mqtt_poll(); // 处理串口收发 }这套时间片轮询结构简单、够用还能为后面上 FreeRTOS 打基础。真要上 RTOS把每个 poll 变成一个任务配上互斥锁就行。4.4 ADC 采样一定要做滤波土壤湿度、光敏这类模拟量单次采样抖得厉害。我一般采 8 到 16 次去极值再求平均uint16_t adc_filter(uint8_t ch, uint8_t times) { uint32_t sum 0; uint16_t min 0xFFFF, max 0; for (uint8_t i 0; i times; i) { uint16_t v adc_read(ch); if (v min) min v; if (v max) max v; sum v; } sum sum - min - max; // 去掉一个最大一个最小 return sum / (times - 2); }如果采样量大用 DMA 定时器触发自动搬运CPU 几乎不参与这个技巧在答辩里很加分。4.5 用状态机管执行逻辑浇水这块别写成if (soil 30) 开泵; if (soil 60) 关泵;这么写容易出现来回抖——湿度在阈值附近反复开关泵。用状态机加滞回就稳了状态进入条件动作退出条件IDLE土壤湿度 ≥ 下限关泵湿度 下限WATERING湿度 下限开泵湿度 上限 或 超时LOCKED连续浇水超时关泵报警手动复位上限、下限之间留一段间隔比如下限 30%、上限 50%就是滞回避免频繁启停。再加一个单次浇水最长 60 秒的超时保护防止传感器故障导致泵一直开着。5. 数据上网STM32 加 ESP8266 接物联网平台5.1 为什么用 AT 指令的 ESP8266STM32 联网主流方案是 ESP8266 模块跑 AT 固件STM32 通过串口发 AT 指令控制它。虽然要解析字符串有点烦但逻辑清晰、调试可见串口助手能直接看指令往来非常适合毕设。ESP8266 一般默认固件就带 MQTT AT 指令集不用自己刷。替代方案是 STM32 自己跑 TCP 移植 MQTT 协议栈工作量大得多不建议在这个时间预算下折腾。5.2 串口通信最容易出的问题STM32 和 ESP8266 之间是串口几个高频坑波特率不匹配ESP8266 默认 115200STM32 也要设 115200别一个 9600 一个 115200。电平ESP8266 是 3.3V 逻辑别接 5V 串口会烧。收发缓冲ESP8266 返回的数据是多帧、不定长的用中断 环形缓冲区接收再在主循环里找关键字符串比如IPD、OK、ERROR别用阻塞式HAL_UART_Receive等固定长度。AT 指令要带回车换行AT\r\n很多人漏了\r\n模块当没收到。5.3 MQTT 的接入核心其实就四步MQTT 是发布/订阅模型接入任何物联网云平台的流程都大同小异配 WiFiATCWMODE1设 STA 模式ATCWJAPssid,pwd连热点。配 MQTT设置客户端 ID、用户名、密码一般平台的三元组连接服务器。订阅控制主题收到下发的指令就解析并执行。定时把你的传感器数据发布到上报主题。云平台一般会给你一个设备三元组ProductKey、DeviceName、DeviceSecret和一对主题上报 topic / 下发 topic。上报的数据用 JSON 拼比如// 用 cJSON 拼一个上报报文 cJSON *root cJSON_CreateObject(); cJSON_AddNumberToObject(root, temp, 25.6); cJSON_AddNumberToObject(root, humi, 48); cJSON_AddNumberToObject(root, soil, 37); cJSON_AddNumberToObject(root, lux, 320); char *payload cJSON_PrintUnformatted(root); mqtt_publish(TOPIC_REPORT, payload); cJSON_Delete(root); free(payload);云端配好数据解析脚本就能在手机或网页上看曲线、下发开关指令。5.4 断网重连必须做否则演示必挂实验室的网络说断就断。你的程序必须能检测连接状态并自动重连思路是每次上报前判断mqtt_connected标志。断线时按指数退避重连1 秒、2 秒、4 秒、8 秒……别死循环刷 AT 指令那样模块会被指令淹没。重连成功后重新订阅主题——很多人忘了重订阅结果重连上了收不到控制指令。本地逻辑自动浇水、本地显示要在联网失败时照常工作做到联网是增强不是依赖。答辩现场哪怕没网系统也能演这点极重要。6. 那些让我熬夜的坑完整排查链路6.1 土壤湿度读数乱飘先别急着换传感器现象OLED 上湿度忽高忽低浇水时更明显。我的排查顺序是先看供电再看采样最后看传感器本体。实测发现大半是 ADC 参考电压不稳或采样被干扰。具体做法用万用表量传感器 AO 输出判断是传感器本身飘还是 ADC 采样问题。如果 AO 稳定而 ADC 读数飘问题在采样。检查 ADC 采样时间太长容易被干扰太短采不准先设 55.5 个周期试试。加去极值滤波见 4.4。最后才换电容式传感器。这个顺序能避免你一上来就买新传感器结果发现白花钱。6.2 水泵一开水就复位元凶是共地供电现象手动开泵单片机立刻重启屏幕上电复位。试过换电源、加电容都没根治。根因泵和单片机共用了同一路 5V泵启动瞬间电流冲击把电压拉到 4V 以下触发 BOR掉电复位。解决办法就一句话——动力电和控制电分开两路共地。12V 给泵经 DC-DC 降到 5V/3.3V 给逻辑再在逻辑电源入口并一个 100uF 电解加一个 0.1uF 陶瓷电容。改完再没复位过。6.3 串口打印乱码往往是时钟没配Keil 里看到全是乱码第一个怀疑波特率但波特率没错。这时候去看系统时钟树CubeMX 里如果外部晶振设成了 HSE 但板上没焊晶振或者焊的是 8M 你写成了 12M主频就是错的所有基于主频的波特率自然全错。检查SystemCoreClock的实际值是不是你以为的那个数。6.4 程序跑飞、进 HardFault抓住这三点跑飞往往是数组越界、指针空引用、或者栈溢出。首先查数组边界尤其是接收缓冲区下标。查printf到串口的重定向如果没关半主机模式会卡死。用 Keil 的Call Stack Locals窗口看死在哪配合 HardFault 处理函数里打印LR、PC值定位。一个习惯把所有可能越界的拷贝换成带长度检查的版本宁可慢一点也别让程序飞。7. 从零到毕设学习路线和时间倒推7.1 给零基础同学的一条线如果你之前只学过 C 语言没碰过单片机按这个顺序走阶段内容建议时间1GPIO 点灯、按键、流水灯3~5 天2串口收发、printf 重定向3 天3定时器中断、PWM4 天4ADC 采集3 天5I2C 驱动 OLED、读传感器5 天6单总线 DHT22 时序4 天7ESP8266 AT 指令联网5 天8MQTT 接入云平台5 天9整体联调、外壳、文档7 天加起来大约一个半月到两个月。别跳步前四步是所有后续的基础。7.2 有基础的同学直接进项目如果玩过 51 或者 Arduino可以直接从第 5 阶段切入前面用两三天复习 HAL 库就够。重点把时间花在联网和整体联调上这两块最容易卡壳。7.3 文档材料怎么组织答辩才有料很多人代码调通了文档却写不出来。我一般按这几块组织材料原理图 接线表每个引脚接什么一张表说清。系统框图 程序流程图三层结构画出来。通信协议说明上报 JSON 字段含义、下发指令格式。测试记录阈值测试、浇水响应时间、联网成功率用数据说话。遇到的问题与解决把第 6 节那些坑整理进去这是最能体现你动手能力的地方。提示答辩 PPT 里放一段实物演示视频比放十张截图都管用。演示前把水泵、传感器都预演三遍。8. 关于配套源码和代码复用的实在建议拿到或整理出一份配套源码之后最忌讳的是照抄不理解。我的用法是先跑通官方例程再逐个模块替换成自己的实现。比如直接烧一份能联网的例程确认硬件没问题然后一个文件一个文件地读把不明白的地方标出来查手册。一个工程能不能复用看三点驱动层是否和硬件解耦换引脚只改一个头文件、协议层是否配置化三元组、主题名集中放宏定义里、是否有 README 说明每个文件的职责。满足这三点这份代码你带到下一个项目里也能接着用。我个人在带的几届学生里发现最后答辩拿高分的那几个都不是功能最多的而是系统最稳、文档最细、能把自己踩的坑讲成故事的那几个。智慧农业这个题目本身不难难的是把采集、决策、执行、联网这条链子磨到不掉链子。把第 6 节那些坑一个个填平你的项目就立住了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询