news 2026/10/6 11:48:20

温室大棚自动化控制系统方案设计:从传感器选型到边缘网关部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
温室大棚自动化控制系统方案设计:从传感器选型到边缘网关部署

简介:这份文档面向智慧农业与设施农业领域的从业者、自动化控制工程师及农业物联网学习者,围绕温室大棚自动化控制系统给出整体解决方案设计。内容涵盖风向、风速、温湿度、光照、气压、雨量、太阳辐射及土壤温湿度等多类环境要素的采集与调控,并涉及开窗、卷膜、风机湿帘、补光、灌溉施肥等执行设备的自动控制逻辑。方案还讨论了以太网组网、生产管理网与生产控制网的分层结构、MODBUS总线通讯协议,以及上位机组态软件、数据库与远程监控系统的配合方式,并延伸至风机、卷帘、滴灌、灯光、能源计量、视频监控与语音广播等核心功能模块。资源包为1个doc文档,大小约23KB,结构紧凑,便于快速通读与方案参考。目前已有74人学习下载,适合需要了解温室环境控制架构、组网思路与远程监控实现路径的读者作为方案设计参考。

1. 温室大棚里那套自动化系统,到底在控什么

很多做农业物联网的同行都遇到过这种场景:甲方指着连栋温室说“给我上一套自动化控制系统”,但问到具体控什么、怎么控、控到什么精度,双方就开始打太极。温室自动化控制系统解决方案设计这件事,核心不是买一堆传感器和执行器堆进去,而是把“环境参数采集—决策逻辑—执行机构动作”这条闭环链路设计清楚。它解决的是人工巡检不及时、昼夜温差波动大、水肥浪费严重这三类典型问题,适合种植经济作物(草莓、番茄、育苗)的温室经营者,也适合承接农业智能化项目的集成商。一套能落地的方案,通常覆盖温度、湿度、光照、CO₂浓度、土壤墒情五个维度的监测,再联动风机、湿帘、遮阳帘、补光灯、滴灌阀这几类执行设备。方案设计文档要回答的不是“用了什么牌子”,而是“什么条件下触发什么动作、动作持续多久、异常怎么兜底”。

2. 温室自动化控制系统的感知层与执行层怎么选型

2.1 传感器选型:精度、接口与布点密度

温室环境跟室外完全不同,高温高湿是常态,普通民用传感器进去撑不过一个梅雨季。选型时我一般按三个维度卡:防护等级至少 IP65,温度量程覆盖 -20~60℃且精度 ±0.3℃以内,湿度量程 0~100%RH 且精度 ±3%RH。CO₂传感器优先选 NDIR 非色散红外原理的,别用那些电化学的,温室里湿度一上来读数就飘。光照用光合有效辐射(PAR)传感器比普通照度计更贴合作物需求,单位是 μmol/(m²·s)。

接口方面,RS485 Modbus-RTU 是最稳妥的选择,抗干扰能力强,一根总线能挂几十个节点。布点密度有个血泪经验:一个 500㎡ 的温室,温度传感器至少布 3 个点(中部、靠窗、靠门),因为温室内部温差能到 3~5℃,只布一个点做控制,靠窗那排作物永远吃亏。

参数推荐指标说明
温度精度±0.3℃低于此精度控制逻辑会频繁误触发
湿度精度±3%RH高湿段误差大的传感器直接淘汰
防护等级IP65 及以上温室喷淋和冷凝水是传感器杀手
通信接口RS485 Modbus-RTU抗干扰、易组网、成本可控
供电12~24V DC与执行器统一供电,减少电源种类

2.2 执行机构:风机、湿帘、遮阳与滴灌的联动逻辑

执行层最容易翻车的地方不是设备本身,而是联动逻辑没设计好。举个例子:夏天降温,正确顺序是先开湿帘水泵,等湿帘湿透后再开风机,否则干吹风只会把热空气灌进来。关的时候反过来,先关风机再关水泵。这个时序如果写反了,降温效果直接打对折。

遮阳帘的控制要跟光照传感器联动,但别只看瞬时值。我一般设两级阈值:光照超过 60000 lux 且持续 5 分钟,展开内遮阳;超过 80000 lux 且持续 3 分钟,展开外遮阳。加“持续时间”这个条件是为了避免云飘过来遮一下又走,帘子来回抖。

滴灌阀的控制要结合土壤墒情和作物生育期。苗期土壤含水量低于 60% 才开阀,结果期低于 70% 就要开。每次灌溉时长根据流量计反馈动态调整,别写死一个固定分钟数。

# 降温联动时序控制伪代码 def cooling_sequence(temp, humidity, temp_threshold=30.0): """ 温室降温联动:先湿帘后风机,关闭时反序 temp: 当前温度 ℃ humidity: 当前湿度 %RH temp_threshold: 降温触发温度阈值 """ if temp > temp_threshold and humidity < 80: # 第一步:开启湿帘水泵,等待湿帘湿透 wet_curtain_pump.on() time.sleep(120) # 等待湿帘充分湿润,实际项目按湿帘面积调整 # 第二步:湿帘湿透后开启风机 fan.on() return "cooling_active" elif temp < temp_threshold - 2: # 关闭时反序:先关风机,再关水泵 fan.off() time.sleep(30) wet_curtain_pump.off() return "cooling_stopped" return "idle"

这段逻辑的关键在time.sleep(120)这个等待时间,它不是随便写的。湿帘从干燥到完全湿透,跟水泵流量、湿帘厚度、面积都有关,一般 100mm 厚度的湿帘需要 90~150 秒。等待时间不够,风机抽进来的就是干热风,温度不降反升。参数temp_threshold建议设在作物适宜温度上限往上 2℃,比如番茄设 30℃,草莓设 26℃。

3. 控制层:PLC、单片机还是边缘网关

3.1 三种控制方案的适用边界

控制层选型是方案设计里分歧最大的地方。PLC 稳定可靠但成本高,适合 1000㎡ 以上的连栋温室;单片机(STM32 这类)成本低但开发周期长,适合小面积单栋棚;边缘网关(树莓派/工控机跑 Node-RED 或 Python)灵活性强、支持复杂逻辑和云端对接,适合需要远程管理和数据分析的场景。

我一般这么分:如果甲方只要求本地自动控制、预算紧张,用 PLC 或单片机;如果要求手机远程看数据、改参数、收报警,直接上边缘网关方案。边缘网关的坑在于稳定性,消费级硬件在温室高温环境下容易死机,必须选宽温工业级产品,工作温度至少 -20~70℃。

方案适用面积成本区间开发周期远程能力
PLC1000㎡以上高中等需加通信模块
单片机500㎡以下低长需自行开发
边缘网关不限中等短原生支持

3.2 边缘网关上的控制逻辑部署

以边缘网关跑 Python 控制逻辑为例,核心是一个定时采集+决策循环。采集周期建议 10~30 秒,太短了数据噪声大,太长了响应滞后。决策逻辑用状态机来写比一堆 if-else 清晰得多。

# 边缘网关主控制循环(简化版) import time from sensors import read_all_sensors from actuators import Fan, WetCurtain, Shade, DripValve fan = Fan(gpio_pin=17) wet_curtain = WetCurtain(gpio_pin=27) shade = Shade(gpio_pin=22) drip = DripValve(gpio_pin=23) STATE = "idle" last_light_high = 0 # 记录光照超阈值起始时间 while True: data = read_all_sensors() # 返回 dict: temp, humidity, light, co2, soil_moisture now = time.time() # 高温降温逻辑 if data["temp"] > 30 and data["humidity"] < 80: if STATE != "cooling": wet_curtain.on() time.sleep(120) fan.on() STATE = "cooling" elif data["temp"] < 28 and STATE == "cooling": fan.off() time.sleep(30) wet_curtain.off() STATE = "idle" # 遮阳逻辑:光照持续超阈值才动作 if data["light"] > 60000: if last_light_high == 0: last_light_high = now elif now - last_light_high > 300: # 持续5分钟 shade.extend() else: last_light_high = 0 shade.retract() # 滴灌逻辑:按土壤墒情 if data["soil_moisture"] < 60: drip.open() elif data["soil_moisture"] > 75: drip.close() time.sleep(15) # 采集间隔15秒

这段代码里time.sleep(15)是采集间隔,实际项目建议设 10~30 秒。last_light_high这个变量用来实现“持续时间”判断,避免遮阳帘频繁抖动。滴灌的阈值 60% 和 75% 之间留了 15% 的回差,这是防止阀门在临界值附近反复开关,继电器寿命会因此大打折扣。

4. 通信与数据链路:从 RS485 到云平台

4.1 现场总线组网与 Modbus 轮询

温室现场通信最稳的方案还是 RS485 总线跑 Modbus-RTU。布线时注意两点:一是总线要走手拉手拓扑,不能星型分叉;二是终端要加 120Ω 匹配电阻,否则长距离通信会丢包。轮询周期跟节点数量有关,每个节点响应时间大约 50~100ms,20 个节点一轮下来 1~2 秒,完全够用。

Modbus 寄存器地址映射要在方案文档里写清楚,别让后面接手的人猜。我一般会做一张表,把每个传感器的寄存器地址、数据类型、缩放因子、单位都列出来。

# Modbus RTU 轮询读取多传感器示例 from pymodbus.client import ModbusSerialClient client = ModbusSerialClient( port='/dev/ttyUSB0', baudrate=9600, parity='N', stopbits=1, bytesize=8, timeout=1 ) # 寄存器映射表:地址 -> (名称, 缩放因子, 单位) REGISTER_MAP = { 0x0000: ("air_temp", 0.1, "℃"), 0x0001: ("air_humidity", 0.1, "%RH"), 0x0002: ("light_par", 1.0, "μmol/(m²·s)"), 0x0003: ("co2", 1.0, "ppm"), 0x0004: ("soil_moisture", 0.1, "%"), } def poll_sensors(slave_id=1): result = {} for addr, (name, scale, unit) in REGISTER_MAP.items(): resp = client.read_holding_registers(addr, 1, slave=slave_id) if not resp.isError(): result[name] = resp.registers[0] * scale else: result[name] = None # 读取失败标记 return result

baudrate=9600是 Modbus 默认速率,节点多、线缆长的时候可以降到 4800 提高抗干扰能力。timeout=1秒是单次读取超时,如果现场干扰大可以适当加大,但别超过 3 秒,否则轮询周期会被拖垮。读取失败返回None而不是抛异常,是为了让上层逻辑能区分“传感器坏了”和“通信暂时抖动”。

4.2 上云链路与断网续传

数据上云有两条路:MQTT 直连和 HTTP 上报。MQTT 更适合温室场景,长连接、低功耗、支持 QoS 等级。QoS 设 1(至少送达一次)就够了,QoS 2 开销太大没必要。

断网续传是必须做的。温室现场网络不稳定是常态,边缘网关本地要缓存至少 24 小时的数据。网络恢复后按时间顺序补传,别一股脑全推上去,容易把云平台打挂。

# MQTT 上报 + 本地缓存断网续传 import paho.mqtt.client as mqtt import sqlite3 import json # 本地缓存数据库 conn = sqlite3.connect('sensor_cache.db') conn.execute('''CREATE TABLE IF NOT EXISTS cache (ts INTEGER, payload TEXT)''') def on_connect(client, userdata, flags, rc): if rc == 0: # 连接成功后补传缓存数据 rows = conn.execute('SELECT ts, payload FROM cache ORDER BY ts').fetchall() for ts, payload in rows: client.publish('greenhouse/sensors', payload, qos=1) conn.execute('DELETE FROM cache') conn.commit() client = mqtt.Client() client.on_connect = on_connect client.connect('mqtt_broker_address', 1883, 60) def upload(data): payload = json.dumps(data) if client.is_connected(): client.publish('greenhouse/sensors', payload, qos=1) else: # 断网时写入本地缓存 conn.execute('INSERT INTO cache VALUES (?, ?)', (int(time.time()), payload)) conn.commit()

缓存表只存时间戳和 JSON 载荷,结构简单但够用。补传时按时间排序,保证云端数据时序正确。qos=1确保消息至少送达一次,极端情况下可能重复,云端做去重就行。

5. 避坑与排查:温室自动化系统落地时最容易翻车的五件事

5.1 传感器被冷凝水泡坏,读数恒定为 99%RH

现象:湿度读数连续几天都是 99%RH 不变,温度也偏高。原因:温室夜间冷凝水顺着线缆流进传感器壳体,PCB 受潮短路。解决:传感器安装时线缆做滴水弯,壳体朝下,接头处缠防水胶带。已经进水的拆开用无水酒精清洗烘干,但多半救不回来,直接换 IP65 以上的。

5.2 遮阳帘频繁抖动,电机过热保护

现象:遮阳帘在阴天反复展开收回,电机烫手。原因:控制逻辑只看瞬时光照值,云层飘动导致光照在阈值附近波动。解决:加持续时间判断,光照超阈值持续 3~5 分钟才动作,同时设 10% 的回差,比如展开阈值 60000 lux,收回阈值设 54000 lux。

5.3 Modbus 通信时通时断,换线也没用

现象:传感器数据偶尔丢失,换屏蔽线、换电源都试了还是断。原因:RS485 总线没加终端电阻,或者拓扑是星型而不是手拉手。解决:检查总线两端是否各有一个 120Ω 电阻,中间节点不能有分支超过 1 米。如果已经布成星型,加一个 RS485 集线器补救。

5.4 边缘网关夏天死机,重启就好

现象:每年 7~8 月网关频繁死机,早上重启后能用半天。原因:消费级网关工作温度上限只有 50~60℃,温室中午内部温度能到 55℃ 以上。解决:换宽温工业级网关(-20~70℃),或者把网关装在控制柜里加散热风扇。别用树莓派裸板放温室里,这是血泪教训。

5.5 滴灌阀关不严,土壤一直过湿

现象:土壤含水量一直偏高,滴灌阀断电后仍有水流。原因:滴灌水压过高,电磁阀关闭时被水压顶开;或者阀芯被泥沙卡住。解决:在电磁阀前加装减压阀,把水压降到阀的额定范围;进水口加 Y 型过滤器,定期清洗滤网。已经卡住的拆开清理阀芯,密封圈老化的换新。

6. 把控制精度再提一档:模糊控制与作物模型联动

前面讲的都是阈值控制,简单可靠但有个硬伤:温度到了 30℃ 才开风机,实际上 28℃ 时作物已经开始受胁迫了。想再进一步,可以上模糊控制。模糊控制不设硬阈值,而是把温度、湿度、光照的偏差和变化率作为输入,输出风机的档位、湿帘水泵的占空比。实现上可以用 Python 的scikit-fuzzy库,定义好隶属度函数和规则表,跑起来比 PID 还稳。

# 模糊控制降温示例(scikit-fuzzy) import numpy as np import skfuzzy as fuzz from skfuzzy import control as ctrl # 输入:温度偏差、温度变化率 temp_error = ctrl.Antecedent(np.arange(-5, 15, 0.5), 'temp_error') temp_rate = ctrl.Antecedent(np.arange(-2, 2, 0.1), 'temp_rate') # 输出:风机档位 0~100% fan_speed = ctrl.Consequent(np.arange(0, 101, 1), 'fan_speed') # 隶属度函数 temp_error['low'] = fuzz.trimf(temp_error.universe, [-5, 0, 3]) temp_error['mid'] = fuzz.trimf(temp_error.universe, [1, 5, 9]) temp_error['high'] = fuzz.trimf(temp_error.universe, [7, 12, 15]) temp_rate['falling'] = fuzz.trimf(temp_rate.universe, [-2, -0.5, 0]) temp_rate['stable'] = fuzz.trimf(temp_rate.universe, [-0.3, 0, 0.3]) temp_rate['rising'] = fuzz.trimf(temp_rate.universe, [0, 0.5, 2]) fan_speed['low'] = fuzz.trimf(fan_speed.universe, [0, 20, 40]) fan_speed['mid'] = fuzz.trimf(fan_speed.universe, [30, 50, 70]) fan_speed['high'] = fuzz.trimf(fan_speed.universe, [60, 80, 100]) # 规则表 rule1 = ctrl.Rule(temp_error['low'] & temp_rate['stable'], fan_speed['low']) rule2 = ctrl.Rule(temp_error['mid'] & temp_rate['rising'], fan_speed['mid']) rule3 = ctrl.Rule(temp_error['high'] | temp_rate['rising'], fan_speed['high']) fan_ctrl = ctrl.ControlSystem([rule1, rule2, rule3]) fan_sim = ctrl.ControlSystemSimulation(fan_ctrl) def compute_fan_speed(error, rate): fan_sim.input['temp_error'] = error fan_sim.input['temp_rate'] = rate fan_sim.compute() return fan_sim.output['fan_speed']

这段模糊控制的核心在规则表。rule3用了“或”逻辑,意思是温度偏差大或者温度还在升,风机直接给高档。实际调的时候,隶属度函数的拐点要根据作物种类改,番茄耐热性好一点,草莓就得把阈值整体下调 2~3℃。

再往深了做,可以把作物生长模型接进来。比如番茄的积温模型,累计有效积温到了某个值,自动调整温度管理策略。这部分我一般建议先跑一个生长季的阈值控制,把数据攒够了再上模型,不然参数没处标定。

我自己做温室项目这些年,最大的习惯是:方案文档里永远留一页“手动兜底”说明。再自动的系统也有抽风的时候,操作员知道怎么切手动、怎么强制开关某个设备,比什么高级算法都管用。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 11:48:15

台达E3伺服脉冲控制实战:接线、参数设置与调试流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:48:00

EMC DS300B光纤交换机维护手册:端口、Zone与固件升级实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:47:13

工业气体手册实战指南:从物性参数到现场选型与安全

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:47:06

Allegro PCB旋转效率提升三大技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:46:55

51单片机最小系统板Type-C供电与5V转3.3V电路设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:46:40

Allegro 17.4 R0603封装绘制全流程:从焊盘参数到DRC检查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华