Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护

2026-10-313

简介

这是一座会自己照顾自己的微缩农场。它以 Arduino Mega2560 做实时控制、以行空板 M10 做数据展示与网络服务,用 10 类传感器把"土壤干不干、水干不干净、天会不会下雨、光够不够"这些原本靠经验判断的事,变成可以量化的判断条件:土壤湿度低于阈值才开泵,水质浊度超标就禁止灌溉,大雨暂停浇水,光照过强自动熄灯、回落后再恢复原状态;温度、空气质量、紫外线异常时蜂鸣器分级报警并与风扇联动。所有数据通过串口送给行空板,再由它推送到自建网页、SIoT 与巴法云,手机或电脑随时可看、可控。

 

系统架构框图

(系统架构框图)

Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_1.webp

(作品全景)


一、我们想解决什么

做这个项目的起因很朴素。我们观察真实的农业生产,发现了三个具体问题:

  1. 浇水靠猜。 浇多了烂根,浇少了减产,而"该不该浇、浇多少"其实是可以算出来的——土壤湿度、水质、雨量都是可测量的量。
  2. 极端天气靠扛。 高温、暴雨、强紫外线来临时,人在现场还好,没人在就只能听天由命。
  3. 水安全没人管。 用脏水浇菜,问题不在当天,而在长期累积。这件事需要在源头就拦住,而不是事后补救。

    ……

于是目标定得很明确:让传感器当"眼睛和皮肤",程序当"大脑",水泵、风扇、灯带当"手脚",做一座能看、能判断、能动手的农场。


二、硬件清单与软件环境

2.1 硬件清单

类别名称型号 / 规格数量作用
主控器Arduino 主控板Mega25601实时控制:采集、判断、驱动执行器
主控器行空板UNIHIKER M101数据展示、网页服务、云端接入
传感器温湿度传感器DHT111监测空气温湿度,高温联动风扇
传感器土壤湿度传感器电阻式1检测土壤含水量,决定是否灌溉
传感器光照传感器光敏模块1光照过强时强制熄灯
传感器空气质量传感器DFRobot ENS1601监测空气质量,超标自动通风
传感器气压传感器DFRobot BMP388(SEN0251)1辅助判断天气趋势
传感器浊度传感器DFRobot SEN01891检测水质,超标禁灌
传感器水位传感器电阻式1监测水箱水位,防水泵空转
传感器雨滴传感器雨滴模块1分级判断小雨 / 大雨
传感器紫外线传感器DFRobot LTR390(SEN0540)1紫外线超标报警
传感器流量传感器YF-S4011累计灌溉用水量
输出模块RGB 灯带WS2812,64 灯1补光,支持调色与调亮度
输出模块显示屏SSD1306 OLED 128×641本地四页数据显示
输出模块直流水泵微型潜水泵1灌溉执行
输出模块继电器单路 5V1驱动水泵
输出模块调速风扇5V PWM 风扇1通风降温
输出模块蜂鸣器有源低电平触发1三路分级报警
交互模块离线语音识别DFRobot DF2301Q119 条语音指令控制
交互模块翻页按键轻触按键2OLED 翻页、双键清零水量
物联网物联网模块DFRobot OBLOQ(TEL0118)1数据上报 EasyIoT 平台
电源太阳能板5V / 6V 太阳能电池板1绿色供电
电源充放电模块太阳能充电管理 + 锂电池1 组储能与续航
结构材料木板、亚克力板、喷漆—若干场景与棚体

wb-table-cont

类别名称型号 / 规格数量作用
连接线材杜邦线、传感器延长线—若干接线

2.2 软件环境

项目说明
Mega2560 开发Arduino IDE,使用 Wire、EEPROM、Adafruit_NeoPixel、Adafruit_SSD1306、DHT、DFRobot_ENS160、DFRobot_DF2301Q、DFRobot_BMP3XX、DFRobot_LTR390UV 等库
行空板 M10Mind+ Python 模式,使用 unihiker(GUI)、pyserial、pinpong、mqtt(SIoT / 巴法云)、内置 http.server
物联网平台EasyIoT(OBLOQ 直连)、行空板自带 SIoT(MQTT 1883)、巴法云(mqtt.bemfa.com:9501)
本地网页行空板自建 Web 服务,端口 9000

三、系统架构:为什么用两块主控

这是整个项目最关键的一次取舍。一开始我们只想用一块板,但做着做着发现两件事很难在一块板上同时做好:实时控制要求"不被打断",而网络服务要求"慢慢等"。

分工Arduino Mega2560行空板 M10
职责采集传感器、执行控制逻辑、驱动执行器展示数据、提供网页、接入云端
时间尺度毫秒级(流量计中断、灯带刷新)秒级(上报、刷新页面)
通信USB 串口,115200同上
好处网络卡顿不影响灌溉算力富余,可跑网页服务

两块板之间只约定了最简单的协议:

  • 上行:Mega 每秒打印一行 JSON,包含全部状态;
  • 下行:M10 发一行文本命令,如 CMD PUMP ON、CMD FAN OFF、CMD LIGHT ON、CMD STATUS;
  • 开机标记:Mega 上电时先发 {"boot":1},M10 收到后重建界面。

这个约定的好处是任何一端重启,另一端都能自动恢复:Mega 重启,M10 收到 boot 标记重建界面;M10 重启,只要重新打开串口就能继续收 JSON。调试时把 Mega 接到电脑,用串口监视器直接看 JSON,也能立刻判断是哪一端的问题。

Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_2.webp

(硬件接线全景(杂乱版)(俯视))


四、制作过程

步骤一:需求调研与方案设计

我们先把需求收敛成四个词——灌溉、环境、安全、交互,然后画系统框图,确定"双主控 + 多传感器 + 语音 + 物联网"的总体方案。

Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_3.webp

(木板结构搭建(非本人出镜))

步骤二:传感器选型与电路搭建

这一步我们做了一件后来被证明非常值得的事:每接一个传感器,先用串口把它的原始读数打出来,看清楚数值范围,再定阈值。比如土壤湿度,干燥时 ADC 约 1023、浸水时接近 0;雨滴传感器干燥时读数高、沾水后下降。有了实测数据,阈值才不是拍脑袋定的。

十路传感器的接口分配如下(部分):

接口器件接口器件
A6土壤湿度D2流量计(中断脚)
A7光照D4风扇(PWM)
A8水位D6水泵继电器
A9旋钮电位器D7蜂鸣器
A10浊度(SEN0189)D8雨滴探头供电控制
A11雨滴(AOUT)D14 / D15OLED 翻页按键 K1 / K2
D22DHT11D23WS2812 灯带
I2C 0x3COLEDI2C 0x64DF2301Q 语音
I2C 0x53ENS160I2C 0x77BMP388
I2C 0x1CLTR390Serial2OBLOQ(D16/D17)
Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_4.webp
Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_5.webp

(装配与调试)

步骤三:核心控制程序编写

全部功能采用非阻塞架构:主循环里没有 delay(),所有定时任务靠 millis() 判断时间差。这一点看似只是写法区别,实际决定了系统能不能同时做多件事——后面"屏幕响应迟钝"那一节会讲到我们为此付出的代价。

本阶段完成的功能模块:自动灌溉(湿度阈值 + 迟滞 + 时序保护)、水质禁灌、雨量分级、光照自适应灯带、三路蜂鸣器分级报警、流量累计与 EEPROM 保存。

Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_6.webp

(e.g.灌溉决策代码)

步骤四:语音控制中心与物联网接入

语音模块是固件内置命令词,不需要训练,但内置编号必须自己实测一遍。我们的方法是:说一条指令,看串口打印的 CMDID,再对照动作,把"编号—动作"做成常量表,并在串口回显动作名。这样即使某条指令厂家固件改了编号,也只需改一个数字。

物联网部分做了三层:OBLOQ 直连 EasyIoT;行空板自带 SIoT 供局域网内控制;巴法云用于外网手机查看。三层互不依赖,任何一层断线不影响本地逻辑。

步骤五:场景搭建与联调迭代

木板棚体完成后进入连续运行联调。这一阶段记录并修复了问题。


五、技术原理

5.1 精准灌溉:一个带时序保护的状态机

灌溉不是"湿度低就开泵"这么简单。真实场景里有四个必须处理的问题:水渗下去需要时间、传感器读数会抖、水泵不能频繁启停、水泵空转会烧线圈。我们把灌溉逻辑写成一个两状态机,每个状态有自己的进入条件:

停机状态下的开泵条件(五个条件同时满足):土壤湿度 < 30%、距上次停泵已超过 10 秒、水箱有水、水质未超标、雨量未达大雨级。

抽水状态下的停泵条件:至少抽满 5 秒后,土壤湿度 > 50% 或单次已超 60 秒;而缺水、水质超标、大雨这三条立即停泵,不受最小时长限制。

三个时间常数的作用分别是:最短运行 5 秒保证水真正渗下去;最短间隔 10 秒避免频繁启停;最长 60 秒防止传感器卡死导致淹水。

if (!pumpState) {
  // 停机:土够干 + 歇够 + 有水 + 水质达标 + 没下大雨 → 开泵
  if (soilPercent < SOIL_DRY_THRESHOLD
      && (now - pumpOffAt) >= PUMP_MIN_OFF_MS
      && tankHasWater && !turbBad && rainLevel < 2) {
    pumpState = true; pumpOnAt = now; setPumpRelay(true);
  }
} else {
  unsigned long runMs = now - pumpOnAt;
  bool soaked  = (soilPercent > SOIL_WET_THRESHOLD);
  bool timeout = (runMs >= PUMP_MAX_ON_MS);
  // 缺水/水质超标/大雨立即停;其余需满 MIN_ON 才允许停
  if (!tankHasWater || turbBad || rainLevel >= 2
      || (runMs >= PUMP_MIN_ON_MS && (soaked || timeout))) {
    pumpState = false; pumpOffAt = now; setPumpRelay(false);
    saveFlowTotal();   // 停泵瞬间把累计水量写入 EEPROM
  }
}
Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_7.webp

5.2 迟滞阈值:让设备不再"打摆子"

所有阈值都成对出现,一个触发、一个恢复,中间留出缓冲带:

项目触发阈值恢复阈值缓冲带
土壤湿度< 30% 开泵> 50% 关泵20%
水质浊度> 800 NTU 禁灌< 600 NTU 解禁200 NTU
雨量(小雨)读数 < 550读数 > 650100
雨量(大雨)读数 < 300读数 > 35050
光照> 700 熄灯< 500 恢复200
温度> 30 ℃ 报警< 28 ℃ 恢复2 ℃
空气质量AQI > 3AQI ≤ 12

没有缓冲带会发生什么?土壤湿度在 30% 附近抖动时,水泵会在一秒内反复开停,继电器咔咔响,电机和继电器都容易坏。加了迟滞之后,设备只在"明确越界"时才动作。

5.3 光照自适应灯带:把"用户意图"和"实际输出"分开

这是我们在联调后期加的一个功能,思路值得单独说。灯带的开关有两类来源:用户(语音 / 网页)想开或想关,和环境(光照过强)要求必须关。如果只用一个变量 ledOn,强光把灯关掉后,用户原本"开灯"的意图就被抹掉了,天黑后灯不会自己亮回来。

我们的做法是拆成两个变量:

  • ledOn:用户意图,语音和网页只改它,不受环境影响;
  • lightForceOff:环境压制标志,光照 > 700 时置位,< 500 且持续满 3 秒才清除;
  • 实际输出 = ledOn && !lightForceOff,统一由 applyLed() 一个出口刷新。

那个 3 秒是必需的。64 颗灯珠本身就会照亮光敏传感器,如果没有最小保持时间,系统会在"关灯→变暗→开灯→变亮→关灯"之间高频自激闪烁。

5.4 语音控制中心:先建映射表,再谈控制

DF2301Q 的命令词是固件内置的,编号需要通过实测确定。我们建立了这样的常量表,并在串口回显动作名:

编号动作编号动作
85 / 86风扇开 / 关117 / 118灯光开 / 关
87 / 88 / 89风速一 / 二 / 三挡119 / 120亮度调高 / 调低
——121 / 122亮度最大 / 最小
——130–137红橙黄绿青蓝紫白八色

这样设计的好处是:万一固件版本不同导致编号变化,只需改表里的数字,控制逻辑一行不用动。

5.5 三路蜂鸣器:非阻塞节奏发生器

三种报警音要能区分,又不能用 delay() 卡住主循环。我们把每种声音定义成"响 / 停"交替的时间序列,用 millis() 推进步进:

报警节奏(毫秒,偶数位响、奇数位停)听感
水位过低200, 800慢长鸣,约 1 秒一声
水质过差100, 100, 100, 700急促双鸣
下雨100, 100, 100, 100, 100, 900三短鸣

优先级:水位过低 > 水质过差 > 下雨。

5.6 双主控串口桥

Mega 每秒上报一行 JSON(节选):

{"temp":22.2,"hum":64.0,"soil":100,"lux":11,"aqi":0,"water":293,
 "ntu":1989,"rain":0,"pump":0,"used":0.00,"fan":0,"fanmode":0,
 "led":1,"ledforce":0,"press":965.7,"remote":0,"turbBad":1,"uv":0}

其中 ledforce 是"是否被强光压制",turbBad 是"水质是否超标被禁灌"。这两个字段让 M10 端能显示真实原因,而不是笼统的"已关闭"。

M10 侧收到命令后,转成 CMD XXX 发给 Mega,所有安全保护仍在 Mega 端把关:水质超标时即使远程下发开泵,Mega 也会拒绝执行。

5.7 行空板 M10:三种联网方式并存

方式地址用途特点
自建网页http://板子IP:9000实时数据、历史曲线、远程控制局域网内最快,曲线支持 10 分钟 / 1 小时 / 6 小时 / 24 小时四档
SIoT板子IP:1883(网页 8080)局域网内下发指令行空板自带 MQTT 服务器
巴法云mqtt.bemfa.com:9501外网手机查看与控制需要私钥,注意保密
Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_8.webp
Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_9.webp

六、关键代码说明

完整代码见附件(v2.6_no_servo.ino 约 1530 行,main.py 约 1190 行),代码中每一处阈值都有中文注释。这里只说明几个容易看不懂的设计:

  1. setPumpRelay() 统一处理继电器极性。 高电平触发和低电平触发的继电器在市场上都有,把极性判断收在一个函数里,换模块时只改一个常量。
  2. saveFlowTotal() 与 EEPROM。 累计水量写入时用 magic 值 0xA5 做有效性校验,断电重启后先校验再读取,避免读到乱码导致水量跳变。抽水过程中每 30 秒存一次,停泵瞬间再存一次。
  3. medianRead() 中值滤波。 模拟量传感器读数偶尔会跳,连续采 5 次取中值,比平均值更能抵抗单点干扰。
  4. 雨滴探头间歇供电。 探头长期通电会电解腐蚀,代码里每 6 秒才通电 1 秒采样。
  5. 流量标定。 YF-S401 按官方公式约 480 脉冲/升,代码里留了常量 PULSES_PER_LITER,用量杯实测后可替换以提高精度。
Mega2560 + 行空板 M10 双主控智慧农场:10 类传感器如何实现精准灌溉与多级安全保护_image_10.webp

注:①代码目前已参加某比赛,完整版将于比赛结果“出炉”后公布;

  ②代码原版有舵机控制可开合顶棚与自动开合的大门(使用手势传感器、超声波传感器、按键传感器等综合判定状态),NFC Module刷卡才上电保证安全性等功能,但因框架原因最后删去了,若想要此部分代码亦可留言,若有新的创新建议,也欢迎积极留言哦~;

  ③木板结构外框架的制作在此处略去(此部分因人而异,想了解的可以留言);

  ④应该就这些了吧?

创作许可协议

本项目采用 CC BY(署名) 进行许可。

评论(0)
- 没有更多了 -