基于STM32的避障小車
1 概述
基于STM32的遙控避障循跡小車,超聲波模塊實(shí)現(xiàn)避障功能,總體來(lái)說(shuō)還是比較簡(jiǎn)單的,對(duì)初學(xué)者很友好。
調(diào)整舵機(jī)方向:通過(guò)STM32的GPIO引腳向舵機(jī)發(fā)送控制信號(hào),逐步調(diào)整其轉(zhuǎn)動(dòng)角度,以改變小車頭部的朝向??梢允褂煤?jiǎn)單的算法(如逐步掃描或根據(jù)超聲波傳感器數(shù)據(jù)直接調(diào)整)來(lái)確定舵機(jī)的最佳轉(zhuǎn)向角度。
檢測(cè)新方向上的障礙物:在舵機(jī)調(diào)整方向后,再次使用超聲波傳感器測(cè)量新方向上的障礙物距離。
選擇行駛路徑:根據(jù)新方向上的障礙物距離,決定小車是繼續(xù)在該方向上行駛、返回原方向、還是嘗試其他方向。
控制驅(qū)動(dòng)電機(jī):根據(jù)避障決策,控制小車的驅(qū)動(dòng)電機(jī)以實(shí)現(xiàn)前進(jìn)、后退或原地轉(zhuǎn)向等操作。
電機(jī)驅(qū)動(dòng)模塊
將GPIOA口的二號(hào)和三號(hào)引腳設(shè)置為復(fù)用推挽輸出,使其不僅具有高驅(qū)動(dòng)能力還能使用引腳復(fù)用的功能,作為PWM輸出口。然后設(shè)置4、5、6、7分別為電機(jī)的方向控制引腳。
開啟定時(shí)器二的時(shí)鐘(不開啟的話也是默認(rèn)開啟的),配置實(shí)基單元為不分頻、向上計(jì)數(shù)、計(jì)數(shù)周期為100、預(yù)分頻為36分頻(計(jì)數(shù)周期100 是為了計(jì)算占空比的時(shí)候好計(jì)算,36分頻是為了配合計(jì)數(shù)周期讓輸出頻率達(dá)到20000Hz,從而解決電機(jī)受阻時(shí)發(fā)出噪聲)、重復(fù)計(jì)數(shù)器設(shè)置為0(只有高級(jí)定時(shí)器才有)
輸出比較配置:設(shè)置默認(rèn)配置、比較模式為PWM1、極性選擇無(wú)、使能、CCR 值為0。
使能定時(shí)器二。
通過(guò)控制方向控制引腳高低電平變化來(lái)實(shí)現(xiàn)控制正轉(zhuǎn)還是反轉(zhuǎn)。
當(dāng)方向控制引腳被設(shè)置為高電平時(shí),驅(qū)動(dòng)電路內(nèi)部的邏輯電路會(huì)相應(yīng)地調(diào)整電流的流向,使得電機(jī)內(nèi)部磁場(chǎng)的方向發(fā)生變化,從而驅(qū)動(dòng)電機(jī)開始正轉(zhuǎn)。這一過(guò)程中,電能的轉(zhuǎn)換與傳輸效率至關(guān)重要,它決定了電機(jī)能否迅速、平穩(wěn)地響應(yīng)控制指令。
相反地,當(dāng)方向控制引腳被設(shè)置為低電平時(shí),驅(qū)動(dòng)電路會(huì)接收到另一個(gè)電平信號(hào),并據(jù)此調(diào)整電流路徑,改變電機(jī)內(nèi)部磁場(chǎng)的方向,使電機(jī)開始反轉(zhuǎn)。這一切換過(guò)程迅速且精確,是實(shí)現(xiàn)電機(jī)雙向控制的關(guān)鍵。
直線行駛:當(dāng)需要小車直線行駛時(shí),同時(shí)給兩側(cè)電機(jī)發(fā)送相同的控制信號(hào),使它們以相同的速度和方向旋轉(zhuǎn)。這樣,小車兩側(cè)的車輪就會(huì)以相同的速度和方向前進(jìn),從而保持直線行駛。
轉(zhuǎn)向行駛:
左轉(zhuǎn):為了實(shí)現(xiàn)左轉(zhuǎn),可以增加左側(cè)電機(jī)的速度或減小右側(cè)電機(jī)的速度(或使右側(cè)電機(jī)反轉(zhuǎn),但通常不推薦這種方式,因?yàn)樗赡軐?dǎo)致小車打滑或不穩(wěn)定)。這樣,左側(cè)車輪會(huì)比右側(cè)車輪轉(zhuǎn)得更快,從而使小車向左偏轉(zhuǎn)。
右轉(zhuǎn):與左轉(zhuǎn)相反,為了右轉(zhuǎn),可以增加右側(cè)電機(jī)的速度或減小左側(cè)電機(jī)的速度(或使左側(cè)電機(jī)反轉(zhuǎn))。
這樣,右側(cè)車輪會(huì)比左側(cè)車輪轉(zhuǎn)得更快,從而使小車向右偏轉(zhuǎn)。
超聲波測(cè)距:
fl oat 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 的某個(gè)GPIO 引腳配置為推挽輸出模式,用于向HC-SR04發(fā)送觸發(fā)信號(hào)(Trig)。
將另一個(gè)GPIO 引腳配置為浮空輸入模式,用于接收HC-SR04的回波信號(hào)(Echo)。
2.發(fā)送超聲波
通過(guò)向Trig 引腳發(fā)送一個(gè)至少10 微秒的高電平信號(hào)來(lái)觸發(fā)HC-SR04發(fā)送超聲波。
發(fā)送完觸發(fā)信號(hào)后,將Trig引腳拉低,等待Echo引腳接收回波信號(hào)。
3.接收回波并計(jì)算距離
初始化一個(gè)定時(shí)器或計(jì)數(shù)器,用于測(cè)量Echo引腳從低電平變?yōu)楦唠娖剑ǔ暡òl(fā)出)到再次變?yōu)榈碗娖剑ǔ暡ǚ祷夭⒈唤邮眨┑臅r(shí)間差(T)。
定時(shí)器或計(jì)數(shù)器應(yīng)配置為足夠高的頻率,以便精確測(cè)量微秒級(jí)的時(shí)間差。
使用公式距離=(T*聲速)/2來(lái)計(jì)算障礙物距離,其中聲速約為340m/s(或轉(zhuǎn)換為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);
}
}
調(diào)整舵機(jī)方向:通過(guò)STM32的GPIO引腳向舵機(jī)發(fā)送控制信號(hào),逐步調(diào)整其轉(zhuǎn)動(dòng)角度,以改變小車頭部的朝向??梢允褂煤?jiǎn)單的算法(如逐步掃描或根據(jù)超聲波傳感器數(shù)據(jù)直接調(diào)整)來(lái)確定舵機(jī)的最佳轉(zhuǎn)向角度。
檢測(cè)新方向上的障礙物:在舵機(jī)調(diào)整方向后,再次使用超聲波傳感器測(cè)量新方向上的障礙物距離。
選擇行駛路徑:根據(jù)新方向上的障礙物距離,決定小車是繼續(xù)在該方向上行駛、返回原方向、還是嘗試其他方向。
控制驅(qū)動(dòng)電機(jī):根據(jù)避障決策,控制小車的驅(qū)動(dòng)電機(jī)以實(shí)現(xiàn)前進(jìn)、后退或原地轉(zhuǎn)向等操作。
(本文來(lái)源于《EEPW》20504)
評(píng)論