arduino小车速度调节_智能小车pwm调速程序及原理图

arduino小车速度调节_智能小车pwm调速程序及原理图Arduino小车——调速篇  在这一篇我们将对小车的行进速度进行调整,将驱动模块的作用发挥出来。首先大家要了解PWM这个概念。PWM  脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

Arduino智能小车——调速篇

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

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

  在这一篇我们将对小车的行进速度进行调整,将驱动模块的作用发挥出来。首先大家要了解PWM这个概念。

PWM

  脉宽调制(PWM)基本原理:控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变逆变电路输出电压的大小,也可改变输出频率。


arduino小车速度调节_智能小车pwm调速程序及原理图

  通俗一点讲那,就是当如果我们想输出5V电压时,只需一直输出高电平即可;当我们想输出3.75V电压时,那我们就需要在一个周期内(一个高电平和一个低电平为一个周期)3.75÷5=75%时间输出高电平,25%时间输出低电平;同理,如果想输出2.5V电压时,我们需要在一个周期内50%时间输出高电平,50%时间输出低电平。


arduino小车速度调节_智能小车pwm调速程序及原理图
  Arduino UNO开发板上只有带有“~”表示的引脚才具有PWM功能,因此我们在控制驱动时可以使用这几个引脚。 ##驱动模块接线   在前面的[教程](http://blog.csdn.net/qq_16775293/article/details/77438499)中已经讲过如果想控制驱动的输出时,需要对驱动的“ENA”“ENB”进行控制,因此我们需要将图中被选中部分的两个跳线帽拔掉。并将“ENA”连接Arduino UNO开发板的“5”引脚,“ENB”连接“6”引脚。

arduino小车速度调节_智能小车pwm调速程序及原理图

代码测试

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() { 

// 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);
pinMode(leftPWM, OUTPUT);
pinMode(rightPWM, 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);
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) // 如果计时时间已达1秒
{ 
  
detachInterrupt(0); // 关闭外部中断0
detachInterrupt(1); // 关闭外部中断1
//把每一秒钟编码器码盘计得的脉冲数,换算为当前转速值
//转速单位是每分钟多少转,即r/min。这个编码器码盘为20个空洞。
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); // 重新开放外部中断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;
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智能小车——蓝牙小车》教程,修改后效果如下:


arduino小车速度调节_智能小车pwm调速程序及原理图

结束语

  大家快连接蓝牙,测试下我们的变速小车吧。大家有兴趣的话可以使用蓝牙串口助手上面的滑动条来控制小车速度,不妨下去试试吧~

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184837.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 增长黑客手册——03

    增长黑客手册——03ToB,ToC案例;增长团队的组建;用数据驱动增长的方法(三个过程、五步搭建方法)

  • vmware15激活密钥最新【2021免费激活】

    (vmware15激活密钥最新)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html4M7HSKPBXS-eyJsaWNlbnNlSWQi…

  • mysql 过滤微信昵称表情符号_js 过滤微信昵称的表情符号

    mysql 过滤微信昵称表情符号_js 过滤微信昵称的表情符号我先说一下我的解决方法://示例名称:varstr=”阿bc?d的fg?hm天l”;//将名称拆分为数组,注意:这样会将表情拆分为两项,其值为代理对.//并且因为,代理对无法被浏览器识别,所以它们的值可能会被转化为U+feffvarstrArr=str.split(“”),result=””,totalLen=0;for(varidx=0;idx<s…

    2022年10月31日
  • auto.js微信自动回复脚本_微信群助手机器人

    auto.js微信自动回复脚本_微信群助手机器人一、前言整体思路1)找到头像右上角有消息标志的聊天(注意直接跑下面代码的时候请确保聊天界面由此前提)2)点击进入聊天窗口,找到所有消息3)取最后一个消息(最新消息)4)和之前的新消息对比是否发生变化5)新消息推送至API6)收到API消息发送微信v8版本发送消息时,不再显示“发送”按钮了,也就没办法用找到“发送”控件的方法实现发送消息了。尝试用KeyCode(code)方式,发送回车键,发现也无效,原因查了一下好像是需要ROOT还是安卓9以上此方法失效。于是用坐标点击的方式点击键盘上的

  • 为eclipse安装gae插件遇到的一点小问题。

    为eclipse安装gae插件遇到的一点小问题。

  • 序列化和反序列化的底层实现原理是什么?

    序列化和反序列化的底层实现原理是什么?序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问了这一个问题,自信满满的说了一大堆,什么是序列化、什么是反序列化、什么场景的时候才会用到等,然后面试官说:那你能说一下序列化和反序列化底层是如何实现的吗?一脸懵逼,然后回家等通知!一、…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号