STM32+K210物联网害虫识别植物养护系统设计与实现 📅 发布时间:2026/8/29 17:31:16 👁 浏览次数: 简介嵌入式系统与边缘AI结合正成为物联网智能设备的重要技术方向。其核心原理是通过多种传感器采集环境数据结合AI视觉算法进行目标识别再由主控芯片完成决策控制最后借助无线通信将数据上云实现远程管理。这种架构在智能农业、智慧城市等领域价值显著能够实现从环境感知到智能决策的闭环提升系统效率与可靠性。以多功能植物养护系统为例STM32作为主控负责土壤湿度、光照等数据的采集与自动灌溉控制K210作为边缘AI协处理器运行害虫识别模型并通过MQTT协议将状态上传到云端实现手机远程监控与手动控制。围绕硬件选型、STM32与K210通信协议、模型训练部署以及物联网联调过程系统总结了常见踩坑问题与解决方案。 如果你正在准备嵌入式方向的毕业设计而且题目里同时出现了stm32、物联网、K210、害虫识别这几个词那你大概率要做的是一套“传感器采集 自动控制 AI视觉 远程监控”全拉满的全栈项目。这套多功能植物养护系统说白了就是给花盆或者小菜园配一个单片机大脑接上土壤湿度、光照、温湿度传感器再挂一个K210摄像头做害虫识别最后把数据送上云端用手机或者网页远程看状态、手动浇水。我接下来按自己做这类项目的顺序把方案选型、硬件连接、软件实现和联调踩坑一并说清楚尤其是stm32和K210之间怎么配合、通信怎么设计这是很多人卡住的地方。这套项目特别适合单片机方向、物联网方向、嵌入式AI方向的毕设选题因为它把“传统控制”和“边缘AI”揉在了一起技术栈完整演示效果好。而且和单纯做个智能浇花器不同加了害虫识别之后系统不是只按湿度阈值干活而是真的“看见”植物状态答辩时讲起来也更有层次。1. 项目整体定位与核心思路1.1 这个系统到底要解决什么问题很多人一看到“植物养护”就以为是自动浇水其实这个题目里的核心不是浇水本身而是“养护决策”。植物生长过程中最常见的两个问题一个是土壤水分不够、光照不足这可能直接导致枯萎另一个是病虫害这才是真正难处理的点。传统传感器只能感知环境数值没法判断叶子上是不是长了蚜虫、红蜘蛛所以这个系统引入了K210做视觉识别这就在“数值控制”的基础上增加了“图像判断”。我把这个系统的功能拆成三层来看底层是环境感知包括土壤湿度、空气温湿度、光照强度中间层是自动控制根据传感器阈值自动开启水泵浇水、打开补光灯上层是AI识别和远程交互K210定时拍照识别害虫识别结果通过串口发给stm32stm32再根据结果决定是否启动驱虫装置或喷洒装置同时把状态推送到云端。这个需求模型很典型等于把一套小型智能农业系统浓缩到了桌面上。我见过不少同学的毕设只做到“监测手动控制”那样其实和课设差不多。这个题目的加分项就在“多功能”和“自动决策”上尤其是K210的加入让系统有了“看”的能力。1.2 为什么是stm32 K210这套组合先说stm32。它做控制是绝对没问题的ADC采集、PWM输出、串口通信、继电器控制外设丰富而且网上的资料多到不行遇到问题基本都能搜到答案。毕设用stm32F103C8T6或者F407都行F1系列性价比高F4主频高一点处理浮点会更快但就这个项目来说F1绰绰有余。但stm32有个短板就是跑不了像样的AI模型。你让stm32去做图像分类哪怕是极简的卷积网络都非常吃力更别说目标检测。所以常见的方案是“主控AI协处理器”。这里对比过几个选择树莓派算力强但成本高而且Linux系统对于纯单片机方向的学生来说学习成本更高OpenMV能做简单的颜色识别但真正训练自己的害虫模型并不方便最终选K210最划算几十块钱一块板子内置KPU神经网络处理器可以跑目标检测模型功耗也低开发方式可以用MicroPython也可以用C SDK上手很快。这套组合还有一个实际好处stm32和K210的分工非常清晰。K210只管“看”和“识别”把识别结果通过串口丢给stm32stm32管所有传感器、执行器和网络不承担任何图像计算。两边各干各的代码结构清晰调试的时候也能单独定位问题。1.3 系统总体架构与数据流设计整个系统的数据流我画出来大概是这样的土壤湿度传感器、温湿度传感器、光照传感器各自把数据送入stm32stm32经过滤波、阈值判断之后控制继电器去开断水泵和补光灯。与此同时K210摄像头定时拍照运行害虫识别模型如果检测到目标害虫并且置信度超过阈值就把害虫类别编号通过串口发送给stm32stm32记录报警事件并触发驱虫模块同时把数据打包成JSON格式通过ESP8266或者板载WiFi模块走MQTT协议上报到云端。手机端或网页端订阅对应的topic就能看到实时数据和历史报警记录也可以下发命令远程开关水泵。还有一个值得注意的设计点控制链路必须区分“本地自动”和“远程手动”。本地自动逻辑完全由stm32独立完成即使断网也要能自动浇水这是基础功能不能依赖云端。远程控制走的是另一条链路云端指令通过MQTT下发到WiFi模块再通过串口发给stm32由stm32决定是否执行。这个分层设计在答辩时非常加分因为它说明你考虑了系统的可靠性和容灾能力。2. 硬件选型与关键电路设计2.1 传感器选型与接线要点传感器这部分我强烈建议不要贪多选最常用的几个就行。土壤湿度我用的是电容式土壤湿度传感器不是那种裸露铜板的电阻式。电阻式的便宜但长时间通电探头容易极化铜面会被电解腐蚀读数漂移很严重做毕设评审时现场演示数据忽高忽低很尴尬。电容式的寿命长得多输出也是模拟电压stm32直接ADC采集就行。空气温湿度用DHT11其实够用了如果预算够就上DHT22精度更好但DHT11在室内演示场景完全没问题。光照传感器用BH1750I2C接口读出来就是勒克斯值不用自己做复杂的换算。传感器接线方面土壤湿度传感器的AO口接stm32的ADC引脚比如PA1BH1750的SCL接PB6、SDA接PB7这是F103的I2C1默认引脚DHT11的数据脚接任意GPIO比如PA4注意要接一个4.7k左右的上拉电阻。这里我踩过坑DHT11如果不加上拉电阻在某些线上会偶发读取超时表现就是有时候能读到有时候卡死排查半天。还有一个细节土壤湿度传感器尽量不要一直供电。我当时的做法是给传感器供电脚接一个三极管或者用stm32的一个GPIO去控制它的VCC只有测量前才上电等几秒稳定后再读取读完断电。这样能减少传感器极化和能耗数据也更稳定。2.2 K210摄像头模块与stm32的接口方式K210开发板常见的有Sipeed Maix Bit、Maix Dock还有创乐博等做的K210板子。选的时候不用纠结品牌核心看三点有没有板载摄像头接口、有没有TF卡槽、能不能直接用USB烧录。Maix Dock带屏现场演示效果会好很多但是功耗也高一些。我建议尽量选带LCD屏幕的版本演示时可以直接看到摄像头画面和识别框感染力很强。K210和stm32之间的通信最常用的是串口。K210的UART是3.3V电平stm32的串口引脚也是3.3V电平所以不需要转换芯片直接TX接RX、RX接TX、GND接GND就行。我用的是stm32的USART1PA9和PA10对应K210的UART1。波特率我设的是115200这个速率对传递控制指令完全够用。这里有个容易忽略的地方K210和stm32必须共地就是两块板的GND一定要连在一起否则串口电平参考点不一致数据会乱码。连好之后可以用一个最简单的回环测试stm32发一个字节K210收到后再发回来stm32收到了就说明物理链路通了。我每次调通信都是先做这个测试避免后面一上来就调试协议出了问题根本分不清是硬件问题还是软件问题。2.3 电源与执行机构的工程处理执行机构上自动浇水我用的是5V的小型潜水泵通过继电器模块接到stm32控制引脚。补光灯和驱虫装置也都是通过继电器控制。继电器模块一般是大电流驱动的用stm32的GPIO输出高电平触发注意继电器模块的JD-VCC和VCC跳线帽有时候需要跳线来隔离电源。整个系统的供电建议这样设计stm32用USB转TTL模块供电或者单独稳压模块K210用单独的USB线供电传感器和继电器共用一个5V电源但要注意继电器线圈动作瞬间的电流冲击。水泵启动瞬间电流很大如果和stm32共用同一个电源轨容易导致主控复位或者ADC采集跳动。实测下来我这边用了一个5V 2A的适配器给所有模块供电但是在水泵电源两端并联了一个1000uF的电解电容继电器线圈两端加了续流二极管这样水泵启动时电压跌落明显变小。还有一点K210在识别模型时电流需求比较高如果用stm32的3.3V引脚给它供电大概率是不够的。K210一定要独立供电。我见过有人把K210接到stm32的3.3V输出上然后K210一跑模型就黑屏重启就是这个原因。3. 核心软件模块实现3.1 stm32侧的程序框架与任务调度stm32侧的程序不要写成一个大循环里从头到尾跑一遍的“裸奔式轮询”那样一旦串口等待或者DHT11读取超时整个系统就会卡住。我在项目里用的是“定时器时基 状态标志”的裸机调度方式。先用SysTick做一个1ms的时基在中断里对几个任务标志位做累加计数主循环里轮询这些标志到了对应时间就去执行对应任务。volatile uint16_t tick_10ms 0; volatile uint16_t tick_100ms 0; volatile uint16_t tick_1s 0; void SysTick_Handler(void) { static uint16_t cnt 0; cnt; if (cnt % 10 0) tick_10ms; if (cnt % 100 0) tick_100ms; if (cnt % 1000 0) tick_1s; } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); MX_ADC1_Init(); MX_I2C1_Init(); while (1) { if (tick_10ms) { tick_10ms--; task_10ms(); } if (tick_100ms) { tick_100ms--; task_100ms(); } if (tick_1s) { tick_1s--; task_1s(); } } }task_10ms里处理K210串口数据的接收和K210状态查询task_100ms里处理土壤湿度采集、滤波、阈值判断和水泵控制task_1s里处理BH1750光照读取、DHT11温湿度读取和OLED刷新。这样每个任务都有自己稳定的时间片任何一个任务卡住其他任务还能继续跑系统整体“活”很多。3.2 传感器采集、滤波与自动灌溉逻辑土壤湿度传感器的ADC读取不能直接拿一次采样值就用因为土壤中的水分分布不均匀而且传感器信号本身有噪声。我做了两层处理第一层是多次采样取平均连续采样10次剔除最大最小值剩下的取平均第二层是加了一个简单的阈值迟滞避免水泵频繁开关。uint16_t get_soil_humidity(void) { uint32_t sum 0; uint16_t min 4096, max 0, val; for (int i 0; i 10; i) { val HAL_ADC_GetValue(hadc1); sum val; if (val min) min val; if (val max) max val; HAL_Delay(2); } sum sum - min - max; return (uint16_t)(sum / 8); }阈值迟滞怎么理解呢比如你设定ADC值小于1200的时候开泵浇水浇到ADC值大于1600的时候停泵。这两个阈值之间有400的差值就是迟滞区间。如果没有迟滞传感器数值在水泵触发点附近波动时就会开泵、停泵、再开泵继电器频繁吸合寿命短不说演示时还显得很不专业。我实测下来湿度从干到湿的变化有一段延迟所以迟滞区间必须够大至少要让水泵持续工作30秒以上水才能真正渗透到土壤里面。完整控制逻辑其实并不复杂先把自动模式标志位打开然后判断湿度是否低于下限阈值满足条件而且距离上次浇水超过一定冷却时间就打开继电器等湿度达到上限或者当前状态超过最大浇灌时间比如120秒就关泵。冷却时间和最大浇灌时间是两个安全保护参数必不可少否则万一传感器失灵系统会一直浇水把植物都给泡死。3.3 K210害虫识别模型的训练与部署K210识别害虫的流程是准备数据集 - 标注 - 训练模型 - 转换为kmodel - 部署到K210。数据集建议用已有的公开昆虫数据集比如IP102、农业害虫数据集里面有很多常见害虫类别做毕设用足够。但公开数据集有一个问题就是图片的拍摄角度、光线和你的摄像头环境差异比较大。我建议一边用公开数据集做预训练一边用自己的摄像头拍三五十张照片做补充尽量让模型适应你实际演示的场景。标注工具可以用labelImg把图片中害虫位置框出来导出VOC格式或者YOLO格式。训练可以选择MaixHub在线训练平台不用配环境上传数据集就能训练也可以本地用ncc或者K210训练框架。在线训练适合初次接触的人本地训练适合追求精度的研究者。K210的KPU支持的检测网络主要是YOLOv2轻量版输入分辨率一般设置为224x224或者320x240分辨率越大精度越高但帧率下降我用的是224x224识别速度在20-30fps完全够用。训练完成后会得到一个kmodel文件把它放到TF卡根目录或者烧录到Flash。K210端如果用的是CanMV固件可以用MicroPython调用模型。核心代码大致是这样import sensor, image, lcd from maix import KPU sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.set_vflip(True) kpu KPU() kpu.load_kmodel(/sd/insect.kmodel) labels [aphid, spider_mite, whitefly] while True: img sensor.snapshot() result kpu.run_with_output(img, get_rawTrue) # 解析输出画出锚框和类别这里要特别提醒一个坑模型训练时背景类别和实际摄像头环境差异大容易把花盆边缘、土壤纹理识别成害虫。所以训练集里一定要加入大量背景图片并且这些背景图片最好是你实际演示环境里拍的比如叶片、土壤、花盆、桌面。我一开始没加背景图结果模型把叶子的阴影识别成了蚜虫置信度还很高后来补充了一批背景图重训误报率才降下来。3.4 stm32与K210之间的通信协议设计K210和stm32之间传数据不能裸发一个字节就完事。比如K210识别到害虫直接发个数字“2”stm32收到了但你不知道这个“2”是害虫类别编号还是状态信息也不知道数据有没有出错。所以一定要定义一套简单的帧协议。我用的帧格式是这样的帧头固定两个字节0xAA 0x55接着是负载长度len再是命令字cmd接下来是数据区data最后是校验字节checksum校验用累加和。比如K210识别出类别2的害虫发送的帧是0xAA 0x55 0x03 0x01 0x02 0x00 0x05其中0x03表示后面还有3个字节0x01是命令字“害虫报警”0x02是害虫类别编号0x00是保留的置信度字段或者预留0x05是前面所有字节的累加和取低8位。stm32这边用串口中断接收然后在上层做状态机解析。串口中断里只负责往缓冲区存字节不做过多逻辑解析放在主循环里uint8_t rx_buf[32]; uint8_t rx_index 0; volatile uint8_t frame_ready 0; void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(huart1, UART_FLAG_RXNE)) { uint8_t ch huart1.Instance-DR; rx_buf[rx_index] ch; if (rx_index 32) rx_index 0; if (ch 0x55 rx_index 2 rx_buf[rx_index - 2] 0xAA) { // 已经收到帧头可以继续判断帧长 } } }实际上更稳的方式是在主循环里判断帧头。先找0xAA 0x55再读取len字段如果len4大于缓冲区剩余长度说明帧还没收完继续等。如果收完了校验和通过就执行对应的命令处理函数。这里我建议不要用HAL库自带的HAL_UART_Receive_IT一字节一字节等效率低容易丢。如果用的是F4芯片直接用串口空闲中断DMA接收接收效率高很多而且不会因为CPU忙而丢数据。F1没有空闲中断就用普通的RXNE中断配合状态机也够用。3.5 物联网上云与远程控制实现物联网部分我选的是MQTT协议原因很简单轻量、稳定、生态好。云端平台可以用阿里云物联网平台、OneNET、EMQX自己搭服务也可以。stm32本身没有WiFi所以外挂一个ESP8266模块stm32通过串口向ESP8266发AT指令完成连接。用ESP8266做MQTT常见做法有两种。一种是用ESP8266的AT固件里自带的MQTT指令指令比较少适合简单场景。另一种是让ESP8266跑NodeMCU固件自己写Lua脚本或者用Arduino写固件把MQTT逻辑写在ESP8266里然后stm32只通过串口和ESP8266传业务数据。第二种方式更灵活但调试量也大一些。第一次做毕设的话我建议直接用AT指令方式虽然指令看起来多但逻辑很直白遇到问题也好查。ATCWMODE1 ATCWJAPyour_wifi_ssid,your_password ATMQTTUSERCFG0,1,client_id,username,password,0,0, ATMQTTCONN0,your_mqtt_broker,1883,1 ATMQTTSUB0,plant/control,1 ATMQTTPUB0,plant/status,{\humidity\:32,\pest\:1},1云端的数据格式统一用JSON。设备上报的topic我设计了两个plant/status上报传感器状态和害虫报警plant/control接收远程控制指令。比如手机端下发“打开水泵”云端往plant/control发一个JSON{cmd:pump_on,ts:1680000000}ESP8266收到后通过串口发给stm32stm32解析JSON里cmd字段执行对应操作。注意ESP8266和stm32之间的数据流也是串口所以不要让业务数据和AT调试日志混在一起stm32发往ESP8266的串口和接K210的串口不要用同一个USART避免相互干扰。4. 联调过程中的常见问题与避坑实录4.1 串口通信数据错乱和丢帧怎么查这是我调试过程中遇到最多的问题。现象是stm32收到的K210数据偶尔多一个字节或者第一帧对、第二帧就乱。排查顺序我一般是这样第一步看波特率两边的波特率必须一模一样K210的MicroPython里用UART.init设置波特率stm32的CubeMX里也要对应起来差的哪怕一丝都不行。第二步看共地两块板子如果分别用两个USB口供电GND没连数据线接了对也白搭电平参考点不一致导致的乱码是那种“看着有数据但完全没规律”的乱码。第三步看缓冲区串口中断里如果接收速度比主循环处理速度快缓冲区被覆盖就会丢帧需要把缓冲区和索引的处理逻辑理顺。还有一点stm32的HAL库串口空闲中断DMA是个好方案。F4系列直接在CubeMX里开启UART的DMA接收和IDLE中断一次性接收不定长数据解析效率高很多。F103没有空闲中断可以开启RXNE中断但接收完成后要尽快把数据搬走或者用环形缓冲区不要在中断里做太多事情否则高波特率下很容易漏数据。4.2 K210识别不准、误报率高怎么办识别不准的原因通常是三类。第一类是训练数据太少样本只有几十张模型没有见过足够多变化换个角度就识别不出来。解决办法是数据增强把图片旋转、平移、翻转、调亮度一条数据变六条不用额外拍太多照片也能明显提升泛化性。第二类是类别不平衡比如蚜虫图片有500张红蜘蛛只有50张模型必然偏向蚜虫。解决办法是让每个类别数据量差不多。第三类是阈值设置问题K210输出的是置信度默认0.5可能太敏感我实际测试下来设到0.6以上误报率会低很多识别不出来总比乱报警好因为毕设现场演示你肯定希望每次识别都准而不是频繁误报。另外还有一个硬件层面的问题摄像头焦距和角度。K210配的摄像头一般是定焦近距离拍叶片时如果超出物距画面是模糊的。我后来把K210固定在一个支架上让摄像头正对植物叶片高度大概15-20cm这样拍出来的图片和训练集更接近识别率提升非常明显。有些同学用一片叶子离镜头特别近拍出来全是大片绿色模型当然分辨不出来。4.3 传感器读数漂移的排查思路传感器读数漂移最典型的两种情况一种是土壤湿度数值在短时间内跳来跳去另一种是光照传感器读值反复跳动。前者一般是因为传感器在通电时受水泵启停的电源干扰后者可能是I2C总线上有干扰或者供电纹波大。排查思路是逐步隔离先把水泵继电器断开只留传感器供电看数值是否稳定如果稳定了说明是电源干扰问题在水泵回路加滤波电容如果还跳看是不是传感器探头接触不良或者线过长。土壤湿度传感器还有个坑探头插入土壤的角度不同读数差异很大。为了演示一致我把探头固定插在花盆的同一位置每次演示都用同一个花盆同一个位置这样至少数据是稳定可复现的。如果换土、换盆、换位置读数基准都会变所以不要临时更换演示用的花盆。4.4 断网情况下云控失效本地保护如何兜底做远程控制时最怕什么怕云端连不上用户发指令没反应系统又没有兜底结果把植物浇死或者一直不浇水。我在设计控制逻辑时明确了一条规则本地自动控制的优先级高于云端手动控制。具体来说即使云端发过来“打开水泵”的指令如果当前土壤湿度已经很高或者水泵上次开启时间距现在太短stm32会拒绝执行并回传一个“rejected”状态。断网的时候ESP8266会反复重连stm32本地逻辑完全不受影响该浇水浇水该报警报警。只有上报状态这件事暂时搁置等网络恢复后重新上报最新数据。这个设计在毕业答辩演示时很有价值你可以现场把WiFi断开让设备继续自动运行然后重新连接云端数据自动补回来评委一眼就看出你考虑了真实场景。5. 答辩演示与项目资料整理建议5.1 演示流程先把最直观的功能展示出来答辩现场时间有限演示一定要按“由快到慢、由直观到深入”的顺序安排。我建议第一步先演示自动浇水把一个干土花盆的传感器插好屏幕上显示当前湿度数值低于阈值水泵自动启动花盆里开始冒水泡评委一眼就能看到效果。第二步演示害虫识别放一张打印好的害虫图片在摄像头前或者拿一片粘了小黑点的叶子K210屏幕直接画出识别框并显示“aphid”字样同时控制板蜂鸣器响一下。第三步再演示远程控制手机打开App看到传感器数据刷新点一下远程浇水水泵响应。这三步演示下来本地控制、AI识别、远程交互全部覆盖每个环节都是三十秒内能出效果的。千万不要花大量时间讲代码细节评委在演示环节更关心“系统能不能跑起来”和“效果是否稳定”。我见过有同学演示时打开Keil工程讲代码讲了十分钟别人也没看到实物效果大打折扣。5.2 技术讲解时如何突出重点讲解技术方案时要围绕四个亮点展开第一stm32和K210的分工架构为什么要用双芯片而不是单芯片第二通信协议的设计你怎么保证数据不丢帧、不错帧第三本地自动控制与云端远程控制的优先级管理怎么解决断网兜底问题第四模型训练和部署流程尤其是如何降低误报率。每一个点都要准备一个“为什么”。比如评委问“为什么不用OpenMV而用K210”你可以说OpenMV适合颜色识别和学习阶段但K210的KPU是专门的神经网络加速单元跑YOLO这类目标检测模型效率更高而且成本低。评委再问“你的数据安全怎么考虑”你可以说MQTT支持用户名密码认证、设备证书上传的数据用JSON格式云端可配置权限。这些问题只要提前准备过现场就不会冷场。5.3 源码、文档与演示视频的整理思路最后说一下项目资料怎么整理。毕业设计最终要提交源码、论文和演示视频这些东西越早准备越好不要最后三天赶工。源码目录我建议这样组织根目录下放README说明项目简介、硬件清单、系统架构、使用方法和演示效果然后分三个子目录stm32_code放stm32工程k210_code放K210端的MicroPython或C代码app_or_cloud放云端配置和手机端代码如果用了Web管理页面再单独放一个web目录。论文结构可以按照“需求分析 - 方案设计 - 硬件实现 - 软件实现 - 系统测试 - 总结”来写重点是系统测试那一部分把每一项功能、测试条件、测试结果用表格列出来比如“土壤湿度采集”、“水泵自动控制”、“害虫识别成功率”、“断网自动控制”等等。演示视频建议控制在5分钟以内录屏加实物画面交替出现先拍实物运行再拍手机App界面最后补一段K210屏幕的特写这三点是评委最想看到的。整套项目做完之后我最大的感受是这个题目看起来复杂但只要把“本地控制”和“AI识别”两条链路分开做先各自跑通再合并联调难度会降低很多。很多同学一上来就想着把所有模块同时调好结果哪里都通不了还分不清问题出在哪个模块。我用的是“先传感器控制、再K210识别、最后上云”的顺序每一步都单独验证通过再进入下一步。如果时间允许建议你也按这个节奏来稳扎稳打比到处找现成代码然后拼在一起要省心得多。本文还有配套的精品资源点击获取