1. 项目概述与核心思路作为一个在电子DIY和智能家居领域折腾了十多年的老玩家我始终认为一个真正好用的自动化项目其灵魂不在于用了多炫酷的芯片而在于它解决问题的逻辑是否足够“聪明”和“可靠”。今天要分享的这个基于Arduino的自动植物浇水系统就是一个典型的“逻辑驱动”案例。它没有依赖常见的土壤湿度传感器而是另辟蹊径采用了称重监测的方案。这个思路的巧妙之处在于它直接测量的是植物、土壤和水分这个“整体系统”的重量变化从而间接但非常可靠地判断植物是否需要浇水。对于家庭园艺爱好者、小型温室种植者或者像我这样经常出差、又舍不得家里绿植的朋友来说这样一个能自主决策、稳定运行数周的系统无疑是个福音。这个项目的核心目标很明确实现长达三周以上的无人值守自动灌溉。为了实现这个目标我们摒弃了内置小型水箱的设计因为对于某些喜水植物如原文提到的海芋小水箱可能一两天就空了失去了“自动”的意义。取而代之的方案是系统连接一个外部的大容量储水容器比如一个水桶真正做到“一次加水管够很久”。系统的“大脑”是Arduino Uno它每小时通过HX711模块读取5kg量程的称重传感器数据判断植物重量。交互方面一个128x32像素的OLED屏幕和三个按键构成了简洁的菜单界面用于设置浇水阈值和水量。执行机构则是一个由继电器控制、独立电池供电的小型水泵。所有关键参数都存储在EEPROM中即使断电重启也无需重新设置。整个逻辑可以概括为持续监测趋势判断连续三小时低于阈值然后执行精准补水。2. 系统设计与核心组件解析2.1 为什么选择“称重”而非“湿度”这是本项目第一个值得深究的设计决策。市面上绝大多数自动浇水套件都使用土壤湿度传感器那为什么我们要绕个弯子用称重呢这里有几个基于实战经验的考量可靠性与耐久性土壤湿度传感器特别是基于电阻原理的的探针长期埋在潮湿土壤中极易发生电解腐蚀导致读数漂移甚至失效。我早期做的几个湿度传感项目基本撑不过三个月就需要更换传感器。而称重传感器本身密封性良好不与土壤和水直接接触寿命要长得多。测量的一致性土壤湿度传感器测量的是某一点或一个小区域的湿度受土壤密度、传感器接触紧密度影响很大容易出现局部干燥但根部仍有水的情况导致误判。称重测量的是整个花盆系统的质量变化反映的是水分的整体盈亏更接近植物真实的“口渴”程度。标定的简易性湿度传感器的“干”和“湿”值需要针对不同土壤类型进行复杂的标定。而称重方案简单粗暴记录下浇水后花盆的总重量设为“满水重量”当重量下降到某个百分比比如“满水重量”减去设定水量时就触发浇水。逻辑直观无需考虑土壤材质。应对特殊场景对于采用特殊基质如陶粒、水苔的种植或者无土栽培土壤湿度传感器可能完全无法工作而称重法则依然有效。当然称重方案也有其局限比如无法区分水分蒸发和植物自身生长带来的重量变化长期来看需要微调阈值但对于数周时间尺度的自动灌溉来说其稳定性和可靠性优势非常明显。2.2 核心组件选型与功能剖析接下来我们拆解一下系统中每个关键部件的选型原因和注意事项。1. 微控制器Arduino Uno选择Uno是因为其生态成熟、引脚数量足够、编程简单。它的ATmega328P芯片有2KB SRAM和32KB Flash对于本项目的代码量绰绰有余。需要注意的是原文特别提到了SRAM的限制这直接影响了OLED库的选择后面会详细说。如果手头只有Nano也完全可以它们核心相同只是封装形式不同。2. 重量监测单元称重传感器 HX711模块称重传感器选择5kg量程是基于一个常见花盆含土、植物、水的总重量估算。建议留出30%-50%的余量所以对于大多数室内中型盆栽5kg是合适的。购买时要区分“悬臂梁式”和“S型”家用一般选悬臂梁式价格便宜安装简单。HX711模块这是24位高精度ADC模数转换器芯片专门为称重传感器设计。它能把传感器输出的微弱差分电压信号放大并转换成单片机可以读取的数字值。其高分辨率是实现“克”级别精准控制的基础。接线时务必注意传感器通常有红E、黑E-、白S-、绿S四根线要对应接到HX711模块的E、E-、A-、A不同厂家颜色可能不同以说明书为准。3. 显示与交互单元OLED (SSD1306) 按键OLED屏幕选择了0.96英寸、128x32像素的I2C接口型号。I2C接口仅需两根信号线SDA, SCL极大简化了布线。选择128x32而非更常见的128x64是为了节省内存和显示刷新开销。按键三个轻触开关分别对应“上”、“选择/确认”、“下”。这是最经典的人机交互配置通过菜单可以设置“最低重量阈值”和“单次补水量”。4. 执行单元继电器 水泵 独立电源继电器模块选用一个线圈电压为5V的信号继电器模块。Arduino的IO口输出电流很小约20mA无法直接驱动水泵继电器起到了“用小电流控制大电流”的开关作用。当Arduino的PIN 7输出高电平时继电器吸合水泵电路导通。水泵选用工作电压3-6V的直流微型潜水泵。关键点来了水泵必须由独立电源4节AA电池供电绝不能从Arduino的5V或Vin引脚取电电机启动和运行时的电流很大可能达到几百mA远超Arduino板载稳压芯片的负载能力强行连接会导致Arduino重启甚至损坏。电源隔离水泵的电池负极需要与Arduino的GND连接以形成共同的参考地确保继电器控制信号有效。但正极完全独立。5. 记忆单元EEPROMATmega328P芯片内部自带1KB的EEPROM。我们用它来保存用户设置的“最低重量”和“补水量”两个参数。这样系统断电重启后无需重新设置能立即按照之前的逻辑运行。这是提升用户体验的关键一步。注意EEPROM有擦写寿命约10万次。避免在循环中频繁写入同一地址。本项目仅在用户通过菜单修改设置时才写入完全在安全范围内。3. 硬件连接与焊接要点根据原文的Fritzing图和描述系统的接线关系已经比较清晰。我这里将其整理成更详细的接线表并补充一些焊接和布局上的实战心得。3.1 详细接线表Arduino Uno 引脚连接至功能说明数字引脚 D2“上”按键 (一脚)菜单中向上移动或增加数值数字引脚 D3“选择”按键 (一脚)确认选择或进入下一级菜单数字引脚 D4HX711模块 DT (数据)接收来自HX711的重量数据数字引脚 D5HX711模块 SCK (时钟)向HX711发送时钟信号控制数据读取数字引脚 D6“下”按键 (一脚)菜单中向下移动或减少数值数字引脚 D7继电器模块 IN (信号)控制继电器开关高电平触发模拟引脚 A4OLED 屏幕 SDA (数据)I2C数据线模拟引脚 A5OLED 屏幕 SCL (时钟)I2C时钟线5VHX711模块 VCC, OLED VCC, 三个按键另一脚为模块和按键上拉提供电源GNDHX711模块 GND, OLED GND, 三个按键第三脚继电器模块 GND电池负极公共接地至关重要补充说明每个按键有三只脚。一侧的两个脚在内部是连通的。我们将其一脚接Arduino引脚对角的一脚接GND中间脚悬空。在Arduino程序内部会将该引脚设置为INPUT_PULLUP模式利用内部上拉电阻。当按键按下时引脚从高电平被拉低到GND从而检测到按下动作。继电器模块通常有3个接口VCC接5V、GND、IN接D7。输出端是常开NO、常闭NC、公共端COM。我们将水泵电路接在COM和NO之间。3.2 焊接与布局实战心得先测试后焊接在将所有元件焊接到洞洞板或定制PCB之前务必使用杜邦线将所有模块连接起来并上传一个简单的测试代码例如分别测试OLED显示、按键读取、HX711读数、继电器开关确保每个模块单独工作正常。这能避免焊接完成后排查故障的噩梦。电源走线要粗虽然主控部分电流不大但为求稳定5V和GND的走线可以适当加粗或者使用双线并联。注意模拟信号的干扰HX711模块输出的是高精度数字信号但本身对电源噪声比较敏感。尽量让它的电源走线远离继电器和水泵的电源线。如果条件允许可以在HX711的VCC和GND之间加一个100uF的电解电容进行滤波。继电器的续流二极管大部分继电器模块已经集成了保护二极管。如果你的模块没有务必在继电器线圈两端反向并联一个1N4007二极管以吸收线圈断电时产生的反向电动势防止高压脉冲损坏Arduino的IO口。水泵电源的开关在4节AA电池盒的输出端可以增加一个拨动开关。这样在调试、维护或者长时间外出时可以彻底关闭水泵电源既安全又省电。4. 软件逻辑与代码深度解析原文提供了代码文件但理解其背后的逻辑更为重要。我们来深入剖析程序是如何“思考”和“决策”的。4.1 内存优化与库的选择文章开头就提到了一个关键问题SRAM不足。Arduino Uno的SRAM只有2KB需要存储全局变量、局部变量和堆栈。Adafruit的OLED驱动库功能强大但比较消耗内存。当同时使用HX711库和Adafruit库时可能导致内存耗尽程序运行异常。解决方案使用了SSD1306Ascii库。这个库是greiman大神编写的特点是极简、高效它只刷新屏幕上需要改变的部分而不是全屏刷新因此占用的内存和计算资源少得多。这正是嵌入式开发中常见的“空间换时间”或“功能换空间”的权衡思维。库的安装HX711_ADC库直接在Arduino IDE的库管理器中搜索安装。SSD1306Ascii库需要从GitHub下载ZIP文件然后通过项目-加载库-添加.ZIP库的方式手动安装。4.2 核心控制逻辑流程图文字描述程序的核心是一个状态机主要运行在loop()函数中初始化启动串口用于调试。初始化OLED并显示欢迎界面。初始化HX711并启动称重传感器可能需要几秒稳定。从EEPROM中读取之前保存的“最低重量阈值”和“单次补水量”。初始化按键引脚为上拉输入模式。设置水泵控制引脚为输出模式并初始化为低电平关闭。主循环实时监测按键随时响应用户操作进入菜单设置模式。每小时执行一次重量监测与决策利用millis()进行非阻塞定时 a.读取当前重量从HX711获取经过滤波处理的重量值单位克。 b.更新重量记录数组维护一个大小为3的数组存储最近3小时的重量数据。每次新读数覆盖最旧的数据。 c.趋势判断检查数组中最近3次的重量值是否全部低于用户设定的“最低重量阈值”。 d.触发条件如果上述条件成立则计算目标重量 当前重量 单次补水量。 e.执行浇水打开继电器水泵启动持续监测当前重量直到达到或超过目标重量立即关闭继电器。 f.重置记录浇水完成后可以用当前重量或一个估计值填充重量记录数组避免刚浇完水又立刻触发判断。菜单模式当用户按下“选择”键进入菜单后系统会暂时中断自动监测循环。用户可以通过“上”“下”键修改参数再次按下“选择”键保存新值到EEPROM并退出菜单。4.3 关键代码片段解读这里解释几个容易出错的代码逻辑点1. 非阻塞定时器避免使用delay(3600000)这样的语句来等待一小时这会阻塞所有其他操作包括按键响应。正确做法是unsigned long previousHourMillis 0; const unsigned long hourInterval 3600000; // 1小时的毫秒数 void loop() { unsigned long currentMillis millis(); // 检查是否过去了一小时 if (currentMillis - previousHourMillis hourInterval) { previousHourMillis currentMillis; // 重置计时器 // 执行每小时的任务称重、判断、浇水 checkWeightAndWater(); } // 其他不阻塞的任务如检查按键 checkButtons(); }2. HX711的初始化和读数HX711需要时间启动和稳定。tare()函数用于去皮归零将当前重量设为零点。务必在花盆空置或仅放置底座的情况下执行去皮。HX711_ADC LoadCell(4, 5); // DT, SCK 引脚 void setup() { LoadCell.begin(); LoadCell.start(2000); // 启动传感器稳定时间2秒 LoadCell.setCalFactor(calibrationValue); // 设置标定系数这个系数需要实测 LoadCell.tare(); // 去皮归零 } float getWeight() { if (LoadCell.update()) { return LoadCell.getData(); // 获取以克为单位的重量 } return 0.0; }3. EEPROM存储与读取存储整数或浮点数时需要将其分解为字节。Arduino的EEPROM库提供了put和get方法可以方便地处理。#include EEPROM.h #define EEPROM_MIN_WEIGHT_ADDR 0 // 定义存储地址 #define EEPROM_WATER_AMOUNT_ADDR sizeof(float) // 下一个地址 float minWeight, waterAmount; void readSettingsFromEEPROM() { EEPROM.get(EEPROM_MIN_WEIGHT_ADDR, minWeight); EEPROM.get(EEPROM_WATER_AMOUNT_ADDR, waterAmount); // 首次运行时EEPROM可能是初始值255需要做默认值判断 if (isnan(minWeight) || minWeight 0) minWeight 1000.0; // 默认1kg } void saveSettingsToEEPROM() { EEPROM.put(EEPROM_MIN_WEIGHT_ADDR, minWeight); EEPROM.put(EEPROM_WATER_AMOUNT_ADDR, waterAmount); }5. 系统校准、调试与外壳制作5.1 称重系统的校准这是整个项目最关键的步骤直接决定浇水精度。硬件安装将称重传感器牢固地安装在花盆底座下方。确保花盆的重量完全由传感器承载且放置平稳。确定标定系数在代码中准备一个已知重量的砝码如500克。上传一个简单的测试程序该程序只读取HX711的原始读数。空载时记录原始读数raw_empty。放上砝码后记录原始读数raw_with_weight。计算标定系数cal_factor (raw_with_weight - raw_empty) / 已知重量(克)。将计算出的cal_factor值填入代码中的LoadCell.setCalFactor(cal_factor);语句。软件去皮在花盆就位但未浇水的情况下运行一次LoadCell.tare()函数将当前重量设为零点。这样后续读到的就是水的净重变化。5.2 系统调试流程分模块调试OLED与按键编写一个简单程序在屏幕上显示“Hello”并打印哪个按键被按下。HX711编写程序连续打印重量读数。用手轻压花盆观察数值变化是否灵敏、稳定。继电器与水泵编写程序控制D7引脚高低电平变化听继电器是否有“咔嗒”声水泵是否随之启停。务必先将水泵水管从花盆移开对准一个空容器进行测试集成联调将所有模块连接好上传完整代码。通过菜单设置一个较高的“最低重量阈值”比如比当前重量少50克和一个较小的“补水量”比如20克。人工模拟失水从花盆中舀出一点水。等待一小时或修改代码缩短测试间隔观察系统是否会正确触发浇水并精准停止。5.3 外壳设计与制作建议原文作者尝试了3D打印、改造塑料花盆、铁丝网加粘土等多种方法过程很真实。结合我的经验提供几个更可行的方向木质底座盒这是最推荐、最易加工的方案。用木板制作一个扁平的盒子将Arduino、继电器、HX711模块等电路固定在内。称重传感器安装在盒子顶部与上方花盆的承重板连接。盒子侧面开孔引出水泵电源线和通往储水桶的水管。木材质地坚固易于加工和密封外观也容易处理得美观。防水与防尘电路部分一定要做好密封。可以使用塑料防水盒或者在木质盒子内壁涂刷防水漆。所有线缆出入口使用防水格兰头。OLED屏幕和按键部分可以开窗并用亚克力板覆盖密封。花盆承重结构花盆不能直接压在传感器上需要一个刚性的承重板如亚克力板、薄钢板将压力均匀传递到传感器。传感器与承重板、底座盒之间的固定要使用螺丝确保牢固。储水桶选择一个带盖子的桶减少水分蒸发和灰尘落入。水泵放入桶中吸水口最好加上滤网防止杂质堵塞。出水管路要确保密封避免虹吸作用导致持续滴水。6. 常见问题排查与优化进阶即使按照步骤操作也可能会遇到一些问题。这里列出一些“踩坑”实录和解决方案。6.1 重量读数不稳定或漂移现象数值在几十克范围内跳动或者缓慢单向变化。排查电源干扰检查HX711的5V电源是否稳定。尝试用一台手机充电器单独为Arduino供电而不是使用电脑USB口。机械结构不稳确保花盆和承重结构放置绝对平稳没有一丝晃动。传感器本身应只承受垂直方向的力。软件滤波HX711_ADC库本身有滤波功能。可以增加LoadCell.setSamplesInUse(8);来使用更多采样点进行平均。也可以在代码中自己对连续读取的多个值进行软件平均。温度影响传感器有轻微的热漂移。避免将整个系统放在阳光直射或暖气片旁边。6.2 水泵启动后重量读数剧烈变化或系统重启现象一开水泵OLED屏幕乱闪或者Arduino重启。原因这是典型的电机干扰问题。水泵电机是感性负载启停时会产生很大的电压尖峰和电磁噪声。解决电源彻底分离再次确认水泵使用的是完全独立的电池组其正极与Arduino的5V没有任何连接。加强隔离在继电器控制水泵的电路上可以并联一个RC吸收电路例如一个0.1uF的CBB电容串联一个100欧姆电阻跨接在继电器输出触点NO和COM上可以有效抑制火花和噪声。信号隔离如果问题依然严重可以考虑使用光耦继电器模块。它用光信号隔离了Arduino控制端和水泵供电端抗干扰能力极强。6.3 EEPROM数据丢失或错乱现象断电重启后设置恢复成了奇怪的数值。排查首次运行判断在readSettingsFromEEPROM()后判断读取的值是否在一个合理范围内如0-5000克。如果超出则加载默认值。这可以解决EEPROM初次使用时内容为0xFF的问题。减少写入频率确保只在用户主动修改设置时调用EEPROM.put()不要在循环里反复写。变量类型对齐确保EEPROM.get和EEPROM.put使用的地址和变量类型匹配。float和int占用的字节数不同。6.4 系统优化与功能扩展思路基础功能稳定后可以考虑以下升级增加土壤湿度传感器作为双重保险虽然以称重为主但可以在花盆深处加装一个耐腐蚀的电容式土壤湿度传感器作为参考。当重量和湿度数据都表明缺水时再浇水逻辑更严谨。接入物联网平台增加一个ESP8266或ESP32模块替换Arduino Uno。这样可以通过Wi-Fi将重量数据、浇水记录发送到手机App如Blynk、Home Assistant进行远程查看并可以手动远程触发浇水。太阳能供电如果放在阳台可以增加一块小型太阳能板和一个锂电池管理模块实现完全能源自给真正做到“放下就不用管”。数据记录与学习增加一个SD卡模块定期记录重量和时间。通过长期数据可以分析植物的耗水规律甚至让系统学习并动态调整浇水阈值实现更智能的灌溉。这个项目的魅力在于它用一个简洁而巧妙的物理原理称重解决了植物养护中的一个日常痛点。从硬件选型、焊接调试到软件逻辑编写、问题排查整个过程涵盖了嵌入式开发的大部分核心环节。当你看到自己制作的系统在某个安静的午后准确地为心爱的植物补充上水分时那种成就感远不是购买一个成品所能比拟的。希望这份详细的拆解能帮助你少走弯路成功打造出属于自己的智能小花匠。
基于Arduino与称重传感器的智能植物自动浇水系统设计与实现
发布时间:2026/5/31 15:17:59
1. 项目概述与核心思路作为一个在电子DIY和智能家居领域折腾了十多年的老玩家我始终认为一个真正好用的自动化项目其灵魂不在于用了多炫酷的芯片而在于它解决问题的逻辑是否足够“聪明”和“可靠”。今天要分享的这个基于Arduino的自动植物浇水系统就是一个典型的“逻辑驱动”案例。它没有依赖常见的土壤湿度传感器而是另辟蹊径采用了称重监测的方案。这个思路的巧妙之处在于它直接测量的是植物、土壤和水分这个“整体系统”的重量变化从而间接但非常可靠地判断植物是否需要浇水。对于家庭园艺爱好者、小型温室种植者或者像我这样经常出差、又舍不得家里绿植的朋友来说这样一个能自主决策、稳定运行数周的系统无疑是个福音。这个项目的核心目标很明确实现长达三周以上的无人值守自动灌溉。为了实现这个目标我们摒弃了内置小型水箱的设计因为对于某些喜水植物如原文提到的海芋小水箱可能一两天就空了失去了“自动”的意义。取而代之的方案是系统连接一个外部的大容量储水容器比如一个水桶真正做到“一次加水管够很久”。系统的“大脑”是Arduino Uno它每小时通过HX711模块读取5kg量程的称重传感器数据判断植物重量。交互方面一个128x32像素的OLED屏幕和三个按键构成了简洁的菜单界面用于设置浇水阈值和水量。执行机构则是一个由继电器控制、独立电池供电的小型水泵。所有关键参数都存储在EEPROM中即使断电重启也无需重新设置。整个逻辑可以概括为持续监测趋势判断连续三小时低于阈值然后执行精准补水。2. 系统设计与核心组件解析2.1 为什么选择“称重”而非“湿度”这是本项目第一个值得深究的设计决策。市面上绝大多数自动浇水套件都使用土壤湿度传感器那为什么我们要绕个弯子用称重呢这里有几个基于实战经验的考量可靠性与耐久性土壤湿度传感器特别是基于电阻原理的的探针长期埋在潮湿土壤中极易发生电解腐蚀导致读数漂移甚至失效。我早期做的几个湿度传感项目基本撑不过三个月就需要更换传感器。而称重传感器本身密封性良好不与土壤和水直接接触寿命要长得多。测量的一致性土壤湿度传感器测量的是某一点或一个小区域的湿度受土壤密度、传感器接触紧密度影响很大容易出现局部干燥但根部仍有水的情况导致误判。称重测量的是整个花盆系统的质量变化反映的是水分的整体盈亏更接近植物真实的“口渴”程度。标定的简易性湿度传感器的“干”和“湿”值需要针对不同土壤类型进行复杂的标定。而称重方案简单粗暴记录下浇水后花盆的总重量设为“满水重量”当重量下降到某个百分比比如“满水重量”减去设定水量时就触发浇水。逻辑直观无需考虑土壤材质。应对特殊场景对于采用特殊基质如陶粒、水苔的种植或者无土栽培土壤湿度传感器可能完全无法工作而称重法则依然有效。当然称重方案也有其局限比如无法区分水分蒸发和植物自身生长带来的重量变化长期来看需要微调阈值但对于数周时间尺度的自动灌溉来说其稳定性和可靠性优势非常明显。2.2 核心组件选型与功能剖析接下来我们拆解一下系统中每个关键部件的选型原因和注意事项。1. 微控制器Arduino Uno选择Uno是因为其生态成熟、引脚数量足够、编程简单。它的ATmega328P芯片有2KB SRAM和32KB Flash对于本项目的代码量绰绰有余。需要注意的是原文特别提到了SRAM的限制这直接影响了OLED库的选择后面会详细说。如果手头只有Nano也完全可以它们核心相同只是封装形式不同。2. 重量监测单元称重传感器 HX711模块称重传感器选择5kg量程是基于一个常见花盆含土、植物、水的总重量估算。建议留出30%-50%的余量所以对于大多数室内中型盆栽5kg是合适的。购买时要区分“悬臂梁式”和“S型”家用一般选悬臂梁式价格便宜安装简单。HX711模块这是24位高精度ADC模数转换器芯片专门为称重传感器设计。它能把传感器输出的微弱差分电压信号放大并转换成单片机可以读取的数字值。其高分辨率是实现“克”级别精准控制的基础。接线时务必注意传感器通常有红E、黑E-、白S-、绿S四根线要对应接到HX711模块的E、E-、A-、A不同厂家颜色可能不同以说明书为准。3. 显示与交互单元OLED (SSD1306) 按键OLED屏幕选择了0.96英寸、128x32像素的I2C接口型号。I2C接口仅需两根信号线SDA, SCL极大简化了布线。选择128x32而非更常见的128x64是为了节省内存和显示刷新开销。按键三个轻触开关分别对应“上”、“选择/确认”、“下”。这是最经典的人机交互配置通过菜单可以设置“最低重量阈值”和“单次补水量”。4. 执行单元继电器 水泵 独立电源继电器模块选用一个线圈电压为5V的信号继电器模块。Arduino的IO口输出电流很小约20mA无法直接驱动水泵继电器起到了“用小电流控制大电流”的开关作用。当Arduino的PIN 7输出高电平时继电器吸合水泵电路导通。水泵选用工作电压3-6V的直流微型潜水泵。关键点来了水泵必须由独立电源4节AA电池供电绝不能从Arduino的5V或Vin引脚取电电机启动和运行时的电流很大可能达到几百mA远超Arduino板载稳压芯片的负载能力强行连接会导致Arduino重启甚至损坏。电源隔离水泵的电池负极需要与Arduino的GND连接以形成共同的参考地确保继电器控制信号有效。但正极完全独立。5. 记忆单元EEPROMATmega328P芯片内部自带1KB的EEPROM。我们用它来保存用户设置的“最低重量”和“补水量”两个参数。这样系统断电重启后无需重新设置能立即按照之前的逻辑运行。这是提升用户体验的关键一步。注意EEPROM有擦写寿命约10万次。避免在循环中频繁写入同一地址。本项目仅在用户通过菜单修改设置时才写入完全在安全范围内。3. 硬件连接与焊接要点根据原文的Fritzing图和描述系统的接线关系已经比较清晰。我这里将其整理成更详细的接线表并补充一些焊接和布局上的实战心得。3.1 详细接线表Arduino Uno 引脚连接至功能说明数字引脚 D2“上”按键 (一脚)菜单中向上移动或增加数值数字引脚 D3“选择”按键 (一脚)确认选择或进入下一级菜单数字引脚 D4HX711模块 DT (数据)接收来自HX711的重量数据数字引脚 D5HX711模块 SCK (时钟)向HX711发送时钟信号控制数据读取数字引脚 D6“下”按键 (一脚)菜单中向下移动或减少数值数字引脚 D7继电器模块 IN (信号)控制继电器开关高电平触发模拟引脚 A4OLED 屏幕 SDA (数据)I2C数据线模拟引脚 A5OLED 屏幕 SCL (时钟)I2C时钟线5VHX711模块 VCC, OLED VCC, 三个按键另一脚为模块和按键上拉提供电源GNDHX711模块 GND, OLED GND, 三个按键第三脚继电器模块 GND电池负极公共接地至关重要补充说明每个按键有三只脚。一侧的两个脚在内部是连通的。我们将其一脚接Arduino引脚对角的一脚接GND中间脚悬空。在Arduino程序内部会将该引脚设置为INPUT_PULLUP模式利用内部上拉电阻。当按键按下时引脚从高电平被拉低到GND从而检测到按下动作。继电器模块通常有3个接口VCC接5V、GND、IN接D7。输出端是常开NO、常闭NC、公共端COM。我们将水泵电路接在COM和NO之间。3.2 焊接与布局实战心得先测试后焊接在将所有元件焊接到洞洞板或定制PCB之前务必使用杜邦线将所有模块连接起来并上传一个简单的测试代码例如分别测试OLED显示、按键读取、HX711读数、继电器开关确保每个模块单独工作正常。这能避免焊接完成后排查故障的噩梦。电源走线要粗虽然主控部分电流不大但为求稳定5V和GND的走线可以适当加粗或者使用双线并联。注意模拟信号的干扰HX711模块输出的是高精度数字信号但本身对电源噪声比较敏感。尽量让它的电源走线远离继电器和水泵的电源线。如果条件允许可以在HX711的VCC和GND之间加一个100uF的电解电容进行滤波。继电器的续流二极管大部分继电器模块已经集成了保护二极管。如果你的模块没有务必在继电器线圈两端反向并联一个1N4007二极管以吸收线圈断电时产生的反向电动势防止高压脉冲损坏Arduino的IO口。水泵电源的开关在4节AA电池盒的输出端可以增加一个拨动开关。这样在调试、维护或者长时间外出时可以彻底关闭水泵电源既安全又省电。4. 软件逻辑与代码深度解析原文提供了代码文件但理解其背后的逻辑更为重要。我们来深入剖析程序是如何“思考”和“决策”的。4.1 内存优化与库的选择文章开头就提到了一个关键问题SRAM不足。Arduino Uno的SRAM只有2KB需要存储全局变量、局部变量和堆栈。Adafruit的OLED驱动库功能强大但比较消耗内存。当同时使用HX711库和Adafruit库时可能导致内存耗尽程序运行异常。解决方案使用了SSD1306Ascii库。这个库是greiman大神编写的特点是极简、高效它只刷新屏幕上需要改变的部分而不是全屏刷新因此占用的内存和计算资源少得多。这正是嵌入式开发中常见的“空间换时间”或“功能换空间”的权衡思维。库的安装HX711_ADC库直接在Arduino IDE的库管理器中搜索安装。SSD1306Ascii库需要从GitHub下载ZIP文件然后通过项目-加载库-添加.ZIP库的方式手动安装。4.2 核心控制逻辑流程图文字描述程序的核心是一个状态机主要运行在loop()函数中初始化启动串口用于调试。初始化OLED并显示欢迎界面。初始化HX711并启动称重传感器可能需要几秒稳定。从EEPROM中读取之前保存的“最低重量阈值”和“单次补水量”。初始化按键引脚为上拉输入模式。设置水泵控制引脚为输出模式并初始化为低电平关闭。主循环实时监测按键随时响应用户操作进入菜单设置模式。每小时执行一次重量监测与决策利用millis()进行非阻塞定时 a.读取当前重量从HX711获取经过滤波处理的重量值单位克。 b.更新重量记录数组维护一个大小为3的数组存储最近3小时的重量数据。每次新读数覆盖最旧的数据。 c.趋势判断检查数组中最近3次的重量值是否全部低于用户设定的“最低重量阈值”。 d.触发条件如果上述条件成立则计算目标重量 当前重量 单次补水量。 e.执行浇水打开继电器水泵启动持续监测当前重量直到达到或超过目标重量立即关闭继电器。 f.重置记录浇水完成后可以用当前重量或一个估计值填充重量记录数组避免刚浇完水又立刻触发判断。菜单模式当用户按下“选择”键进入菜单后系统会暂时中断自动监测循环。用户可以通过“上”“下”键修改参数再次按下“选择”键保存新值到EEPROM并退出菜单。4.3 关键代码片段解读这里解释几个容易出错的代码逻辑点1. 非阻塞定时器避免使用delay(3600000)这样的语句来等待一小时这会阻塞所有其他操作包括按键响应。正确做法是unsigned long previousHourMillis 0; const unsigned long hourInterval 3600000; // 1小时的毫秒数 void loop() { unsigned long currentMillis millis(); // 检查是否过去了一小时 if (currentMillis - previousHourMillis hourInterval) { previousHourMillis currentMillis; // 重置计时器 // 执行每小时的任务称重、判断、浇水 checkWeightAndWater(); } // 其他不阻塞的任务如检查按键 checkButtons(); }2. HX711的初始化和读数HX711需要时间启动和稳定。tare()函数用于去皮归零将当前重量设为零点。务必在花盆空置或仅放置底座的情况下执行去皮。HX711_ADC LoadCell(4, 5); // DT, SCK 引脚 void setup() { LoadCell.begin(); LoadCell.start(2000); // 启动传感器稳定时间2秒 LoadCell.setCalFactor(calibrationValue); // 设置标定系数这个系数需要实测 LoadCell.tare(); // 去皮归零 } float getWeight() { if (LoadCell.update()) { return LoadCell.getData(); // 获取以克为单位的重量 } return 0.0; }3. EEPROM存储与读取存储整数或浮点数时需要将其分解为字节。Arduino的EEPROM库提供了put和get方法可以方便地处理。#include EEPROM.h #define EEPROM_MIN_WEIGHT_ADDR 0 // 定义存储地址 #define EEPROM_WATER_AMOUNT_ADDR sizeof(float) // 下一个地址 float minWeight, waterAmount; void readSettingsFromEEPROM() { EEPROM.get(EEPROM_MIN_WEIGHT_ADDR, minWeight); EEPROM.get(EEPROM_WATER_AMOUNT_ADDR, waterAmount); // 首次运行时EEPROM可能是初始值255需要做默认值判断 if (isnan(minWeight) || minWeight 0) minWeight 1000.0; // 默认1kg } void saveSettingsToEEPROM() { EEPROM.put(EEPROM_MIN_WEIGHT_ADDR, minWeight); EEPROM.put(EEPROM_WATER_AMOUNT_ADDR, waterAmount); }5. 系统校准、调试与外壳制作5.1 称重系统的校准这是整个项目最关键的步骤直接决定浇水精度。硬件安装将称重传感器牢固地安装在花盆底座下方。确保花盆的重量完全由传感器承载且放置平稳。确定标定系数在代码中准备一个已知重量的砝码如500克。上传一个简单的测试程序该程序只读取HX711的原始读数。空载时记录原始读数raw_empty。放上砝码后记录原始读数raw_with_weight。计算标定系数cal_factor (raw_with_weight - raw_empty) / 已知重量(克)。将计算出的cal_factor值填入代码中的LoadCell.setCalFactor(cal_factor);语句。软件去皮在花盆就位但未浇水的情况下运行一次LoadCell.tare()函数将当前重量设为零点。这样后续读到的就是水的净重变化。5.2 系统调试流程分模块调试OLED与按键编写一个简单程序在屏幕上显示“Hello”并打印哪个按键被按下。HX711编写程序连续打印重量读数。用手轻压花盆观察数值变化是否灵敏、稳定。继电器与水泵编写程序控制D7引脚高低电平变化听继电器是否有“咔嗒”声水泵是否随之启停。务必先将水泵水管从花盆移开对准一个空容器进行测试集成联调将所有模块连接好上传完整代码。通过菜单设置一个较高的“最低重量阈值”比如比当前重量少50克和一个较小的“补水量”比如20克。人工模拟失水从花盆中舀出一点水。等待一小时或修改代码缩短测试间隔观察系统是否会正确触发浇水并精准停止。5.3 外壳设计与制作建议原文作者尝试了3D打印、改造塑料花盆、铁丝网加粘土等多种方法过程很真实。结合我的经验提供几个更可行的方向木质底座盒这是最推荐、最易加工的方案。用木板制作一个扁平的盒子将Arduino、继电器、HX711模块等电路固定在内。称重传感器安装在盒子顶部与上方花盆的承重板连接。盒子侧面开孔引出水泵电源线和通往储水桶的水管。木材质地坚固易于加工和密封外观也容易处理得美观。防水与防尘电路部分一定要做好密封。可以使用塑料防水盒或者在木质盒子内壁涂刷防水漆。所有线缆出入口使用防水格兰头。OLED屏幕和按键部分可以开窗并用亚克力板覆盖密封。花盆承重结构花盆不能直接压在传感器上需要一个刚性的承重板如亚克力板、薄钢板将压力均匀传递到传感器。传感器与承重板、底座盒之间的固定要使用螺丝确保牢固。储水桶选择一个带盖子的桶减少水分蒸发和灰尘落入。水泵放入桶中吸水口最好加上滤网防止杂质堵塞。出水管路要确保密封避免虹吸作用导致持续滴水。6. 常见问题排查与优化进阶即使按照步骤操作也可能会遇到一些问题。这里列出一些“踩坑”实录和解决方案。6.1 重量读数不稳定或漂移现象数值在几十克范围内跳动或者缓慢单向变化。排查电源干扰检查HX711的5V电源是否稳定。尝试用一台手机充电器单独为Arduino供电而不是使用电脑USB口。机械结构不稳确保花盆和承重结构放置绝对平稳没有一丝晃动。传感器本身应只承受垂直方向的力。软件滤波HX711_ADC库本身有滤波功能。可以增加LoadCell.setSamplesInUse(8);来使用更多采样点进行平均。也可以在代码中自己对连续读取的多个值进行软件平均。温度影响传感器有轻微的热漂移。避免将整个系统放在阳光直射或暖气片旁边。6.2 水泵启动后重量读数剧烈变化或系统重启现象一开水泵OLED屏幕乱闪或者Arduino重启。原因这是典型的电机干扰问题。水泵电机是感性负载启停时会产生很大的电压尖峰和电磁噪声。解决电源彻底分离再次确认水泵使用的是完全独立的电池组其正极与Arduino的5V没有任何连接。加强隔离在继电器控制水泵的电路上可以并联一个RC吸收电路例如一个0.1uF的CBB电容串联一个100欧姆电阻跨接在继电器输出触点NO和COM上可以有效抑制火花和噪声。信号隔离如果问题依然严重可以考虑使用光耦继电器模块。它用光信号隔离了Arduino控制端和水泵供电端抗干扰能力极强。6.3 EEPROM数据丢失或错乱现象断电重启后设置恢复成了奇怪的数值。排查首次运行判断在readSettingsFromEEPROM()后判断读取的值是否在一个合理范围内如0-5000克。如果超出则加载默认值。这可以解决EEPROM初次使用时内容为0xFF的问题。减少写入频率确保只在用户主动修改设置时调用EEPROM.put()不要在循环里反复写。变量类型对齐确保EEPROM.get和EEPROM.put使用的地址和变量类型匹配。float和int占用的字节数不同。6.4 系统优化与功能扩展思路基础功能稳定后可以考虑以下升级增加土壤湿度传感器作为双重保险虽然以称重为主但可以在花盆深处加装一个耐腐蚀的电容式土壤湿度传感器作为参考。当重量和湿度数据都表明缺水时再浇水逻辑更严谨。接入物联网平台增加一个ESP8266或ESP32模块替换Arduino Uno。这样可以通过Wi-Fi将重量数据、浇水记录发送到手机App如Blynk、Home Assistant进行远程查看并可以手动远程触发浇水。太阳能供电如果放在阳台可以增加一块小型太阳能板和一个锂电池管理模块实现完全能源自给真正做到“放下就不用管”。数据记录与学习增加一个SD卡模块定期记录重量和时间。通过长期数据可以分析植物的耗水规律甚至让系统学习并动态调整浇水阈值实现更智能的灌溉。这个项目的魅力在于它用一个简洁而巧妙的物理原理称重解决了植物养护中的一个日常痛点。从硬件选型、焊接调试到软件逻辑编写、问题排查整个过程涵盖了嵌入式开发的大部分核心环节。当你看到自己制作的系统在某个安静的午后准确地为心爱的植物补充上水分时那种成就感远不是购买一个成品所能比拟的。希望这份详细的拆解能帮助你少走弯路成功打造出属于自己的智能小花匠。