基于stm32f4的五路循迹小车(四、五路循迹模块)

文章讲述了作者在智能车比赛中使用STM32F1开发五路黑白循迹小车的过程,从模仿传感器信号到遇到帕金森小车问题,通过调整代码逻辑解决整型判断问题,最终成功调试并完成比赛。
摘要由CSDN通过智能技术生成

#这一部分现在回想起来也是很怀念,当时马上就要进行智能车比赛了,然后为了赶时间,专门挑了一个“水课”,坐在思政课最后面拿个电脑在那里想该怎么构建代码。

最开始我想的是模拟信号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,就说明小车已经偏移的很严重了,要进行大幅度的左拐操作。

如何实现小小的左拐和大大的左拐操作呢,我们只需要控制我们电机的转速,让他们的差值越来越大,那么我们就能实现较大的左转弯。

当时就这样按照这个思路来一步一步进行,最后代码也写完了,运行也没问题,拷录芯片进去,发现小车跟一个帕金森老头一样,一卡一卡的,根本走不了。

帕金森小车

帕金森小车-CSDN直播

(我把视频放在这里,感兴趣的可以欣赏一下“帕金森小车”)

后来呀,也是咨询了好多好多人,问了好多学长,最后都是说我写的代码也没有问题,但是就是说不出来问题,我也是想的好久,然后过了几天之后,我突然意识到,我的判断条件11000,00111之类的条件其实是每个摄像头反映出来的数字,如果连接起来其实是整型,并不是字符串。

意识到这一点之后,我便调整了算法,一整个代码完全用if else来执行。

最后写出来了下面的代码,这个代码运行起来没有一点问题,最终映射在小车上也是十分成功的,就是在一个弯道的判断条件会出现一些问题,可以看下面这个视频。

调试小车

调试小车-CSDN直播

代码部分我拷在下面

这个是五路循迹的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;
}
	*/
}





注释掉的内容就是之前我不断调试的过程,自己有点怀旧没有将他们删掉,嘿嘿


调试的过程真的很痛苦,就是那种下午到实验室不断修改电机转速,一遍一遍调试,看小车到底在哪个条件下运行的最好,完美的概率最高,这种小车跑图真的有运气的成分,小车有时候给你脸,会走的很完美,不给你脸,就真的走不了一点(哈哈哈哈哈)

最后也是成功完赛,取得了一定的名次。

成功的小车

成功的小车-CSDN直播

小车也是十分的帅气,我都想把他放家里每天烧香供上哈哈哈哈。

//到这里为止小车的主要学习部分基本上就要结束了,之后我会最后出一个这个系列的最后一篇总结文章,主要总结一下电机转速设置的问题,以及部分走线会出现或者遇到的问题。

跟着我的思路和文章走下去,一定能得到和我一样成功的结果的。相信自己,不要因为一时的挫折就放弃了智能车的学习,最后成功了真的会十分激动的!

ps:不会调节视频大小/(ㄒoㄒ)/~~,还得继续学习

谢谢大家的支持啦!!!!!!(希望大家来点小小的赞和关注,给我更多的创作动力,我臭不要脸/(ㄒoㄒ)/~~)

  • 55
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值