1、小车架构
(1)车架:
车架是淘宝上买的双层亚克力的两轮小车,配备了两个直流电机,两个驱动轮,两个辅助万向轮,一个两节的电池盒,这些东西淘宝上很多都是打包售卖的。
底部照片
正面照片
(2)电源模块
电源模块采用的是两节高电压的5号可充电电池(没节电池3.2V),由于手上没有DC线,干脆直接将电池盒连上了两根飞线插在面包板上,然后又将DC接口下面的正负极引脚焊接了两根公对公的杜邦线然后插在面包板上,这样就可以直接利用电池给这块HW-131面包板供电模块供电了。这块供电模块内置稳压芯片可以输出多路的3.3V和5V的电压,这样就正好可以解决电机和循迹班5V供电的问题啦。
(3)驱动板
驱动板
非常尴尬,不会利用画图软件画原理图,所以用的洞洞板焊接,用的是一块STM32F103C8T6、TB6612电机驱动模块,另外还预留了一块NRF24L01-2.4G无线通信模块想要后面做个遥控器,加上遥控功能。刚练习焊接,所以洞洞板的后面其实焊得跟块大便一样,就不做介绍了,核心思想就是用飞线各种飞。。。。。。好在利用万用表一直测,没有出现短路烧板子之类的坏现象,并且最后功能也都可以完成。
2、采用TCRT5000五路循迹模块实现循迹功能
循迹模块
循迹模块用的是TCRT5000五路循迹模块,便宜好用,非常nice,至少自己用来玩玩是可以的,如果比赛要用的话应该需要哪种灰度循迹模块(太贵了舍不得买),循迹函数的话中规中矩。
void Track_Correct(uint8_t RoadwayData)
{
if(RoadwayData == 0x00)
{
Track_Flag=0;
Stop_Flag=1;
}else if(RoadwayData==0x1B)//11011
{
LSpeed=Car_Speed;
RSpeed=Car_Speed;
}else if(RoadwayData==0x1D)//11101
{
LSpeed=Car_Speed+20;
RSpeed=Car_Speed-20;
}else if(RoadwayData==0x19)//11001 有向右的大弯道
{
LSpeed=Car_Speed+20;
RSpeed=Car_Speed-40;
}else if(RoadwayData==0x18)//11000 有向右的直角弯道
{
LSpeed=Car_Speed;
RSpeed=-Car_Speed;
}else if(RoadwayData==0x1E)//11110
{
LSpeed=Car_Speed+40;
RSpeed=Car_Speed-40;
}else if(RoadwayData==0x17)//10111
{
LSpeed=Car_Speed-20;
RSpeed=Car_Speed+20;
}else if(RoadwayData==0x13)//10011 有向左的大弯道
{
LSpeed=Car_Speed-40;
RSpeed=Car_Speed+20;
}else if(RoadwayData==0x03)//00011 有向左的直角弯道
{
LSpeed=-Car_Speed;
RSpeed=Car_Speed;
}else if(RoadwayData==0x0F)//01111
{
LSpeed=Car_Speed-40;
RSpeed=Car_Speed+40;
}else
{
LSpeed=Car_Speed;
RSpeed=Car_Speed;
}
if(Track_Flag != 0)
{
Track_Go(LSpeed,RSpeed);
}
}
3、超声波
超声波用的是一个HC-SR04超声波模块,实现了正向避障的功能,该模块有一个Trig引脚和Echo引脚,当给Trig触发引脚一个大于10us的高电平脉冲,则Echo会开始工作,模块会给出一个与距离等比的高电平脉冲信号,在Echo工作前清零计数器的计数值,并在电平重新变为低电平后获取计数值,就可以根据计数值的大小来计算距离。
void Wave_TimerInit(void){ //超声波定时器初始化函数
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
TIM_InternalClockConfig(TIM1);
TIM_TimeBaseInitTypeDef Timer_InitStructure;
Timer_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
Timer_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
Timer_InitStructure.TIM_Period=10000-1;
Timer_InitStructure.TIM_Prescaler=7200-1;//7200Hz=0.0001s=0.1ms=10us
Timer_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1,&Timer_InitStructure);
//TIM_Cmd(TIM3,ENABLE);
}
void Wave_Init(void){ //超声波中断初始化函数
Wave_TimerInit();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource11);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line11;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
}
void Wave_Start(void){ //超声波开始函数
if(Wave_Flag==1){
GPIO_SetBits(GPIOA,GPIO_Pin_5);
Delay_us(50);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
}
}
void Wave_Check(void){ //超声波避障实现函数
if(Distance<=1300){
Car_Stop();Delay_ms(500);
Car_Back(60);Delay_ms(1000);
Car_Stop();Delay_ms(500);
Car_Left(40);
}else if(Distance >=2000){
Car_Go(Car_Speed);
}
}
void EXTI15_10_IRQHandler(void){ //外部中断处理函数
Delay_us(10);
if(EXTI_GetITStatus(EXTI_Line11)!=RESET){
TIM_SetCounter(TIM1,0);
TIM_Cmd(TIM1,ENABLE);
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11));
TIM_Cmd(TIM1,DISABLE);
Distance=TIM_GetCounter(TIM1)*340/2.0;
OLED_ShowNum(2,6,Distance,5);
Wave_Check();
EXTI_ClearITPendingBit(EXTI_Line11);
}
}