大家好,我是老王,一个喜欢捣鼓硬件的嵌入式工程师。养花这事儿,说起来都是泪,因为工作忙,经常忘了浇水,好几盆心爱的花就这么被我“养”枯了。痛定思痛,我决定发挥一下自己的“特长”,给花盆装上“大脑”和“手脚”,让它自己能去晒太阳、能自己喝水,甚至能自己充电。这不,第一版“智能花盆机器人”就这么诞生了。
今天,我就把这个项目的完整DIY过程分享给大家。这个项目用到了ESP32和Arduino Uno作为核心,还集成了语音交互、手机App控制和表情显示屏,非常适合想入门物联网和嵌入式开发的创客朋友们练手。我会从硬件选型、系统架构,再到具体的模块集成,一步步带大家把这个会自己照顾自己的花盆做出来。
咱们先来聊聊这个机器人的“大脑”是怎么分工的。一个完整的智能花盆机器人,需要完成几件核心任务:移动(去晒太阳)、浇水、感知环境(温湿度)、与人交互(语音、手机App)。如果把这些任务都交给一个单片机,可能会让它手忙脚乱,处理不过来。
所以,我采用了“主从协同”的架构,让两块板子各司其职:
主控大脑(Arduino Uno):负责“思考”和“决策”。它收集各个传感器的数据(比如温湿度),处理语音指令,控制表情显示屏,并通过Wi-Fi与手机App通信,下达各种命令。执行单元(ESP32):负责“动手干活”。它专门控制机器人的“手脚”——也就是驱动电机让花盆移动,以及控制水泵进行浇水。ESP32本身也带Wi-Fi,可以很方便地与主控通信。这种分工的好处是,Arduino Uno可以专注于逻辑和交互,而ESP32则专注于实时性要求较高的电机控制,两者通过串口通信,互不干扰,系统更稳定。
接下来,我们看看需要准备哪些“食材”。硬件是项目的骨架,选对了,后面开发会顺利很多。
2.1 核心控制器 Arduino Uno R3:这是项目的主控。选择它是因为其生态极其丰富,有海量的库和教程,对于初学者来说非常友好。它通过串口与ESP32通信,并连接其他交互模块。ESP32 DevKitC开发板:这是项目的执行控制器。我选择ESP32而不是更简单的ESP8266,主要是看中它有两个独立的硬件核心,一个可以用来处理网络通信,另一个可以专心做电机控制,性能更强,也更灵活。 2.2 感知与交互模块 DHT11温湿度传感器:用来监测花盆土壤附近的空气温湿度,数据会显示在手机App上,也是自动浇水的一个参考依据。MB08语音识别模块:这是一个集成了语音识别芯片的模块。你可以训练它识别特定的指令,比如“去喝水”、“去充电”,让花盆机器人能听懂你的话,实现语音交互。OLED显示屏(0.96寸,I2C接口):用来显示机器人的“表情包”。比如浇水时显示一个笑脸,电量低时显示一个哭脸,让冷冰冰的机器多了一丝趣味和亲和力。 2.3 执行机构 L298N电机驱动模块:这是一个非常经典的双路直流电机驱动模块。ESP32的IO口驱动能力很弱,无法直接驱动电机,需要用它来“放大”控制信号,从而驱动两个减速电机,实现花盆的前进、后退和转向。微型直流水泵(5V或12V):负责从水箱中抽水浇花。需要根据水泵的工作电压,配合一个合适的继电器或MOS管模块,由ESP32来控制其开关。减速电机与轮子:选择带有编码器的减速电机更好,这样可以实现更精确的移动控制(比如走多远、转多少度)。不过第一版为了简化,我用了普通的TT马达,通过控制通电时间来实现大致移动。 2.4 电源与结构 18650锂电池组与充电管理模块:为整个系统提供移动电源。需要搭配一个支持充放电保护的电池管理板(BMS),确保安全。底盘与结构件:可以用亚克力板激光切割,或者直接用现成的机器人底盘套件。需要留出空间放置花盆、水箱、电路板和电池。硬件齐了,咱们开始动手把它们连接起来。接线是硬件项目的基础,一定要仔细。
3.1 主控系统接线(Arduino Uno侧)这一部分主要是连接传感器和交互设备。
DHT11温湿度传感器:
VCC -> Arduino 5VGND -> Arduino GNDDATA -> Arduino 数字引脚 2 (可自定义)MB08语音识别模块:
通常通过串口(RX/TX)与Arduino通信。注意:Arduino Uno的硬件串口(Pin 0 RX, Pin 1 TX)通常用于和电脑通信调试,所以我们可以用 SoftwareSerial 库将其连接到其他数字引脚,比如 Pin 10 (RX), Pin 11 (TX)。VCC -> 5VGND -> GNDOLED显示屏 (I2C):
VCC -> Arduino 5VGND -> Arduino GNDSCL -> Arduino A5 (或SCL引脚)SDA -> Arduino A4 (或SDA引脚)与ESP32的通信线:
这是主控和执行器之间的“对话通道”。我们将使用另一组 SoftwareSerial。Arduino Pin 8 (TX) -> ESP32 Pin 16 (RX)Arduino Pin 9 (RX) -> ESP32 Pin 17 (TX)GND一定要共地! 将Arduino的GND和ESP32的GND用导线连接起来。 3.2 执行系统接线(ESP32侧)这一部分负责控制电机和水泵,是机器人的“手脚”。
L298N电机驱动模块:
输入电源:接锂电池的正负极(比如12V)。注意电压要匹配你的电机额定电压。输出A/B:分别接左轮电机和右轮电机。控制信号(来自ESP32): IN1 -> ESP32 GPIO 12 (控制电机A方向)IN2 -> ESP32 GPIO 14 (控制电机A方向)IN3 -> ESP32 GPIO 27 (控制电机B方向)IN4 -> ESP32 GPIO 26 (控制电机B方向)ENA -> ESP32 GPIO 13 (PWM引脚,控制电机A速度)ENB -> ESP32 GPIO 25 (PWM引脚,控制电机B速度)水泵控制:
水泵功率如果较小(5V),可以用一个MOS管模块(如IRF520)控制。将水泵正极接电源(通过MOS管),负极接GND。MOS管的控制极(Gate)接ESP32的一个GPIO,例如 GPIO 33。当ESP32将这个引脚设为高电平时,MOS管导通,水泵工作。注意:电机和水泵在启动和停止时会产生很大的瞬间电流,可能会干扰微控制器。一个实用的技巧是在ESP32的电源入口处加一个大电容(如1000uF),并在每个电机的两端并联一个续流二极管,可以有效减少干扰,让系统更稳定。
硬件连好了,我们来给它注入“灵魂”。代码部分我尽量讲清楚逻辑,大家可以根据自己的引脚定义进行调整。
4.1 Arduino Uno主控程序框架主控程序就像一个总指挥,需要轮询各个模块,并做出决策。
#include <SoftwareSerial.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial voiceSerial(10, 11);
SoftwareSerial espSerial(8, 9);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
Serial.begin(9600);
voiceSerial.begin(9600);
espSerial.begin(9600);
dht.begin();
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
displayWelcomeFace();
}
void loop() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (voiceSerial.available()) {
String command = voiceSerial.readStringUntil('n');
command.trim();
if (command == "GO_WATER") {
sendCommandToESP("WATER_ON");
displayWateringFace();
} else if (command == "GO_CHARGE") {
sendCommandToESP("GO_CHARGE");
displayChargingFace();
}
}
if (Serial.available()) {
String appCmd = Serial.readStringUntil('n');
processAppCommand(appCmd);
}
static unsigned long lastSendTime = 0;
if (millis() - lastSendTime > 5000) {
sendSensorData(temperature, humidity);
lastSendTime = millis();
}
}
void sendCommandToESP(String cmd) {
espSerial.println(cmd);
}
void displayWelcomeFace() {
display.clearDisplay();
display.display();
}
cpp
4.2 ESP32执行器控制程序ESP32的程序相对纯粹,就是接收命令,然后执行动作。
#include <WiFi.h>
#define MOTOR_A_IN1 12
#define MOTOR_A_IN2 14
#define MOTOR_B_IN3 27
#define MOTOR_B_IN4 26
#define MOTOR_A_PWM 13
#define MOTOR_B_PWM 25
#define PUMP_PIN 33
void setup() {
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, 16, 17);
pinMode(MOTOR_A_IN1, OUTPUT);
pinMode(MOTOR_A_IN2, OUTPUT);
pinMode(PUMP_PIN, OUTPUT);
digitalWrite(PUMP_PIN, LOW);
}
void loop() {
if (Serial2.available()) {
String command = Serial2.readStringUntil('n');
command.trim();
if (command == "GO_FORWARD") {
moveForward(2000);
} else if (command == "GO_BACKWARD") {
moveBackward(2000);
} else if (command == "TURN_LEFT") {
turnLeft(500);
} else if (command == "TURN_RIGHT") {
turnRight(500);
} else if (command == "WATER_ON") {
digitalWrite(PUMP_PIN, HIGH);
delay(3000);
digitalWrite(PUMP_PIN, LOW);
Serial2.println("WATER_DONE");
} else if (command == "STOP") {
stopMotor();
}
}
}
void moveForward(int duration) {
digitalWrite(MOTOR_A_IN1, HIGH);
digitalWrite(MOTOR_A_IN2, LOW);
digitalWrite(MOTOR_B_IN3, HIGH);
digitalWrite(MOTOR_B_IN4, LOW);
analogWrite(MOTOR_A_PWM, 200);
analogWrite(MOTOR_B_PWM, 200);
delay(duration);
stopMotor();
}
void stopMotor() {
digitalWrite(MOTOR_A_IN1, LOW);
digitalWrite(MOTOR_A_IN2, LOW);
digitalWrite(MOTOR_B_IN3, LOW);
digitalWrite(MOTOR_B_IN4, LOW);
analogWrite(MOTOR_A_PWM, 0);
analogWrite(MOTOR_B_PWM, 0);
}
cpp
为了让控制更方便,我简单做了一个手机App(可以用MIT App Inventor或Blynk这类快速开发工具),主要实现三个功能:
数据显示界面:实时显示从花盆机器人传回来的温度和湿度。手动控制界面:有前进、后退、左转、右转、停止、浇水等虚拟按钮,点击后通过Wi-Fi发送指令给Arduino。自动模式设置:可以设置当土壤湿度低于某个值时自动启动浇水任务。Arduino Uno这边需要连接一个Wi-Fi模块(如ESP-01S,或者直接换用NodeMCU这类带Wi-Fi的开发板),接收App的指令,并定时上传传感器数据。这部分网络通信的代码逻辑和上面的串口通信类似,只是数据载体变成了网络协议(如TCP/UDP或MQTT)。
做项目不可能一帆风顺,这里分享几个我踩过的坑,希望大家能避开:
电源干扰问题:电机启动瞬间,整个系统的电压会被拉低,可能导致ESP32或Arduino重启。解决方案:电机驱动模块的电源和单片机逻辑电源尽量分开(用两个稳压模块),并在单片机电源入口处加一个大电容(470uF以上)。串口通信乱码:软串口通信不稳定,容易出现乱码或丢数据。解决方案:确保通信双方(Arduino和ESP32)的波特率设置完全一致;尽量降低波特率(如9600);通信线不要太长;如果条件允许,使用硬件串口。电机不动或转动无力:检查L298N的使能引脚(ENA/ENB)是否被正确设置为高电平或PWM信号;检查电机驱动模块的供电电压是否足够。语音模块不识别:MB08模块需要先进行“训练”,把你说的话和特定的指令码绑定。一定要按照模块手册的步骤,在安静的环境下进行训练。这个智能花盆机器人的第一版,已经实现了自动浇水、手机遥控、环境监测和语音交互这些核心功能。你可以根据自己的想法继续扩展,比如增加土壤湿度传感器实现更精准的自动浇水,加上光敏电阻让机器人自动寻找阳光充足的地方,或者集成红外传感器实现自动避障。
嵌入式开发的乐趣就在于,把想法一点点变成现实。希望这个详细的解析能给你带来启发,动手做出属于你自己的那个会跑会跳的智能花盆。如果在制作过程中遇到任何问题,欢迎一起交流探讨。
相关知识
探秘智能园艺:gardenAutomation —— 开源的自动化种植助手
基于ESP32的开源定时浇花系统
Arduino智能花盆 – 太极创客
探索未来园艺:LilyGO HiGrow智能植物生长监测系统
基于Arduino智能节水灌溉设计(原理、PCB图、源程序)
基于Arduino的植物浇水系统
arduino智能浇花系统
如何用ESP32做一个智能检测花盆
Arduino Uno乐高支架
基于Python和Arduino的智能花盆系统
网址: 立创EDA开源项目:基于ESP32与Arduino Uno的智能花盆机器人DIY全解析 https://m.huajiangbk.com/newsview2581989.html
| 上一篇: 金钱树用什么花盆最好,要用排水性 |
下一篇: 花泥砖可以种菜吗 |