基于STM32cubemx的电磁智能车-基于stm32的两轮自平衡小车参考文献英文翻译

作者dyy_hh参加了校内智能车比赛,这是为这段时间做的总结。在此感谢dyy_hh的总结分享。

一.硬件部分

必需:STM32F103C6T6(或者STM32F103C8T6),舵机(MG 996R),电机(TT马达 130电机),L298n驱动,电磁杆(可以自己制作),干簧管,两节18650电池,基础四轮车模。

辅助:OLED,HC-05蓝牙模块。

二.软件部分

必需:ADC多路采集的DMA配置,定时器PWM波输出,普通GPIO口,滤波,归一化,差比和,PID算法。

辅助:OLED驱动,串口打印。

1.舵机

三根线:VCC,GND,信号线。 我们给VCC接的6V。信号线接相应PWM波输出口。

舵机调中值:可以使用编码器调节占空比,看舵机一共能够转动多少占空比的范围(注意!舵机不是可以360度旋转的)。然后取最中间的占空比输出给舵机。小菜花当时是设置的20ms为周期,Counter Period 设置的20000-1。

2.电机

开环控制两个电机:两个PWM波输出,四个普通GPIO口控制高低电平。

3.L298n驱动

可以自己去了解如何接线,这里推荐一篇小菜花看到的文章http://t.csdn.cn/Anzwy

4.干簧管

用于在终点处停车。话不多说,上链接https://share.weiyun.com/2m5eUtRv

5.电磁杆的电感值采集

我们组开始准备使用两个水平电感,两个竖直电感;但是最后由于种种原因,我们使用了两个水平电感,两个内八字电感。(最后我们环岛没有进,所以就只使用了两个水平电感完成了最基础的寻迹)。

ADC给四个电感 开了四路DMA采集 ,分别是A1,A2,A3,A4。

如果有条件可以在电磁杆中间使用第五路电感,就是小菜花开的A5(虽然我最后没有用到)。

还有两路ADC 是采集 两个干簧管的IO口 高低电平。

基于STM32cubemx的电磁智能车-基于stm32的两轮自平衡小车参考文献英文翻译基于STM32cubemx的电磁智能车-基于stm32的两轮自平衡小车参考文献英文翻译 6.一些算法

软件滤波

滤波(Wave filtering)是将信号中特定波段频率滤除的操作,很大程度上保证了采集到的数据的稳定与真实,是抑制和防止干扰的一项重要措施。

这是参考的别的博主的一种滤波算法: 中位算数平均滤波 。 即结合了中位值滤波和算数平均值滤波的一种算法。

这一篇文章非常详细的讲了滤波http://t.csdn.cn/a8DbF

void Get_ADC(void) //得到的ADC电压存储在ADC_Val中

{

int num = 0,count = 0;

for(num = 0; num < 10; num++)

{

HAL_ADC_Start_DMA (&hadc1 ,(uint32_t *)adci,7);//开启七路DMA

HAL_ADC_Start_DMA (&hadc1 ,(uint32_t *)adcj,7);

HAL_ADC_Start_DMA (&hadc1 ,(uint32_t *)adck,7);

for(count = 0; count < 7;count++)//取中值

{

if (adci[count] > adcj[count])

{

adctmp[count] = adci[count]; adci[count] = adcj[count]; adcj[count] = adctmp[count];

}

if (adck[count] > adcj[count])

adctmp[count] = adcj[count];

else if(adck[count] >adci[count])

adctmp[count] = adck[count];

else

adctmp[count] = adci[count];

sum1[count]+=adctmp[count];

}

}

for(count = 0; count < 7;count++)

{

AD_Val[count]=sum1[count]/10;

sum1[count]=0;

}

}

归一化

关于为什么要使用归一化:我看到的很多文章说使用归一化可以提高对不同赛道的适应性。我的理解是,在不同的赛道只用去测每一路电感的最大最小值就可以正常跑了,对于特殊元素的特征值不用再去测量。大大提高了对不同赛道的适应性。

归一化的定义:将数据映射到0-1范围之内处理,可以更快速便捷地观察数据。

归一化的公式:(X – Min) / (Max – Min).

其中 X为某一路电感 滤波后的ADC值;Min / Max为某一路电感 滤波后ADC采集到的最小 / 大值。

/*归一化后每一路ADC的值*/

uint16_t AD_left1;

uint16_t AD_left2;

uint16_t AD_right1;

uint16_t AD_right2;

/*归一化算法*/

void GuiYi_ADC(void)

{

AD_left1 = (uint16_t) (100 * (AD_Val[1] – AD_left1_min) / (AD_left1_max – AD_left1_min));

AD_left2 = (uint16_t) (100 * (AD_Val[2] – AD_left2_min) / (AD_left2_max – AD_left2_min));

AD_right1 = (uint16_t) (100 * (AD_Val[3] – AD_right1_min) / (AD_right1_max – AD_right1_min));

AD_right2 = (uint16_t) (100 * (AD_Val[4] – AD_right2_min) / (AD_right2_max – AD_right2_min));

}

可以进行适度放大(一般是放大100倍),使车能够更容易的根据电磁值判断路况。

差比和

电磁智能车 是根据电磁杆上电感 采集到的值判断路况,可以说电磁杆上的电感就是一辆电磁智能车的眼睛。差比和值能够让车更直观的判断路况。

差比和公式:(L-R)/(L+R)。差比和值范围0-1。

原理:当电感离中心磁感线越近,采集到的值就越大,反之越小。

所以当差比和值为负的时候,可以判断到车向左偏移了,为正则向右偏移了(公式里面的左右交换了则反之)。

int16_t ad_1_sum;

int16_t ad_1_diff;

double count_1;

double position_1;

/*差比和算法*/

void ChaBiHe_ADC(void)

{

ad_1_sum = (int16_t)AD_left2 + (int16_t)AD_right1+1;

ad_1_diff = (int16_t)AD_left2 – (int16_t)AD_right1;

count_1 = (double)ad_1_diff / ad_1_sum;

position_1 = count_1 * 100;

HAL_Delay(5);

}

小菜花给差比和值乘了100,这里的100可以自行修改,根据需要调整。

PID算法

小菜花采用的位置式PD控制舵机。

小菜花将差比和值乘100后(就是上段代码中的position)直接传给PD算法中作为误差error。

那么为什么可以这样呢,因为我把 差比和值为0作为目标,采集回来的差比和值作为实际值,那么误差error就是 实际值-目标值。 注意,我的目标值为0,所以error可以直接为采集回的差比和实际值。

typedef struct

{

double PID_P; /* 比例常数 */

double PID_D; /* 微分常数 */

double LastError; /* 前一项误差 */

double PrevError; /* 前第二项误差 */

}PID;

double PID_Vertical (PID *pp)

{

double dError1, Error1;

Error1 = position_1;//差比和的值作为error /*目标值为差比和值为0,所以可以直接将差比和实际所得值作为error*/

dError1 = pp->LastError – pp->PrevError;

pp->PrevError = pp->LastError;

pp->LastError = Error1;

PWMValue1 = pp->PID_P * Error1 + pp->PID_D * dError1;

return PWMValue1;

}

然后就开始调P和D,如果P D调得好,车就跑得很丝滑。小菜花建议可以使用分段PD来调车,亲测有效!车跑起来确实丝滑。

PD算法返回的值传给

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3,PWMValue1+745);

745是小菜花当时找到的舵机中值,PWMValue1可正可负,调节舵机可以左右转动。

7.特殊元素

十字路口

小菜花当时是用两路水平电感寻迹,到了十字路口也不会出现误判,能够正常行进。

三岔路口

当两路水平电感采集的归一化后的值 出现同时突然下降时,强制打角。

环岛检测

基于STM32cubemx的电磁智能车-基于stm32的两轮自平衡小车参考文献英文翻译 小菜花是设置了三个标志位,到赛道上去采集阈值。当三个标志位都满足时,进行了强制打角(可以在此时切换为内八字电感寻迹,由内八电感的PD算法输出占空比拐弯进环岛。不推荐强制打角,会降低对不同赛道的适应性)。

然后用水平电感跑环岛。出环的时候检测两条磁感线重合的位置,到赛道测阈值,设置标志位,满足条件则强制直行,延时控制出环岛(依旧不推荐强制控制,但小菜花的能力有限,只能想到这个办法)。

出库

小菜花当时的思路是:开机就强制打角,延时控制直到出库,随后正常水平巡线。(所以出库函数只运行一遍!)

void chuKu(void)

{

uint16_t i;

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,7000);//先低速跑电机

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2,7000);

for(i=155;i<192;i++)

{

Value1=i+745;

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3,Value1);

HAL_Delay(15);

}

}

用了一个for循环(也可以不用,直接输出占空比)。for循环 使舵机打角时不会突然一下就转到相应角度,而是更加丝滑地转过去。

入库

干簧管经过终点磁铁,会由高电平变为低电平。因此,检测到干簧管的IO口有一个电平变化,标志位加一。在while循环里面标志位变为一的时候进行强制打角,延时控制入库,舵机转回中值,电机停止转动。

/*干簧管标志位*/

static uint16_t ganflag = 0;

if ((AD_Val[0]<300||AD_Val[6]<300) )//干簧管检测出入库

{

ganflag++;

HAL_Delay(100);

if ((AD_Val[0]<300||AD_Val[6]<300) && ganflag == 1)

{

ruKu();

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);//电机GPIO口高低电平

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3,745);

}

}

void ruKu(void)

{

uint16_t i;

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1,7000);//先低速跑电机

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2,7000);

for(i=150;i<220;i++)

{

Value1=i+745;

__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3,Value1);

HAL_Delay(15);

}

}

干簧管标志位检测可以放在中断里面更好,检测到一次下降沿,触发一次中断,标志位加一。

小菜花放在while循环里面会存在一个问题:过一次磁铁,标志位不只加一(我猜测是干簧管检测到一次电平变化,但是代码已经刷过好几遍了,所以标志位加的次数不定)。所以,我加了一个延时,HAL_Delay(100),试了一下,可以过一次干簧管,标志位加一。

8. 一些建议

电磁杆

我们当时是自己做了电磁杆,但是由于其中有一路重要电感不能用,所以最终放弃,买了一个电磁杆(所以被迫使用水平+内八字电感)。 建议大家有条件的可以买一个电磁杆,不要把过多的时间都放在修电磁杆上面了!!!

OLED

可以用OLED来显示数据,观察起来很方便。 不幸的是,小菜花当时的OLED不知道为啥用不了,

插核心板上面一点反应都没有!!!

HC-05蓝牙模块

可以使用空闲中断,用蓝牙与手机通信,直接在手机上面调节PD值,十分方便。

Debug

如果你跟我一样,不幸地 OLED用不了,蓝牙串口不,打印那么就用Debug看变量的值吧!!!

文末

还有一个电脑端上位机VOFA+,推荐使用(由于小菜花能力和时间有限,没有深入了解这个VOFA+),读者可以自己去了解使用。

免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:基于STM32cubemx的电磁智能车-基于stm32的两轮自平衡小车参考文献英文翻译 https://www.yhzz.com.cn/a/5719.html

上一篇 2023-04-12 13:05:26
下一篇 2023-04-12

相关推荐

联系云恒

在线留言: 我要留言
客服热线:400-600-0310
工作时间:周一至周六,08:30-17:30,节假日休息。