Record:2021/5/12日学院举办的智能小车比赛落下帷幕,特地将比赛出现的问题和经历总结一下,以表纪念。
比赛要求蓝牙模板和超声波,测距,目标跟踪四个功能整合在一个程序上,另一项就是红外循迹加避障(不是绕碍,不过也不难)。
我先将记忆深刻的红外循迹避障程序记录下来:
首先直接上代码:
* 晶振:11.0592MHZ
ZYWIFI0939WIFI控制智能机器人杜邦线接线方法,请一定照做,否则可能不工作,并烧毁小车。
J3 接到实验板 P4 J4 接实验板 P7接口
IN1--接到--实验板上的P1.2 IN5--接到--实验板上的P2.1
IN2--接到--实验板上的P1.3 IN6--接到--实验板上的P2.0
EN1--接到--实验板上的P1.4
EN2--接到--实验板上的P1.5
IN3--接到--实验板上的P1.6
IN4--接到--实验板上的P1.7
J5 接实验班P3接口
OUT1--接到--实验板上的P3.2 OUT3--接到--实验板上的P3.4
OUT2--接到--实验板上的P3.3 OUT4--接到--实验板上的P3.5
VCC-- 接到--实验班上的VCC GND--接到--实验板上的GND
******************************************************************/
#ifndef _LED_H_
#define _LED_H_
//定义小车驱动模块输入IO口
sbit L293D_IN1=P1^2;
sbit L293D_IN2=P1^3;
sbit L293D_IN3=P1^4;
sbit L293D_IN4=P1^5;
sbit L293D_EN1=P1^6;
sbit L293D_EN2=P1^7;
/***蜂鸣器接线定义*****/
sbit BUZZ=P2^3;
#define Left_1_led P3_7 //左传感器
#define Right_1_led P3_6 //右传感器
#define mid_1_led P0^0 //中间循迹
#define Left_2_led P3_4 //左避障传感器
#define Right_2_led P3_5 //右避障传感器
#define Left_moto_pwm P1_6 //PWM信号端
#define Right_moto_pwm P1_7 //PWM信号端
#define Left_moto_go {P1_2=1,P1_3=0;} //左电机向前走
#define Left_moto_back {P1_2=0,P1_3=1;} //左边电机向后转
#define Left_moto_Stop {P1_2=0,P1_3=0;} //左边电机停转
#define Right_moto_go {P1_4=1,P1_5=0;} //右边电机向前走
#define Right_moto_back {P1_4=0,P1_5=1;} //右边电机向后走
#define Right_moto_Stop {P1_4=0,P1_5=0;} //右边电机停转
unsigned char pwm_val_left =0;//变量定义
unsigned char push_val_left =0;// 左电机占空比N/20
unsigned char pwm_val_right =0;
unsigned char push_val_right=0;// 右电机占空比N/20
bit Right_moto_stop=1;
bit Left_moto_stop =1;
unsigned int time=0;
/************************************************************************/
//延时函数
void delay(unsigned int k)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<200;y++);
}
/************************************************************************/
//前速前进
void run(void)
{
push_val_left=20; //速度调节变量 0-20。。。0最小,20最大
push_val_right=20;
Left_moto_go ; //左电机往前走
Right_moto_go ; //右电机往前走
}
//后退函数
void backrun(void)
{
push_val_left=12; //速度调节变量 0-20。。。0最小,20最大
push_val_right=12;
Left_moto_back; //左电机往后走
Right_moto_back; //右电机往后走
}
//左转
void leftrun(void)
{
push_val_left=14;
push_val_right=20;
Right_moto_go ; //右电机往前走
Left_moto_go ; //左电机后走
}
//急左转
void moreleft(void)
{
push_val_left=15;
push_val_right=15;
Right_moto_go ; //右电机往前走
Left_moto_back ; //左电机后走
}
//右转
void rightrun(void)
{
push_val_left=20;
push_val_right=14;
Left_moto_go ; //左电机往前走
Right_moto_go ; //右电机往后走
}
//急右转
void moreright(void)
{
push_val_left=16;
push_val_right=16;
Left_moto_go ; //左电机往前走
Right_moto_back ; //右电机往后走
}
//停止
void stop(void)
{
Right_moto_Stop ; //右电机停止
Left_moto_Stop ; //左电机停止
}
/************************************************************************/
/* PWM调制电机转速 */
/************************************************************************/
/* 左电机调速 */
/*调节push_val_left的值改变电机转速,占空比 */
void pwm_out_left_moto(void)
{
if(Left_moto_stop)
{
if(pwm_val_left<=push_val_left)
{
Left_moto_pwm=1;
// Left_moto_pwm1=1;
}
else
{
Left_moto_pwm=0;
// Left_moto_pwm1=0;
}
if(pwm_val_left>=20)
pwm_val_left=0;
}
else
{
Left_moto_pwm=0;
// Left_moto_pwm1=0;
}
}
/******************************************************************/
/* 右电机调速 */
void pwm_out_right_moto(void)
{
if(Right_moto_stop)
{
if(pwm_val_right<=push_val_right)
{
Right_moto_pwm=1;
// Right_moto_pwm1=1;
}
else
{
Right_moto_pwm=0;
// Right_moto_pwm1=0;
}
if(pwm_val_right>=20)
pwm_val_right=0;
}
else
{
Right_moto_pwm=0;
// Right_moto_pwm1=0;
}
}
/***************************************************/
///*TIMER0中断服务子函数产生PWM信号*/
void timer0()interrupt 1 using 2
{
TH0=0XFc; //1Ms定时
TL0=0X18;
time++;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
/*********************************************************************/
#endif
#include<AT89X52.H> //包含51单片机头文件,内部有各种寄存器定义
#include<ZY-4WD_PWM.H> //包含HL-1蓝牙智能小车驱动IO口定义等函数
//主函数
void main(void)
{
unsigned char i;
unsigned char flag; // 标记点
P1=0X00; //关电机
TMOD=0X01;
TH0= 0XFc; //1ms定时
TL0= 0X18;
TR0= 1;
ET0= 1;
EA = 1; //开总中断
while(1) //无限循环
{
if(Left_2_led==0 || Right_2_led==0) //遇到障碍物
{
backrun();
delay(1);
stop();
}
//有信号为0 没有信号为1
if(Left_1_led==1&&mid_1_led==1&&Right_1_led==1)//亮的时候为0,1才检测到黑线
{
run();
}
if(Left_1_led==1&&mid_1_led==1&&Right_1_led==0)
{
leftrun();
flag=0;
delay(1);
}
if(Left_1_led==0&&mid_1_led==1&&Right_1_led==1)
{
rightrun();
flag=1;
delay(1);
}
if(Right_1_led==1&&Left_1_led==1)
{
run();
}
if(Left_1_led==0&&mid_1_led==0&&Right_1_led==0)//亮的时候为0,1才检测到黑线
{ //跑出赛道
if(flag==1)
{ //右急转
moreright();
}
if(flag==0)
{ //左急转
moreleft();
}
}
}
}
我们在基础的代码上进行的修改,让它的速度尽量发挥到极致,这个小车在淘宝上买的,大概两百多,感兴趣的话可以买一辆挺好玩的。
根据小车传感器原理图我们可以知道P3.6,P3.7,P0.0为三个红外循迹传感器,P3.4,P3.5为左右避障传感器大家要根据原理图进行更改,需要原理图的可以私聊我,在调试小车时,就因为没有认真看原理图在代码编写的时候一直出问题,还有一定一定一定要将代码放在准确的文件夹里,我好多次就是改代码改了一下午没找到错误,后来才发现代码写到另一个备份的文件夹里,白白浪费一个下午的时间。
代码部分,我们在原代码的基础上增加了flag函数,这是为了在速度极高的情况之下,小车就有跑出赛道的可能却依然能跑回赛道(这也就意味着没检测到黑线小车就会跑了)。正是这个flag函数的存在使得可以将小车的硬件发挥到极致,所以我们把PWM调速调到最高小车也不会跑离赛道太多(会有一丢丢的跑出去),避障的话我加了一个后退的函数,避免速度太快直接撞上。至少电机反转减速倒退然后保持一定距离。
下面就是测试哪个速度能将跑出最快的成绩了,我们用黑色胶带在宿舍自己搞了一个赛道然后测试时间:
最左边是前进速度左右电机都为20,左右电机在转向的时候都是向前走,依靠两边的速度差进行转向(测试过一边电机向后一边向前转,不过速度不太理想);后面最好速度为一圈11.3秒,可能存在一些偶然误差,不过这确实是比较理想的数据了。
然后静静等待比赛结果了,不管怎样这五天和同学一起研究挺开心的,不论结果如何不断冲刺吧!
我们的目标可是不断超越!