电磁循迹智能车基于stm32cubeMX、HAL库 | 您所在的位置:网站首页 › 迹寻软件是干什么的 › 电磁循迹智能车基于stm32cubeMX、HAL库 |
我的第一辆智能车—电磁循迹智能车
提示:本文适用于初学,想完成一个基础四轮车练练手者,大佬还请勿喷,不过欢迎提出意见,有纰漏之处我将及时纠正。 注:工程代码链接已贴在文末。 所用到的硬件平台: stm32f103c8t6,舵机,电机,L298N驱动模块,OLED,电磁杆,干簧管,基础四轮车模。 所用到软件部分: PID算法,ADC多路采集配置DMA,OLED驱动程序,环岛处理,普通GPIO口使用。 智能车图片 一、舵机模块 (1)舵机,三条线路,一条GND,一条VCC,一条给予PWM波输入。 控制舵机角度主要是控制PWM波的大小,不同的PWM对应不同的角度。中间角度的占空比为7.5%。这个值上下加减对应控制舵机左右角度。 (2)一个对应的PWM确定一个对应的角度。注意的是时间周期应配为20MS,频率50HZ。 (3)在设置最大主频72MHZ的情况下,计数值设为2000-1,预分频系数设为720-1。CUBEMX注意通道使能。工程代码中可以直接操纵寄存器TIM1->CCR3 = 143。(143是我设置的中间值,正常情况下应该是150) 二、电机、L298N驱动模块 (1)电机引出的两条线路不分正负,表现出来只是正反转,之后用代码普通GPIO口控制即可。LM298N左右端子分别接电机的引脚。 (2)中间排针四个口接普通GPIO口,用于stm32单片机控制其正反转。 (3)两边的口接PWM,设置占空比控制电机的转速。 三、PID算法 add.c文件中的PID控制部分 使用的是位置式PID 传入主函数控制 void main(void) { while(1) //用户理想值 { TIM1->CCR3 =143+Control(); //转向控制系统,核心部分 } }P:proportion,比例,就是用户期望值,与传感器返回值的差值,偏差。 I:integral,积分,记录了从某一时刻开始,所有的偏差的累积。 D:derivative,微分,是偏差的偏差,相当于偏差的导数,偏差变化的速率。 四、OLED (1)对于OLED来说一般网上有很多相关的驱动文件,和其能调用的子函数。直接加入工程,修改一下引脚就可以调用了。使用CUBEMX配置使能硬件IIC驱动IIC。 (2)链接:https://download.csdn.net/download/cubejava/21518138 五、电磁杆 (1)电磁杆我们组硬件员是自己画板去某创开板拿回来自己制好了的,但是在使用时发现两边对称的电感值不一样,相差很大。这个情况是也许是可以用卡尔曼滤波算法解决的,但是由于我目前的技术太菜,无法实现,所以很遗憾,我们不能用自己的电磁感进行循迹,而这恰恰是这个比赛最关键的一步。 (2)我们最后只能买了某龙的电磁杆,说实话,买的电磁杆质量那叫一个好。可以直接拿来用,完全可以不用滤波,效果贼好。六个电感,我们只用了4个,两个水平的用于检测直道和弯道,两个竖直的用于检测环岛。(电感检测电磁场的变化,转化为电压—电磁感应,用多路ADC采集值传回)。 (3)所以如果是初次参加比赛建议买现成的电磁杆,可用省去很多麻烦,把精力放在代码优化上。 六、ADC多路采集配置DMA 以下为cubeMX的配置 在程序中添加以下代码即可使用 uint16_t adcbuf[5];//五路ADC存储数组。 HAL_ADCEx_Calibration_Start(&hadc1 );//开启ADC。 HAL_ADC_Start_DMA (&hadc1 ,(uint32_t *)adcbuf,5);//开启五路DMA后面使用数组数据即可,如电感一的值则是adcbuf[0],电感二的值则是adcbuf[1],以此类推。 八、干簧管(用于检测停车) (1)提到干簧管是比较难受的(不是因为难,很简单),我真的直接裂开。比赛时干簧管没有检测到。 (2)干簧管模块一般有三条线路,一条VCC(用3.3V即可,之前我接的5V,多用几次芯片就烧坏了),一条GND,还有一条信号线,用于检测电平变化。若没有检测到永磁铁时,处于高电平,检测到永磁铁后处于低电平。程序控制的方式是用一路ADC检测其传回来的值,判断其高低电平,进而写对应的用户代码。 (3)而我当时比赛时干簧管为什么没有检测到,因为我把我的干簧管检测程序写在了子函数里,并设置了一个标志位,当检测到时标志位计数,加到我的预设值后实现相应的用户代码。思路是没有问题,但是我的子函数有问题!!!原因是每次进去我的子函数里,变量值就会被刷新为0,根本达不到我的预设值!所以根本进不去我的用户代码。 (4)比赛结束后那天晚上我一直睡不着在想为什么会检测不到,最后我发现我忘记加static,静态变量了(变量只初始化一次)。所以平时写代码要多多灵活应用static啊!static,static,static,重要的东西说三遍。 八、普通GPIO口使用 这个也不用多说了,直接在cubeMX使能配置就好了。 程序里需要调用的函数一般就三个: HAL_GPIO_WritePin (GPIOX ,GPIO_PIN_X , x(0或1)); HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); HAL_GPIO_Toggle(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);九、环岛处理 (1)环岛处理部分我使用的是比较容易想到的思路——闭环控制,即检测到标志点则卡死程序强行打角度进入环岛,好处是程序简单,容易理解,效果明显。坏处时会出现一些偶然性,受环境影响大。 (2)如图环岛的关键点,我分为四个点,刚到,即将入,刚出,即将出。分设相应的检测值范围和标志位。 具体程序处理见工程代码。 总结(1)怎么说呢,这次比赛也还是算尽力了吧,一个月来天天去赛道调车,基本上都是晚上11:00左右才依依不舍离开实验室。最后比赛时轮胎打滑,速度没来得及提上去,只得了三等奖,能力还不够啊!不足的地方还很多,需要学的东西还有很多,在这里就不多说了。路漫漫其修远兮,吾将上下而求索! (2)以上写的很多只是我自己片面的想法,而且能力有限,有不足的地方欢迎指出。 (3)最后,因为自己也是花了时间和心血一点一点才完成的工程、写出的代码,所以不太想被人白嫖,故设置了付费,还请大家理解。不过博文中大部分已经进行了详细说明,只要稍微会一点stm32应该就能独立完成整个智能车了。欲速则不达,加油! 工程代码链接:https://download.csdn.net/download/cubejava/41879499 |
CopyRight 2018-2019 实验室设备网 版权所有 |