ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32与ESP8266智慧农业监测与自动灌溉系统实战

STM32与ESP8266智慧农业监测与自动灌溉系统实战 1. 为什么智慧农业毕设我最后选了STM32这条路线1.1 一个真实需求是怎么长出来的去年帮学弟整理毕设的时候他的题目是自己拍脑袋定的大棚环境监测与自动灌溉。听起来平平无奇但真动手才发现这个题目几乎把物联网专业四年学的东西全串起来了——传感器采集、单片机驱动、通信协议、云端存储、上位机展示、控制执行一个都不少。这也是我后来一直推荐这个方向的原因智慧农业是少有的麻雀虽小五脏俱全的选题工作量可控但每个环节都能写出东西来答辩。具体来说这个项目要解决的问题很实在大棚里温度和湿度每天都在变土壤含水量靠人拿手捏判断浇水全凭经验水多了烂根、水少了蔫苗。一套基于STM32的监测加自动灌溉系统要做的就是让土壤湿度、空气温湿度、光照强度这几个指标持续被采回来超过阈值就自动开泵同时把数据传到云平台让手机能看到。这件事的技术含量不算高但链路足够长长到你必须把STM32的GPIO、ADC、定时器、串口、中断全部用一遍。适合谁参考如果你是物联网、电子信息、自动化方向的学生手上有一块STM32开发板、一个面包板、几根杜邦线想找一个既有硬件又有软件、既能在实验室跑通又能写进论文的题目这个方向基本是闭眼入。我在做这个项目前后大概踩了二十多个坑下面把选型、原理、代码、调试全部摊开讲能让你少走至少一半弯路。1.2 STM32还是ESP32一个被问烂但必须回答的问题每次有人问我这个项目用什么主控我都会先反问一句你论文的核心亮点想写什么如果重点是实时控制和硬件驱动选STM32如果重点是联网和数据处理ESP32省事得多。STM32F103C8T6这块片子72MHz主频、64KB Flash、20KB SRAM价格十来块钱资料铺天盖地正点原子、野火、江科大的教程随便挑一套跟着做就行。它的优势在于外设齐全而且原始——你要自己配时钟树、自己写ADC采样、自己处理串口中断这些在答辩时都是可以展开讲的点。缺点是联网要外挂模块常见做法是STM32跑主逻辑ESP8266或ESP32做WiFi透传两者用串口对接。ESP32则是另一种思路双核、自带WiFi和蓝牙、支持FreeRTOS一个芯片搞定采集和联网开发用Arduino框架几行代码就能连上MQTT。省事但答辩时老师容易问你这个联网部分是不是调库如果你答不出底层分数会吃亏。我的建议是主控用STM32F103联网用ESP8266透传。这样硬件部分你有充分的驱动代码可以写软件部分也不至于全被库函数盖住。下面这张表是我当时选型的对比记录供你参考。对比维度STM32F103C8T6ESP32-S3主频72MHz 单核240MHz 双核联网能力需外挂模块内置WiFi/BT开发门槛中等需懂寄存器/库较低Arduino快答辩可讲点多外设驱动全靠自己少库偏多功耗控制精细可做低功耗一般单板成本约10-15元约20-35元提示别为了看起来高级去选STM32H7或F4系列毕设不是堆料F103的资源足够跑完整个农业监控逻辑选贵了反而增加调试成本。2. 系统整体架构与模块拆解2.1 三层架构感知、控制、应用整套系统我按物联网经典的三层来搭画在论文里也好看讲起来逻辑清楚。感知层负责把物理世界的量变成电信号。土壤湿度用电容式传感器空气温湿度用DHT22或者SHT30光照用BH1750数字光照传感器这几样加起来几十块钱覆盖了大棚最关键的环境参数。之所以选电容式土壤湿度而不是老式的电阻式是因为电阻式探头插在土里会电解腐蚀用不了两个月就报废电容式不接触土壤寿命长得多。控制层是STM32的核心工作区。它要做三件事定时采集各个传感器的数据、根据阈值决定是否打开水泵和补光灯、把数据打包通过串口发给WiFi模块。这里的水泵我用的是5V微型潜水泵配继电器模块驱动补光灯用LED灯带加MOS管开关都是低成本的方案。应用层是云平台加手机端。数据通过MQTT协议上报到云服务器手机小程序或者网页端订阅对应主题就能实时看到数值还能远程手动控制水泵开关。整个链路的时延实测在1到3秒之间对于农业场景完全够用。2.2 核心模块清单与采购建议把模块列清楚你在淘宝下单一次就能买齐避免分几次买最后发现少个电阻。这套清单我帮三个学弟配过实测没缺件。模块型号建议数量参考价备注主控板STM32F103C8T6最小系统板112元认准带ST-Link接口的下载器ST-Link V2115元别用串口下载麻烦土壤湿度电容式模拟量输出1-28元认准电容式别买电阻式温湿度DHT22 / SHT30115-25元SHT30精度高I2C接口光照BH175016元I2C接口直接读luxWiFi模块ESP8266-01S110元需要3.3V供电注意电平继电器5V单路光耦隔离1-25元光耦隔离能救命水泵5V微型潜水泵112元记得配硅胶管电源12V/2A适配器 降压模块120元水泵和逻辑分开供电面包板杜邦线-1套15元建议直接焊洞洞板这套配置总价不到150元做毕设绰绰有余。我特别提醒一点水泵启动瞬间电流能到1A以上如果和STM32共用一路电源单片机极可能复位。我第一版就是这么接的水泵一动板子就重启折腾了一晚上才发现是电源问题。后来改成12V适配器单独给水泵再用LM2596降压到5V给逻辑电路问题立刻消失。3. 硬件选型与电路设计的关键细节3.1 最小系统与供电设计的坑STM32F103C8T6的最小系统板上通常已经焊好了8MHz晶振、复位电路和稳压芯片但你得确认它的供电是5V输入还是3.3V输入。市面上的板子大多支持5V输入板载AMS1117-3.3把电压降到3.3V给芯片。这里有个隐藏问题AMS1117的压差大约1.1V输入必须高于4.4V才能稳定输出3.3V如果你用3.7V锂电池直接供电输出电压会掉到2.6V左右单片机可能半死不活。要电池供电就得换低压差稳压器比如ME6211。ESP8266-01S是个吃电大户工作时峰值电流能到300mA而且它对电压特别敏感低于3.0V就开始乱发数据或者直接重启。我最早把它接在最小系统板的3.3V输出上只要WiFi一发数据板子就复位。后来单独用一个AMS1117给它供电并在它的VCC和GND之间并了一个100μF电解电容加一个0.1μF陶瓷电容才彻底稳定下来。// 一个容易被忽略的点ADC参考电压 // STM32F103的VDDA默认接3.3V但实际可能是3.28V或3.35V // 如果你直接用3.3这个理论值算土壤湿度误差会有几个百分点 // 正确做法用内部参考电压通道(VREFINT)校准 #define VREFINT_CAL_ADDR 0x1FFFF7BA // 出厂校准值存放地址 #define VREFINT_DATA_ADDR 0x1FFFF7B8 uint16_t get_vdda_mv(void) { uint16_t vrefint_cal *(uint16_t*)VREFINT_CAL_ADDR; // 先读一次内部参考通道的ADC值再按比例算真实VDDA uint16_t vrefint_data adc_read_channel(ADC_CHANNEL_VREFINT); return (3300UL * vrefint_cal) / vrefint_data; }这段代码是我从ST的参考手册里翻出来的很多人做毕设从来不校准ADC导致土壤湿度读数始终差个10%答辩时被老师一问就露馅。花二十分钟加上这个校准数据立刻就准了。3.2 传感器怎么选才不后悔土壤湿度传感器的选择上我吃过一次大亏。第一版买的是那种带比较器输出的电阻式模块探头是两块裸露的敷铜板插进土里两周后探头表面就开始发黑腐蚀读数从原来的60%一路漂到20%最后完全失效。原因是直流电流通过湿润土壤时发生了电解反应正极那侧被腐蚀掉了。换成电容式之后探头表面有一层阻焊油覆盖不直接接触土壤靠测量介电常数变化来反推含水量寿命长很多。它的输出是模拟电压0到3V左右对应从干到湿。这里要注意电容式传感器的输出范围并不是标准的0-3.3V一般是1.1V全干到2.6V泡水所以你的映射公式不能简单按0-4095来算。// 电容式土壤湿度换算以实测标定为准 // 干燥空气中ADC约1300泡在水里约2600 #define SOIL_DRY_ADC 1300 #define SOIL_WET_ADC 2600 uint8_t soil_moisture_percent(uint16_t adc_val) { if (adc_val SOIL_DRY_ADC) return 0; if (adc_val SOIL_WET_ADC) return 100; return (uint8_t)((uint32_t)(adc_val - SOIL_DRY_ADC) * 100 / (SOIL_WET_ADC - SOIL_DRY_ADC)); }这两个标定值你必须自己实测——把探头放在干燥空气里读一次再插进一杯水里读一次把两个值填进去。每批传感器差异不小照抄别人的参数必然不准。DHT22和SHT30之间我推荐SHT30虽然贵十块钱但它是I2C数字输出不需要像DHT22那样处理微秒级的单总线时序。DHT22的时序对中断特别敏感只要你在读它的过程中被别的中断打断读出来的就是0或者校验失败。我最初用DHT22成功率只有七成后来换了SHT30一次成功。如果你非要用DHT22读的时候一定要关全局中断。3.3 执行机构驱动为什么需要ULN2003A水泵和补光灯都是功率器件STM32的GPIO输出电流最大20mA直接驱动会烧掉引脚。常见的做法有两条路一是用继电器模块二是用MOS管。继电器模块我推荐买带光耦隔离的那种输入侧和输出侧电气完全隔离水泵启动时产生的反向电动势不会串回单片机。市面上便宜的继电器模块省掉了光耦和续流二极管用起来风险很大。如果你自己搭电路一定要在继电器线圈两端反接一个1N4148续流二极管否则线圈断电瞬间的反向高压能把三极管击穿。这里顺便说说ULN2003A这颗芯片。它是一个七路达林顿阵列每路可以吸收500mA电流内部已经集成了续流二极管用来驱动继电器、小电机、步进电机特别方便。当你发现STM32的IO口不够用或者要驱动多个负载时用ULN2003A做一级缓冲是很省事的方案。它的每一路输入直接接STM32的GPIO输出接负载的一端负载另一端接正电源逻辑是反相的——输入高电平输出导通到地。// 用ULN2003A驱动继电器时的简单控制函数 // 注意输出是反相的写1才是拉低输出端导通 void pump_set(uint8_t on) { if (on) { GPIO_ResetBits(GPIOB, GPIO_Pin_0); // 输出低ULN2003导通 } else { GPIO_SetBits(GPIOB, GPIO_Pin_0); // 输出高断开 } }如果你直接用继电器模块它的输入通常是高电平触发逻辑就正好反过来写代码前一定要先确认模块的触发极性别烧了泵才发现逻辑搞反。4. 软件架构与核心代码实现4.1 工程目录与代码分层毕设代码最容易犯的毛病是全部塞在main.c里几百行堆在一起答辩时老师让你改个参数你都找不到在哪。我建议按模块分层每个外设一个文件主循环只负责调度。Project/ ├── CMSIS/ 内核与启动文件 ├── FWLIB/ ST标准外设库 ├── User/ │ ├── main.c 主循环与调度 │ ├── bsp_gpio.c GPIO初始化与继电器控制 │ ├── bsp_adc.c ADC采集与土壤湿度换算 │ ├── bsp_i2c.c I2C底层读写 │ ├── sht30.c 温湿度传感器驱动 │ ├── bh1750.c 光照传感器驱动 │ ├── esp8266.c AT指令封装与MQTT对接 │ ├── oled.c 本地显示 │ └── timer.c 定时器与软件定时 └── Doc/ 论文、原理图、说明这样分层的好处是答辩时你可以顺着调用链讲主循环每2秒调一次采集函数采集函数内部调用各传感器驱动得到数据后进控制决策再调通信函数上报。老师听起来清楚你自己改bug也快。我当时答辩时老师特意夸了这个结构说比很多同学一坨代码强。4.2 GPIO与ADC采集那些事GPIO的使用有几个必须记住的原则。第一每个引脚用之前必须开对应的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)这行不写后面配置全部无效但编译不会报错只会运行时没反应新手最容易在这里卡住。第二ADC采样的引脚必须配成模拟输入GPIO_Mode_AIN配成浮空输入也能读到值但会引入噪声读数跳得厉害。第三输入引脚记得配上下拉悬空的模拟输入引脚会读到随机值。ADC这块STM32F103有12位精度参考电压3.3V理论分辨率是3.3/4096约0.8mV。但实际有效精度受噪声影响通常在10到11位左右。要提高稳定性有两个办法一是多次采样求平均二是开启ADC的采样时间加长。我一般采样16次去掉最大最小各两个再平均读数抖动能从±30降到±5。#define SAMPLE_TIMES 16 uint16_t adc_get_average(uint8_t ch) { uint32_t sum 0; uint16_t val[SAMPLE_TIMES]; for (int i 0; i SAMPLE_TIMES; i) { ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); val[i] ADC_GetConversionValue(ADC1); } // 简单冒泡排序后去掉头尾各两个 for (int i 0; i SAMPLE_TIMES - 1; i) for (int j 0; j SAMPLE_TIMES - 1 - i; j) if (val[j] val[j1]) { uint16_t t val[j]; val[j] val[j1]; val[j1] t; } for (int i 2; i SAMPLE_TIMES - 2; i) sum val[i]; return sum / (SAMPLE_TIMES - 4); }采样时间选239.5个周期是有讲究的。STM32的ADC内部有个采样保持电容如果采样时间太短高阻抗信号源比如土壤湿度传感器的输出来不及给电容充电读出来的值会偏低。土壤湿度传感器输出阻抗在几十千欧量级必须用最长的采样时间。这一点我是在数据老是偏小之后才想明白的。4.3 通信方案AT指令、MQTT和心跳STM32自己不带网络联网全靠ESP8266。两者之间用串口通信STM32发AT指令ESP8266执行后回结果。整个联网流程分四步复位模块、连WiFi、连MQTT服务器、订阅和发布。// ESP8266初始化流程简化版 void esp8266_init(void) { esp_send_cmd(ATRST\r\n, 2000); // 复位 esp_send_cmd(ATCWMODE1\r\n, 500); // Station模式 esp_send_cmd(ATCWJAP\SSID\,\PWD\\r\n, 8000); // 连WiFi esp_send_cmd(ATCIPMUX0\r\n, 500); // 单连接 // 连接MQTT服务器 esp_send_cmd(ATCIPSTART\TCP\,\broker.example.com\,1883\r\n, 5000); // 发送MQTT CONNECT报文十六进制 esp_send_cmd(ATCIPSEND32\r\n, 500); }MQTT协议本身要自己拼报文这是整个项目最有技术含量也最容易出错的部分。CONNECT报文第一个字节固定是0x10后面跟剩余长度、协议名MQTT、协议级别、连接标志、保活时间、客户端ID。PUBLISH报文第一个字节是0x30后面跟主题长度、主题内容、载荷。每拼错一个字节服务器就会直接断开连接而且不告诉你哪里错了。我建议的做法是先用电脑上的MQTT客户端比如MQTTX手动连一遍服务器确认服务器地址、端口、用户名密码都对再回到STM32上拼报文。调试时把ESP8266返回的原始数据全程打印到串口用USB转TTL接到电脑上看能省大量时间。注意载荷里的JSON字符串要转义双引号在AT指令里要用反斜杠转义否则CIPSEND会截断数据。这个坑我第一次写的时候卡了整整一个下午。保活机制是MQTT必须处理的。如果客户端在保活时间内不发任何报文服务器会认为客户端掉线并断开。我设置的保活时间是60秒STM32每隔30秒发一次PINGREQ报文固定两个字节0xC0 0x00服务器回PINGRESP。这个心跳用定时器中断触发千万别放在主循环里靠延时判断否则一次采集卡住就会错过心跳。5. 云端与上位机对接5.1 数据上报与阈值告警数据上报我用的是JSON格式每条消息带时间戳、温度、湿度、土壤湿度、光照四个值发布到类似sensor/data这样的主题。云平台那边配置规则引擎把数据存到数据库或者时序库同时判断是否超阈值超了就触发告警。{ ts: 1716800000, temp: 25.6, humi: 68.2, soil: 35, lux: 4200 }关于云平台的选择我要多说两句。市面上主流云厂商的物联网平台功能都很全但计费方式和免费额度差异很大有的新账号不支持直接购买旧套餐需要改用新版实例。选之前一定先看清楚免费额度和连接数限制毕设阶段用免费额度完全够。如果你不想被平台绑定可以自己在一台云主机上装EMQX或者Mosquitto成本更低数据也完全自己掌控答辩时还能讲一句服务端自建加分不少。告警这块我做了两层。第一层是本地告警STM32判断土壤湿度低于20%就自动开泵这个逻辑不依赖网络断网也能工作。第二层是云端告警数据到云端后判断一次超限给手机推送消息。本地优先是农业场景的基本要求因为大棚经常在信号不好的地方全指望网络会出事。5.2 上位机界面的几种做法上位机我做过三个版本可以按你的能力挑一个。最简单的是串口调试助手加ExcelSTM32通过USB转TTL把数据打到电脑你用串口助手接收并保存成CSV再用Excel画曲线。这个方法五分钟就能出图适合赶进度的同学缺点是实时性差。中间档是Python加PyQt或Flask。Python订阅MQTT主题拿到数据用Matplotlib实时画曲线或者用Flask做一个网页通过WebSocket推送数据到浏览器。这套方案代码量不大一个下午能搞定界面也拿得出手。最完整的是微信小程序或安卓App。小程序用MQTT.js或者WebSocket连接服务器能实时显示数值和曲线还能下发控制指令。做小程序对毕设来说是很好的加分项但要注意小程序的网络请求有域名限制测试阶段可以开启不校验合法域名选项。# Python版数据订阅与实时绘图核心部分 import paho.mqtt.client as mqtt import matplotlib.pyplot as plt from collections import deque temp_data deque(maxlen100) humi_data deque(maxlen100) def on_message(client, userdata, msg): import json d json.loads(msg.payload) temp_data.append(d[temp]) humi_data.append(d[humi]) client mqtt.Client() client.on_message on_message client.connect(broker.example.com, 1883, 60) client.subscribe(sensor/data) client.loop_start()这套代码我在树莓派和电脑上都跑过稳定运行几天不掉线。如果你要做更完整的界面推荐用Flask加ECharts前端页面刷新效果比Matplotlib好看得多。6. 常见问题与排查技巧实录6.1 传感器数据跳变和漂移这是最高频的问题。土壤湿度读数一会儿30%一会儿80%看着像坏了其实多半是三个原因。第一个原因是采样时间不够前面讲过土壤湿度传感器输出阻抗高ADC采样时间必须拉到最长。第二个原因是电源噪声水泵、继电器工作时会在电源线上产生尖峰如果传感器和它们共地读数必然抖。解决办法是给传感器单独走一路电源或者在其输出和地之间并一个0.1μF电容滤波。第三个原因是探头接触不良探头没插稳或者土壤里有空气间隙介电常数测得就不准。做实验时把探头插深一点插到土壤里至少三分之二长度。我在实验室见过一个同学他的湿度数据每隔几秒就跳一次最后发现是面包板上的一根杜邦线松了接触电阻不稳定。这种物理问题靠看代码永远找不到一定要有先查硬件再查软件的意识。6.2 通信断连与数据丢失ESP8266掉线是另一个大坑。表现是运行几小时后突然不发数据了重启又能好。原因通常有三个。一是供电不稳ESP8266发数据时电流突增导致电压跌落模块复位。前面说的独立供电加大电容就是解法。二是WiFi信号弱模块和路由器之间隔了两堵墙信号强度低于-80dBm就容易断。可以用ATCWJAP?查询信号强度或者干脆把路由器挪近点。三是MQTT保活超时心跳没发出去被服务器踢了。这时候要做的是加断线重连机制检测到发送失败或者收到断开提示就重新走一遍连接流程每5秒重试一次。// 简化的重连判断 void mqtt_task(void) { static uint32_t last_heartbeat 0; if (HAL_GetTick() - last_heartbeat 30000) { if (mqtt_ping() ! 0) { // 心跳失败重连 mqtt_disconnect(); delay_ms(1000); mqtt_connect(); } last_heartbeat HAL_GetTick(); } }6.3 常见问题速查表把我在这个项目里遇到并在帮别人时反复看到的问题整理成表出问题时按表排查能省很多时间。现象可能原因排查方法解决单片机反复复位水泵与逻辑共电源单独给水泵供电后观察分离供电加去耦电容ADC读数跳动大采样时间短/参考电压未校准换最长采样时间对比加滤波多次平均土壤湿度始终偏低探头氧化/接触不良用万用表量探头电阻换电容式探头DHT22读数为0读取时被中断打断关闭中断重试换SHT30或关中断ESP8266连不上WiFi3.3V供电不足量模块VCC电压独立LDO供电加电容MQTT连上就来数据断保活时间太短查看断开日志心跳周期设为保活的一半Keil编译报错找不到头文件头文件路径没加打开Options检查Include Paths添加对应文件夹路径ST-Link识别不到芯片驱动或接线问题换USB口、检查SWD接线重装驱动确认SWDIO/SWCLK数据上报延迟高主循环有阻塞延时检查是否有delay_ms改状态机去掉长延时网页/小程序收不到数据主题名不一致对比订阅和发布主题统一主题字符串6.4 几个没人告诉你但很关键的细节第一初始化顺序有讲究。先配时钟再配GPIO再配外设最后才是应用逻辑。如果串口还没初始化就调用了打印函数程序会卡死在等待发送完成那里而且不报错。我见过有人在SystemInit之前就调用printf结果板子上电就不动。第二调试信息一定要留。哪怕最后要删开发阶段每个关键节点都打一行日志。我用OLED加串口双路输出OLED看实时状态串口看详细数据。有一次土壤湿度突然归零正是靠串口打印才定位到是ADC通道配置错了。第三代码里不要留长延时。delay_ms(1000)这种在主循环里出现整个系统的实时性就废了。正确做法是用定时器做软件定时主循环只查标志位。// 用SysTick做非阻塞定时 volatile uint32_t tick_ms 0; void SysTick_Handler(void) { tick_ms; } uint8_t time_elapsed(uint32_t *last, uint32_t interval) { if (tick_ms - *last interval) { *last tick_ms; return 1; } return 0; }7. 毕设文档与答辩准备7.1 论文怎么写才有内容硬件项目最怕论文写不厚。其实这个题目能展开的点非常多选题背景可以写农业现代化的需求方案设计可以写三层架构和选型对比硬件章节可以画系统框图和电路原理图软件章节贴流程图和关键代码测试章节放实测数据表格和曲线图。我建议在论文里重点突出两个地方。一是选型对比的表格和理由比如为什么选STM32不选ESP32、为什么选电容式探头、为什么用MQTT不用HTTP。老师最喜欢问的就是你为什么这么做你能答出对比和取舍说明你真的思考过。二是实测数据把系统连续运行24小时的数据做成曲线标出阈值触发点比任何文字都有说服力。原理图建议用立创EDA或者Altium画别用手绘拍照。系统框图用Visio或者draw.io层次画清楚。附录里放完整代码正文里只贴关键片段。7.2 答辩时最可能被问的问题我把答辩现场听到的问题列几个提前准备好答案。老师问你的系统有什么创新点。直接说我就是照着教程做的会很难看。你可以这样答在本地自动控制的基础上增加了云端远程监控实现了双端冗余控制在数据采集上做了ADC校准和滤波提高了土壤湿度测量精度采用了MQTT协议降低了通信开销相比HTTP轮询更适合低带宽的农业场景。这些都是实打实的工作。老师问如果网络断了怎么办。答本地控制逻辑独立于网络运行土壤湿度低于阈值会自动浇水网络只负责数据展示和远程控制不影响核心功能。这是一个很加分的回答。老师问系统的功耗是多少。如果你没做过低功耗设计如实说用的是12V适配器供电没有做专门的功耗优化但可以提出后续用STOP模式加定时唤醒的改进方向。8. 学习路线与后续扩展方向8.1 从零到跑通的四阶段路线经常有人问我该先学什么。我按自己的经历总结成四阶段每阶段大概一到两周别跳步。阶段一点亮第一颗LED。跟着江科大或正点原子的教程学会用Keil建工程、配置时钟、操作GPIO、用ST-Link下载程序。目标是能控制LED闪烁理解GPIO的推挽、开漏、上拉、下拉这几种模式的区别。这个阶段不要求看懂寄存器能跑通就行。阶段二串口和定时器。把串口通信搞明白能用printf打印调试信息。然后学定时器做定时中断。这两个是后面所有模块的基础串口用于调试和联网定时器用于采样周期和心跳。这个阶段大概要花一周。阶段三ADC和I2C/SPI。学ADC采集模拟量理解分辨率和参考电压。学I2C总线能读SHT30和BH1750。学SPI为后面如果需要接显示屏做准备。这个阶段是硬件能力的核心。阶段四联网和协议。学ESP8266的AT指令理解TCP连接然后学MQTT报文格式。这一步最难建议先在上位机上用Python跑通整个MQTT流程再移植到STM32上。整个过程走完一个完整的毕设项目基本就成型了。8.2 还能往哪些方向扩展如果你做完了基础版本还有时间可以加这些东西让项目更完整。加OLED本地显示实时显示四个参数和继电器状态成本十几块效果立刻不一样。加SD卡存储把数据存成本地文件断网时数据不丢联网后补传。加太阳能加锂电池供电做真正适合野外部署的节点这里就需要仔细算功耗了——STM32在STOP模式下电流大约20μADHT22待机1μA如果每5分钟唤醒采一次数据一块2000mAh电池能撑几个月。加多节点组网用LoRa或WiFi Mesh让几个大棚的节点组网数据汇总到一个网关上报这就涉及到更复杂的通信协议设计。我个人觉得最值得扩展的是低功耗和多节点这两个方向因为它们真正体现了物联网的核心思想——大量分布式的节点、长时间无人值守运行。把这两个做好你的项目就不只是一个课程作业而是一个有实际落地价值的方案。最后分享一个我在整个项目里体会最深的东西这个题目看起来简单真正做起来时间基本花在排查硬件和通信问题上写代码反而占不到三成。所以别指望一次成功把每一次调试当成必须经历的过程串口日志多打、电源多量、模块分开验证问题总会一个一个解决掉。
返回列表