stm32配置图:
颜色识别模块对应接线:
/接线方法
/VCC 接3.3
/GND 接GND
/LED 接3.3
#define S0 PCout(6)
#define S1 PCout(7)
#define S2 PCout(8)
#define S3 PCout(9)
#define OUT PAin(8)
Oled屏幕的对应接线:
// ----------------------------------------------------------------
// GND 电源地
// VCC 接5V或3.3v电源
// D0 接PA5(SCL)
// D1 接PA7(SDA)
// RES 接PB0
// DC 接PB1
// CS 接PA4
// ----------------------------------------------------------------
以下接线准备用来控制舵机驱动板:
PC12 PC11
如果不使用舵机驱动板:
通过PB12,PB13,PB14,PB15进行控制
定时器1用来进行颜色识别模块的输入捕获
定时器2 用来输出控制电机的PWM波
定时器3用来控制舵机的PWM
定时器4用来延时
距离模块是IIC通讯:
决定采用B6,B7进行驱动,只用一个的情况下
如果需要第二个的话,采用A12 A11进行驱动
如果实际中采取光电开关以下为光电开关预留引脚:
C5 B2 C15 C4
截止到目前,程序已经将PWM输出,PWM输入捕获,OLED屏幕,定时器中断,颜色识别模块驱动,配置完毕。
修改后的引脚配置情况
PA0 PA1 PA2 PA3对应的是两个驱动板上的PWM端口。
PB12 PB13 控制驱动板一号电机的正反转
PC0 PC1 控制驱动板二号电机的正反转
PC2 PC3 控制驱动板三号电机的正反转
PB14 PB15 控制驱动板四号电机的正反转
今天实验完毕,舵机驱动板可以正常使用,所以一开始给舵机的预留端口可以取消了。
PB12 PB13 PB14 PB15可以供其他功能使用了,舵机通过IIC已经驱动完成。
驱动板接线:
一号驱动板:PC0–>IN1
PC1–>IN2
PC2–>IN3
PC3–>IN4
PA0–>ENA
PA1–>ENB
二号驱动板:PB12–>IN1
PB13–>IN2
PB14–>IN3
PB15–>IN4
PA2–>ENA
PA3–>ENB
颜色识别模块运行正常,正在调试激光测距模块。
激光测距模块已经搞定。
颜色识别模块需要白平衡,可以靠白纸启动。
跑道是单面墙(全是弧形),使用距离模块进行单面墙寻迹,初步思想是将车控制与墙相距5cm左右,外轮稍微快点,车如果大约5cm时,车的运动方向有向里的趋势,如果距离大于5cm向里调整姿态,小于5cm前面有万向轮,如果撞到了速度稍微快点就行了,可以出去。
单个测距不能实现姿态调整,
现在方案:双测距
双触点
双触点加中间测距
以下程序代码为初步试验可应用,效果比较良好。
Get_Distance();
dis = count[2]-50;
if(JIE_JIN_KAIGUANWU)
{
if((dis<100)&&(dis>50))
{
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
}
}
if(JIE_JIN_KAIGUAN == GPIO_PIN_SET)
{
ZhiDong();
delay_ms(10);
You_Xing(30,30,30,30,1000);
while(JIE_JIN_KAIGUANYOU);
}
if(dis>=100&&(JIE_JIN_KAIGUANWU))
{
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
// while(JIE_JIN_KAIGUANWU);
while(dis>50&&JIE_JIN_KAIGUAN==WU);
// if(dis>=150&&(JIE_JIN_KAIGUANWU))
// {
// ZhiDong();
// delay_ms(10);
// You_Xing(30,30,30,30,10);
// }
}
有注释:
if(JIE_JIN_KAIGUANWU)//接近开关优先级最高
{
if((dis<100)&&(dis>50))
{
/以下代码实现了车向左倾斜着向前行进/
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
}
}
if(JIE_JIN_KAIGUAN == GPIO_PIN_SET)
{
ZhiDong();
delay_ms(10);
/当撞墙后的,车原地右转1S时间/
You_Xing(30,30,30,30,1000);
while(JIE_JIN_KAIGUANYOU);
}
if(dis>=100&&(JIE_JIN_KAIGUANWU))
{
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
// while(JIE_JIN_KAIGUAN==WU);
while(dis>50&&JIE_JIN_KAIGUAN==WU);
}
/以下代码用来车一旦偏离,来找车左侧的墙/
if(dis>200&&(JIE_JIN_KAIGUANWU))
{
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
Zhi_Xing(30,30,30,30,0);
while(JIE_JIN_KAIGUANYOU);
}
PC4口用来光电开关的输入捕获。
有光电开关的程序如下:
if(GuanDian == GPIO_PIN_RESET)
{
ZhiDong();
}
if(GuanDian == GPIO_PIN_SET)
{
if(JIE_JIN_KAIGUANWU)//接近开关优先级最高
{
if((dis<100)&&(dis>50))
{
/以下代码实现了车向左倾斜着向前行进/
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
}
}
if(JIE_JIN_KAIGUAN == GPIO_PIN_SET)
{
ZhiDong();
delay_ms(10);
/当撞墙后的,车原地右转1S时间/
You_Xing(30,30,30,30,1000);
while(JIE_JIN_KAIGUANYOU);
}
if(dis>=100&&(JIE_JIN_KAIGUANWU))
{
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
// while(JIE_JIN_KAIGUANWU);
while(dis>50&&JIE_JIN_KAIGUAN==WU);
}
/*以下代码用来车一旦偏离,来找车左侧的墙*/
if(dis>200&&(JIE_JIN_KAIGUAN==WU))
{
ZhiDong();
delay_ms(10);
Zhi_Xing(10,40,10,40,1000);
Zhi_Xing(30,30,30,30,0);
while(JIE_JIN_KAIGUAN==YOU);
}
}
对代码部分进行了简化,初步思路认定是当车的光电检测到盒子(树洞)的时候停车,再根据颜色识别模块判定地面的颜色是什么颜色,然后通过机械臂把树放在树洞里面。颜色识别模块启动后一直对地面进行扫描,用来获取地面的颜色,在检测到地面颜色是绿色或者蓝色的时候且光电开关部分没有检测到盒子的时候进行停车,执行抓取动作。
目前使用的是200r/min的电机,在代码中使用宏定义。
舵机控制的度数基本上已经搞定。
一共采取四个光电开关,第一个光电开关和距离传感器进行寻迹,剩下三个光电开关用来停车和抓取或者卸货
目前比较好用的寻迹程序程序:
void XunJi(void)
{
/行进测试程序/
//程序逻辑:接近开关优先级最高,车的靠边走始终在接近开关有信号的范围里进行寻迹
// Zhi_Xing(YouLun_Sudu,YouLun_Sudu,YouLun_Sudu,YouLun_Sudu,0);
if(JIE_JIN_KAIGUAN== WU)//接近开关优先级最高
{
/当距离传感器靠的太近时,车向右倾斜/
if(dis<40)
{
/以下代码实现了车向右倾斜着向前行进/
Zhi_Xing(ZuoLun_Sudu,YouLun_Sudu,ZuoLun_Sudu,YouLun_Sudu,0);
}
if(dis>=40)
{
Zuo_Xing(ZuoGuai_Sudu,ZuoGuai_Sudu,ZuoGuai_Sudu,ZuoGuai_Sudu,MS_10);
Zhi_Xing(ZuoLun_Sudu,YouLun_Sudu+30,ZuoLun_Sudu,YouLun_Sudu+30,0);
}
}
if(JIE_JIN_KAIGUAN == YOU)
{
/*向右拐*/
You_Xing(ZuoGuai_Sudu,ZuoGuai_Sudu,ZuoGuai_Sudu,ZuoGuai_Sudu,MS_10);
/*向左倾斜前进*/
You_Qing_Xie(0,0);
}
}
/以下是进行抓物的程序
delay_ms(3000);
PCA_MG9XX(1,Du_135,Du_105,2,1);
delay_ms(1000);
PCA_MG9XX(4,Du_135,Du_225,2,1);
delay_ms(1000);
PCA_MG9XX(3,Du_180,Du_45,2,1);
delay_ms(1000);
PCA_MG9XX(2,Du_135,Du_90,2,1);
delay_ms(1000);
PCA_MG9XX(5,Du_180,Du_135,2,1);
delay_ms(1000);
PCA_MG9XX(1,Du_105,Du_5,2,1);
delay_ms(2000);
PCA_MG9XX(3,Du_45,Du_135,2,1);
delay_ms(1000);
PCA_MG9XX(2,Du_90,Du_5,2,1);
delay_ms(1000);
//放物的程序
delay_ms(3000);
PCA_MG9XX(4,Du_225,Du_135,2,1);
delay_ms(1000);
PCA_MG9XX(5,Du_135,Du_180,2,1);
delay_ms(1000);
//复位
PCA_MG9XX(2,Du_5,Du_135,2,1);
delay_ms(1000);
PCA_MG9XX(1,Du_5,Du_135,2,1);
delay_ms(1000);
PCA_MG9XX(3,Du_135,Du_180,2,1);
delay_ms(1000);
PCA_MG9XX(5,Du_180,Du_180,2,1);
delay_ms(1000);
初赛过程中可以看出来光电开关的寻迹效果不是十分明显,因此决定使用超声波模块进行寻迹,车接近墙达到一定距离之后,向外偏一点,然后继续前进,向外偏的距离达到一定程度后,继续向里走。这里面的向前走,是斜着向前走。左倾斜或者右倾斜。
可以使用的机器人大赛完结程序:
#if 1
Get_Distance();
dis = count[2];//读取距离
ju = Get_JuLi2_Us100();
if(GuanDian_Panduan_Keng == YOU&&flag_dou == 0)
{
ZhiDong();
delay_ms(MS_50);
G = 238;
B = 225;
G1 = 236;
B1 = 220;
flag_dongxi = flag_dongxi + 1;
if(flag_dongxi==1)
{
OLED_Clear();
sprintf(str,":%d",B);
OLED_ShowString(0,2,"B1:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Zhua:Blue1!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
//蓝
Zhua();
delay_ms(1000);
PCA_MG9XX(1,Du_110,Du_120,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(2,Du_120,Du_110,2,2);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(5,Du_150,Du_50,1,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(1,Du_120,Du_45,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(2,Du_110,Du_145,2,2);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(4,Du_115,Du_50,2,1);
delay_ms(Duoji_Xian_Jie_T);
/*弯腰*/
PCA_MG9XX(1,Du_45,Du_1,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(2,Du_145,Du_75,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(5,Du_50,Du_150,1,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(2,Du_75,Du_145,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(4,Du_50,Du_115,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(1,Du_1,Du_45,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(1,Du_45,Du_110,2,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(2,Du_145,Du_120,2,2);
delay_ms(1000);
}
if(flag_dongxi==2)
{
OLED_Clear();
sprintf(str,":%d",B1);
OLED_ShowString(0,2,"B2:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Zhua:Blue2!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
PCA_MG9XX(0,1,50,1,1);
delay_ms(500);
//蓝
Zhua();
Fang();
}
if(flag_dongxi==3)
{
OLED_Clear();
sprintf(str,":%d",G);
OLED_ShowString(0,2,"G1:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Zhua:Green1!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
PCA_MG9XX(0,50,108,1,1);
delay_ms(500);
//绿
Zhua();
Fang();
}
if(flag_dongxi==4)
{
OLED_Clear();
sprintf(str,":%d",G1);
OLED_ShowString(0,2,"G2:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Zhua:Green2!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
PCA_MG9XX(0,108,155,1,1);
delay_ms(500);
//绿
Zhua();
Fang();
PCA_MG9XX(3,Du_60,Du_120,1,1);
delay_ms(Duoji_Xian_Jie_T);
PCA_MG9XX(0,155,1,1,1);
flag_dou = 1;
}
}
if(flag_dou==1&&GuanDian_Panduan_Keng == YOU)
{
ZhiDong();
delay_ms(MS_50);
G = 229;
B = 230;
G1 = 234;
B1 = 227;
flag_dongxi = flag_dongxi-1;
if(flag_dongxi == 3)
{
OLED_Clear();
sprintf(str,":%d",B);
OLED_ShowString(0,2,"B1:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Fang:Blue1!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
delay_ms(200);
/*拿出来放下*/
Xianjie1();
WangTongLiFang();
Xianjie2();
Zhi_Xing(200,200,200,200,200);
}
if(flag_dongxi == 2)
{
OLED_Clear();
sprintf(str,":%d",G);
OLED_ShowString(0,2,"G1:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Fang:Green1!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
PCA_MG9XX(0,1,108,1,1);
delay_ms(200);
/*拿出来放下*/
Xianjie1();
WangTongLiFang();
Xianjie2();
Zhi_Xing(200,200,200,200,200);
}
if(flag_dongxi == 1)
{
OLED_Clear();
sprintf(str,":%d",B1);
OLED_ShowString(0,2,"B2:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Fang:Blue2!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
PCA_MG9XX(0,108,55,1,1);
delay_ms(200);
/*拿出来放下*/
Xianjie1();
WangTongLiFang();
Xianjie2();
Zhi_Xing(200,200,200,200,200);
}
if(flag_dongxi == 0)
{
OLED_Clear();
sprintf(str,":%d",G1);
OLED_ShowString(0,2,"G2:"); OLED_ShowString(36,2,str);
OLED_ShowString(0,4,"Fang:Green2!");
sprintf(str,":%d",dis);
OLED_ShowString(0,6,"dis:"); OLED_ShowString(36,6,str);
PCA_MG9XX(0,55,155,1,1);
delay_ms(200);
/*拿出来放下*/
Xianjie1();
WangTongLiFang();
Xianjie2();
Zhi_Xing(200,200,200,200,200);
flag_dou = 0;
}
}
if(GuanDian_Panduan_Keng == WU)
{
OLED_Clear();
OLED_ShowString(0,6,"Go!!!");
if(GuanDian_Biao_Zhi== YOU)
{
You_Xing(YouGuai_Sudu,YouGuai_Sudu,YouGuai_Sudu,YouGuai_Sudu,10);
}
if(GuanDian_Biao_Zhi== WU)
{
if(ju<70)
{
You_Xing(200,200,200,200,5);
}
if(ju>=70&&ju<=100)
{
Zhi_Xing(200,200,200,200,5);
}
if(ju>100)
{
Zuo_Xing(200,200,200,200,0);
}
}
}
#endif