Arduino智能小车——小车测速

Arduino智能小车——小车测速

Arduino智能小车系列教程时空门:

  1. Arduino智能小车——拼装篇 点击跳转
  2. Arduino智能小车——测试篇 点击跳转
  3. Arduino智能小车——调速篇 点击跳转
  4. Arduino智能小车——超声波避障 点击跳转
  5. Arduino智能小车——蓝牙小车 点击跳转
  6. Arduino智能小车——循迹篇 点击跳转
  7. Arduino智能小车——小车测速 点击跳转

  可以用于测速的模块很多,比如加速度计、激光、超声波、编码器等等,由于我们对小车速度的测量精度要求不高,因此我们可以借助小车套件里面的码盘配上测速模块对其速度进行测量。
##准备材料
测速模块
  网上的测速模块有很多种外观,但是其工作原理类似,下面列出来了几种常见的测速模块,这些测速模块接线类似。

  以上两种模块只能对一路电机的速度进行测量,下面这个可以同时测量两路电机,但是由于其间距固定,在安装时可能不兼容不同小车底盘,因此为了安装方便,在此篇教程中使用第一种模块。

固定铜柱

  建议铜柱长度30CM,大小为M3

  由于铜柱导电,有些电路板如果固定孔设计不当的话很容易导致电路板烧坏,尤其是在以后的项目中可能会用到更高的电压,因此在这里我建议大家可以准备一些尼龙柱来固定电路板。尼龙柱的尺寸跟铜柱尺寸相同M3,30CM。大家也可以顺便买一点尼龙螺丝。

  除此之外还需要准备杜邦线

测速模块的安装

  驱动模块的安装需要由尼龙柱支撑

  驱动模块安装时需要注意,不能影响轮子的正常工作,不能触碰到轮轴上的码盘。
  编码器上有三个引脚分别是“VCC”,“GND”,“OUT”。左右两边两个测速模块的“VCC”引脚接电源或开发板的“5V”或“3.3V”引脚,“GND”接电源或开发板的“GND”引脚,左边测速模块“OUT”接开发板的“3”引脚,右边测速模块“OUT”接开发板的“2”引脚。引脚接错的话可以再随后调试过程中换过来,也可以在代码里更改。
  最终接线图如下:

测速模块讲解

  测速模块的工作原理比较简单,如下图所示,在于电机同轴的码盘上有很多开孔(光栅),编码器相当于光敏元件。码盘随着小车轮子的运动转动时,码盘(光栅)会不断遮挡光敏元件发出的光波,这时候编码器就会根据光栅的遮挡不断的产生方波信号,方波信号会从“OUT”引脚输出,我们只需不断检测“OUT”引脚的输出,根据方波信号的周期简介计算出小车运行的速度。小车上使用的码盘(光栅)精度不高,在某些高精度的编码器上光栅会更加密集,测量效果会更好。

  由于要不断检测编码器输出端的输出,因此我们需要借助Arduino的外部中断来读取编码器的输出。Arduino开发板外部中断对应的引脚如下:
型号int0int1int2int3int4int5
UNO\Ethernet23
Mega25602321201918
Leonardo3201
DueAllAllAllAllAllAll

  由表中可以知道在此我们使用的Arduino UNO只有“2”,“3”引脚可以触发外部中断,因此在接线的时候我们便将左右两边的输出“OUT”引脚分别接在“2”“3”引脚上。
  在程序初始化阶段中调用函数attachInterrupt(interrupt, function, mode)可以对中断引脚初始化,其中
interrupt: 要初始化的外部中断编号,由上表可知我们Arduino UNO只能使用外部中断0和外部中断1;
function: 中断服务函数的名字,即当外部中断被触发时,将会自动调用这个函数;
mode: 中断触发的方式,可选方式如下

mode含义
LOW低电平触发
CHANGE电平变化,高电平变低电平、低电平变高电平
RISING上升沿触发
FALLING下降沿触发
HIGH高电平触发(该中断模式仅适用于Arduino due)

测试代码如下

int leftCounter=0,  rightCounter=0;
unsigned long time = 0, old_time = 0; // 时间标记
unsigned long time1 = 0; // 时间标记
float lv,rv;//左、右轮速度

#define STOP      0
#define FORWARD   1
#define BACKWARD  2
#define TURNLEFT  3
#define TURNRIGHT 4

int leftMotor1 = 4;
int leftMotor2 = 5;
int rightMotor1 = 6;
int rightMotor2 = 7;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
  attachInterrupt(0,RightCount_CallBack, FALLING);
  attachInterrupt(1,LeftCount_CallBack, FALLING);

  pinMode(leftMotor1, OUTPUT);
  pinMode(leftMotor2, OUTPUT);
  pinMode(rightMotor1, OUTPUT);
  pinMode(rightMotor2, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  SpeedDetection();
  if(Serial.available()>0)
  {
    char cmd = Serial.read();
  
    Serial.print(cmd);
    motorRun(cmd);
      
  }  
}
/*
 * *速度计算
 */
bool SpeedDetection()
{
  time = millis();//以毫秒为单位,计算当前时间 
  if(abs(time - old_time) >= 1000) // 如果计时时间已达1秒
  {  
    detachInterrupt(0); // 关闭外部中断0
    detachInterrupt(1); // 关闭外部中断1
    //把每一秒钟编码器码盘计得的脉冲数,换算为当前转速值
    //转速单位是每分钟多少转,即r/min。这个编码器码盘为20个空洞。
    lv =(float)leftCounter*60/20;//小车车轮电机转速
    rv =(float)rightCounter*60/20;//小车车轮电机转速
    Serial.print("left:");
    Serial.print(lv);//向上位计算机上传左车轮电机当前转速的高、低字节
    Serial.print("     right:");
    Serial.println(rv);//向上位计算机上传左车轮电机当前转速的高、低字节
    //恢复到编码器测速的初始状态
    leftCounter = 0;   //把脉冲计数值清零,以便计算下一秒的脉冲计数
    rightCounter = 0;
    old_time=  millis();     // 记录每秒测速时的时间节点   
    attachInterrupt(0, RightCount_CallBack,FALLING); // 重新开放外部中断0
    attachInterrupt(1, LeftCount_CallBack,FALLING); // 重新开放外部中断0
    return 1;
  }
  else
    return 0;
}
/*
 * *右轮编码器中断服务函数
 */
void RightCount_CallBack()
{
  rightCounter++;
}
/*
 * *左轮编码器中断服务函数
 */
void LeftCount_CallBack()
{
  leftCounter++;
}
/*
 * *小车运动控制函数
 */
void motorRun(int cmd)
{
  switch(cmd){
    case FORWARD:
      Serial.println("FORWARD"); //输出状态
      digitalWrite(leftMotor1, HIGH);
      digitalWrite(leftMotor2, LOW);
      digitalWrite(rightMotor1, HIGH);
      digitalWrite(rightMotor2, LOW);
      break;
     case BACKWARD:
      Serial.println("BACKWARD"); //输出状态
      digitalWrite(leftMotor1, LOW);
      digitalWrite(leftMotor2, HIGH);
      digitalWrite(rightMotor1, LOW);
      digitalWrite(rightMotor2, HIGH);
      break;
     case TURNLEFT:
      Serial.println("TURN  LEFT"); //输出状态
      digitalWrite(leftMotor1, HIGH);
      digitalWrite(leftMotor2, LOW);
      digitalWrite(rightMotor1, LOW);
      digitalWrite(rightMotor2, HIGH);
      break;
     case TURNRIGHT:
      Serial.println("TURN  RIGHT"); //输出状态
      digitalWrite(leftMotor1, LOW);
      digitalWrite(leftMotor2, HIGH);
      digitalWrite(rightMotor1, HIGH);
      digitalWrite(rightMotor2, LOW);
      break;
     default:
      Serial.println("STOP"); //输出状态
      digitalWrite(leftMotor1, LOW);
      digitalWrite(leftMotor2, LOW);
      digitalWrite(rightMotor1, LOW);
      digitalWrite(rightMotor2, LOW);
  }
}

  看了这个代码大家应该就明白为什么之前我建议大家将每个功能都封装成函数了,封装成函数很利于程序的移植。

测速效果

  借助于蓝牙串口助手我们可以清楚的看到小车左右轮的转速如图,由于电机自身的误差和摩擦力的作用,因此两个轮子的转速不相等,但是差别不是很大。

欢迎各位有兴趣的朋友加入Q群1:789127261点评、交流

Arduino智能⼩车——拼装篇 Arduino智能⼩车——拼装篇 Arduino智能⼩车系列教程时空门: 1. Arduino智能⼩车——拼装篇 2. Arduino智能⼩车——测试篇 3. Arduino智能⼩车——调速篇 4. Arduino智能⼩车——超声波避障 5. Arduino智能⼩车——蓝⽛⼩车 6. Arduino智能⼩车——循迹篇 7. Arduino智能⼩车——⼩车测速 ⽂章⽬录 简介 Arduino是⼀款便捷灵活、⽅便上⼿的开源电⼦原型平台,⽐较适合刚接触硬件的⼊门级开发者学习。在我⾝边有很多初学者都陷⼊了这么 ⼀种困境,已经将Arduino官⽹的教程全部跑完,然⽽还是没有太⼤的成就感,看到⽹上⼤神们基于Arduino各种各样的开发很羡慕,想动 ⼿做⼩项⽬⼜不知从何下⼿。由于⽹上较少看到完整项⽬开发流程,作为⼀个有较多嵌⼊式开发经验的"⽼江湖",在此想⾃⼰综合⾃⼰的 多年的开发经验,为以后的新⼈铺⼀条路。 作为Arduino的第⼀个项⽬,我⽐较建议朋友们去做⼀下智能⼩车。优点如下: 1.可以熟悉做项⽬的⼤概流程,为以后的开发⽣涯奠定基础; 2.需要⾃⼰动⼿拼装制作,完成后有满满的成就感; 3.⼩车作为⼀个基本的开发平台,可以在上⾯搭建各种传感器,⾃定义功能; 4.相对于四旋翼等安全系数⾼,技术能⼒要求较低,适合初学者; 初学的朋友们⼊⼿⼀套智能⼩车套件,某宝上搜智能⼩车可以看到很多,再根据需要购买⼀些模块。 我们准备制作的⼩车终极 形态就类似这种,觉得很帅的话就快开始动⼿做吧!!! 准备材料 智能⼩车的基本构成组件如下: ⼩车套件: 驱动模块:(在此我选⽤⽐较经典的驱动模块L298N,该驱动可以满⾜我们的需求,也可以把电池的⾼电压转换为我们需要的5V,3.3V电 压) 电池:(在此我选⽤的电池型号是18650) 电池座:(电池座⼀定要选取与电池型号相匹配) 当然Arduino板⼦也肯定必不可少,在此我使⽤的是Arduino UNO,其他版本的Arduino也可以参照该教程 做项⽬开发肯定少不了电烙铁,焊锡,电源线,杜邦线,排针,排插这些基本⼯具。 ⾄此,所需的基本材料已经准备完毕,接下来就可以进⾏⼩车的拼装了。 拼装步骤 电机线的焊接 套件中的电机⼀般都是没有连线的,我们需要⾃⼰动⼿把准备好的电源线固定在电机上,⼀般不建议直接把电源线绑在电机上,这样会经常 导致⼩车的电机接触不良,因此我建议⼤家把电源线直接焊在电机上。 电机固定 将上图所⽰的电机固定架插⼊⼩车底盘底板中,⼀般⼩车有上下两个底板,任意拿⼀块即可当做底板。 再将焊接好的电机配套另外⼀个固定架固定在底板上。 同样固定其他三个电机 安装背板⽀柱 安装背板 ⼀般套件都会提供六根铜柱,我们将其固定在⼩车的周围。 安装轮⼦ 总结 ⾄此⼩车的基本拼装已经完成,⼩车驱动、电池等其他模块的安装,以及⼩车的调试将在接下来的教程中为⼤家依次讲解。 欢迎各位朋友添加Q群交流:789127261
学习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;
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值