简洁版轮式小车走直线

该博客介绍了使用Arduino UNO板结合霍尔编码器进行电机速度控制的方法。通过外部中断捕捉编码器的AB相脉冲,计算电机转速,并根据左右轮速差调整PWM输出,以实现车轮直线行驶。虽然文中未给出实际轮速与设定轮速的修正代码,但提供了硬件连接及基本程序框架。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键词:Arduino 霍尔编码器 PWM 中断 轮速
硬件:12V直流电源(或电池)、直流电机(带霍尔编码器)、Arduino UNO板
简单原理:设定一定目标左右轮速,Arduino板根据车轮电机上霍尔编码器采集AB相脉冲数判定车轮实际轮速,根据实际左右轮速差,转换为修正左轮的轮速的PWM。
注意,本文并没有实现实际轮速与设定轮速的修正,后续会增加此部分的代码实现。
在这里插入图片描述

#include "Wire.h"            //serial
#include "I2Cdev.h"          //IIC
#include "MPU6050.h"         //acc&gyro Sensor

//把小车右侧电机的编码器OUTA信号连接到Arduino控制器的数字端口2
int PinA_right = 2; 数字端口2是Arduino的外部中断0的端口
int PinB_right = 8; //右侧电机的编码器OUTB 信号对于数字端口8
//把小车左侧电机的编码器OUTA信号连接到Arduino控制器的数字端口3
int PinA_left = 3; //数字端口3是Arduino的外部中断1的端口
int PinB_left = 10; //左侧电机的编码器OUTB 信号对于数字端口10
int E_right =5; //连接小车右侧电机的PWM控制端口到数字接口5
int M_right =4; //连接小车右侧电机的转向控制端口到数字接口4
int M_right2 =12; //连接小车右侧电机的转向控制端口到数字接口12
int E_left =6; //连接小车左侧电机的PWM控制端口到数字接口6
int M_left =7;  //连接小车左侧电机的转向控制端口到数字接口7
int M_left2 =13; //连接小车右侧电机的转向控制端口到数字接口13
int PWM_right=150;//设置电机初始PWM功率值
int PWM_left=PWM_right;
int flag;   //暂存变量,用于Arduino接受Andriod手机的控制字符
long count_right = 0;  //定义编码器码盘计数值(此编码器转一圈发出334个脉冲)
long count_left = 0;
long rpm_right = 0;    //每分钟(min)转速(r/min)
long rpm_left = 0;
unsigned long time = 0, old_time = 0;// 时间标记
 
//初始化
void setup()
{
  Wire.begin();
  Serial.begin(115200);    // 启动串口通信,波特率9600b/s
  pinMode(M_right, OUTPUT);   //直流电机驱动板的控制端口设置为输出模式
  pinMode(M_right2, OUTPUT); 
  pinMode(E_right, OUTPUT);
  pinMode(M_left, OUTPUT);
  pinMode(M_left2, OUTPUT);  
  pinMode(E_left, OUTPUT);
  pinMode(PinA_right,INPUT); //伺服电机编码器的OUTA和OUTB信号端设置为输入模式
  pinMode(PinB_right,INPUT);
  pinMode(PinA_left,INPUT);
  pinMode(PinB_left,INPUT);
  //定义外部中断的中断子程序Code(),中断触发为下跳沿触发
  //当编码器码盘的正交编码板OUTA脉冲信号发生下跳沿中断时,
  //将自动调用执行中断子程序Code()。
  attachInterrupt(0, Code_right, FALLING);
  attachInterrupt(1, Code_left, FALLING);
}
//对直流电机驱动板的使能端口和转向端口进行设置,以使小车
//执行前进、后退、左转、右转、停止和速度切换动作。
void advance()//小车前进
{ 
     digitalWrite(M_right,HIGH);
     digitalWrite(M_right2,LOW);
     analogWrite(E_right,PWM_right);
     digitalWrite(M_left,HIGH);
     digitalWrite(M_left2,LOW);
     analogWrite(E_left,PWM_left);
}

//主程序
void loop()
{
  //Serial.print("Advance!\t");
  advance();       //小车前进 
  time = millis();//以毫秒为单位,计算当前时间
  //计算出每0.5秒钟内,编码器码盘计得的脉冲数,
  if(abs(time - old_time) >= 500) // 如果计时时间已达0.5秒
  {
    detachInterrupt(0); // 关闭外部中断0
    detachInterrupt(1); // 关闭外部中断1  
     //此直流减速电机的编码器码盘为334个齿,减速比为21.3。
    //把编码器每0.5秒钟计得的脉冲数,换算为当前转速值的计算式 
    rpm_right =(float)count_right*60*2/(334*21.3);
    rpm_left =(float)count_left*60*2/(334*21.3); 
    //根据左右车轮转速差,乘以比例调节因子2,获得比例调节后的左侧电机PWM功率值
    PWM_left=(float)PWM_left+(rpm_right-rpm_left)*2;      
//根据刚刚调节后的小车电机PWM功率值,
//及时修正小车前进或者后退状态,以使小车走直线
  
    count_right = 0;   //把脉冲计数值清零,以便计算下一个0.5秒的脉冲计数
    count_left = 0; 
    old_time=  millis();     // 记录每次0.5秒测速后的时间节点    
    attachInterrupt(0, Code_right,FALLING); // 重新开放外部中断0
    attachInterrupt(1, Code_left,FALLING); // 重新开放外部中断1
  }
}
 
//右侧电机编码器码盘计数中断子程序
void Code_right()
{  
  count_right += 1; // 编码器码盘计数加一
  Serial.print("count_right\t");
  Serial.print(count_right);
  Serial.print("\n");
  
}
//左侧电机编码器码盘计数中断子程序
void Code_left()
{ 
  count_left += 1; // 编码器码盘计数加一
  Serial.print("count_left\t");
  Serial.print(count_left);
  Serial.print("\n");   
}
前言: 开始之前先要说为什么要采用PID的算法来控制小车。玩过小车的DIY爱好者们都会碰到这样一种情况:为什么本该直线行驶的小车着轨迹就会发生偏移,即所谓的“不直”。 小车不直的原因有:两个电机本身的驱动特性不可能完全相同,两个电机外形大小不可能是完全一致,组装时精度也会出现差异,另外轮胎在滚动时打滑、遇到细小的障碍物等因素都会造成左右轮的速度出现差异,从而不直。开环控制是无法消除左右轮的速度误差的,因为上述的扰动是随机的。 要想小车一条直线,唯有实现闭环控制,当小车受到扰动时能对左右轮及时给予反馈,修正两轮的速度偏差,从而可以出一条直线。PID算法就是一种闭环控制算法,实现PID算法需得从硬件上实现闭环控制,即存在反馈,所以我采用的是带测速装置的电机。 项目简介: 本项目采用的是PID控制算法来修正小车两轮的速度偏差,实现小车可以直线小车是使用一个安卓App来控制小车的行路径,App通过App Inventor2来进行编写。 完成作品图: 需要用到的材料: 1. Arduino Uno 2. Arduino Uno的扩展板 3. DFRobot L298 双路2A直流电机驱动板 4. HC-05或HC-06的蓝牙模块 5. 坦克小车底盘 6. 两个带霍尔传感器的电机 7. 锂电池 8. 杜邦线若干 软件部分: 1. Arduino IDE 2. App Invent 附件内容截图:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值