智能盆栽小车
智能盆栽小车

智能盆栽小车

目录

本作品名称为智能盆栽小车。其基于传统的智能小车硬件和自动浇花系统,通过 arduino 单片机控制多个传感器,使放在智能车上的盆栽能被自动照顾。可实现如:缺水时浇花,选择阳光照射最大处,环境温度过高时前往阴影处的等功能。。

设计灵感

本项目的智能盆栽小车是同学基于智能家居新的创新尝试,灵感来源于某位 同学暑假出门家庭旅行时,自己种植的植物因为在家中无人照顾,导致该其回家 时发现植物已经因为缺水而死从而收到的启发,通过以往实训课程和 C 语言的学 习,我们选择 Arduino UNO R3 单片机和小车组合的方式来完成整套系统,同时 arduino 的多传感器和模拟数字(A/D pin)输入为我们智能盆栽小车提供了更多 的功能可行性。

设计方案

设计思路

本项目的智能盆栽小车可分为测距小车系统,自动浇花系统两大部分。 

测距小车系统:由马达模块(含继电器模块),双测距模块(含舵机模块),光传感器模块(四个),温度传感器模块组成。首先光传感器模块判断出阳光最强处,通过单片机系统控制马达模块指示小车往阳光最大处移动,在移动前,经双测距模块判断该方向是否可前进,能前进则继续前往该方向,其他情况则中断前进指令。温度传感器负责检测环境温度,若检测到环境温度过高不适合植物生长,则通过马达模块让小车前往阴影处。

自动浇花系统:由土壤湿度传感器模块,水泵模块,水位传感器模块组成。将盆栽放在小车上,将土壤湿度传感器插入泥土并在小车的储水箱内加入足量的水。土壤湿度传感器反馈土壤湿度值给 arduino 单片机,在检测到土壤较干时(植物缺水状态),系统通过在储水箱内的水位传感器判断储水箱内是否有足够的水,若储水量充足,通过给水泵模块使能,经由水管将储水箱的水浇入盆栽,
待土壤湿度传感器判断土壤水分充足时停止浇水。

总体来说,本项目首创的智能盆栽小车,类似将家中的植物交给专人管理,应用较广,需求可观,开发前景较大。此原型可编程也可调节各个传感器阈值,适用于其他多种不同植物,如仙人掌、水仙、薄荷、多肉,而目前市场基本空白,存在需求无法满足的情况,而且此项目成本较低,相信在投入市场后会有客观回报。

系统结构

智能盆栽小车
成品图
前测距避障模块(180°)
后测距避障模块(固定)

马达模块

光传感器模块

土壤湿度传感器模块
水箱水位传感器模块
水泵模块
环境温度传感器模块

PCB电路设计

总体线路设计和接发因人而异,在这里我给出了核心注意点的电路:主要的驱动部分电路、周围传感器之一-光传感器,作为样板,其他模块接法可参考各自的说明手册以及代码即可反推。

驱动部分

光传感器

工程代码

此代码基于 Arduino 语言。 在第一部分,我们需要定义主板的引脚并设置通信波特率。 管脚的定义因人而异,根据自己的接线方式设置相应的管脚即可。

				
					#include <SoftwareSerial.h>
int motorL1=6; //定义左边轮子前进方向
int motorL2=5; //定义左边轮子后退方向
int motorR1=9; //定义右边轮子前进方向
int motorR2=11; //定义右边轮子后退方向
int water_machine=13; //定义水泵使能管脚
int water_testPin=A4; //定义土壤湿度输入管脚
int water_test=0; //定义土壤湿度全局变量
int water_level=512; //定义土壤湿度判定值
int temP=12; //定义温度输入管脚
int box_level=A5; //定义储水槽水位输入管脚
int box=0; //定义储水槽水位全局变量
Servo s; //超声波转向舵机
int trig_f=4; //发射信号(前部测距)
int echo_f=2; //接收信号(前部测距)
int trig_b=3; //发射信号(后部测距)
int echo_b=7; //接收信号(后部测距)
int level=250;//光阈值
unsigned int S_l; //距离存储(前左)
unsigned int S_r; //距离存储(前右)
unsigned int S_m; //距离存储(前中)
unsigned int S_b; //距离存储(后)
int sensorPin_fl= A0; // 定义光传感器(左前)模拟输入管脚
int sensorValue_fl= 0; // 定义光传感器(左前)模拟输入全局变量
int sensorPin_fr= A1; //定义光传感器(右前)模拟输入管脚
int sensorValue_fr= 0; // 定义光传感器(右前)模拟输入全局变量
int sensorPin_bl= A2; // 定义光传感器(左后)模拟输入管脚
int sensorValue_bl= 0; // 定义光传感器(左后)模拟输入全局变量
int sensorPin_br= A3; //定义光传感器(右后)模拟输入管脚
int sensorValue_br= 0; // 定义光传感器(右后)模拟输入全局变量

void setup() {
Serial.begin(9600); //设置波特率
pinMode(trig_f,OUTPUT); //设置引脚模式
pinMode(echo_f,INPUT); //设置引脚模式
pinMode(trig_b,OUTPUT); //设置引脚模式
pinMode(echo_b,INPUT); //设置引脚模式
pinMode(motorL1,OUTPUT);
pinMode(motorL2,OUTPUT);
pinMode(motorR1,OUTPUT);
pinMode(motorR2,OUTPUT);
pinMode(sensorPin_fl,INPUT);
pinMode(sensorPin_fr,INPUT);
pinMode(sensorPin_bl,INPUT);
pinMode(sensorPin_br,INPUT);
pinMode(water_machine,OUTPUT);
pinMode(water_test,INPUT);
pinMode(temP,INPUT);
pinMode(box_level,INPUT);

s.attach(8); //定义舵机所用引脚
s.write(90); //初始化舵机角度
tone(12,800,500);
delay(2000); //开机延时
}
				
			

以下代码是主要功能。 上述初始化设置代码依次执行一次后,主控芯片会循环执行下面的函数。这部分汽车的控制和汽车对环境的自动识别的实现也主要通过代码来实现。

				
					void loop() //主函数
{
// read the value from the sensor:   
sensorValue_fl = analogRead(sensorPin_fl);   
Serial.print("sensorValue_fl = ");  //串口输出"Intensity = "   
Serial.println(sensorValue_fl); 
//向串口发送 sensorValue_fl 的值,可以在显示器上显示光强值   
sensorValue_fr = analogRead(sensorPin_fr);   
Serial.print("sensorValue_fr = ");  //串口输出" sensorValue_fr = " 
 
Serial.println(sensorValue_fr);   
sensorValue_bl = analogRead(sensorPin_bl);   
Serial.print("sensorValue_bl = ");     
Serial.println(sensorValue_bl);     
sensorValue_br = analogRead(sensorPin_br);   
Serial.print("sensorValue_br = ");      
Serial.println(sensorValue_br);        
water_test = analogRead(water_testPin);   
Serial.print("water_test = ");   //输出土壤湿度值   
Serial.println(water_test);    
int temP_level = digitalRead(12);   
box = analogRead(box_level);   
Serial.print("box_level = ");   //输出水箱储水值 
 
Serial.println(box);     
delay(500);      
// stop the program for <sensorValue> milliseconds:   
//delay(sensorValue_fl);   
//delay(sensorValue_fr);   
//delay(sensorValue_bl);   
//delay(sensorValue_br); 
 
 
// 
//下面的 XXXX 分别代表小车四个角的光传感器判定的亮暗 
//如 1010 代表小车左前和左后光照更强,小车执行左转指令 
//如 0001 代表小车右后光照更强,小车执行左转指令后再判断执行后退指令 
//   
if(temP_level==HIGH)
    {      
    if(sensorValue_fl<506 && sensorValue_fr<506 && sensorValue_bl<506 && sensorValue_br<506)
        {            
        if(sensorValue_fl<level && sensorValue_fr>level && sensorValue_bl>level && sensorValue_br>level)    //1000               
            {range_f(); //执行测距函数                 
            if(S_l>30 && S_m>30)                    
            L();                  
            }            
        else if(sensorValue_fl>level && sensorValue_fr<level && sensorValue_bl>level && sensorValue_br>level)//0100                
            {range_f(); //执行测距函数                 
            if(S_r>30 && S_m>30)                    
            R(); 
            }            
        else if(sensorValue_fl>level && sensorValue_fr>level && sensorValue_bl<level && sensorValue_br>level)//0010               
            {range_b(); //执行测距函数                 
            if(S_b>30)                   
            {R();
            }                  
            }            
        else if(sensorValue_fl>level && sensorValue_fr>level && sensorValue_bl>level && sensorValue_br<level)//0001                
            {range_b(); //执行测距函数                 
            if(S_b>30)                   
            {L();}                  
            }            
        else if(sensorValue_fl<level && sensorValue_fr<level && sensorValue_bl>level && sensorValue_br>level)//1100                
            {range_f(); //执行测距函数                 
            if(S_r>30 && S_m>30 && S_l>30)                    
                line();                  
            }            
        else if(sensorValue_fl<level && sensorValue_fr>level && sensorValue_bl<level && sensorValue_br>level)//1010                
            {range_f(); //执行测距函数                 
            if(S_l>30 && S_m>30)                    
                {L();}                  
            }            
        //    else if(sensorValue_fl<level && sensorValue_fr>level && sensorValue_bl>level && sensorValue_br<level){}  1001            
        //    else if(sensorValue_fl>level && sensorValue_fr<level && sensorValue_bl<level && sensorValue_br>level){}  0110            
        else if(sensorValue_fl>level && sensorValue_fr<level && sensorValue_bl>level && sensorValue_br<level)//0101                
                {range_f(); //执行测距函数                 
                if(S_r>30 && S_m>30)                    
                    {R();}}            
        else if(sensorValue_fl>level && sensorValue_fr>level && sensorValue_bl<level && sensorValue_br<level)//0011                
                {range_b(); //执行测距函数                 
                if(S_b>30)                    
                    back();                  
                }            
        else if(sensorValue_fl>level && sensorValue_fr<level && sensorValue_bl<level && sensorValue_br<level)//0111                
                {L();}            
        else if(sensorValue_fl<level && sensorValue_fr>level && sensorValue_bl<level && sensorValue_br<level)//1011                
                {R();}            
        else if(sensorValue_fl<level && sensorValue_fr<level && sensorValue_bl>level && sensorValue_br<level)//1101                
                {R();}            
        else if(sensorValue_fl<level && sensorValue_fr<level && sensorValue_bl<level && sensorValue_br>level)//1110                
                {L();}            
                   
        else   
                {line();    
                delay(5000);    
                lull();}
        }}              
if(water_test>water_level && box>300)//如果土壤湿度值较低且水箱有水   
    {digitalWrite(water_machine,HIGH);}   //给水泵使能给植物浇水   
else   
    digitalWrite(water_machine,LOW);       
     
}
				
			

以下部分定义的代码是实现操作小车的基本功能。 通过将其集成到一个函数中,可以使上一部分的代码更加简洁易懂。

				
					void range_f(){ //测距函数 
s.write(90); //舵机中位 
delay(500); //留时间给舵机转向 
digitalWrite(trig_f,LOW); //测距 
delayMicroseconds(2); //延时 2 微秒 
digitalWrite(trig_f,HIGH); 
delayMicroseconds(20); 
digitalWrite(trig_f,LOW); 
int distance = pulseIn(echo_f,HIGH); //读取高电平时间 
distance = distance/58; //按照公式计算 
S_m = distance; //把值赋给 S 

s.write(45); //舵机 
delay(500); //留时间给舵机转向 
digitalWrite(trig_f,LOW); //测距 
delayMicroseconds(2); //延时 2 微秒 
digitalWrite(trig_f,HIGH); 
delayMicroseconds(20); 
digitalWrite(trig_f,LOW); 
distance = pulseIn(echo_f,HIGH); //读取高电平时间 
distance = distance/58; //按照公式计算 
S_l = distance; //把值赋给 S 

s.write(135); //舵机 
delay(500); //留时间给舵机转向 
digitalWrite(trig_f,LOW); //测距 
delayMicroseconds(2); //延时 2 微秒 
digitalWrite(trig_f,HIGH); 
delayMicroseconds(20); 
digitalWrite(trig_f,LOW); 
distance = pulseIn(echo_f,HIGH); //读取高电平时间 
distance = distance/58; //按照公式计算 
S_r = distance; //把值赋给 S 
//Serial.println(S); //向串口发送 S 的值,可以在显示器上显示距离 
//if (S<30){ 
//tone(12,800,50); 
//delay(50); 
//延时 
//} 

} 
void range_b(){ //测距函数 
digitalWrite(trig_b,LOW); //测距 
delayMicroseconds(2); //延时 2 微秒 
digitalWrite(trig_b,HIGH); 
delayMicroseconds(20); 
digitalWrite(trig_b,LOW); 
int distanceb = pulseIn(echo_b,HIGH); //读取高电平时间 
distanceb = distanceb/58; //按照公式计算 
S_b = distanceb; //把值赋给 S 
//Serial.println(S); //向串口发送 S 的值,可以在显示器上显示距离 
//if (S<30){ 
//tone(12,800,50); 
//delay(50); 
//延时} 
} 

void line(){//前进 
digitalWrite(motorR1,HIGH); //启动所有电机向前 
digitalWrite(motorL1,HIGH); 
digitalWrite(motorR2,LOW); 
digitalWrite(motorL2,LOW); 
} 

void L(){//左转 
digitalWrite(motorL1,LOW); 
digitalWrite(motorR2,LOW); 
analogWrite(motorL2,100); 
analogWrite(motorR1,100); 
//delay(500); 
//lull(); 
//暂停所有电机 
} 

void R(){//右转 
digitalWrite(motorL2,LOW); 
digitalWrite(motorR1,LOW); 
analogWrite(motorL1,100); 
analogWrite(motorR2,100); 
//delay(500); 
//lull(); } 

void back(){ //后退函数 
digitalWrite(motorL1,LOW); 
digitalWrite(motorR1,LOW); 
analogWrite(motorL2,100); 
analogWrite(motorR2,100); 
//delay(500); 
} 

void lull(){//停止 
digitalWrite(motorL1,LOW); 
digitalWrite(motorL2,LOW); 
digitalWrite(motorR1,LOW); 
digitalWrite(motorR2,LOW); 
}
				
			

创新点

  1. 在传统的浇花系统上加入水位传感器,检测储水箱真实水位,防止水泵空转,节约系统电能让系统可以持续运行更长的时间。
  2. 在智能小车的基础上增加智能浇花系统,实现了两套系统的结合与创新。
  3. 在智能盆栽小车的四个角上加入了光传感器,并设定阈值。只有在白天,小车才会通过检测光强,自动前往光线最强处进行光合作用。
  4. 整套系统通过温度传感器能对环境温度做出反应,温度过高能前往阴影处,多种传感器都是围绕能让植物实现自己照顾自己而设计,完全实现托管植物或懒人法养植物

技术总结

目前市场上暂无同类可照顾植物的智能家居,本项目首创的智能盆栽小车, 类似将家中的植物交给专人管理,应用较广,需求可观,开发前景较大。此原型 可编程也可调节各个传感器阈值,可以控制土壤的湿度,后期也可拓展做温箱从 而控制环境温度,可适用于其他多种不同植物,如仙人掌、水仙、多肉、热带植物,而目前市场基本空白,存在需求无法满足的情况,而且此项目成本较低,可拓展功能多,针对不同人士对不同植物的养殖要求,可定制不同的智能盆栽小车, 相信在投入市场后会有客观回报。 

同时小车现在 demo只是初步模型,完成了功能但是做工较为粗糙,当时选材导致体型的限制让小车走线较乱,样貌不佳,而且代码因为时间有限原因较为简单,后期还有改进空间。若能成功商用,可通过 PCB 和集成电路优化系统,使小车更加精简漂亮、电能节约,后期还可加入太阳能模块等,完全真正自主。

发表回复

您的电子邮箱地址不会被公开。