简介本资源是一份基于STM32的养殖场环境监测系统完整项目文档面向物联网、嵌入式开发学习者及毕业设计开发者帮助解决环境参数采集、远程监控与智能控制等实际问题。文档以STM32F103RCT6为主控整合SHT30温湿度、MQ135空气质量、BH1750光照等传感器并借助ESP8266-WIFI模块通过MQTT协议将数据上传至华为云物联网平台支持Android与Windows端远程查看与控制。资源包共1个PDF文件约50.43MB内容涵盖项目背景、功能设计、硬件模块组成、系统原理图、框架图与实物模型图等结构完整便于按模块查阅。目前已有311人学习下载。读者可从中获取从传感器驱动、OLED显示、自动与手动模式切换到云端数据存储、远程设备控制及智能报警的完整实现思路适合作为课程设计、竞赛项目或养殖智能化改造的参考方案。1. 养殖场环境监测为什么值得用 STM32 加云平台重做一遍很多做嵌入式的人都接过类似的活一个养殖场老板说夏天棚里温度一高鸡就开始扎堆喘气等工人发现的时候已经死了几十只。传统做法是挂几个温湿度计靠人定时去抄表问题是人不可能 24 小时盯着夜里和凌晨的异常基本靠运气发现。这套「267 基于 STM32 设计的养殖场环境监测系统华为云 IOT」要解决的就是把温湿度、氨气、光照这些指标自动采上来本地判断、本地报警同时通过物联网平台把数据推到云端让老板在手机上就能看到每个棚的实时状态。它适合谁一类是做嵌入式课程设计或毕设的人需要一套从传感器到云端的完整链路另一类是真的想给中小养殖场做低成本改造的工程师预算有限、现场没有稳定有线网络、也不希望数据只存在本地。核心思路是 STM32 做采集和控制WiFi 或 4G 模组做上行物联网平台做数据存储和远程查看。下面按选型、硬件、固件、上云、避坑、进阶的顺序讲透能照着复现。2. 方案选型与硬件链路为什么是 STM32 而不是树莓派2.1 主控选型的三个现实约束养殖场现场的第一个约束是供电和稳定性。棚里通常只有 220V 市电电压波动大夏天风机一启动就有干扰。STM32 这类 MCU 功耗低、没有操作系统、掉电重启后能立刻恢复采集比跑 Linux 的板子更适合长期无人值守。第二个约束是成本一个棚一套采集节点主控加传感器加模组控制在百元级别养殖场才愿意批量铺。第三个约束是实时性氨气超标需要秒级触发本地声光报警MCU 裸机或 RTOS 的响应确定性比应用层进程调度更可控。常见做法是选 STM32F103 系列做入门资源够用、资料多如果要多路模拟量采集和更多串口可以上 STM32F407。我一般会预留一个调试串口和一个模组串口别把 UART 全占满否则后期加屏或加 4G 会很被动。2.2 传感器与执行器的搭配清单监测项常见传感器接口注意事项温度湿度数字温湿度传感器单总线远离热源和风机直吹位置氨气电化学氨气模块UART/模拟需要预热标定周期短光照光照强度模块I2C/模拟避免被灯具直射二氧化碳红外 CO2 模块UART成本较高按需选配执行器继电器组GPIO控制风机、加热、补光氨气传感器是这套系统里最容易翻车的一环。电化学式模块上电后需要预热几分钟才稳定直接拿刚上电的数据去判断会误报。另外它的输出会随温湿度漂移如果只做单点标定用几周后数值就偏了。稳妥做法是记录温湿度并做补偿或者选带温度补偿的模块。2.3 上行链路WiFi 模组还是 4G 模组棚区网络条件决定选型。如果场区有可用的 WiFi 覆盖用 ESP8266 或 ESP32 做透传成本最低AT 指令也简单。如果棚在偏远位置没有 WiFi就得用 4G 模组通过串口发 AT 指令拨号再走 MQTT 上云。两者在固件层的差别主要是初始化流程和断线重连策略业务逻辑可以共用一套。提示模组供电要单独走一路 LDO 或 DC-DC别和传感器共用一条细线模组发射瞬间的电流尖峰会把传感器读数拉偏。3. 固件实现从裸机采集到 MQTT 上云的完整链路3.1 采集任务与数据滤波先看采集部分。下面是一段简化的采集与滤波代码跑在 STM32 上用定时器触发周期采集对模拟量做滑动平均避免单次跳变触发误报。// 采集周期 2s对氨气模拟量做 8 点滑动平均 #define FILTER_LEN 8 static float nh3_buf[FILTER_LEN]; static uint8_t nh3_idx 0; float nh3_filter(float raw) { nh3_buf[nh3_idx] raw; nh3_idx (nh3_idx 1) % FILTER_LEN; float sum 0; for (int i 0; i FILTER_LEN; i) { sum nh3_buf[i]; } return sum / FILTER_LEN; // 返回滤波后的氨气浓度 } void task_sample(void) { float t sht_read_temp(); // 温湿度 float h sht_read_humi(); float nh3 nh3_filter(adc_read_nh3()); float lux bh1750_read(); // 光照 // 本地阈值判断超限立即驱动继电器和蜂鸣器 if (nh3 NH3_ALARM || t TEMP_ALARM) { gpio_set(RELAY_FAN, 1); gpio_set(BUZZER, 1); } pack_and_send(t, h, nh3, lux); // 打包后交给上行任务 }逻辑说明nh3_filter用环形缓冲做滑动平均长度 8 对应约 16 秒窗口能压掉大部分尖峰又不至于让响应太迟钝。task_sample里先做本地判断再上传这样即使网络断了本地报警依然有效这是养殖场场景的底线。参数上NH3_ALARM和TEMP_ALARM要根据养殖品种设定比如禽类对氨气更敏感阈值要调低。3.2 上行数据打包与 MQTT 连接数据打包建议用轻量的 JSON字段名短一点省流量也省解析时间。下面是拼接和发布的示意。// 拼接 JSON 并通过 MQTT 发布到平台 void pack_and_send(float t, float h, float nh3, float lux) { char payload[128]; snprintf(payload, sizeof(payload), {\t\:%.1f,\h\:%.1f,\nh3\:%.2f,\lux\:%.0f}, t, h, nh3, lux); // topic 形如 /sys/{设备ID}/thing/event/property/post mqtt_publish(PROPERTY_TOPIC, payload, strlen(payload)); }逻辑说明snprintf控制长度防止溢出浮点保留位数按传感器精度来温湿度一位小数、氨气两位、光照取整即可。PROPERTY_TOPIC是平台约定的属性上报主题设备侧只需要按格式发平台会自动解析成物模型属性。参数上要注意 MQTT 的 keepalive 和重连间隔网络差的时候把 keepalive 设短一点能更快发现掉线但太短会频繁重连一般 60 秒起步。3.3 断网缓存与补传养殖场网络不稳定是常态断网期间的数据不能直接丢。做法是在本地开一块环形缓冲区把未确认发送的记录存起来重连后按时间顺序补传。// 简易环形缓存存最近 200 条未发送记录 #define CACHE_MAX 200 static char cache[CACHE_MAX][128]; static uint16_t head 0, tail 0; void cache_push(const char *rec) { strncpy(cache[head], rec, 127); head (head 1) % CACHE_MAX; if (head tail) tail (tail 1) % CACHE_MAX; // 覆盖最旧 } void cache_flush(void) { while (tail ! head mqtt_connected()) { mqtt_publish(PROPERTY_TOPIC, cache[tail], strlen(cache[tail])); tail (tail 1) % CACHE_MAX; } }逻辑说明cache_push在每次采集后调用cache_flush在 MQTT 连接成功后调用。缓冲区大小按断网时长和采集频率估算2 秒一条、断网 10 分钟约 300 条所以 200 条只够几分钟实际项目里建议放到 500 条以上或改用外部 Flash。参数上要注意覆盖策略满了之后覆盖最旧数据保证最新数据一定在。4. 上云对接设备注册、物模型与数据流转4.1 设备注册与三元组配置在物联网平台上创建产品定义好物模型属性然后注册设备拿到设备 ID、密钥等信息。这些信息烧进固件或存在外部 Flash 里用于 MQTT 连接时的鉴权。常见做法是把三元组放在一个单独的配置区方便批量生产时用工具写入而不是每次改代码重编译。连接流程一般是模组初始化 → 拨号或连 WiFi → 建立 TCP → MQTT CONNECT带 clientId、username、password→ 订阅下发主题 → 周期上报属性。每一步都要有超时和重试不能卡死在一个状态。4.2 物模型属性与上报格式物模型是平台理解设备数据的关键。把温度、湿度、氨气、光照定义成属性指定类型和单位平台才能正确存储和展示。上报时按属性名组织 JSON平台解析后自动更新设备影子。如果字段名和物模型对不上数据会进不来这是新手最常踩的坑之一。属性名类型单位说明temperaturefloat℃棚内温度humidityfloat%相对湿度nh3floatppm氨气浓度luxintlx光照强度4.3 云端规则与告警联动数据上云后可以配置规则比如氨气连续三次超过阈值就触发告警推送到手机或短信。也可以在云端下发命令控制风机但养殖场场景里本地控制优先级更高云端命令只作为远程手动干预的补充。规则引擎的表达式要写清楚时间窗口和聚合方式否则容易出现一超标就狂发告警的情况。注意云端下发命令和本地自动控制可能冲突固件里要定义优先级本地自动逻辑优先云端命令只在手动模式下生效。5. 避坑与排查这套系统最容易出问题的五个地方5.1 氨气读数一直偏高或漂移现象刚上电读数正常运行几小时后数值缓慢升高或者换一个棚读数差很多。原因电化学传感器需要预热且输出受温湿度影响没有补偿就会漂移。解决上电后先预热 3 到 5 分钟再采信数据固件里加入温湿度补偿系数并定期用标准气体或对比仪器标定。5.2 MQTT 频繁掉线重连现象设备在线状态反复跳变数据时有时无。原因keepalive 设置过短、网络信号弱、模组供电不足导致重启。解决keepalive 设到 60 秒以上检查模组供电是否独立且足够信号弱的地方加天线或改用 4G固件里加重连退避避免疯狂重连把模组拖死。5.3 传感器读数被继电器干扰现象风机一启动温湿度或氨气读数就跳一下。原因继电器动作时产生电磁干扰或者共用电源被拉低。解决继电器线圈加续流二极管传感器供电和继电器供电分开走模拟量走线远离强电软件上继续用滑动平均压尖峰。5.4 数据上报了但平台看不到现象串口打印显示 MQTT 发布成功但平台上设备属性不更新。原因topic 写错、物模型属性名不匹配、JSON 格式不合法。解决对照平台文档检查 topic 层级确认属性名和物模型一致用串口把 payload 打出来逐字核对必要时先用平台提供的调试工具手动发一条验证。5.5 断网后数据丢失现象网络恢复后断网期间的数据查不到。原因没有本地缓存或者缓存被覆盖。解决加环形缓冲区并扩大容量重连后按顺序补传补传时加时间戳平台侧按时间入库。如果断网时间可能很长改用外部 Flash 存容量按小时级估算。6. 进阶技巧让这套系统真正能长期跑下去先说一个验证方法。系统搭好后别急着交付先做 72 小时连续运行测试记录掉线次数、数据完整率、报警触发次数。我一般会写一个简单的统计脚本把串口日志里的上报记录和平台侧数据做比对算一下丢包率。如果丢包超过 1%就要回头查网络和缓存策略而不是安慰自己「差不多能用」。再讲一个具体技巧把阈值判断做成可配置的存在 Flash 里通过云端下发或本地按键修改而不是写死在代码里。养殖场不同季节、不同品种的阈值不一样写死意味着每次调整都要重新烧录现场根本没法维护。下面是一个配置读取的示意。// 阈值配置结构存在 Flash 固定地址 typedef struct { float temp_alarm; float nh3_alarm; uint16_t sample_interval; } alarm_cfg_t; alarm_cfg_t cfg; void cfg_load(void) { flash_read(CFG_ADDR, cfg, sizeof(cfg)); // 校验失败则加载默认值 if (cfg.sample_interval 1 || cfg.sample_interval 60) { cfg.temp_alarm 32.0f; cfg.nh3_alarm 20.0f; cfg.sample_interval 2; } }逻辑说明cfg_load在启动时读取配置做范围校验异常时回落到默认值避免 Flash 损坏导致系统跑飞。参数上sample_interval限制在 1 到 60 秒之间太短费流量太长漏掉突发变化。还有一个容易被忽略的点是设备时间。上报数据带时间戳能让平台侧排序和追溯但 STM32 本身没有 RTC 的话重启后时间就乱了。常见做法是加一颗 RTC 芯片配纽扣电池或者每次连上平台后通过时间同步接口校准。没有准确时间戳断网补传的数据在平台上就是一堆乱序记录排查问题时非常痛苦。最后说一个我自己的习惯每套设备出厂前把固件版本、传感器批次、标定日期写进 Flash 的一个信息区现场出问题时先读这个区能快速判断是硬件批次问题还是软件问题。这个习惯帮我省过很多次来回跑现场的油钱。养殖场环境监测这方向值不值得做如果目标是低成本、可批量、能长期无人值守STM32 加物联网平台的组合目前依然是性价比很高的选择难点不在写代码而在现场细节和长期稳定性。希望帮到你。本文还有配套的精品资源点击获取