#这一部分现在回想起来也是很怀念,当时马上就要进行智能车比赛了,然后为了赶时间,专门挑了一个“水课”,坐在思政课最后面拿个电脑在那里想该怎么构建代码。
最开始我想的是模拟信号01来判断灰度,也参考了好多资料。
STM32F1编写简单的五路黑白循迹_五路循迹小车代码-CSDN博客
最开始参考了类似这些的循迹模块的代码,我在这里将他们复制上来,便于我说明
这个是我最开始参考别人的代码
/********
功 能:读取5个传感器输出的状态
形 参:无
返回值:state 传感器状态
说 明:传感器检测到白线输出1,黑线输出0。。
因为使用的时GPIOA端口的5到9引脚,这里直接读出GPIOA所有引脚的状态,
然后将得到的数据向右移动5位,去掉0到4引脚的数据,
再与上0x001f,得到5到9引脚的状态,
******/
u8 Get_Infrared_State(void)
{
u8 state = 0;
state = (u8)(GPIO_ReadInputData(TRACK_PORT) >> 5) & 0x001f;
return state;
}
/********
功 能:循迹调整函数
形 参:无
返回值: 无
说 明:根据获取到的传感器输出状态,进行左右电机的速度调整
******/
void Track_Adjust(void)
{
u8 flag = 1;//是否复位标志
u8 state = 0;//状态获取变量定义
while(flag)
{
state = Get_Infrared_State();//获取传感器状态
switch(state)
{
case 0b00000:
case 0b10001:
case 0b00001:
case 0b10000: Motor_Speed_Adjust(0,0); break;//停止
case 0b10011: Motor_Speed_Adjust(STARTER_SPEED-100,STARTER_SPEED+100); break;//右偏1级
case 0b10111: Motor_Speed_Adjust(STARTER_SPEED-250,STARTER_SPEED+250); break;//右偏2级
case 0b00111: Motor_Speed_Adjust(STARTER_SPEED-400,STARTER_SPEED+400); break;//右偏3级
case 0b01111: Motor_Opposite(L); break;//右偏4级,
case 0b11001: Motor_Speed_Adjust(STARTER_SPEED+100,STARTER_SPEED-100); break;//左偏1级
case 0b11101: Motor_Speed_Adjust(STARTER_SPEED+250,STARTER_SPEED-250); break;//左偏2级
case 0b11100: Motor_Speed_Adjust(STARTER_SPEED+400,STARTER_SPEED-400); break;//左偏3级
case 0b11110: Motor_Opposite(R); break;//左偏4级
case 0b11011: Motor_Speed_Adjust(STARTER_SPEED,STARTER_SPEED);flag = 0; break;//正常
case 0b11111: Motor_Speed_Adjust(0,0); break;
default: Motor_Speed_Adjust(0,0); break;
}
}
}
(主要是从别人的代码中得到一些思路来指导自己的整体过程)
当时差不多也是这个思路,01110,之类的进行判断,检测到黑线就是1,检测不到黑线就是0,01110就是指我们车的方向是正确的,接下来进行直走就行了。
同理11100则说明小车已经开始发生了偏移,要进行左拐操作,同时这个偏移的幅度也不是很大,所以进行较小的左拐操作。
类似的11000或者10000,就说明小车已经偏移的很严重了,要进行大幅度的左拐操作。
如何实现小小的左拐和大大的左拐操作呢,我们只需要控制我们电机的转速,让他们的差值越来越大,那么我们就能实现较大的左转弯。
当时就这样按照这个思路来一步一步进行,最后代码也写完了,运行也没问题,拷录芯片进去,发现小车跟一个帕金森老头一样,一卡一卡的,根本走不了。
帕金森小车
(我把视频放在这里,感兴趣的可以欣赏一下“帕金森小车”)
后来呀,也是咨询了好多好多人,问了好多学长,最后都是说我写的代码也没有问题,但是就是说不出来问题,我也是想的好久,然后过了几天之后,我突然意识到,我的判断条件11000,00111之类的条件其实是每个摄像头反映出来的数字,如果连接起来其实是整型,并不是字符串。
意识到这一点之后,我便调整了算法,一整个代码完全用if else来执行。
最后写出来了下面的代码,这个代码运行起来没有一点问题,最终映射在小车上也是十分成功的,就是在一个弯道的判断条件会出现一些问题,可以看下面这个视频。
调试小车
代码部分我拷在下面
这个是五路循迹的track.h文件
#ifndef __TRACK_H__
#define __TRACK_H__
#include "motor.h"
void Track_Adjust(void);
int Track_State(void);
#endif
这个是循迹模块的track.c文件
#include "gpio.h"
#include "motor.h"
#include "stdio.h"
#include "main.h"
/*int Track_State(void)
{
int LED_1, LED_2, LED_3, LED_4, LED_5,LED;
LED_1 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2);
LED_2 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3);
LED_3 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4);
LED_4 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5);
LED_5 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6);
LED = (LED_1 * 10000) + (LED_2 * 1000)+ (LED_3 * 100) + (LED_4 * 10) + LED_5;
return (LED);
}*/
void Track_Adjust(void)
{
int LED_1, LED_2, LED_3, LED_4, LED_5,LED;
LED_1 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2);
LED_2 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3);
LED_3 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4);
LED_4 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5);
LED_5 = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6);
if(LED_1==0&&LED_2==0&&LED_3==0&&LED_4==0&&LED_5==0)
runCarStop();
else if(LED_1==1&&LED_2==1&&LED_3==1&&LED_4==1&&LED_5==1)
runCarGo();
else if(LED_1==1&&LED_2==0&&LED_3==0&&LED_4==1&&LED_5==1)
runCarLittleRight();
else if(LED_1==1&&LED_2==0&&LED_3==1&&LED_4==1&&LED_5==1)
runCarLittleRight();
else if(LED_1==0&&LED_2==0&&LED_3==0&&LED_4==1&&LED_5==1){
//runCarStop();
//HAL_Delay(20);
runCarRight();
}
else if(LED_1==0&&LED_2==0&&LED_3==1&&LED_4==1&&LED_5==1){
//runCarStop();
//HAL_Delay(20);
runCarRight();}
else if(LED_1==0&&LED_2==1&&LED_3==1&&LED_4==1&&LED_5==1){
runCarRight();}
else if(LED_1==1&&LED_2==1&&LED_3==0&&LED_4==0&&LED_5==1)
runCarLittleLeft();
else if(LED_1==1&&LED_2==1&&LED_3==1&&LED_4==0&&LED_5==1)
runCarLittleLeft();
else if(LED_1==1&&LED_2==1&&LED_3==1&&LED_4==0&&LED_5==0)
runCarLeft();
else if(LED_1==1&&LED_2==1&&LED_3==1&&LED_4==1&&LED_5==0)
runCarLeft();
else if(LED_1==1&&LED_2==1&&LED_3==0&&LED_4==1&&LED_5==1)
runCarGo();
else
runCarGo();
/*switch (LED)
{
case 00000:runCarStop(); break;
//case 10000:runCarRight();break;
case 11111:runCarGo(); break;
case 00110:
case 10010:
case 10110:
case 00001:
case 00101:
case 00011:
case 10011: runCarLittleLeft(); break;
case 10111: runCarLittleLeft(); break;
case 00111: runCarLeft(); break;
case 01111: runCarLeft(); break;
case 10100:
case 11000:
case 11001:runCarLittleRight(); break;
case 11101:runCarLittleRight(); break;
case 11100:runCarRight(); break;
case 11110:runCarRight(); break;
case 01110:
case 10101:
case 10001:
case 11011: runCarGo(); break;
default:runCarGo(); break;
}
*/
}
注释掉的内容就是之前我不断调试的过程,自己有点怀旧没有将他们删掉,嘿嘿
调试的过程真的很痛苦,就是那种下午到实验室不断修改电机转速,一遍一遍调试,看小车到底在哪个条件下运行的最好,完美的概率最高,这种小车跑图真的有运气的成分,小车有时候给你脸,会走的很完美,不给你脸,就真的走不了一点(哈哈哈哈哈)
最后也是成功完赛,取得了一定的名次。
成功的小车
小车也是十分的帅气,我都想把他放家里每天烧香供上哈哈哈哈。
//到这里为止小车的主要学习部分基本上就要结束了,之后我会最后出一个这个系列的最后一篇总结文章,主要总结一下电机转速设置的问题,以及部分走线会出现或者遇到的问题。
跟着我的思路和文章走下去,一定能得到和我一样成功的结果的。相信自己,不要因为一时的挫折就放弃了智能车的学习,最后成功了真的会十分激动的!
ps:不会调节视频大小/(ㄒoㄒ)/~~,还得继续学习
谢谢大家的支持啦!!!!!!(希望大家来点小小的赞和关注,给我更多的创作动力,我臭不要脸/(ㄒoㄒ)/~~)