基于ESP8266与YOLOv4的智慧养殖物联网系统实战
1. 项目概述一个面向中小型养殖场的物联网AI实战方案最近几年身边不少从事农业的朋友都在聊“智慧养殖”但一提到具体落地往往被高昂的自动化设备成本和复杂的系统集成吓退。这让我想起之前带学生做的一个毕业设计项目核心目标就是用尽可能低的成本和成熟的开源技术为中小型猪场打造一套实用的监测系统。这个项目麻雀虽小五脏俱全它没有选择昂贵的PLC或工业总线而是基于常见的ESP8266Wi-Fi模块和STM32单片机结合免费的机智云AIoT平台再引入YOLOv4视觉算法实现从环境感知到猪只行为分析的完整闭环。对于想入门农业物联网、嵌入式开发或者边缘AI应用的朋友来说这是一个非常棒的练手项目其设计思路完全可以迁移到鸡舍、牛棚乃至温室大棚等场景。今天我就把这个项目的完整设计、踩过的坑以及核心代码逻辑掰开揉碎了和大家分享一下。2. 系统整体架构与核心设计思路拆解做任何物联网项目第一步永远是理清架构。我们不能一上来就埋头焊电路、写代码必须想清楚数据怎么流、设备怎么控、人怎么交互。2.1 为什么选择“云-管-边-端”四层架构我们最终采用的架构可以概括为“云-管-边-端”。这听起来有点玄乎其实很好理解端终端层就是部署在猪舍现场的“感官”和“手脚”。包括各类传感器温湿度、光照、氨气、火焰、雨水、人体红外和执行器风机、加热灯、喷淋、照明灯。它们负责采集原始数据和执行具体动作。边边缘层这是系统的“本地大脑”核心是一块STM32F407单片机开发板。它负责三件事第一轮询采集所有传感器的数据第二根据预设逻辑自动模式或云端指令手动模式控制执行器第三通过串口与负责视觉处理的树莓派或类似边缘计算设备通信接收猪只分析结果。管管道层即网络通信。本项目核心是ESP8266 Wi-Fi模块它通过AT指令或SDK与STM32通信将边缘层处理后的数据稳定地上传到云端同时将云端的控制指令下发给STM32。为什么不用NB-IoT或LoRa对于室内有稳定220V供电的猪舍Wi-Fi的带宽高、成本低、开发资料丰富的优势非常明显足以传输传感器数据和简单的控制指令。云平台与应用层我们选择了机智云AIoT平台作为云端中枢。它的价值在于提供了设备接入、数据解析、存储、转发和规则引擎等一站式服务省去了自建服务器的巨大工作量。手机APP基于机智云提供的SDK开发可以快速实现数据展示和设备控制。此外我们还接入了极光推送服务用于实现短信和邮件的报警通知。这个架构的优势在于解耦和弹性。边缘层保证了在网络中断时基础的自动控制如温度过高自动开风机依然能工作实现了“断网可用”。云端则提供了远程监控、数据历史和灵活告警的能力。视觉分析任务单独放在树莓派上避免了对主控单片机实时性的干扰。2.2 核心功能定义与方案选型背后的考量根据实际调研我们提炼了以下几个核心需求并做出了对应的技术选型多环境因子实时监测需求需要监测温度、湿度、光照、有害气体氨气、火灾风险火焰、漏水风险雨水和非法闯入人体感应。选型温湿度选用DHT22精度和稳定性比DHT11好数字接口简单。光照选用BH1750数字光照传感器I2C接口精度高无需额外模拟电路。氨气选用MQ-135模拟气体传感器。注意这类传感器对多种气体敏感且受温湿度影响大不能用于精确计量但用于判断浓度“趋势”和“超标”是成本可行的方案。我们在STM32端做了简单的温湿度补偿算法。火焰、雨水、人体红外均选用常见的数字开关量输出模块。火焰传感器检测红外线雨水传感器检测板间电阻人体红外HC-SR501检测运动热源。它们输出高/低电平STM32直接读取GPIO状态即可非常可靠。双模式控制逻辑自动模式STM32内部维护一套阈值如温度28℃开风机湿度80%开除湿器。该模式优先级最高确保环境基线稳定。手动模式当用户通过APP切换为手动模式后所有执行器控制权移交云端/APP。此时自动控制的阈值比较逻辑被暂停。这是关键设计避免了自动和手动指令冲突逻辑清晰。低成本视觉猪只分析需求统计数量、跟踪轨迹、初步分割为健康分析打基础。选型没有采用昂贵的工业摄像头或专用设备而是使用普通的USB摄像头树莓派4B。算法选用YOLOv4-tiny轻量版。为什么不是更快的YOLOv5或更准的YOLOv8因为在项目进行时YOLOv4-tiny在树莓派上的部署资料最成熟且在COCO数据集预训练模型上微调猪只检测速度和精度能达到很好的平衡实测FPS5满足监控需求。跟踪算法选用经典的卡尔曼滤波预测位置匈牙利算法关联ID计算量小适合边缘设备。稳定可靠的数据上云与告警需求数据不掉线关键事件火情、闯入能及时通知到人。选型ESP8266固件刷写了机智云提供的GAgent使其能够自动连接机智云。通信协议采用机智云自定义的透传格式STM32只需按照数据点模板组包发送即可。告警方面机智云平台可以配置规则当火焰或人体传感器触发时自动向极光推送的API发送请求极光推送则负责调用短信和邮件网关。这里有个坑务必在机智云规则引擎里设置“触发条件持续X秒后才告警”以避免因传感器误报如蚊虫飞过火焰传感器产生骚扰信息。3. 硬件终端搭建与核心电路设计要点硬件是系统的骨架稳定可靠的硬件设计是后续所有工作的基础。3.1 主控与电源模块设计主控MCUSTM32F407VET6。选择它是因为其丰富的资源168MHz主频512KB Flash192KB RAM多个定时器、ADC、USART足以轻松处理多路传感器数据、逻辑判断和通信任务且为未来功能扩展留有余地。电源模块这是最容易忽视却最关键的环节。猪舍环境可能存在电压波动。我们的设计是220V AC转5V DC开关电源模块为整个系统供电。5V转3.3V LDO如AMS1117-3.3给STM32、ESP8266和数字传感器供电。特别注意ESP8266在发射Wi-Fi信号时瞬时电流可能超过300mA必须确保LDO或DC-DC芯片能提供足够电流否则会导致MCU复位。建议为ESP8266单独一路供电或使用最大输出电流1A以上的稳压芯片。模拟传感器如MQ-135的加热丝需要5V供电且加热电流较大应从5V总线上直接取电并避免和数字电路共用细导线。3.2 传感器与执行器接口设计数字传感器DHT22 BH1750 火焰、雨水、人体模块DHT22是单总线接一个GPIO注意上拉电阻。BH1750是I2C接STM32的I2C1PB6/PB7记得接上拉电阻通常4.7K。火焰、雨水、人体模块输出数字开关量接GPIO输入配置为上拉输入模式。可以在输入端并联一个0.1uF电容到地滤除高频毛刺。模拟传感器MQ-135接STM32的ADC引脚如PA0。ADC需配置为12位分辨率。由于MQ-135输出的是电压值且受温湿度影响STM32需要先读取其电压再结合DHT22读取的当前温湿度通过一个补偿公式可在传感器手册或实验数据中拟合计算出较准确的氨气浓度参考值。执行器控制继电器模块STM32的GPIO输出能力不足以驱动继电器线圈必须通过三极管如S8050或光耦进行隔离驱动。继电器输出端接220V交流设备风机、灯等。安全第一强电部分务必做好绝缘继电器模块最好选用带光耦隔离和线圈续流二极管的成品模块。3.3 ESP8266通信模块连接ESP8266-01S模块通过串口USART2或USART3与STM32连接。TX接STM32的RXRX接STM32的TX。电平匹配ESP8266是3.3V电平STM32F407的IO口可容忍3.3V因此可以直接连接。如果使用5V MCU则必须加电平转换电路。接线除了TX/RX还需连接CH_PD使能和VCC到3.3VGND接地。RST引脚可以接STM32的GPIO用于软件复位。固件务必刷入机智云官方的GAgent固件这是设备能无缝接入机智云平台的关键。4. 下位机软件设计双模式与控制逻辑实现下位机程序是系统的“灵魂”它决定了整个系统是否智能、可靠。4.1 程序主框架与任务调度我们没有使用复杂的操作系统如FreeRTOS而是采用基于定时器中断的前后台时间片轮询架构这对于单片机资源有限且逻辑清晰的项目来说更简单高效。// 伪代码示意主循环框架 int main(void) { // 初始化所有硬件时钟、GPIO、ADC、定时器、串口... Hardware_Init(); // 连接机智云通过ESP8266发送特定序列 Gizwits_Init(); while(1) { // 任务1每100ms采集一次传感器数据除温湿度 if (timer_flag_100ms) { timer_flag_100ms 0; Read_Light(); // 光照 Read_Gas(); // 氨气含ADC读取与补偿计算 Read_Flame(); // 火焰 Read_Rain(); // 雨水 Read_PIR(); // 人体红外 // 数据存入全局结构体 } // 任务2每2秒采集一次温湿度DHT22响应较慢 if (timer_flag_2s) { timer_flag_2s 0; Read_DHT22(temperature, humidity); } // 任务3每500ms执行一次控制逻辑 if (timer_flag_500ms) { timer_flag_500ms 0; Control_Logic_Process(); // 核心控制逻辑函数 } // 任务4处理串口数据包括来自ESP8266的云指令和树莓派的视觉数据 UART_Data_Process(); // 任务5每5秒上报一次数据到云端避免过于频繁 if (timer_flag_5s) { timer_flag_5s 0; Gizwits_ReportData(); // 将全局结构体中的数据按机智云协议打包上报 } // 其他任务...如按键扫描、LCD刷新等 } }4.2 核心控制逻辑实现细节Control_Logic_Process()函数是自动模式的核心其逻辑如下void Control_Logic_Process(void) { // 首先判断当前模式 if (system_mode AUTO_MODE) { // 自动控制逻辑 // 温度控制 if (current_temperature TEMP_HIGH_THRESHOLD) { FAN_ON(); // 开启风机降温 HEATER_OFF(); } else if (current_temperature TEMP_LOW_THRESHOLD) { HEATER_ON(); // 开启加热灯 FAN_OFF(); } else { FAN_OFF(); HEATER_OFF(); } // 湿度控制 if (current_humidity HUMIDITY_HIGH_THRESHOLD) { DEHUMIDIFIER_ON(); // 开启除湿器或通风 } else { DEHUMIDIFIER_OFF(); } // 光照控制模拟昼夜 if (current_light LIGHT_LOW_THRESHOLD is_night_time()) { LIGHT_ON(); // 夜晚且光照不足补光 } else { LIGHT_OFF(); } // 报警逻辑自动模式下也报警但可能只本地声光报警 if (flame_detected) { BUZZER_ON(); // 报警状态会上报云端触发极光推送 } if (pir_detected) { BUZZER_ON(); } } else if (system_mode MANUAL_MODE) { // 手动模式控制指令完全来自云端通过gizwitsEventProcess处理 // 本函数在手动模式下不执行任何自动控制仅执行云端下发的开关指令 // 云端指令会更新如fan_status_cmd这样的变量 Execute_Cloud_Command(); } }关键点模式切换变量system_mode由手机APP通过云端下发指令来改变。当切换到手动模式时APP下发所有执行器的期望状态STM32执行后会将这些状态作为“当前状态”上报回云端确保APP显示与实际一致。4.3 与机智云平台的数据协议对接机智云使用“数据点”来定义设备与云端交换的数据。我们需要在机智云开发者中心创建对应的数据点。数据点标识名类型读写类型说明temperature数值只读温度单位℃范围-20~60humidity数值只读湿度单位%范围0-100light数值只读光照强度单位luxgas数值只读氨气浓度单位ppmflame布尔只读true表示检测到火焰pir布尔只读true表示检测到人体mode枚举可写0-自动模式1-手动模式fan_switch布尔可写手动模式下控制风机的开关heater_switch布尔可写手动模式下控制加热灯的开关............在STM32代码中需要根据机智云提供的MCU SDK实现一个关键函数gizwitsEventProcess()。当有数据从云端下发如模式切换、手动开关指令时这个函数会被调用。// 机智云协议处理回调函数 void gizwitsEventProcess(eventInfo_t *info) { if (info-wifiStatus_event) { // 处理Wi-Fi状态变化如连接成功/断开 } if (info-mode_event) { // 收到模式切换指令 system_mode info-value.mode; // 更新系统模式 // 切换模式时可能需要初始化一些状态 } if (info-fan_switch_event) { // 收到手动控制风机的指令 if (system_mode MANUAL_MODE) { if (info-value.fan_switch) FAN_ON(); else FAN_OFF(); } // 注意即使在自动模式也更新这个命令值但控制逻辑以自动判断为准 } // ... 处理其他可写数据点 }5. 猪只视觉检测算法的部署与优化这是项目的“智能”亮点将AI从云端下沉到边缘侧。5.1 基于YOLOv4-tiny的猪只检测模型训练数据收集与标注在猪舍安装摄像头采集不同时段、不同光照、不同猪只密度的图片和视频。使用LabelImg等工具标注猪只生成YOLO格式的标签文件.txt包含类别和边界框。环境配置在Ubuntu服务器或PC上配置Darknet框架YOLO原作者实现。安装CUDA和cuDNN以利用GPU加速训练。模型训练使用yolov4-tiny.conv.29作为预训练权重。修改配置文件yolov4-tiny-custom.cfg调整filters和classes数量我们只有“pig”一类所以classes1对应filters18。准备train.txt和val.txt文件列表。开始训练./darknet detector train data/obj.data cfg/yolov4-tiny-custom.cfg yolov4-tiny.conv.29 -map。训练过程要监控损失loss和平均精度mAP曲线防止过拟合。5.2 在树莓派上的部署与加速模型转换Darknet训练的.weights文件需要转换为TensorFlow Lite或OpenCV DNN支持的格式如.pb或.onnx以便在树莓派上高效运行。我们使用darknet自带的darknet2onnx.py脚本转换为ONNX格式。树莓派环境安装OpenCV带DNN模块和ONNX Runtime。ONNX Runtime对ARM处理器有较好优化。推理代码核心import cv2 import onnxruntime as ort import numpy as np # 加载模型 session ort.InferenceSession(yolov4-tiny-pig.onnx) # 预处理 def preprocess(image, net_shape(416, 416)): blob cv2.dnn.blobFromImage(image, 1/255.0, net_shape, swapRBTrue, cropFalse) return blob # 推理 def detect(blob): inputs {session.get_inputs()[0].name: blob} outputs session.run(None, inputs) return outputs[0] # 输出为(1, num_boxes, 85)的数组 # 后处理非极大值抑制NMS def postprocess(output, conf_thresh0.5, nms_thresh0.4): # 解析输出筛选置信度应用NMS boxes, confidences, class_ids [], [], [] # ... 解析逻辑 ... indices cv2.dnn.NMSBoxes(boxes, confidences, conf_thresh, nms_thresh) return [boxes[i] for i in indices], [class_ids[i] for i in indices]加速技巧使用uint8量化模型牺牲极少精度换取大幅速度提升。降低输入图像分辨率如从416x416降到320x320。树莓派超频需做好散热。5.3 卡尔曼滤波与匈牙利算法实现多目标跟踪检测只能得到每一帧的猪只框跟踪才能赋予它们持续的身份ID。卡尔曼滤波为每个检测到的目标初始化一个卡尔曼滤波器用于预测其在下一帧的位置。我们主要使用其匀速运动模型。class KalmanFilter: def __init__(self): # 状态向量 [x, y, w, h, dx, dy] 即中心点坐标、宽高和速度 self.kf cv2.KalmanFilter(6, 4) # 6维状态4维测量x,y,w,h # ... 初始化状态转移矩阵F、测量矩阵H、协方差矩阵等... def predict(self): return self.kf.predict() def update(self, measurement): self.kf.correct(measurement)匈牙利匹配将当前帧的检测框detections与上一帧预测的跟踪器位置predictions进行关联。使用IoU交并比作为代价矩阵通过scipy.optimize.linear_sum_assignment或自己实现匈牙利算法找到最优匹配。跟踪流程步骤一对现有所有跟踪器进行predict。步骤二计算所有predictions与detections的IoU矩阵。步骤三使用匈牙利算法进行匹配。步骤四匹配成功的用检测框update对应的卡尔曼滤波器未匹配的检测框初始化为新跟踪器未匹配的预测框可能是目标离开或暂时遮挡连续若干帧未匹配后删除。5.4 与STM32的串口通信协议设计树莓派分析完成后需要将结果如猪只数量发送给STM32再由STM32上报云端。我们设计了一个简单的文本协议PIG_COUNT:3\nSTM32端通过串口中断接收解析出数字“3”然后将其赋值给一个全局变量如pig_count在数据上报函数中将这个变量填入对应的数据点上报给机智云。6. 手机APP与云端规则配置实战6.1 基于机智云SDK的Android APP快速开发机智云提供了Android SDK大大简化了开发。核心步骤导入SDK将GizWifiSDK的jar包或aar依赖添加到项目中。初始化在Application中初始化SDK填入机智云分配的AppID和AppSecret。设备配网使用SDK提供的AirLink或SoftAP模式引导用户将设备ESP8266连接到家庭Wi-Fi。这是物联网设备入网的关键一步。设备列表与绑定APP登录后从云端拉取已绑定的设备列表。用户也可以扫描设备二维码添加新设备。数据监听与控制这是核心交互。订阅设备的数据点变化并发送控制指令。// 监听数据点变化例如温度更新 gizWifiDevice.setListener(new GizWifiDeviceListener() { Override public void didReceiveData(GizWifiDevice device, ConcurrentHashMapString, Object dataMap, int result) { if (result 0) { // 成功收到数据 Object temp dataMap.get(temperature); if (temp ! null) { runOnUiThread(() - mTvTemperature.setText(temp.toString())); } // ... 更新其他UI } } }); // 发送控制指令例如切换为手动模式 ConcurrentHashMapString, Object command new ConcurrentHashMap(); command.put(mode, 1); // 1代表手动模式 gizWifiDevice.write(command);6.2 机智云平台规则引擎与极光推送配置这是实现无人值守报警的关键。在机智云创建产品定义好前面提到的所有数据点。配置规则引擎进入“规则引擎”-“创建规则”。触发条件选择设备设置条件如flame true火焰报警或pir true人体报警。执行动作选择“推送通知到第三方平台”。填写极光推送的API URL和认证信息。消息模板可以写为“【猪舍报警】检测到火焰请立即处理设备ID${did}时间${time}”。在极光推送配置创建应用获取AppKey和Master Secret。在“推送设置”中配置短信和邮件通道通常需要企业认证或充值。提供一个HTTP API给机智云调用。当机智云触发规则时会向这个API发送POST请求极光推送服务则根据请求内容向预设的手机号发送短信或邮箱发送邮件。7. 系统联调与常见问题排查实录将硬件、固件、云端、APP全部打通的过程是最容易踩坑的环节。7.1 硬件与下位机常见问题问题1ESP8266连接机智云一直超时。排查检查固件是否为机智云官方GAgent。检查Wi-Fi热点名称和密码是否包含特殊字符最好只用字母数字。使用串口调试助手手动发送AT指令测试ESP8266是否能正常连接路由器ATCWJAPSSID,PASSWORD。检查路由器是否开启了MAC地址过滤或禁止了新设备接入。关键确保设备、手机APP和机智云后台创建的产品属于同一个“产品密钥”Product Key。问题2传感器数据跳动剧烈不稳定。排查电源噪声用示波器看传感器供电电压是否平稳。在电源引脚就近增加一个10uF电解电容并联一个0.1uF瓷片电容。信号干扰模拟信号线如MQ-135尽量短并远离MCU的晶振、数字信号线。可以尝试加一个RC低通滤波电路。软件滤波在STM32端实现软件滤波。对于变化慢的数据如温湿度采用“滑动平均滤波”对于开关量采用“延时消抖”判断。// 滑动平均滤波示例 #define FILTER_LEN 10 float temp_buffer[FILTER_LEN]; float filter_average(float new_val) { static int index 0; temp_buffer[index] new_val; index (index 1) % FILTER_LEN; float sum 0; for(int i0; iFILTER_LEN; i) sum temp_buffer[i]; return sum / FILTER_LEN; }7.2 云端与通信问题问题3手机APP显示设备离线但设备本身指示灯正常。排查登录机智云开发者中心查看设备日志。看设备最后一次心跳包或数据上报时间。检查设备端的网络环境。是否路由器断网是否ESP8266假死可以在STM32程序中加入“看门狗”复位机制并定时检测ESP8266的连接状态异常时对其进行硬件复位。可能是机智云服务器区域选择错误。国内设备应接入api.gizwits.com中国区。问题4规则引擎报警不触发。排查检查规则条件是否配置正确。例如flame数据点上报的是true/false布尔值条件应写flame true而不是flame 0。在机智云“设备日志”中查看设备上报的数据是否包含了flame这个字段且值正确。在极光推送后台查看“推送记录”看是否收到了调用请求。如果没有说明机智云规则未触发或调用失败如果有则问题在极光推送的通道配置如短信余额不足。7.3 视觉算法相关问题问题5树莓派上YOLO推理速度太慢1 FPS。优化模型层面使用更轻量的版本如YOLOv4-tiny已经是最优选择之一。可以尝试使用TensorFlow Lite的uint8量化模型。代码层面确保使用的是OpenCV的DNN模块或ONNX Runtime进行推理而不是原始的Darknet在ARM上极慢。使用多线程摄像头采集一帧推理一帧同时处理上一帧的结果。硬件层面为树莓派加装散热风扇并适当超频如arm_freq2000。使用树莓派官方的高质量电源保证供电稳定。问题6猪只跟踪ID频繁跳变ID Switch。优化调整卡尔曼滤波的过程噪声Q和测量噪声R矩阵参数让预测更相信测量值还是更相信模型预测。优化匈牙利匹配的成本计算。除了IoU可以加入外观特征如使用简单的颜色直方图作为辅助成本在目标遮挡后重现时能更好关联。对于短暂遮挡不要立即删除跟踪目标可以设置一个“最大丢失帧数”如30帧在此帧数内重新匹配上的目标保留原ID。8. 项目总结与可扩展方向回顾整个项目从需求分析、架构设计、硬件选型、嵌入式编程、AI模型训练与部署到云平台对接和APP开发完成了一个完整的物联网AI应用闭环。对于学生或初学者而言最大的收获不是某个技术点有多深而是掌握了如何将多种技术有机整合解决一个实际问题的系统工程能力。这个系统本身也有许多可以继续深化的方向数据深化将历史环境数据与猪只的增重、患病率进行关联分析利用云端机器学习服务如机智云的数据分析功能或阿里云PAI建立预测模型实现真正的“预警”比如提前预测疾病风险。算法升级将猪只检测升级为猪只姿态估计或行为识别如躺卧、站立、饮水、争斗这需要更精细的数据标注和更强大的模型如HRNet。成本优化主控MCU可以换为更便宜的STM32F103或国产GD32视觉部分可以尝试使用算力更强的专用AI芯片如K210或更廉价的 Jetson Nano。协议扩展在大型养殖场多个猪舍单元可以组成局域网使用LoRa进行远距离数据汇集再通过一个网关统一上云进一步降低网络布线成本和复杂度。这个项目就像一颗种子展示了物联网和AI技术在传统农业中落地的巨大潜力。它的价值不在于用了多前沿的技术而在于用恰当的技术组合切实地解决了一个痛点。希望这次详细的分享能为你开启自己的智能硬件项目带来一些实实在在的帮助。