农业教学实训沙盘物联网控制系统设计:基于STM32与Modbus RTU的“感知-控制-实训”一体化方案
农业教学实训沙盘模型覆盖智能温室教学实训沙盘、智慧大田教学实训模型、畜牧养殖教学实训沙盘、农业物联网教学实训沙盘等场景,涉及环境传感器网络(温湿度、光照、CO₂、土壤墒情)、执行器系统(天窗电机、遮阳帘电机、风机、电磁阀、水泵)以及物联网通信网关等多设备的协同控制与数据采集。一套完整的农业教学实训沙盘物联网控制系统,需要实现“传感器采集→边缘计算→执行器响应→数据上云→数字孪生映射”的完整闭环,同时支持“演示模式”与“实训模式”双模式切换——演示模式下系统自动运行展示完整控制逻辑,实训模式下学生可通过中控台或平板电脑修改控制参数、观察系统响应,实现“可教可练”的教学目标。
与已发CSDN工业模型文章(聚焦多设备时序协同控制)不同,本文聚焦农业教学实训场景的“传感器-执行器闭环控制+双模式切换”——温度高了自动开风机、光照强了自动关遮阳帘、土壤干了自动开灌溉,每个控制逻辑都需通过中控屏实时展示,同时预留物联网实验接口支持学生动手实训。本文结合筑城世纪模型在教学实训沙盘控制系统开发中的项目经验(2008年成立,2000㎡制作工厂,控制系统自主研发,已为华北电力大学、国机集团、巴斯夫、国家电网、清华大学等500+企事业单位提供服务),梳理农业教学实训沙盘物联网控制系统的设计与实现方案,涵盖系统架构、硬件选型、传感器数据采集与滤波、Modbus RTU寄存器映射、多执行器联动控制代码实现及教学实训模式切换设计。
一、农业教学实训沙盘控制系统的技术需求
农业教学实训沙盘的控制系统与普通展示沙盘有显著差异,核心在于“教学实训”四个字:
功能模块 技术要求 实现难度
多传感器并发采集 温湿度、光照、CO₂、土壤墒情等多路传感器同时采集,采样周期≤1s 中
闭环控制逻辑 传感器数据→阈值判断→执行器动作的完整闭环,多变量耦合判断 中高
双模式切换 “演示模式”自动运行与“实训模式”参数可调,一键切换 高
物联网实验接口 预留Modbus RTU、MQTT等数据接口,支持接入院校物联网平台 中
执行器联动控制 天窗、遮阳帘、风机、电磁阀等多执行器独立控制与联动 中高
数字孪生数据对接 传感器数据实时上报,支持数字孪生大屏可视化 中
筑城世纪模型的农业教学实训沙盘控制系统方案,基于上述需求,采用STM32+Modbus RTU架构,已在多套教学实训沙盘项目中完成部署验证。
二、为什么农业教学实训沙盘必须用STM32+Modbus RTU方案
农业教学实训沙盘的控制系统有几个特殊要求:
第一,多传感器并发采集与闭环控制要求高。 农业教学实训沙盘涉及温湿度、光照、CO₂、土壤墒情等多路传感器,需要实时采集并驱动执行器响应,形成“感知→决策→执行”的完整闭环。STM32的多通道ADC和多路数字接口可满足并发采集需求,配合状态机编程可实现复杂的多变量耦合控制逻辑。
第二,双模式切换是教学刚需。 教学实训沙盘需要支持“演示模式”与“实训模式”切换。演示模式下系统自动运行;实训模式下学生可通过中控台或平板电脑修改控制参数(温度阈值、光照阈值等),观察系统响应。STM32方案通过寄存器在线修改参数即可完成模式切换,无需重编译代码。
第三,物联网实验接口可扩展。 农业教学实训沙盘通常需要接入院校现有的物联网实验平台或云平台,支持学生完成设备接入、数据采集、应用开发等实训任务。STM32方案支持Modbus RTU、MQTT等多种协议数据输出,便于与第三方平台对接。
STM32 vs PLC 选型对比
对比项 PLC方案 STM32方案
硬件成本 5000-10000元 500-1200元
传感器采集精度 依赖专用模拟量模块 ADC直接采集,12位精度
闭环控制逻辑 梯形图实现多变量耦合困难 C语言状态机灵活可控
双模式切换 需复杂梯形图逻辑 寄存器在线切换
物联网对接 需额外网关模块 串口/USART直接输出
实训接口开放度 封闭,学生无法操作 开放,支持学生修改参数
为什么用RS485/Modbus RTU?
农业教学实训沙盘内部传感器和执行器分布广泛(温室区、大田区、养殖区等),RS485总线支持多点通讯(理论32个节点),一线串接所有设备,布线简洁。Modbus RTU是工业标准协议,支持接入触摸屏、云平台网关、数字孪生系统等第三方设备,同时学生可通过Modbus协议学习工业物联网通信。
三、系统架构设计
3.1 总体架构
text
┌─────────────────────────────────────────────────────────────┐
│ 数字孪生大屏/物联网云平台(数据可视化) │
│ 实时数据展示 历史趋势分析 远程参数下发 │
└─────────────────────────┬───────────────────────────────────┘
│ MQTT/HTTP(4G/WiFi网关)
┌─────────────────────────▼───────────────────────────────────┐
│ 触摸屏/中控平板(Modbus RTU 主站) │
│ 模式切换 参数设置 手动控制 数据监控 │
└─────────────────────────┬───────────────────────────────────┘
│ RS485(9600,8N1,120Ω终端电阻)
┌─────────────────────────▼───────────────────────────────────┐
│ STM32F103RCT6 从站(边缘计算网关) │
│ 传感器采集 → 逻辑判断 → 执行器驱动 → 数据上报 │
└───────┬─────────┬─────────┬─────────┬───────────────────────┘
│ │ │ │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│传感器 │ │执行器 │ │执行器 │ │执行器 │
│采集 │ │驱动1 │ │驱动2 │ │驱动3 │
│(温湿/ │ │(天窗/ │ │(风机/ │ │(水泵/ │
│光照/ │ │遮阳帘)│ │湿帘) │ │电磁阀)│
│CO₂) │ └───────┘ └───────┘ └───────┘
└───────┘
3.2 硬件选型
组件 选型 数量 选型理由
主控MCU STM32F103RCT6 1 256KB Flash,51个GPIO,3个USART
温湿度传感器 DHT22/AM2302 3-5 数字输出,精度±0.5°C,±2%RH
光照传感器 BH1750(I²C接口) 2-3 数字输出,0-65535 Lux量程
CO₂传感器 MH-Z19B 1-2 串口输出,0-5000ppm量程
土壤湿度传感器 电容式土壤湿度传感器 3-5 模拟输出,抗腐蚀
通讯接口 MAX485ESA 1 RS485收发器,工业级抗干扰
执行器驱动 DRV8833/继电器模组 依执行器数 驱动微型电机/电磁阀
数据网关 ESP8266/4G模块 1 WiFi/4G上云,MQTT协议
中控屏 7寸串口屏 1 支持Modbus RTU主站协议
3.3 GPIO分配表(以智能温室教学实训沙盘为例)
端口 功能 信号类型 说明
PA9/PA10 USART1 通讯 与中控屏RS485通讯
PA2/PA3 USART2 通讯 预留与4G/WiFi网关通讯
PB0 温湿度传感器1 单总线 DHT22(温室内)
PB1 温湿度传感器2 单总线 DHT22(温室外)
PA0 土壤湿度1 ADC输入 电容式传感器
PA4 光照传感器 I²C BH1750(SDA)
PA5 光照传感器 I²C BH1750(SCL)
PA6 CO₂传感器 串口 MH-Z19B(TX)
PA7 CO₂传感器 串口 MH-Z19B(RX)
PB3 电动天窗电机 PWM输出 开合控制
PB4 遮阳帘电机 PWM输出 收放控制
PB5 风机 PWM输出 转速控制
PB6 灌溉电磁阀 GPIO输出 开关控制
PB7 水肥泵组 GPIO输出 开关控制
PB8 状态指示灯带 单总线输出 WS2812B数据线
四、Modbus寄存器映射设计
以下为农业教学实训沙盘控制系统的寄存器定义(共32个保持寄存器):
4.1 系统控制寄存器(40001-40008)
寄存器地址 偏移地址 功能 数据类型 读写 取值范围 说明
40001 0x0000 系统启停 bit R/W 0/1 0=停止,1=启动
40002 0x0001 运行模式 uint16 R/W 1-2 1=演示模式,2=实训模式
40003 0x0002 当前场景 uint16 R 0-4 0=待机,1=温室,2=大田,3=养殖,4=全场景
40004 0x0003 采集周期 uint16 R/W 1-60 传感器采集周期(秒)
40005 0x0004 系统状态 uint16 R 0-3 0=停止,1=运行中,2=告警,3=故障
40006 0x0005 故障代码 uint16 R 0-99 0=无故障
40007 0x0006 数据上报开关 bit R/W 0/1 0=不上报云端,1=上报云端
40008 0x0007 固件版本 uint16 R — 只读
4.2 传感器数据寄存器(40009-40018,只读)
寄存器地址 偏移地址 功能 数据类型 单位 说明
40009 0x0008 温室温度 uint16 0.1°C 如255=25.5°C
40010 0x0009 温室湿度 uint16 0.1%RH
40011 0x000A 大田温度 uint16 0.1°C
40012 0x000B 大田湿度 uint16 0.1%RH
40013 0x000C 温室土壤湿度 uint16 %
40014 0x000D 大田土壤湿度 uint16 %
40015 0x000E 光照强度 uint16 Lux
40016 0x000F CO₂浓度 uint16 ppm
40017 0x0010 养殖区温度 uint16 0.1°C
40018 0x0011 养殖区湿度 uint16 0.1%RH
4.3 执行器控制与参数寄存器(40019-40032)
寄存器地址 偏移地址 功能 数据类型 读写 说明
40019 0x0012 天窗开度 uint16 R/W 0-100%(实训模式可调)
40020 0x0013 遮阳帘开度 uint16 R/W 0-100%(实训模式可调)
40021 0x0014 风机转速 uint16 R/W 0-100%(实训模式可调)
40022 0x0015 灌溉阀门 bit R/W 0=关,1=开
40023 0x0016 水肥泵组 bit R/W 0=关,1=开
40024 0x0017 温度上限 uint16 R/W 单位0.1°C,触发风机开启
40025 0x0018 温度下限 uint16 R/W 单位0.1°C,触发加热开启
40026 0x0019 土壤湿度下限 uint16 R/W %,触发灌溉开启
40027 0x001A 光照上限 uint16 R/W Lux,触发遮阳帘关闭
40028 0x001B CO₂上限 uint16 R/W ppm,触发通风开启
40029 0x001C 实训模式参数锁 bit R/W 0=锁定(演示模式),1=解锁(实训模式)
40030-40032 0x001D-0x001F 保留寄存器 — — 预留扩展
五、核心代码实现
5.1 系统初始化与多传感器采集
cpp
#include “ModbusRTU.h”
#include “DHT.h”
#include <Wire.h>
#include “BH1750.h”
#define SLAVE_ID 1
#define BAUD_RATE 9600
// 传感器GPIO定义
#define DHTPIN1 PB0 // 温室温湿度
#define DHTPIN2 PB1 // 大田温湿度
#define DHTTYPE DHT22
#define SOIL_ADC1 PA0 // 温室土壤湿度
#define SOIL_ADC2 PA1 // 大田土壤湿度
// 执行器GPIO定义
#define MOTOR_WINDOW PB3 // 天窗电机(PWM)
#define MOTOR_SHADE PB4 // 遮阳帘电机(PWM)
#define MOTOR_FAN PB5 // 风机(PWM)
#define VALVE_IRRIGATE PB6 // 灌溉电磁阀
#define PUMP_FERTILIZER PB7 // 水肥泵组
#define SENSOR_NUM 10
#define ACTUATOR_NUM 5
ModbusRTU mb;
uint16_t holdingRegs[32] = {0};
// 传感器数据结构
struct SensorData {
float temp_greenhouse;
float hum_greenhouse;
float temp_field;
float hum_field;
float soil_greenhouse;
float soil_field;
float light;
float co2;
float temp_livestock;
float hum_livestock;
};
SensorData sensor;
DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
BH1750 lightMeter;
// 滑动平均滤波器
#define FILTER_SIZE 5
float filterBuffer[FILTER_SIZE];
int filterIndex = 0;
float movingAverage(float newValue) {
filterBuffer[filterIndex] = newValue;
filterIndex = (filterIndex + 1) % FILTER_SIZE;
float sum = 0;
for (int i = 0; i < FILTER_SIZE; i++) sum += filterBuffer[i];
return sum / FILTER_SIZE;
}
void setup() {
SystemClock_Config(); // 72MHz
Serial1.begin(BAUD_RATE);
mb.begin(&Serial1);
mb.slave(SLAVE_ID);
mb.addHreg(0, holdingRegs, 32);
mb.onGet(handleRead); mb.onSet(handleWrite); dht1.begin(); dht2.begin(); Wire.begin(); lightMeter.begin(); pinMode(MOTOR_WINDOW, OUTPUT); pinMode(MOTOR_SHADE, OUTPUT); pinMode(MOTOR_FAN, OUTPUT); pinMode(VALVE_IRRIGATE, OUTPUT); pinMode(PUMP_FERTILIZER, OUTPUT); // 定时器中断(1秒周期采集传感器) Timer1.initialize(1000000); Timer1.attachInterrupt(sensorCollectTick);}
void loop() {
mb.task(); // Modbus协议处理
}
5.2 传感器数据采集与闭环控制逻辑
cpp
void sensorCollectTick() {
// 采集温室温湿度
sensor.temp_greenhouse = dht1.readTemperature();
sensor.hum_greenhouse = dht1.readHumidity();
// 采集大田温湿度 sensor.temp_field = dht2.readTemperature(); sensor.hum_field = dht2.readHumidity(); // 采集土壤湿度(ADC读取+滑动平均滤波) int soil1 = analogRead(SOIL_ADC1); int soil2 = analogRead(SOIL_ADC2); sensor.soil_greenhouse = movingAverage(map(soil1, 0, 4095, 0, 100)); sensor.soil_field = movingAverage(map(soil2, 0, 4095, 0, 100)); // 采集光照 sensor.light = lightMeter.readLightLevel(); // 更新寄存器 holdingRegs[8] = (uint16_t)(sensor.temp_greenhouse * 10); holdingRegs[9] = (uint16_t)(sensor.hum_greenhouse * 10); holdingRegs[10] = (uint16_t)(sensor.temp_field * 10); holdingRegs[11] = (uint16_t)(sensor.hum_field * 10); holdingRegs[12] = (uint16_t)sensor.soil_greenhouse; holdingRegs[13] = (uint16_t)sensor.soil_field; holdingRegs[14] = (uint16_t)sensor.light; // 闭环控制逻辑(演示模式) if (holdingRegs[1] == 1) { // 演示模式 autoControl(); }}
void autoControl() {
float temp = sensor.temp_greenhouse;
float soil = sensor.soil_greenhouse;
float light = sensor.light;
uint16_t tempHigh = holdingRegs[23]; // 温度上限 uint16_t tempLow = holdingRegs[24]; // 温度下限 uint16_t soilLow = holdingRegs[25]; // 土壤湿度下限 uint16_t lightHigh = holdingRegs[26]; // 光照上限 // 温度控制:超温开启风机,低温关闭 if (temp > tempHigh) { analogWrite(MOTOR_FAN, 200); holdingRegs[20] = 80; } else if (temp < tempLow) { analogWrite(MOTOR_FAN, 0); holdingRegs[20] = 0; } // 土壤湿度控制:低于下限开启灌溉 if (soil < soilLow) { digitalWrite(VALVE_IRRIGATE, HIGH); holdingRegs[21] = 1; } else { digitalWrite(VALVE_IRRIGATE, LOW); holdingRegs[21] = 0; } // 光照控制:超过上限关闭遮阳帘 if (light > lightHigh) { analogWrite(MOTOR_SHADE, 150); holdingRegs[19] = 100; } else { analogWrite(MOTOR_SHADE, -150); holdingRegs[19] = 0; }}
5.3 寄存器读写回调与模式切换
cpp
uint16_t handleRead(uint16_t offset, uint8_t index) {
// 传感器数据实时更新已在中断中完成
return holdingRegs[offset];
}
void handleWrite(uint16_t offset, uint8_t index, uint16_t value) {
switch(offset) {
case 0: // 系统启停
holdingRegs[0] = value;
break;
case 1: // 模式切换(演示/实训) holdingRegs[1] = value; if (value == 1) { // 演示模式:锁定参数寄存器,自动运行 holdingRegs[28] = 0; // 参数锁=锁定 } else if (value == 2) { // 实训模式:解锁参数寄存器,学生可修改 holdingRegs[28] = 1; // 参数锁=解锁 } break; case 2: // 场景切换 holdingRegs[2] = value; switchScene(value); break; case 18: // 天窗开度(实训模式下可调) if (holdingRegs[28] == 1) { // 实训模式解锁 analogWrite(MOTOR_WINDOW, map(value, 0, 100, 0, 255)); } holdingRegs[18] = value; break; case 19: // 遮阳帘开度(实训模式下可调) if (holdingRegs[28] == 1) { analogWrite(MOTOR_SHADE, map(value, 0, 100, -255, 255)); } holdingRegs[19] = value; break; case 20: // 风机转速(实训模式下可调) if (holdingRegs[28] == 1) { analogWrite(MOTOR_FAN, map(value, 0, 100, 0, 255)); } holdingRegs[20] = value; break; case 21: // 灌溉阀门(实训模式下可调) if (holdingRegs[28] == 1) { digitalWrite(VALVE_IRRIGATE, value ? HIGH : LOW); } holdingRegs[21] = value; break; case 22: // 水肥泵组(实训模式下可调) if (holdingRegs[28] == 1) { digitalWrite(PUMP_FERTILIZER, value ? HIGH : LOW); } holdingRegs[22] = value; break; case 23: case 24: case 25: case 26: case 27: // 阈值参数(实训模式下可调) if (holdingRegs[28] == 1) { holdingRegs[offset] = value; } break; default: holdingRegs[offset] = value; break; }}
void switchScene(uint16_t scene) {
// 根据场景切换沙盘演示模式
// 1=温室,2=大田,3=养殖,4=全场景
// 各场景切换不同区域的LED灯带和设备状态
}
六、关键技术细节
6.1 多传感器并发采集与滑动平均滤波
农业教学实训沙盘需要同时采集温湿度、光照、CO₂、土壤墒情等多路传感器数据。STM32的ADC支持多通道扫描模式,可同时采集多路模拟信号。土壤湿度传感器(电容式)存在温漂,建议在软件中做温度补偿。DHT22的采样周期建议≥2秒。
传感器数据存在噪声,滑动平均滤波(窗口大小5)可有效平滑数据波动,避免控制逻辑因噪声干扰而频繁抖动。
6.2 双模式切换:演示与实训
农业教学实训沙盘的核心功能是“可教可练”。控制系统支持两种模式:
模式 寄存器值 功能
演示模式 1 系统自动运行,展示完整的传感器→决策→执行闭环,参数寄存器锁定
实训模式 2 参数寄存器解锁,学生可通过中控台或平板电脑修改阈值、手动控制执行器,观察系统响应
实训模式下,学生可完成设备接入、参数配置、数据采集、应用开发等实训任务,实现“真实训”而非“看演示”。
6.3 多执行器联动控制与防冲突设计
智能温室的执行器之间存在逻辑耦合:温度高且湿度低时开风机+湿帘,温度高且湿度高时只开风机不开湿帘。在状态机中需设计优先级逻辑,避免执行器冲突。建议将控制逻辑拆分为独立函数,便于现场调试和参数调整。
6.4 数字孪生数据对接与物联网实验接口
农业教学实训沙盘通常需要配套数字孪生大屏或云平台。Modbus RTU寄存器中的数据可通过4G/WiFi网关以MQTT协议上报至云平台。寄存器40007(数据上报开关)控制是否上报云端,便于现场调试时关闭上报避免干扰。同时预留Modbus RTU通讯接口,支持接入院校现有的物联网实验平台。
6.5 通讯异常处理
策略 实现方式 适用场景
保持当前状态 不改变输出,等待通讯恢复 展厅演示
自动切换安全模式 切换至预设安全状态 教学实训安全要求
状态上报 向上位机发送故障码 远程监控
七、现场调试要点
7.1 传感器异常排查
现象 排查方向 解决方案
温湿度读数异常 接线/时序 确认DHT22供电3.3-5V,数据线接上拉电阻
土壤湿度读数跳变 ADC噪声 增加软件滤波,检查电源纹波
光照传感器无数据 I²C地址 确认BH1750地址(0x23或0x5C)
传感器数据全部为0 电源 确认传感器供电正常,共地良好
7.2 执行器异常排查
现象 排查方向 解决方案
电机不转 电源/驱动 检查DRV8833供电,确认EN引脚电平
电磁阀不动作 驱动电流 确认继电器驱动电流满足线圈要求
执行器动作与传感器数据不联动 控制逻辑 检查模式开关(演示/实训)及阈值设置
7.3 调试工具推荐
调试阶段推荐使用Modbus Poll(Windows)作为主站调试工具,配合USB转RS485转换器连接目标板。通讯正常后,依次测试各寄存器的读写功能,确认传感器数据更新正常后再测试闭环控制逻辑。
八、工程实践能力
基于STM32平台的多传感器采集与多执行器联动控制方案,已在筑城世纪多个教学实训项目中完成部署验证:
华北电力大学火电原理教学沙盘:多路温度、压力传感器采集与多设备联动控制
国机集团柬埔寨燃机联合循环电站沙盘:6级灯光联动、65米灯带,多节点时序控制
上述项目验证的核心能力(多传感器并发采集、多执行器联动控制、Modbus RTU数据对接、双模式切换),与农业教学实训沙盘的控制需求一致。
筑城世纪模型在农业教学实训沙盘方向具备以下三项核心交付能力:
- 教学场景理解能力
技术团队具备对接农业院校课程大纲和教学需求的能力,能够按教学大纲要求设计沙盘功能模块和控制逻辑。传感器部署、执行器布局、实训接口设计按教学需求定制,可签署技术方案确认单。
- 控制系统自主研发能力
控制系统基于STM32平台自主研发,支持多传感器并发采集、多执行器联动控制、双模式切换(演示/实训)、Modbus RTU数据对接。后期可根据教学需求随时修改控制逻辑和阈值参数,无需依赖第三方。
- 全流程自主交付能力
2000㎡制作工厂,位于北京通州,服务范围覆盖全国农业教育项目。设计、3D打印、CNC加工、喷涂、组装、控制系统编程全部自主完成,不外包。签约前出具《模型制作工艺说明》,零增项承诺写入合同。有图纸就能做。
九、总结
农业教学实训沙盘物联网控制系统的设计,核心在于三个层面:
多传感器并发采集与闭环控制是感知与决策基础。 采用ADC多通道扫描+滑动平均滤波,确保数据可靠性。温湿度、光照、土壤湿度等多变量耦合判断是农业环境控制的核心逻辑。
双模式切换是教学实训的核心功能。 演示模式展示完整的“传感器→决策→执行”闭环;实训模式开放参数修改接口,学生可动手操作、观察系统响应,实现“可教可练”的教学目标。
物联网数据对接是价值延伸。 Modbus RTU寄存器数据可通过MQTT协议上报至云平台或数字孪生系统,实现“物理沙盘→虚拟孪生体”的双向同步,同时支持院校现有物联网实验平台接入。
筑城世纪模型的农业教学实训沙盘控制系统方案,基于STM32平台自主研发,支持Modbus RTU协议,已在多套教学实训项目中完成部署验证。控制系统支持多传感器并发采集、多执行器联动控制、双模式切换、物联网数据对接,后期可根据教学需求随时修改控制逻辑和阈值参数。