stm32循迹小车问题

stm32寻迹小车,有四路红外探头,怎么摆放探头才能快速跑完约1.5厘米的黑色循迹线。
目前已经有控制小车的模块以及获取红外信息的模块,需要一个根据红外信息控制小车的模块
可以用伪代码形式表示,基于KEIL的IDE,HAL库编写
循迹线有S型也有直角转弯,最后还要入库
自己有GPT PLUS,拒绝GPT回答。

寻迹的算法其实是很简单的,网上搜一下一大把

在设计红外探头的摆放位置时,需要考虑到小车行驶时可能遇到的各种情况,以便尽可能准确地检测到循迹线。以下是一些可能有用的提示:

将探头分布在小车的前、后、左、右四个方向,以便检测到循迹线的各个部分。例如,可以将两个探头安装在小车的前方,以便检测到循迹线的前面和中心部分。

探头的距离和角度需要适当调整,以便能够检测到循迹线。例如,可以将探头与地面之间的距离设置为约1-2毫米,以确保能够检测到黑色循迹线。

在探头周围放置黑色胶带或黑色绝缘胶,以减少外界光线的干扰。

可以将探头的输出信号连接到一个模数转换器(ADC),以将模拟信号转换为数字信号,然后使用数字信号处理算法来分析红外信号并控制小车运动。以下是一个可能的伪代码示例:

apache
Copy
while(1)
{
  // 读取红外信号
  uint16_t ir1 = HAL_ADC_GetValue(&hadc1);
  uint16_t ir2 = HAL_ADC_GetValue(&hadc2);
  uint16_t ir3 = HAL_ADC_GetValue(&hadc3);
  uint16_t ir4 = HAL_ADC_GetValue(&hadc4);

  // 计算红外信号的加权平均值
  float average = (float)(ir1 * 0.1 + ir2 * 0.3 + ir3 * 0.5 + ir4 * 0.1);

  // 根据加权平均值计算小车运动方向
  if (average < threshold)
  {
    // 小车偏左,向右转
    turn_right();
  }
  else
  {
    // 小车偏右,向左转
    turn_left();
  }

  // 延时一段时间,等待小车运动到下一个位置
  HAL_Delay(100);
}
在这个示例中,我们使用了四个红外探头(ir1、ir2、ir3、ir4),并将它们的输出信号连接到四个ADC通道(hadc1、hadc2、hadc3、hadc4)上。然后,我们计算了红外信号的加权平均值,以便更准确地检测循迹线的位置。如果加权平均值小于一个阈值(即小车偏左),则调用“turn_right()”函数向右转;否则,如果加权平均值大于阈值(即小车偏右),则调用“turn_left()”函数向左转。

在“turn_left()”和“turn_right()”函数中,您可以使用PWM控制小车的左右轮以实现转向。例如,以下是一个可能的“turn_left()”函数的示例:

ini
Copy
void turn_left()
{
  // 启动左轮
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  // 启动右轮
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);

  // 控制左轮速度
  TIM3->CCR1 = 500;

  // 控制右轮速度
  TIM3->CCR2 = 1000;
}
在这个示例中,我们使用GPIO控制小车的左右轮,将左轮向前转动,将右轮向后转动。然后,使用TIM控制左轮和右轮的速度,以便小车向左转。您可以根据您的具体需求调整速度和PWM占空比。同样的,您可以编写一个“turn_right()”函数来控制小车向右转。

stm32寻迹小车,有四路红外探头,怎么摆放探头才能快速跑完约1.5厘米的黑色循迹线。前辈博客参考:
https://blog.csdn.net/Dustinthewine/article/details/124831614
https://blog.csdn.net/k_ksy/article/details/105859319

四路红外探头需要前后两组,左右宽度和循迹线边缘一致,前后两组可以一组偏外,一组偏内,方便编程实现循迹控制

可以借鉴下

#include "find.h"
#include "Moto.h"

extern TIM_HandleTypeDef htim3;

/*
函数功能:调节小车左右电机PWM
Left:左电机PWM
Right:右电机PWM
*/
void Moto_speed_set(int Left,int Right)
{
  __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, Right);
  __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, Left); 
}

/*
函数功能:循迹
*/
void Find(void)
{
  //全是白线前进
  if((IO1_read()==0)&&(IO2_read()==0)&&(IO3_read()==0)&&(IO4_read()==0))
  {
    Moto_speed_set(800,800);
    car_move(0);    
  }
  //右边有黑线小车向左即左轮加速右轮减速
  else if((IO1_read()==0)&&(IO2_read()==1)&&(IO3_read()==0)&&(IO4_read()==0))
  {
    Moto_speed_set(800,0);
    car_move(0);    
  }
  //右边有黑线小车向左即左轮加速右轮减速
  else if((IO1_read()==1)&&(IO2_read()==1)&&(IO3_read()==0)&&(IO4_read()==0))
  {
    Moto_speed_set(800,0);
    car_move(0);    
  }
  //右边有黑线小车向左即左轮加速右轮减速
  else if((IO1_read()==1)&&(IO2_read()==0)&&(IO3_read()==0)&&(IO4_read()==0))
  {
    Moto_speed_set(800,0);
    car_move(0);    
  }
  
  
  //左边有黑线小车向右即右轮加速左轮减速
  else if((IO1_read()==0)&&(IO2_read()==0)&&(IO3_read()==1)&&(IO4_read()==0))
  {
    Moto_speed_set(0,800);
    car_move(0);    
  }
  //左边有黑线小车向右即右轮加速左轮减速
  else if((IO1_read()==0)&&(IO2_read()==0)&&(IO3_read()==1)&&(IO4_read()==1))
  {
    Moto_speed_set(0,800);
    car_move(0);    
  }
  //左边有黑线小车向右即右轮加速左轮减速
  else if((IO1_read()==0)&&(IO2_read()==0)&&(IO3_read()==0)&&(IO4_read()==1))
  {
    Moto_speed_set(0,800);
    car_move(0);    
  }
  
  //全是黑线停车
  if((IO1_read()==1)&&(IO2_read()==1)&&(IO3_read()==1)&&(IO4_read()==1))
  {
    Moto_speed_set(0,0);
    car_move(2);
  }
}


前后各两组,一组在循迹线偏内,另一组在循迹线偏外