这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【原创】基于STM32的避障小车--from浩

共1条 1/1 1 跳转至

【原创】基于STM32的避障小车--from浩

工程师
2024-07-17 21:13:50     打赏

概述

基于STM32的遥控避障循迹小车,超声波模块实现避障功能,总体来说还是比较简单的,对初学者很友好。

调整舵机方向:通过STM32GPIO引脚向舵机发送控制信号,逐步调整其转动角度,以改变小车头部的朝向。可以使用简单的算法(如逐步扫描或根据超声波传感器数据直接调整)来确定舵机的最佳转向角度。

检测新方向上的障碍物:在舵机调整方向后,再次使用超声波传感器测量新方向上的障碍物距离。

选择行驶路径:根据新方向上的障碍物距离,决定小车是继续在该方向上行驶、返回原方向、还是尝试其他方向。

控制驱动电机:根据避障决策,控制小车的驱动电机以实现前进、后退或原地转向等操作。

电机驱动模块

1721221349397569.png

图片2.png

GPIOA口的二号和三号引脚设置为复用推挽输出,使其不仅具有高驱动能力还能使用引脚复用的功能,作为PWM输出口。然后设置4567分别为电机的方向控制引脚。

图片3.png

开启定时器二的时钟(不开启的话也是默认开启的),配置实基单元为不分频、向上计数、计数周期为100、预分频为36分频(计数周期100是为了计算占空比的时候好计算,36分频是为了配合计数周期让输出频率达到20000Hz,从而解决电机受阻时发出噪声)、重复计数器设置为0(只有高级定时器才有)

输出比较配置:设置默认配置、比较模式为PWM1、极性选择无、使能、CCR值为0

使能定时器二。

1721221637772662.png

1721221717581152.png

通过控制方向控制引脚高低电平变化来实现控制正转还是反转。

当方向控制引脚被设置为高电平时,驱动电路内部的逻辑电路会相应地调整电流的流向,使得电机内部磁场的方向发生变化,从而驱动电机开始正转。这一过程中,电能的转换与传输效率至关重要,它决定了电机能否迅速、平稳地响应控制指令。

相反地,当方向控制引脚被设置为低电平时,驱动电路会接收到另一个电平信号,并据此调整电流路径,改变电机内部磁场的方向,使电机开始反转。这一切换过程迅速且精确,是实现电机双向控制的关键。

1721221770255898.png

直线行驶:当需要小车直线行驶时,同时给两侧电机发送相同的控制信号,使它们以相同的速度和方向旋转。这样,小车两侧的车轮就会以相同的速度和方向前进,从而保持直线行驶。

转向行驶:

左转:为了实现左转,可以增加左侧电机的速度或减小右侧电机的速度(或使右侧电机反转,但通常不推荐这种方式,因为它可能导致小车打滑或不稳定)。这样,左侧车轮会比右侧车轮转得更快,从而使小车向左偏转。

右转:与左转相反,为了右转,可以增加右侧电机的速度或减小左侧电机的速度(或使左侧电机反转)。这样,右侧车轮会比左侧车轮转得更快,从而使小车向右偏转。

超声波测距

1721221862976351.png

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)。

超声波避障

1721221930543838.png

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);

}



}

调整舵机方向:通过STM32GPIO引脚向舵机发送控制信号,逐步调整其转动角度,以改变小车头部的朝向。可以使用简单的算法(如逐步扫描或根据超声波传感器数据直接调整)来确定舵机的最佳转向角度。

检测新方向上的障碍物:在舵机调整方向后,再次使用超声波传感器测量新方向上的障碍物距离。

选择行驶路径:根据新方向上的障碍物距离,决定小车是继续在该方向上行驶、返回原方向、还是尝试其他方向。

控制驱动电机:根据避障决策,控制小车的驱动电机以实现前进、后退或原地转向等操作。




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]