概述
基于STM32的遥控避障循迹小车,超声波模块实现避障功能,总体来说还是比较简单的,对初学者很友好。
调整舵机方向:通过STM32的GPIO引脚向舵机发送控制信号,逐步调整其转动角度,以改变小车头部的朝向。可以使用简单的算法(如逐步扫描或根据超声波传感器数据直接调整)来确定舵机的最佳转向角度。
检测新方向上的障碍物:在舵机调整方向后,再次使用超声波传感器测量新方向上的障碍物距离。
选择行驶路径:根据新方向上的障碍物距离,决定小车是继续在该方向上行驶、返回原方向、还是尝试其他方向。
控制驱动电机:根据避障决策,控制小车的驱动电机以实现前进、后退或原地转向等操作。
电机驱动模块
将GPIOA口的二号和三号引脚设置为复用推挽输出,使其不仅具有高驱动能力还能使用引脚复用的功能,作为PWM输出口。然后设置4、5、6、7分别为电机的方向控制引脚。
开启定时器二的时钟(不开启的话也是默认开启的),配置实基单元为不分频、向上计数、计数周期为100、预分频为36分频(计数周期100是为了计算占空比的时候好计算,36分频是为了配合计数周期让输出频率达到20000Hz,从而解决电机受阻时发出噪声)、重复计数器设置为0(只有高级定时器才有)
输出比较配置:设置默认配置、比较模式为PWM1、极性选择无、使能、CCR值为0。
使能定时器二。
通过控制方向控制引脚高低电平变化来实现控制正转还是反转。
当方向控制引脚被设置为高电平时,驱动电路内部的逻辑电路会相应地调整电流的流向,使得电机内部磁场的方向发生变化,从而驱动电机开始正转。这一过程中,电能的转换与传输效率至关重要,它决定了电机能否迅速、平稳地响应控制指令。
相反地,当方向控制引脚被设置为低电平时,驱动电路会接收到另一个电平信号,并据此调整电流路径,改变电机内部磁场的方向,使电机开始反转。这一切换过程迅速且精确,是实现电机双向控制的关键。
直线行驶:当需要小车直线行驶时,同时给两侧电机发送相同的控制信号,使它们以相同的速度和方向旋转。这样,小车两侧的车轮就会以相同的速度和方向前进,从而保持直线行驶。
转向行驶:
左转:为了实现左转,可以增加左侧电机的速度或减小右侧电机的速度(或使右侧电机反转,但通常不推荐这种方式,因为它可能导致小车打滑或不稳定)。这样,左侧车轮会比右侧车轮转得更快,从而使小车向左偏转。
右转:与左转相反,为了右转,可以增加右侧电机的速度或减小左侧电机的速度(或使左侧电机反转)。这样,右侧车轮会比左侧车轮转得更快,从而使小车向右偏转。
超声波测距
float Test_Distance(void){
GPIO_SetBits(GPIOB,GPIO_Pin_12);
Delay_us(20);
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==RESET){
};
TIM_Cmd(TIM1, ENABLE);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==SET){
};
TIM_Cmd(TIM1, DISABLE);
Cnt=TIM_GetCounter(TIM1);
distance=(Cnt*1.0/10*0.34)/2;
TIM1->CNT=0;
Delay_ms(100);
return distance;
}
将STM32的某个GPIO引脚配置为推挽输出模式,用于向HC-SR04发送触发信号(Trig)。
将另一个GPIO引脚配置为浮空输入模式,用于接收HC-SR04的回波信号(Echo)。
2. 发送超声波
通过向Trig引脚发送一个至少10微秒的高电平信号来触发HC-SR04发送超声波。
发送完触发信号后,将Trig引脚拉低,等待Echo引脚接收回波信号。
3. 接收回波并计算距离
初始化一个定时器或计数器,用于测量Echo引脚从低电平变为高电平(超声波发出)到再次变为低电平(超声波返回并被接收)的时间差(T)。
定时器或计数器应配置为足够高的频率,以便精确测量微秒级的时间差。
使用公式 距离 = (T * 声速) / 2 来计算障碍物距离,其中声速约为340m/s(或转换为cm单位:距离(cm) = (T * 100 * 声速(cm/s)) / 2)。
超声波避障
void obstacle_avoidance(void){
uint16_t Dis1 = 0;
uint16_t Dis2 = 0;
uint16_t Dis3 = 0;
uint16_t Dis4 = 0;
uint16_t Dis5 = 0;
Speed1 = Motor_Speed();
Car_ForWard(Speed1);
Dis1 = Test_Distance();
Serial_SnedNumber(Dis1,3);
OLED_ShowNum(4,11,Dis1/100%10,1);
OLED_ShowNum(4,12,Dis1/10%10,1);
OLED_ShowNum(4,13,Dis1%10,1);
if(Dis1 < 15){
Car_Stop();
Servo_SetPwm(20);
Servo_SetPwm4(30);
Delay_ms (1000);
Dis2 = Test_Distance();
Serial_SnedNumber(Dis2,3);
if(Dis2 < 15){
Car_Stop();
Servo_SetPwm(160);
Servo_SetPwm4(30);
Delay_ms (1000);
Dis3 = Test_Distance();
Serial_SnedNumber(Dis3,3);
if(Dis3 < 15){
Car_Stop();
Servo_SetPwm(90);
Servo_SetPwm4(0);
Car_Retret(Speed1);
Servo_SetPwm(160);
Servo_SetPwm4(90);
Delay_ms (1000);
Dis4 = Test_Distance();
Serial_SnedNumber(Dis4,3);
if(Dis4 > 15){
Servo_SetPwm(90);
Servo_SetPwm4(0);
Car_Left(Speed1);
Delay_ms (1000);
}else{
Servo_SetPwm(20);
Servo_SetPwm4(30);
Delay_ms (1000);
Dis5 = Test_Distance();
Serial_SnedNumber(Dis5,3);
if(Dis5 > 15){
Servo_SetPwm(90);
Servo_SetPwm4(0);
Car_Right(Speed1);
Delay_ms (1000);
}else{
Servo_SetPwm(90);
Servo_SetPwm4(0);
Car_Right(Speed1);
Delay_ms (4000);
}
}
}else{
Servo_SetPwm(90);
Servo_SetPwm4(0);
Delay_ms (1000);
Car_Left(Speed1);
Delay_ms (1000);
Car_ForWard(Speed1);
}
}else{
Servo_SetPwm(90);
Servo_SetPwm4(0);
Delay_ms (1000);
Car_Right(Speed1);
Delay_ms (1000);
Car_ForWard(Speed1);
}
}else{
Car_ForWard(Speed1);
}
}
调整舵机方向:通过STM32的GPIO引脚向舵机发送控制信号,逐步调整其转动角度,以改变小车头部的朝向。可以使用简单的算法(如逐步扫描或根据超声波传感器数据直接调整)来确定舵机的最佳转向角度。
检测新方向上的障碍物:在舵机调整方向后,再次使用超声波传感器测量新方向上的障碍物距离。
选择行驶路径:根据新方向上的障碍物距离,决定小车是继续在该方向上行驶、返回原方向、还是尝试其他方向。
控制驱动电机:根据避障决策,控制小车的驱动电机以实现前进、后退或原地转向等操作。