开始前的准备——Arduino小车配置探究

为对PID调速进行学习研究,笔者采用了由南京嵌入之梦提供的单轮驱动小车平台,以此作为接下来进行PID学习的一个载体。在开始一切工作前,首先需要对手上的这个小车本身的特点以及开发方式进行探究。本文就是建立在笔者这两天以来对小车的探索下写的。


首先需要介绍一下小车的硬件配置。如上图所示,这是一个单轮驱动的小车,它的主要部件包含了一个控制转向的舵机,一个将轮子、电机、电机驱动、码盘反馈、电流检测等驱动相关的内容集成在一起的轮式驱动单元部件,控制板采用连接了Arduino扩展板的nano控制板,还以组成小车车架的有机玻璃结构以及从动轮等部件。

小车的舵机选用的是300°的数字舵机,主要用于控制小车的转向用,因此只要廉价好用就完全可以满足一般的需求。舵机的转动角度是靠控制输出PWM波的占空比来实现的。标准的PWM信号周期为20ms,因此通过调整PWM占空比就可以实现转动角控制。而此小车的控制板为Arduino板,在官方提供的库文件中包含了控制舵机的库文件Servo,在实际操控中只要调用该库中的函数便可以实现对舵机的控制,大大简化了舵机的控制难度。

小车的轮式驱动单元包含了电机、电机驱动、码盘反馈等内容。小车的车轮上集成了一百尺的简易码盘,与遮断式光电采样器配合,用于采集码盘信号进行测速。电机采用直流减速电机,控制小车的前进后退。此外,笔者也取得了与该轮式驱动单元配套的库文件,通过简单的调用函数便可实现对小车行进的编程控制。

接下来笔者将通过编写一个简单的程序,实现小车运动的简单控制和码盘测速功能,以此来说明小车的软件配置方法,以及介绍 用到库中的函数。首先,因为小车的控制器是Arduino nano板,因此需要用Arduino IDE进行编程和编译上传。在程序的开始,需要引入两个头文件

#include < Servo.h >
#include < YM3Wheel.h >

在包含的头文件中,第一个Servo文件是Arduino官方提供的舵机控制文件,第二个文件是随小车提供的轮式驱动单元库文件,使用时需要先将库文件拷贝到Arduino IDE的libraries目录中。

在Arduino nano板上有4个LED灯,其中标记为L的LED灯与Pin13相连,常用于检测板子是否正常工作,因此笔者在所有函数体之外先进行如下定义

int LED = 13;
boolean LED_On;            
int FlashTime = 500ms;

官方提供的Servo舵机库文件仅可以使用Pin9或Pin10控制舵机,因此在该小车上,舵机与nano板的Pin10相连。使用Servo库,需要先声明一个Servo类型的类,把它作为进行控制的对象。

int ServoPWM = 10;
Servo myServo;

我们还需要对轮式驱动单元进行设置。轮式驱动单元库文件中定义了一个名为YM3_Motor的类,以及一个构建函数YM3_Motor(unit8_t freq),其中freq是PWM频率,可支持的值有MOTORPWM_64KHZ、MOTORPWM_8KHZ、MOTORPWM_1KHZ,这些常量的具体值在库文件中已宏定义过,可直接使用。为了不影响舵机的驱动,笔者选择MOTORPWM_1KHZ。

YM3_Motor YM3(MOTORPWM_1KHZ);



接下来需要编写void setup(){}函数体中的代码。在Arduino中程序运行时将首先调用 setup() 函数。用于初始化变量、设置针脚的输出\输入类型、配置串口等等。每次 Arduino 上电或重启后,setup 函数只运行一次。在setup()函数体中,需要对连接LED引脚的工作模式、轮式驱动单元的初始状态、舵机接口以及串口波特率进行设置。同时还需要设置用于码盘测速的中断。

void setup() {
  pinMode(LED, OUTPUT);                     

  YM3.run(RELEASE, 0);                 
  attachInterrupt(ENCODE_INT,pulseSample, FALLING);
                                             
  myServo.attach(ServoPWM);          
  Serial.begin(9600);
}


连接LED灯的13号引脚用Arduino库自带的pinMode(引脚号,模式) 函数来设置引脚工作模式,函数的第一个参数为引脚号,第二个参数可选OUTPUT(输出模式)和INPUT(输入模式),此处设置为输出模式。

之前定义的轮式驱动单元类YM3的成员函数有run(uint8_t cmd, uint8_t pwm) 该函数为电机运行函数,第一个参数为电机运行模式,支持的四个模式为FORWARD(前进)、BACKWARD(后退)、BRAKE(刹车)、RELEASE(惰行)。第二个参数为pwm值,范围为0~255,与Arduino的模拟输出一致。在初始化中,笔者将电机工作模式设置为惰行模式,pwm设为0。

舵机的接口设置函数attach()的参数是与舵机相连的引脚号,使用Arduino舵机库可选的引脚只有9和10,此处直接按照之前的设置填写即可。

设置Arduino串口波特率的函数为Serial.begin(),参数为波特率大小,此处将波特率设置为9600。

为了实现码盘检测,还需要设置外部中断。这辆小车实现码盘检测的方法是将码盘输出信号与数字引脚Pin2相连,通过外部中断触发码盘脉冲计数函数,每当光电采样器经过一个码盘的齿,则触发一次中断,在中断函数中实现脉冲数加一,再退出中断。Arduino设置外部中断的函数为attachInterrupt(interrupt, function, mode)。第一个参数为中断引脚数,大多数的Arduino板有两个外部中断0和1,分别对应着数字引脚pin2和pin3。第二个参数为调用的中断函数名,第三个参数为触发中断的情形。mode可选的有LOW、CHANGE、RISING、FALLING。小车的轮式驱动单元的码盘输出线与Pin2相连,因此第一个参数填ENCODE_INT,该常量已在轮式单元库文件中经宏定义为0。第二个参数填写的中断函数名为pulseSample,该函数的功能为码盘检测,将在整个程序的最后给出。第三个参数填写的为FALLING,意味着当中断引脚电平由高到低发生变化时才触发中断。码盘输出电平高低随着光电采样器遮光漏光而变化,每经过一个齿,则由高到低变化一次,触发一次中断。


接下来编写程序执行的主体部分void loop(){},该部分类似于c/c++里的int main()函数。在实际执行过程中,程序将在这个函数中循环执行。

void loop() {
  myServo.write(98);
  YM3.run(FORWARD, 200);

  int pulseInterval = 0;
  float speed = 0;

  while(1) {
    pulseInterval = YM3.pulseSample();
    digitalWrite(LED, LED_On);
    delay(SAMPLE_DELAY);

    pulseInterval = YM3.pulseSample() - pulseInterval;
    speed = pulseInterval * 2.5133 / SAMPLE_DELAY * 1000;
    LED_On = !LED_On;
    
    Serial.println(speed);
  }


 首先调用myServo的成员函数write(),参数为转角,这里把它定为98。接着设置轮式驱动单元的电机运行方式,调用run()函数,这里设置为前进,pwm值设定为200。 

定义四个变量,用于码盘测速计算。

因本程序要达到的功能为简单的小车运行控制和码盘测速,前一部分已经实现了小车的方向控制和电机运行方式控制,接下来编写一个while()循环来实现简单的码盘测速功能。轮式驱动单元库文件中包含了一个码盘采样处理函数pulseSample(void),若没有设置行进距离,则该函数返回累计行走的脉冲数。循环体中首先将已经行经的脉冲数返回给变量pulseInterval,同时将LED灯用digitalWrite()函数点亮。接着设定延迟时间的毫秒数为SAMPLE_DELAY,在本程序的开头对该常量进行宏定义为500。延迟过后再次将此时的脉冲总数减延迟之前的pulseInterval的值赋给pulseInterval,即500毫秒进行一次码盘测速。因为小车轮式驱动单元的车轮直径为80mm,码盘齿数为100,所以每经过一齿,小车行进2.5133mm,计算得小车的速度并赋值给变量speed,单位为mm/s。同时改变LED灯的状态,在进入下一次循环时改变LED亮灭。此时得到了小车的速度,用serial.println()函数将速度发送到串口。

因为小车码盘检测调用了中断函数pulseSample(),因此还需要添加一段中断函数代码。该中断函数在轮式驱动单元库中已经给出,此处仅需写下如下代码即可:

 void pulseSample(void)
 {
   YM3.pulseSample();
 }
值得注意的是,外部中断函数必须为无参数无返回值的函数。


至此,一个简单的能控制小车运动和测速的程序已经写好啦,同时也为接下来的PID调速做好了初步的准备工作。由于笔者是第一次真正接触这种小车以及Arduino控制板,所以即便如此也花费了许多功夫。小车的轮式驱动单元库中还有一些其他实用的函数,没有在本文以上内容中提到,笔者将在之后进行PID调速的文章中进行介绍。


作为一名初学者写的文章,难免会有不正确之处,还望各位前辈能耐心指出,感谢!





学习Arduino有段时间了,也看了很多东西,所以打算最近做了一辆3轮的智能车。 Arduino智能车制作配件 3轮小车底盘(能安装UNO、带其他配件) 1块 UNO控制板 1块 Arduino电机驱动 1块 UNO扩展板 1块 7.4V充电锂电池(充电器) 1块 电源端转DC端口线 1块 超声波云台(包含超声波、舵机及固定支架) 1块 LCD12864液晶显示器 1块 测速模块 2块 杜邦线(连接模块) 20根左右 焊接导线(连接电机及点击驱动) 6根左右 铜柱螺丝(必要时加高) 热缩管+扎带+黑胶布 工具:烙铁、锡丝、斜口钳或者剪刀、打火机(热缩管用)、螺丝刀 小车所用到的装备: 1、首先当然是小车底盘了,我用的是3轮小车底盘,带开关(很方便); 2、控制板(我用的是UNO兼容版),电机驱动,扩展板(方便用杜邦线,VCC及GND也很多);3块板子可以直接插在一起,节省了很多空间,如下图: 3、供电电源,我使用的是7.4V充电锂电池加DC转接头,当然还有充电器~~如下图: 4、超声波舵机云台,如图: 5、显示模块LCD12864,我的买回来后又加工了一次,原来是直排针(不太还接线),将它改成弯排针了,如下图: 6、最后就是测速模块,现在还没调试到它,但是已经将它安装在小车上;还有些配件:螺丝、铜柱、杜邦线等,还有些简单的工具:烙铁、螺丝刀什么的;我还有用扎带,热缩管,这样小车看起来会更美观! 超声波使用的是 A2 和A3脚,这个自行定义也可以的!我使用的扩展板上就有这个接口舵机使用的是D13 12864 使用的是杜邦线连接的,引脚使用下面也有! 所有的连接方式都有写到程序中,打开一看就知道了! Arduino避障小车 電路連接: D3、D4和D6、D7分别连接左右电机,控制电机 超聲波連接: VCC ---- +5V;Trig ---- A2;Echo ---- A3;GND ---- GND; 舵機控制:D13 LCD12864引脚连接: RS ---- D2;R/W ---- D8;E ---- D9;PCB ---- GND;VSS ---- GND;VDD ---- VCC;LED+ ---- VCC;LED- ---- GND;
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值