1. 作品概述
本作品是一个基于行空板的智能种植系统,旨在通过自动化技术实现植物的智能养护。系统结合了3D打印技术、传感器技术、运动控制技术、语音交互技术和实时数据显示功能,能够自动检测土壤湿度、环境温度、湿度、光线亮度以及储水罐水位,并通过屏幕实时显示这些数据。用户可以通过语音交互或屏幕信息了解植物状态,系统还能自动完成浇水任务,并通过拍照功能记录植物生长过程。
2. 系统组成
花盆模块:系统包含6个3D打印的花盆模型,每个花盆内嵌一个土壤湿度传感器,用于实时监测土壤湿度。
储水罐模块:3D打印的储水罐用于存放浇花用水,侧面安装了一个非接触式水位传感器,用于检测水位。当水位过低时,系统会通过语音报警提示用户加水。储水罐顶部安装了一个水泵电机和水管,用于向花盆供水。
运动控制模块:在两列花盆之间设计了一个基于螺杆的运动装置,装置上搭载了一个舵机,能够实现左右运动。通过电机带动螺杆和舵机,系统可以在6个花盆之间自由移动。运动装置的最前端安装了一个触碰传感器,用于实现浇水后的回位限制和位置初始化功能。确保每次浇花定位的精准移动。
语音交互模块:系统支持通过语音唤醒“小行”进行交互,用户可以通过语音指令控制浇水、拍摄照片、显示照片等功能。
环境监测模块:系统配备了环境温度传感器、环境湿度传感器和光线亮度传感器,用于实时监测植物生长环境。
显示模块:系统配备了一个屏幕,实时显示当前环境温度、环境湿度、光线亮度、1到6号花盆的土壤湿度以及储水罐的水位状态。
3. 功能描述
自动浇水功能:系统会实时监测每个花盆的土壤湿度。当检测到某个花盆的土壤湿度低于设定值时,运动装置会自动移动到该花盆的位置,启动水泵进行浇水,持续3秒钟。
语音控制功能:用户可以通过语音唤醒“小行”进行交互。例如,说出“小行你好,一号田浇水”,系统会自动移动到一号花盆的位置,启动水泵进行浇水。用户还可以通过语音指令让“小行”拍摄照片或显示照片,记录植物的生长变化。
水位报警功能:当储水罐的水位低于设定值时,系统会通过语音报警提示用户需要加水,确保系统正常运行。
精准运动功能:在螺杆运动装置的最前端安装了一个触碰传感器,用于实现浇水后的回位限制和运动装置的位置初始化功能。每次浇水完成后,运动装置会自动回位到初始位置,确保下一次运行的精准性。
环境监测与显示功能:系统实时监测环境温度、环境湿度、光线亮度、1到6号花盆的土壤湿度以及储水罐的水位状态,并通过屏幕直观显示。用户可以通过屏幕随时了解植物生长环境和系统状态。
拍照与记录功能:用户可以通过语音指令让“小行”拍摄照片,并显示在屏幕上,用于记录植物的生长变化。
4. 技术亮点
3D打印技术:花盆和储水罐均采用3D打印技术制作,结构轻便且美观,能够根据实际需求进行个性化设计。
传感器技术:土壤湿度传感器、水位传感器、环境温度传感器、环境湿度传感器和光线亮度传感器的使用,使得系统能够全面监测植物生长环境和系统状态。
运动控制技术:基于螺杆的运动装置和舵机的结合,配合限位装置实现了系统在多个花盆之间的精准移动和定位。
语音交互技术:通过语音唤醒和指令识别,用户可以与系统进行自然交互,提升了系统的易用性和趣味性。
实时数据显示:通过屏幕实时显示环境数据和系统状态,用户可以直观了解植物生长情况和系统运行状态。
5. 应用场景
本作品适用于家庭、办公室、学校等场景,特别适合那些喜欢种植植物但缺乏时间或经验进行日常养护的用户。通过自动化浇水、环境监测和实时数据显示,用户可以轻松管理多个植物,同时通过语音交互和拍照功能,记录植物的生长过程,享受种植的乐趣。
6. 未来改进方向
远程控制:未来可以通过手机APP或网页端实现远程监控和控制,用户即使不在家也能随时了解植物的状态并进行浇水操作。
数据分析:系统可以记录土壤湿度、环境温度、湿度、光线亮度等数据,并通过数据分析为用户提供植物养护建议。
扩展功能:可以增加更多传感器(如CO₂传感器)或功能模块(如自动施肥),进一步优化植物的生长环境。
7. 总结
本作品通过创新的设计和技术的融合,实现了植物的智能化养护。它不仅解决了日常浇水的繁琐问题,还通过语音交互、实时数据显示和拍照功能,为用户提供了更加便捷、直观和有趣的种植体验。未来,随着技术的进一步升级,该系统将具备更多的功能和更广泛的应用场景。

/*!
* MindPlus
* esp32s3bit
*
*/
#include "asr.h"
#include "unihiker_k10.h"
#include <Microbit_Motor.h>
// 动态变量
volatile float mind_n_XianShiZhaoPianZhuangTai;
// 函数声明
void DF__14();
void DF__25();
void DF__36();
void DF_KaiShiJiaoShui();
void DF_FanHui();
// 创建对象
UNIHIKER_K10 k10;
uint8_t screen_dir=2;
ASR asr;
Microbit_Motor motorbit;
AHT20 aht20;
// 主程序开始
void setup() {
k10.begin();
pinMode(P1, INPUT);
Serial.begin(9600);
pinMode(P0, INPUT);
k10.initScreen(screen_dir);
k10.initBgCamerImage();
k10.setBgCamerImage(false);
k10.creatCanvas();
asr.asrInit(CONTINUOUS, CN_MODE, 9000);
while(asr._asrState == 0){delay(100);}
asr.setAsrSpeed(1);
k10.initSDFile();
k10.canvas->canvasClear();
k10.setScreenBackground(0xFFFFFF);
k10.canvas->canvasText(" 智慧农业", 1, 0x0000FF);
asr.addASRCommand(0+1, "yi hao tian jiao shui");
asr.addASRCommand(1+1, "er hao tian jiao shui");
asr.addASRCommand(2+1, "pai she zhao pian");
asr.addASRCommand(3+1, "xian shi zhao pian");
asr.addASRCommand(4+1, "san hao tian jiao shui");
asr.addASRCommand(5+1, "si hao tian jiao shui");
asr.addASRCommand(6+1, "wu hao tian jiao shui");
asr.addASRCommand(7+1, "liu hao tian jiao shui");
motorbit.servo(S8, 90);
mind_n_XianShiZhaoPianZhuangTai = 0;
}
void loop() {
Serial.println((digitalRead(P1)));
if ((mind_n_XianShiZhaoPianZhuangTai==0)) {
k10.canvas->canvasText((String("环境温度 :") + String(aht20.getData(AHT20::eAHT20TempC))), 2, 0x0000FF);
k10.canvas->canvasText((String("环境湿度 :") + String(aht20.getData(AHT20::eAHT20HumiRH))), 3, 0x0000FF);
k10.canvas->canvasText((String("光线强度 :") + String(k10.readALS())), 4, 0x0000FF);
}
if (((digitalRead(P0))==1)) {
k10.canvas->canvasText((String("储水罐状态:") + String("缺水")), 11, 0x0000FF);
asr.speak("储水罐该加水了");
k10.canvas->updateCanvas();
delay(3000);
}
else {
k10.canvas->canvasText((String("储水罐状态:") + String("充足")), 11, 0x0000FF);
k10.canvas->updateCanvas();
}
if (((digital_read(eP8))==1)) {
k10.canvas->canvasText((String("一号田湿度:") + String("正常")), 5, 0x0000FF);
}
else {
k10.canvas->canvasText((String("一号田湿度:") + String("缺水")), 5, 0x0000FF);
k10.canvas->updateCanvas();
delay(3000);
asr.speak("一号田缺水,正在进行自动浇灌");
DF__14();
motorbit.servo(S8, 0);
DF_KaiShiJiaoShui();
k10.canvas->canvasText((String("一号田湿度:") + String("正常")), 5, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
DF_FanHui();
}
if (((digital_read(eP12))==1)) {
k10.canvas->canvasText((String("二号田湿度:") + String("正常")), 6, 0x0000FF);
k10.canvas->updateCanvas();
}
else {
k10.canvas->canvasText((String("二号田湿度:") + String("缺水")), 6, 0x0000FF);
k10.canvas->updateCanvas();
delay(3000);
asr.speak("二号田缺水,正在进行自动浇灌");
DF__25();
motorbit.servo(S8, 0);
DF_KaiShiJiaoShui();
k10.canvas->canvasText((String("二号田湿度:") + String("正常")), 6, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
DF_FanHui();
}
if (((digitalRead(P1))==1)) {
k10.canvas->canvasText((String("三号田湿度:") + String("正常")), 7, 0x0000FF);
}
else {
k10.canvas->canvasText((String("三号田湿度:") + String("缺水")), 7, 0x0000FF);
k10.canvas->updateCanvas();
delay(3000);
asr.speak("三号田缺水,正在进行自动浇灌");
DF__36();
motorbit.servo(S8, 0);
DF_KaiShiJiaoShui();
k10.canvas->canvasText((String("三号田湿度:") + String("正常")), 7, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
DF_FanHui();
}
if (((digital_read(eP14))==1)) {
k10.canvas->canvasText((String("四号田湿度:") + String("正常")), 8, 0x0000FF);
}
else {
k10.canvas->canvasText((String("四号田湿度:") + String("缺水")), 8, 0x0000FF);
k10.canvas->updateCanvas();
delay(3000);
asr.speak("四号田缺水,正在进行自动浇灌");
DF__14();
motorbit.servo(S8, 180);
DF_KaiShiJiaoShui();
k10.canvas->canvasText((String("四号田湿度:") + String("正常")), 8, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
DF_FanHui();
}
if (((digital_read(eP15))==1)) {
k10.canvas->canvasText((String("五号田湿度:") + String("正常")), 9, 0x0000FF);
}
else {
k10.canvas->canvasText((String("五号田湿度:") + String("缺水")), 9, 0x0000FF);
k10.canvas->updateCanvas();
delay(3000);
asr.speak("五号田缺水,正在进行自动浇灌");
DF__25();
motorbit.servo(S8, 180);
DF_KaiShiJiaoShui();
k10.canvas->canvasText((String("五号田湿度:") + String("正常")), 9, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
DF_FanHui();
}
if (((digital_read(eP13))==1)) {
k10.canvas->canvasText((String("六号田湿度:") + String("正常")), 10, 0x0000FF);
}
else {
k10.canvas->canvasText((String("六号田湿度:") + String("缺水")), 10, 0x0000FF);
k10.canvas->updateCanvas();
delay(3000);
asr.speak("六号田缺水,正在进行自动浇灌");
DF__36();
motorbit.servo(S8, 180);
DF_KaiShiJiaoShui();
k10.canvas->canvasText((String("六号田湿度:") + String("正常")), 10, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
DF_FanHui();
}
k10.canvas->updateCanvas();
if (asr.isDetectCmdID(0+1)) {
asr.speak("收到");
delay(1000);
DF__14();
motorbit.servo(S8, 0);
DF_KaiShiJiaoShui();
delay(1000);
DF_FanHui();
}
if (asr.isDetectCmdID(1+1)) {
asr.speak("收到");
delay(1000);
DF__25();
motorbit.servo(S8, 0);
DF_KaiShiJiaoShui();
delay(1000);
DF_FanHui();
}
if (asr.isDetectCmdID(2+1)) {
asr.speak("收到");
delay(1000);
k10.photoSaveToTFCard("S:/photo.bmp");
asr.speak("拍摄完成");
delay(1000);
}
if (asr.isDetectCmdID(4+1)) {
asr.speak("收到");
delay(1000);
DF__36();
motorbit.servo(S8, 0);
DF_KaiShiJiaoShui();
delay(1000);
DF_FanHui();
}
if (asr.isDetectCmdID(5+1)) {
asr.speak("收到");
delay(1000);
DF__14();
motorbit.servo(S8, 180);
DF_KaiShiJiaoShui();
delay(1000);
DF_FanHui();
}
if (asr.isDetectCmdID(6+1)) {
asr.speak("收到");
delay(1000);
DF__25();
motorbit.servo(S8, 180);
DF_KaiShiJiaoShui();
delay(1000);
DF_FanHui();
}
if (asr.isDetectCmdID(7+1)) {
asr.speak("收到");
delay(1000);
DF__36();
motorbit.servo(S8, 180);
DF_KaiShiJiaoShui();
delay(1000);
DF_FanHui();
}
if (asr.isDetectCmdID(3+1)) {
k10.canvas->canvasClear();
asr.speak("好的");
delay(1000);
mind_n_XianShiZhaoPianZhuangTai = 1;
k10.canvas->canvasDrawImage(0, 0, "S:/photo.bmp");
k10.canvas->updateCanvas();
delay(1000);
k10.canvas->canvasText("3", 1, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
k10.canvas->canvasText("2", 1, 0x0000FF);
k10.canvas->updateCanvas();
delay(1000);
k10.canvas->canvasText("1", 1, 0x0000FF);
k10.canvas->updateCanvas();
k10.canvas->canvasClear();
mind_n_XianShiZhaoPianZhuangTai = 0;
}
if ((((k10.isGesture(ScreenUp)) || (k10.isGesture(ScreenDown))) || ((k10.isGesture(TiltLeft)) || (k10.isGesture(TiltRight))))) {
asr.speak("别碰我,别碰我,放回原位");
delay(2000);
}
}
// 自定义函数
void DF__14() {
motorbit.motorRun(M3, CCW, 255);
delay(500);
motorbit.motorRun(M3, CCW, 0);
}
void DF__25() {
motorbit.motorRun(M3, CCW, 255);
delay(12000);
motorbit.motorRun(M3, CCW, 0);
}
void DF__36() {
motorbit.motorRun(M3, CCW, 255);
delay(22000);
motorbit.motorRun(M3, CCW, 0);
}
void DF_KaiShiJiaoShui() {
delay(2000);
motorbit.motorRun(M4, CW, 255);
delay(1500);
motorbit.motorRun(M4, CW, 0);
digital_write(eP15, HIGH);
k10.rgb->write(-1, 0x0000FF);
delay(1000);
motorbit.motorRun(M4, CW, 0);
digital_write(eP15, LOW);
k10.rgb->write(-1, 0x000000);
motorbit.servo(S8, 90);
}
void DF_FanHui() {
while (!((digital_read(eP16))==0)) {
motorbit.motorRun(M3, CW, 255);
}
motorbit.motorRun(M3, CW, 0);
delay(1000);
motorbit.motorRun(M3, CCW, 200);
delay(500);
motorbit.motorRun(M3, CCW, 0);
}
宋云辉2025.03.23
厉害👍
思乐泮水2025.03.18
用传输带会不会好些
cY4k0QuD2025.02.18
酷酷的,感谢分享
小黑猫2025.02.18
很炫的效果
yuyuyuyu2025.02.18
有智能自动化的感觉,不错