stm32+k210视觉小车

您所在的位置:网站首页 k210物体检测电路流程图 stm32+k210视觉小车

stm32+k210视觉小车

2024-07-11 21:31| 来源: 网络整理| 查看: 265

stm32F407+k210视觉小车

文章目录 前言 一、制作思路 二、讲解与说明 1.控制部分代码思路 2.通信部分代码讲解 3.过程经验以及注意事项 开源网址 前言

暑假没事做,从学校带回了一些开发板(stm32F407和k210),在B站学习了串口的多位通信以及串级PID,制作了一个具有来拒去留、可控制位置、控制轮子转速以及舵机转向功能的视觉小车。在这里做一个开源,顺便讲解一下该视觉小车的制作思路和过程。演示视频戳这里https://www.bilibili.com/video/BV15Y4y1F7VQ?spm_id_from=333.999.0.0&vd_source=25a8aa89291db245e99a1e95bd6f2b19 (开源链接在文章最后)

小车整体

一、制作思路

小车最基本的就是它的轮子了,其实每个小车基本上都会用到读轮子的编码器以及用PID控制它的转速。知道了这一点,那么接下来便是操控它的转速,来靠近目标。而想要识别目标位置,则需要用到视觉模块(这里用的是k210)。 当识别到目标的时候,k210会将图中白框的面积以及中间的十字坐标通过串口传将数据包递给stm32,stm32获得数值(下图OLED屏幕最下面一行就是数据包)

二、讲解与说明 1.控制部分代码思路

上文说到,k210会回传解析包。单片机则会解析它们,具体方式也就是取余数或者是取百位/千位。比如我这里使用十位数据进行数据包传输,其中后三位数据是位置判断,那么就需要对十位数据DATA_NUM进行取余运算。

Orientation=DATA_NUM%1000; Distance=(DATA_NUM-Orientation)/1000%1000000;

这样就得到了方位-Orientation,以及距离-Distance 通过白框的面积大小判断与物体的间距,通过中心十字判断左右。 距离控制:当白框变大且小车在不断靠近目标的时候,白框变大,轮子将会减速,并停在期望位置,此时再拉开小车与目标的距离,白框变小,轮子将会加速。 方向控制:假定期望数值是目标在中间的数值(我测出为190),那么小于190时,就该左转,大于时候要右转。

该怎样控制距离呢?是距离增大我就一股脑的往前冲,然后距离减小我就直接往后退?显然这样是不行的,假设目标距离为4000,这时候你靠近了,变成了3999,小车就会突然后退,而它一旦后退,3999就变化成大于4000的数字,这时又向前冲…这便产生了振荡。这并不是我们想要的现象,所以我们应该在目标刚靠近小车时,缓慢后退,靠近的越多,退的越快。靠近的时候如果手里的“目标物”突然停下,小车会从刚才的快速后退变成慢速后退,直到不断接近期望距离。这种思路便是PID了。PID这一部分的讲解,推荐各位去B站一个叫“天下行走”的UP那里学习,他讲的很详细,这里不在赘述。 该UP的个人空间链接 轮子速度控制部分代码

int Speed_PID_1(float true_speed) { hope_speed_1=Speed_PID(); err=hope_speed_1-true_speed; integral += err; if(integral=899)out=899; return out; }

小车位置控制部分代码

S_Distance=Hope_Distance-Distance; if(S_Distance GO_flag=0; S_err=Distance-Hope_Distance; S_integral += S_err/1000; if(S_integral0)?S_out:0; S_out=(S_out static uint8_t RxState = 0; static uint8_t pRxPacket = 0; if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { uint8_t RxData = USART_ReceiveData(USART1); if (RxState == 0) { if (RxData == 0x0A) { RxState = 1; pRxPacket = 0; } } else if (RxState == 1) { Serial_RxPacket[pRxPacket] = (RxData/16)*10+RxData%16-30;//十六进制转十进制 pRxPacket ++; if (pRxPacket = DATALONG) { for(j=0;j //将信息包整理成一串数字 DATA_NUM=DATA_NUM*10+Serial_RxPacket[j]; //信息包解析 Orientation=DATA_NUM%1000; Distance=(DATA_NUM-Orientation)/1000%1000000; // OLED_ShowNum(0, 0,Orientation , 10,16,1); OLED_ShowChinese(0,32,11,16,1);//距 OLED_ShowChinese(16,32,15,16,1);//: OLED_ShowNum(24,32,Distance, 5,16,1); OLED_ShowChinese(70,32,14,16,1);//位 OLED_ShowChinese(86,32,15,16,1);//: OLED_ShowNum(94,32,Orientation, 3,16,1); OLED_ShowNum(0,48,DATA_NUM, 10,16,1); } RxState = 2; } } else if (RxState == 2) { if (RxData == 0x0D) { DATA_NUM=0; RxState = 0; Serial_RxFlag = 1; } } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } }  ⌒ヽ    /   へ\    /  / \\    レ ノ   ヽ_つ   / /   / /|  ( (ヽ  | |、\  | 丿 \ ⌒)  | |  ) / `ノ )   Lノ (/

您可能感兴趣的内容: STM32串口通信教程:使用USART进行串口数据包传输 江科大STM32开发板使用指南 深入理解STM32中的USART串口协议 嵌入式学习:STM32F103 USART串口通信教程 STM32F4驱动42步进电机(使用驱动器)的完整教程


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3