一、功能简介
本项目使用Proteus8仿真51单片机控制器,使用继电器模块、LCD1602模块、红外寻迹模块、电机驱动模块、SR04超声波模块、水位传感器模块等。
主要功能:
植保机器人能够实现红外线寻迹超声波避障,能够前进后退转弯,
在一开始没有找到轨迹时水泵不喷洒,找到轨迹后,水泵喷洒,
在遇到障碍物倒退是水泵停止喷洒,回到轨迹后水泵开始喷洒,
当水箱中没有水时,机器人停止运行,加满水后继续运行,
直到喷洒完成后,机器人停止喷洒回到初始位置。
二、软件设计
/*
作者:嗨小易(QQ:3443792007)
*/
//系统数据采集
void sys_data_get(void)
{
while(1)
{
//距离检测
sys_ctrl.dis=ultrasonicwave_measure(0);
//如果水箱有水
if(SX_H_PIN==0)
sys_ctrl.level=1;
else if(SX_L_PIN==0)
sys_ctrl.level=1;
//如果水箱没有水
else
sys_ctrl.level=0;
//如果左右红外检测到黑线
if(HW_L_PIN==0 && HW_R_PIN==0)
{
sys_ctrl.ired=3;
}
//如果仅左侧检测到黑线
else if(HW_L_PIN==0)
{
sys_ctrl.ired=1;
}
//如果仅右侧检测到黑线
else if(HW_R_PIN==0)
{
sys_ctrl.ired=2;
}
//如果左右未检测到黑线
else
sys_ctrl.ired=0;
break;
}
}
//红外检测状态显示
void _ir_staus_show(u8 sta)
{
//根据左右红外检测状态显示
switch(sta)
{
case 0://左右红外未检测
lcd1602_show_string(14,1,"NO");
break;
case 1://左红外检测
lcd1602_show_string(14,1,"L ");
break;
case 2://右红外检测
lcd1602_show_string(14,1," R");
break;
case 3://左右红外检测
lcd1602_show_string(14,1,"LR");
break;
}
}
//小车方向状态显示
void _car_staus_show(u8 sta)
{
switch(sta)
{
case 0://停止
lcd1602_show_string(4,1,"Stop");
break;
case 1://前进
lcd1602_show_string(4,1,"Forw");
break;
case 2://后退
lcd1602_show_string(4,1,"Back");
break;
case 3://左转
lcd1602_show_string(4,1,"Left");
break;
case 4://右转
lcd1602_show_string(4,1,"Righ");
break;
}
}
//系统数据显示
void sys_data_show(void)
{
while(1)
{
//距离检测值显示
lcd1602_show_nums(4,0,sys_ctrl.dis,2,0);
//根据左右红外检测状态显示
_ir_staus_show(sys_ctrl.ired);
//根据水箱检测状态显示
if(sys_ctrl.level==1)lcd1602_show_string(14,0,"OK");
else lcd1602_show_string(14,0,"NO");
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
break;
}
}
//系统功能控制
void sys_fun_ctrl(void)
{
static u8 sta=0;
//水箱有水
if(sys_ctrl.level==1)
{
//如果还未检测到轨迹,小车前进,不喷洒
if(sys_ctrl.track_flag==0)
{
PS_PIN=1;//不喷洒
//如果未检测到障碍物
if(sys_ctrl.dis>ALARM_DISTANCE)
{
sys_ctrl.dir=1;
car_forward();//小车前进
if(sys_ctrl.ired==3 && sta==0)//左右均检测到,起点,开始喷洒
{
sys_ctrl.track_flag=1;
delay_ms(1000);
}
if(sys_ctrl.ired==3 && sta==1)
{
sys_ctrl.dir=0;//停止
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_stop();
while(1);
}
}
//如果遇到障碍物
else
{
sys_data_get();
sys_data_show();
//绕过障碍物
sys_ctrl.dir=2;//后退
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_back();
delay_ms(1000);
sys_data_get();
sys_data_show();
sys_ctrl.dir=3;//左转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_left();
delay_ms(1000);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
delay_ms(1000);
sys_ctrl.dir=4;//右转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_right();
delay_ms(1000);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
delay_ms(2000);
sys_data_get();
sys_data_show();
sys_ctrl.dir=4;//右转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_right();
delay_ms(1000);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
delay_ms(1000);
sys_ctrl.dir=4;//右转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_right();
delay_ms(1000);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
//等待红外检测则停止
while(1)
{
sys_data_get();
if(sys_ctrl.ired==3)break;
}
sys_ctrl.dir=0;//停止
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_stop();
while(1);
}
}
//检测到轨迹
else
{
//如果未检测到障碍物
if(sys_ctrl.dis>ALARM_DISTANCE)
{
//如果左右边红外没有检测,开始喷洒,小车前进
if(sys_ctrl.ired==0)
{
PS_PIN=0;//喷洒
sys_ctrl.dir=1;
car_forward();
}
//如果左边红外检测,开始喷洒,小车左转
else if(sys_ctrl.ired==1)
{
PS_PIN=0;//喷洒
sys_ctrl.dir=3;
car_left();
}
//如果右边红外检测,开始喷洒,小车右转
else if(sys_ctrl.ired==2)
{
PS_PIN=0;//喷洒
sys_ctrl.dir=4;
car_right();
}
//如果左右边红外检测,终点,关闭喷洒,小车右转,进入无轨迹道路
else if(sys_ctrl.ired==3)
{
PS_PIN=1;//关闭喷洒
sys_ctrl.dir=0;//停止
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_stop();
delay_ms(1000);
sys_ctrl.track_flag=0;
sta=1;
sys_ctrl.dir=4;//右转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_right();
delay_ms(1000);
}
}
//如果遇到障碍物
else
{
sys_data_get();
sys_data_show();
//后退,关闭喷洒,寻找轨迹,找到轨迹退出
PS_PIN=1;//关闭喷洒
sys_ctrl.dir=2;//后退
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_back();
delay_ms(1000);
sys_data_get();
sys_data_show();
sys_ctrl.dir=3;//左转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_left();
delay_ms(1000);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
delay_ms(1000);
sys_ctrl.dir=4;//右转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_right();
delay_ms(1000);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
delay_ms(2000);
sys_data_get();
sys_data_show();
sys_ctrl.dir=4;//右转
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_right();
delay_ms(500);
sys_ctrl.dir=1;//前进
//小车方向状态显示
_car_staus_show(sys_ctrl.dir);
car_forward();
delay_ms(1000);
//等待红外检测则退出
while(1)
{
sys_data_get();
if(sys_ctrl.ired!=0)break;
}
}
}
}
//水箱没有水
else
{
PS_PIN=1;//关闭喷洒
sys_ctrl.dir=0;//停止
car_stop();
}
}
//应用控制系统
void appdemo_show(void)
{
lcd1602_init();
sys_parm_init();//系统参数初始化
sys_open_show();//系统开机显示
ultrasonicwave_init();//超声波初始化
while(1)
{
sys_data_get();//系统数据采集
sys_data_show();//系统数据显示
sys_parm_set();//系统参数设置
sys_fun_ctrl();//系统功能控制
}
}
三、实验现象
B站演示视频:https://space.bilibili.com/444388619
联系作者
专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。