• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

NXP智能车竞赛笔记(室外电磁组)

人工智能 WillChan_ 2144次浏览 0个评论

一、概要 比赛规则与赛道: 比赛没有赛道,只有电磁线。但赛道元素包括有直道、弯道、坡道、十字路口以及横断路障。室外电磁组原则上选择室外的马路、草坪、体育场组织比赛,场地内可能会存在高度不大于 2 厘米的硬质路坎、沙坑、深度不超过 2 厘米的水坑等。 选手制作的车模完成赛道运行一周。比赛时间从车模冲过起跑线到重新回到起跑线为止。 越野车外形  
NXP智能车竞赛笔记(室外电磁组)   车的功能与实现:  
NXP智能车竞赛笔记(室外电磁组)   本文脉络  
NXP智能车竞赛笔记(室外电磁组)  

二、硬件部分:

1.主控板 (1)原理图: K60引脚分配: 引脚通过查K60引脚功能来分配,除去特殊功能引脚外,其余引脚为普通I/O口 特殊引脚: I2C通信:SDA,SCL FTM(PWM输出):PWMA,DPWM AD(模数转换):AD1~AD6 串口通信:TX2,RX2  
NXP智能车竞赛笔记(室外电磁组)   电源部分及笔记:(7~8v输入,5v和3.3v输出)  
NXP智能车竞赛笔记(室外电磁组)   以下为原理笔记:  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   按键模块:(SW2为4并排按键,用于设置车的模式)  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   电机输出(为排针插座,接驱动板,DIRA为电机方向控制,PWMA为速度控制):  
NXP智能车竞赛笔记(室外电磁组)   舵机输出(为排针插座,5v供电电压,DPWM为脉冲输出,以控制舵机转角):  
NXP智能车竞赛笔记(室外电磁组)   AD输入(为排针插座,接传感器板,6路电感值输入):  
NXP智能车竞赛笔记(室外电磁组)   普通IO口:  
NXP智能车竞赛笔记(室外电磁组)   蜂鸣器:  
NXP智能车竞赛笔记(室外电磁组)   (2)PCB和3D图 PCB中,logo部分和敷铜(GND)已去除,以更清晰显示电路  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   2.电机驱动板:用于驱动电机 (1)原理图 H桥电机驱动: VCC直接接电池(7~8V)  
NXP智能车竞赛笔记(室外电磁组)   H桥原理:  
NXP智能车竞赛笔记(室外电磁组)   12v升压(用于IR2104s驱动mos管):  
NXP智能车竞赛笔记(室外电磁组)   电源部分: VCC是电机供电  
NXP智能车竞赛笔记(室外电磁组)   12V(用于IR2104s驱动MOS)和3.3v(逻辑芯片供电):  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   调速及转向: Led显示电机方向及速度大小(速度越大越亮):  
NXP智能车竞赛笔记(室外电磁组)   排针插座信号输入,3.3v用于逻辑芯片供电:  
NXP智能车竞赛笔记(室外电磁组)   逻辑非和逻辑与芯片:  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   原理笔记:  
NXP智能车竞赛笔记(室外电磁组)   (2)PCB(GND敷铜已去)和3D图  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   3.传感器板:处理电感数据 (1)原理图 电源部分:
NXP智能车竞赛笔记(室外电磁组) 信号放大:(opa2350为运放,根据电阻,放大倍数最大50倍,输入输出为正弦波,共6路)  
NXP智能车竞赛笔记(室外电磁组)   信号整流(经实验,连接AD输出和GND的电容会严重削弱信号,故去除):  
NXP智能车竞赛笔记(室外电磁组)   信号输入输出(为插座):  
NXP智能车竞赛笔记(室外电磁组)   (2)PCB(GND敷铜已去除)和3D图  
NXP智能车竞赛笔记(室外电磁组)    
NXP智能车竞赛笔记(室外电磁组)   4.电磁探测板:探测电磁线信号 (1)原理图 谐振部分:谐振可以很好放大信号,电感电容值根据20K频率谐振计算。  
NXP智能车竞赛笔记(室外电磁组)   其他部分(LED和排针插座):  
NXP智能车竞赛笔记(室外电磁组)     2)PCB(GND敷铜已去除)和3D图  
NXP智能车竞赛笔记(室外电磁组)
NXP智能车竞赛笔记(室外电磁组) 电感与电磁线垂直时信号最强,故六路电感位置摆放:
在这里插入图片描述 这样放置电感,可以满足在多方位的检测需求。  

三、软件部分

智能车主要用到的几样硬件需要软件驱动,包括电机,舵机,编码器,ADC采集和超声波模块;还有一些调车的辅助模块,如OLED,蓝牙,串口,这些部分都采用了相应的例程做了需要的修改。 1.电机和舵机 (1).电机 电机部分需要主控芯片输出PWM波控制电机转速,编写了电机初始化及控制函数,包括了电机正反转的设置。  

void Motor_Init()    
{
	GPIO_Init(PORTA,7,1,1);//GPIO初始化
	FTM_PWM_Init(FTM0, FTM_CH2, 0,0);//PWM初始化
	Motor_Control(0,0);
}

void Motor_Control(int16 PWM,int DIR)//PWM为速度参数,DIR为正反转
{
  if(DIR==0)
  {
    GPIO_Ctrl(PORTA,7,0);
  }
  else
  {
    GPIO_Ctrl(PORTA,7,1);
  }
  FTM_PWM_Duty(FTM0,FTM_CH2,PWM);//PWM最大1000
}

    (2).舵机 舵机正常工作需要的50hz的PWM波来控制转角,通过控制占空比在5%到15%之间,可以实现舵机180度范围的旋转。在前期的调试过程中确定了舵机状态处于中点的占空比值,在这一值的基础上直接加减实现舵机控制左右转。 测试代码:使轮子到达两个最大转向角  

     FTM_PWM_Duty(FTM2,FTM_CH0,730);
     time_delay_ms(2000);
     FTM_PWM_Duty(FTM2,FTM_CH0,835);
     time_delay_ms(2000);

    2、传感器(电感,编码器和超声波) 越野组采用电感电容谐振来感应电磁引导线的磁场信号,信号经过谐振放大以及运放放大后通过芯片的ADC模块采集。由于采集的信号可能存在较大波动,采用了均值滤波的方式,选取四次采样平均值作为实际使用的数据。考虑到车前的三组电感相对电磁线的位置有区别,为了使收集到的数据尽量趋于线性变化,对数据做了线性化处理,根据三组电感的位置乘上了参数用作矫正。  

void ADC_6()
{
  int i;
  volt[0]=ADC_Ave(ADC1,ADC1_SE14,ADC_16bit,4);//均值滤波
  volt[1]=ADC_Ave(ADC1,ADC1_SE15,ADC_16bit,4);
  volt[2]=ADC_Ave(ADC1,ADC1_SE12,ADC_16bit,4);
  volt[3]=ADC_Ave(ADC1,ADC1_SE13,ADC_16bit,4);
  volt[4]=ADC_Ave(ADC1,ADC1_SE10,ADC_16bit,4);
  volt[5]=ADC_Ave(ADC1,ADC1_SE11,ADC_16bit,4);
  sprintf(txt,"0%06d",volt[0]);
  LCD_P6x8Str(5,1,(uint8 *)txt); //LCD屏显示
  sprintf(txt,"1%06d",volt[1]);
  LCD_P6x8Str(5,2,(uint8 *)txt);
  sprintf(txt,"4%06d",volt[4]);
  LCD_P6x8Str(5,3,(uint8 *)txt);
  sprintf(txt,"5%06d",volt[5]);
  LCD_P6x8Str(5,4,(uint8 *)txt);
  sprintf(txt,"2%06d",volt[2]);
  LCD_P6x8Str(54,1,(uint8 *)txt);
  sprintf(txt,"3%06d",volt[3]);
  LCD_P6x8Str(54,2,(uint8 *)txt);
}

    均值和终值滤波代码:  

u16 ADC_Ave(ADCn_e adc_n,ADCn_Ch_e adc_ch,ADC_nbit bit,u16 N) //均值滤波
{
    u32 tmp = 0;
    u8  i;
    for(i = 0; i < N; i++)
       tmp += ADC_Mid(adc_n,adc_ch,bit); 
    tmp = tmp / N; 
    return (u16)tmp;
}
u16 ADC_Mid(ADCn_e adc_n,ADCn_Ch_e adc_ch,ADC_nbit bit) //中值滤波
{
    u16 i,j,k,tmp;
    //1.取3次A/D转换结果
    i = ADC_Once(adc_n,adc_ch,bit); 
    j = ADC_Once(adc_n,adc_ch,bit); 
    k = ADC_Once(adc_n,adc_ch,bit); 
        //2.取中值
        if (i > j)
        {
          tmp = i; i = j; j = tmp;
         }
         if (k > j) 
           tmp = j;
         else if(k > i) 
           tmp = k; 
         else 
          tmp = i;
     return tmp;
}

    (2)编码器 实物图  
NXP智能车竞赛笔记(室外电磁组)   AB相增量式编码器原理:  
NXP智能车竞赛笔记(室外电磁组)  
NXP智能车竞赛笔记(室外电磁组)   发光二极管发射的光通过光栅到达光敏管,引起电平变化。如果正转,A相输出超前B相90度,如果反转A相滞后B相90度。 AB相正交解码原理:  
NXP智能车竞赛笔记(室外电磁组)   CNT寄存器:寄存器通过正解解码的得到的脉冲值,最后只要读取CNT的值就可以得到编码器转数(正值为正转,负值为反转)。 CNTIT寄存器:CNT计数的初始值。 AB相的电平和跳变沿决定了CNT的加数和减数。 CNT增计数时: A上升沿,B逻辑低 B上升沿,A逻辑高 B下降沿,A逻辑低 A下降沿,B逻辑高 CNT减计数是: A下降沿,B逻辑低 B下降沿,A逻辑高 B上升沿,A逻辑低 A上升沿,B逻辑高 编码器数值的读取我们使用了k60芯片的FTM模块中的正交解码功能来实现,直接调用库中的正交解码函数就可以获得脉冲数,通过比例换算可以获得当前速度。  

SPEED=FTM_AB_Get(FTM1);    //读取正交解码数值

  获取FTM正交解码脉冲数的函数:  

int16 FTM_AB_Get(FTMn_e ftmn)
{
    uint32 val;
    val = FTM_CNT_REG(FTMN[ftmn]);// 计数器,只有低16位可用(写任何值到此寄存器,都会加载 CNTIN 的值)
    FTM_CNT_REG(FTMN[ftmn]) = 0;             
    return val;
}

    (3).超声波 超声波模块的使用主要根据模块的测距原理编写,首先使Trig口输出不少于的10us的高电平信号,随后通过k60低功耗计时器(lptmr)计算Echo端高电平持续时间,即超声波从发送到接收的时间,最后用时间计算出距离。  

void US_Init()
{
  GPIO_Init(PORTA,27,1,0);
  GPIO_Init(PORTA,29,0,0);
}

void Distance_Get()
{
  i=0;
  char txt[20]=' ';
  GPIO_Ctrl(PORTA,27,1);
  LPTMR_delay_us(20);
  GPIO_Ctrl(PORTA,27,0);
  while(GPIO_Get(PTA29)==0);
  LPTMR_time_start_us();
  while(GPIO_Get(PTA29)==1);
  i = LPTMR_time_get_us();
  if(i > 65535)
  {
    d=10000;
  }
  else
  {
    d=(int)(i*0.2);
  }
  sprintf(txt,"dis= %06dmm",d);
  UART_Put_Str(UART4,txt); //串口输出
  LCD_P6x8Str(28,7,(uint8 *)txt); //LCD输出
}

    3、控制部分:舵机和电机 (1)PID代码 智能车的控制主要采用了经典的PID控制算法,分为电机速度控制和舵机方向控制。   舵机的控制是最重要的部分,是巡线的关键。通过ADC采集的三组电感的电压值来判断当前车身的状态,将当前值与期望值比较得到误差,代入增量式PID,调节出合适的参数,从而能够输出调整量使车能够始终巡线运行。   电机控制要求精度不高,只采用了PI控制,保证车速相对稳定,不至于产生太大波动,主要为了应对粗糙路面以及上下坡的情况。通过编码器传回的速度值判断当前车速,调整至稳定值。主要应用于上坡时,通过PID增大电机电流。   PID及其参数特点:  
NXP智能车竞赛笔记(室外电磁组)   增量式PID介绍:  
NXP智能车竞赛笔记(室外电磁组)   实现代码:  

typedef struct //把PID定义为结构体形式
{
  float Kp,Ki,Kd;
  float Feedback;
  float Target;
  float error0,error1,error2;
  float Output;
  float Range; //控制输出范围,防止输出过大
}Type_PID;

void PID(Type_PID* PID)
{
 PID->error0 = (PID->Target) - (PID->Feedback);
PID->Output = (PID->Kp)*(PID->error0)+PID->Kd*(PID->error0-2*PID->error1+PID->error2)+PID->Ki*(PID->error0+PID->error2); 
	//更新偏差
	PID->error2 = PID->error1;
	PID->error1 = PID->error0;
	//对PID死区控制,因输出电流太小不足以驱动电机
	if (abs(PID->Output) < 20)
		PID->Output = 0;
	PID->Output = limit(PID->Output, PID->Range, -PID->Range);//把output限制在+-range之内
}

    (2)主函数中PID代码  

//pid初始设置
pid=(Type_PID *)malloc(sizeof(Type_PID));
   memset(pid,0,sizeof(Type_PID));
   pid_speed=(Type_PID *)malloc(sizeof(Type_PID));
   memset(pid_speed,0,sizeof(Type_PID));
   //电机速度PID
   pid_speed->Kp=1;
   pid_speed->Ki=4;
   pid_speed->Range=700;
   //舵机转角PID
   pid->Kp=1.5;
   pid->Ki=0.7;
   pid->Kd=7.5;
   pid->Range=142;

    4.显示部分 (1)串口与蓝牙 蓝牙模块用的是HC-05,可以与串口共用。 下面给出库中的串口发送字符串函数,不赘述。  

//例子:uart_putchar (UART4, "123456789");实际发送9个字节
void UART_Put_Str (UARTn_e uratn, char *str) //参数: uratn:模块名如:UART0 ,str: 发送的地址   
{
    while(*str)
    {
        UART_Put_Char(uratn, *str++);
    }
}

    (2)LCD屏 列出库中函数,具体实现不赘述。  

LCD_P6x8Str(unsigned char x,unsigned char y,unsigned char *p)// 写入一组标准ASCII字符串, 显示的位置(x,y),y为页范围0~7,要显示的字符串
void LCD_P14x16Str(unsigned char x,unsigned char y,unsigned char ch[])  //输出汉字字符串

     


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明NXP智能车竞赛笔记(室外电磁组)
喜欢 (0)

您必须 登录 才能发表评论!

加载中……