Arduino智能小车——调速篇
Arduino智能小车系列教程时空门:
Arduino智能小车——拼装篇 点击跳转Arduino智能小车——测试篇 点击跳转Arduino智能小车——调速篇 点击跳转Arduino智能小车——超声波避障 点击跳转Arduino智能小车——蓝牙小车 点击跳转Arduino智能小车——循迹篇 点击跳转Arduino智能小车——小车测速 点击跳转
文章目录
Arduino智能小车——调速篇PWM代码测试修改蓝牙串口助手结束语
在这一篇我们将对小车的行进速度进行调整,将驱动模块的作用发挥出来。首先大家要了解PWM这个概念。
PWM
脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变逆变电路输出电压的大小,也可改变输出频率。
通俗一点讲那,就是当如果我们想输出5V电压时,只需一直输出高电平即可;当我们想输出3.75V电压时,那我们就需要在一个周期内(一个高电平和一个低电平为一个周期)3.75÷5=75%时间输出高电平,25%时间输出低电平;同理,如果想输出2.5V电压时,我们需要在一个周期内50%时间输出高电平,50%时间输出低电平。
Arduino UNO开发板上只有带有“~”表示的引脚才具有PWM功能,因此我们在控制驱动时可以使用这几个引脚。 ##驱动模块接线 在前面的[教程](http://blog.csdn.net/qq_16775293/article/details/77438499)中已经讲过如果想控制驱动的输出时,需要对驱动的“ENA”“ENB”进行控制,因此我们需要将图中被选中部分的两个跳线帽拔掉。并将“ENA”连接Arduino UNO开发板的“5”引脚,“ENB”连接“6”引脚。
代码测试
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
#define CHANGESPEED 5
int leftMotor1
= 16;
int leftMotor2
= 17;
int rightMotor1
= 18;
int rightMotor2
= 19;
bool speedLevel
=0;
int leftPWM
= 5;
int rightPWM
= 6;
void setup() {
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
);
pinMode(leftPWM
, OUTPUT
);
pinMode(rightPWM
, OUTPUT
);
}
void loop() {
SpeedDetection();
if(Serial
.available()>0)
{
char cmd
= Serial
.read();
Serial
.print(cmd
);
motorRun(cmd
);
if(speedLevel
)
{
analogWrite(leftPWM
, 120);
analogWrite(rightPWM
, 120);
}
else
{
analogWrite(leftPWM
, 250);
analogWrite(rightPWM
, 250);
}
}
}
bool
SpeedDetection()
{
time
= millis();
if(abs(time
- old_time
) >= 1000)
{
detachInterrupt(0);
detachInterrupt(1);
Serial
.print("left:");
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
);
attachInterrupt(1, LeftCount_CallBack
,FALLING
);
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;
case CHANGESPEED
:
Serial
.println("CHANGE SPEED");
if(speedLevel
)
speedLevel
=0;
else
speedLevel
=1;
break;
default:
Serial
.println("STOP");
digitalWrite(leftMotor1
, LOW
);
digitalWrite(leftMotor2
, LOW
);
digitalWrite(rightMotor1
, LOW
);
digitalWrite(rightMotor2
, LOW
);
}
}
由于之前设计不太合理,占用了太多的PWM引脚,因此在代码里对控制小车电机的引脚做了点小改动,如下所示
int leftMotor1 = 5;
int leftMotor2 = 6;
int rightMotor1 = 7;
int rightMotor2 = 8;
现在改为
int leftMotor1 = 16;
int leftMotor2 = 17;
int rightMotor1 = 18;
int rightMotor2 = 19;
改完代码大家记得要把对应的接线也改过来哦!! 在前面的宏定义中加入换挡的定义#define CHANGESPEED 5
#define STOP 0
#define FORWARD 1
#define BACKWARD 2
#define TURNLEFT 3
#define TURNRIGHT 4
#define CHANGESPEED 5
Arduion的PWM引脚需要和正常引脚一样,在void setup()函数中初始化为输出模式
pinMode(leftPWM
, OUTPUT
);
pinMode(rightPWM
, OUTPUT
);
在小车的控制状态函数void motorRun(int cmd)中添加多一个选择项,用来切换速度。
case CHANGESPEED
:
Serial
.println("CHANGE SPEED");
if(speedLevel
)
speedLevel
=0;
else
speedLevel
=1;
break;
在主函数void loop()中添加PWM输出的函数,analogWrite(pin, value)函数中“pin”代表使用的引脚,“value”代表输出PWM值的大小,范围是0~255。
if(speedLevel
)
{
analogWrite(leftPWM
, 120);
analogWrite(rightPWM
, 120);
}
else
{
analogWrite(leftPWM
, 250);
analogWrite(rightPWM
, 250);
}
修改蓝牙串口助手
在串口助手中,将“按键1”修改为“换挡”键,蓝牙串口助手的使用方法和使用详细的修改过程可以参考前面的《Arduino智能小车——蓝牙小车》教程,修改后效果如下:
结束语
大家快连接蓝牙,测试下我们的变速小车吧。大家有兴趣的话可以使用蓝牙串口助手上面的滑动条来控制小车速度,不妨下去试试吧~
欢迎各位有兴趣的朋友加入Q群1:789127261点评、交流