《Arduino直流电机控制教程》

在这个Arduino教程中,我们将学习如何使用Arduino控制直流电机。我们来看看控制直流电机的一些基本技术,并通过两个例子,学习如何使用L298N电机驱动器和Arduino板来控制直流电机。

在以往的文章中,我们知道可以通过简单地控制输入电压来控制直流电机的速度,最常用的方法是使用PWM信号。延伸可阅读: PWM

使用PWM控制直流电机

PWM,即脉冲宽度调制技术,它是一种允许我们通过调整进入电机的电压的平均值,通过高电平和低电平的持续时间来控制电机运动的技术。平均电压取决于占空比,即信号在一段时间内打开的时间与关闭的时间之比。

脉冲宽度调制技术

因此,根据电机的大小,我们可以简单地将Arduino PWM输出连接到晶体管的底座或MOSFET的栅极,通过控制PWM输出来控制电机的速度。低功率Arduino PWM信号开关在MOSFET上,通过 PWM信号开关可驱动大功率电机。

Arduino PWM 控制直流电机

H桥直流电机控制

另一方面,为了控制电机的旋转方向,我们只需要对电流流过电机的方向进行逆转,最常用的方法是用H桥。一个H桥电路包含四个开关元件,晶体管或mosfet,形成一个类似于H的结构。通过同时激活两个特定的开关,我们可以改变电流流动的方向,从而改变电机的旋转方向。

H桥的结构

所以,如果我们把PWM和H桥这两种方法结合起来,我们就可以完全控制直流电机的运动了。有许多直流电机驱动器都具有这些特性,L298N就是其中之一。

L298N驱动模块

L298N是一个双H桥电机驱动器,它允许在同一时间,在速度和方向上对两个直流电机进行控制。该模块可以驱动电压在5 – 35V之间的直流电机,峰值工作电流可达2A。

L298N驱动模块

让我们仔细看看L298N模块的接口定义,并解释它是如何工作的。该模块包括两个 电机(A、B)的连接端子、接地GND端子、电机的VCC和一个可作为输入或输出的5V引脚, 这主要取决于在电机VCC上使用的电压,具体使用请往下看。

该模块有一个板载5V调节器,可通过跳线启用或禁用。如果电机供电电压低于12V,我们可以启用5V调节器,5V引脚可以作为输出,例如为我们的Arduino板供电;但是如果电机电压大于12V,我们必须断开跳线,因为这些电压会对板载5V调节器造成损坏。在这种情况下,5V引脚将作为输入,因为我们需要连接到5V电源,以便IC正常工作。

使用中这个集成电路的电压降大约是2V。例如,如果我们使用12V电源,电机端子的电压大约是10V,这意味着我们无法从12V直流电机中获得最大速度。

L298N的电压降

接下来是逻辑控制信号输入。使能A和使能B引脚用于使能和控制电机的速度。如果跳线出现在这个引脚上,电机将被启用并以最大速度工作,如果我们移除跳线,我们可以将PWM输入连接到这个引脚上,以这种方式控制电机的速度。如果我们把这个插针接在地GND上,马达就会不工作。

L298N的逻辑输入控制

其中,输入1和2针用于控制电动机A的转动方向,输入3和4用于控制电机B。这些插针实际上控制的是H桥的开关L298N 芯片。的控制原理是:当输入1是低,2是高马达A会向前转动,反之亦然,如果输入1高2低电机A将反方向旋转。如果两个输入都相同,无论高低电平,电机A都会停止。同样的道理也适用于输入3和4。

Arduino 上 L298N 的使用

现在让我们做一些实际的测试。在第一个示例中,我们将使用电位器控制电机的速度,并使用一个按钮改变旋转方向。这是电路原理图。

Arduino 上 L298N 的使用

测试元件包括:一个L298N驱动器,一个直流电机,一个电位器,一个按钮开关和一个Arduino板以及12V电源。

Arduino 控制代码如下

/* Arduino DC Motor Control - PWM | H-Bridge | L298N - Example 01

*/

#define enA 9

#define in1 6

#define in2 7

#define button 4

int rotDirection = 0;

int pressed = false;

void setup() {

pinMode(enA, OUTPUT);

pinMode(in1, OUTPUT);

pinMode(in2, OUTPUT);

pinMode(button, INPUT);

// Set initial rotation direction

digitalWrite(in1, LOW);

digitalWrite(in2, HIGH);

}

void loop() {

int potValue = analogRead(A0); // Read potentiometer value

int pwmOutput = map(potValue, 0, 1023, 0 , 255); // Map the potentiometer value from 0 to 255

analogWrite(enA, pwmOutput); // Send PWM signal to L298N Enable pin

// Read button - Debounce

if (digitalRead(button) == true) {

pressed = !pressed;

}

while (digitalRead(button) == true);

delay(20);

// If button is pressed - change rotation direction

if (pressed == true & rotDirection == 0) {

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

rotDirection = 1;

delay(20);

}

// If button is pressed - change rotation direction

if (pressed == false & rotDirection == 1) {

digitalWrite(in1, LOW);

digitalWrite(in2, HIGH);

rotDirection = 0;

delay(20);

}

代码解释:首先我们需要为程序定义引脚和一些变量。在 setup 部分,我们需要设置引脚模式和电机的初始旋转方向。在 loop 部分,我们首先读取电位器的值,然后将我们从电位器中得到的值,0到 1023 映射到PWM信号值 0 到 255,也就是PWM信号从0到100%的占空比。然后使用 analogWrite() 函数,发送PWM信号到L298N板的使能端,从而实现电机的驱动。接下来,检查是否按下了按钮,如果是,将通过反方向设置输入1和输入2的状态来改变电机的旋转方向。这个按钮将作为切换按钮工作,每次我们按下它,它都将改变电机的旋转方向。

Arduino采用L298N驱动机器人小车

如果我们理解了上面的知识,下面我们就可以制造自己的Arduino机器人小车了。下面是电路原理图:

Arduino采用L298N驱动机器人小车

我们需要两个直流电机,L298N驱动器,一个Arduino板和一个操纵杆Joystick。在电源方面,我选择了三节3.7V的锂离子电池作为电源,电压约11V。小车采用3毫米的胶合板做了底盘,用金属支架把电机固定在上面,把轮子连在电机上,底盘的前面安装了一个转向轮。在网上有成品底盘,例如:智能小车底盘

现在让我们看看Arduino代码,看看它是如何工作的。

int xAxis = analogRead(A0); // Read Joysticks X-axis

int yAxis = analogRead(A1); // Read Joysticks Y-axis

在loop部分定义了引脚之后,我们首先读取操纵杆X和Y轴的值。操纵杆实际上是由两个电位器连接到Arduino的模拟输入,它们的值从0到1023。当操纵杆保持在中心位置时,电位器或轴的值都在512左右。

操纵杆Joystick 模块的值

我们将增加一点公差,以470到550的值为中心。所以如果向后移动操纵杆的Y轴,数值低于470,将使用四个输入引脚将两个电机的旋转方向设置为向后。然后,我们将从470到0的下降值转换为PWM从0到255的上升值,这实际上是控制电机的速度。

// Y-axis used for forward and backward control

if (yAxis < 470)

{

// Set Motor A backward

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

// Set Motor B backward

digitalWrite(in3, HIGH);

digitalWrite(in4, LOW);

// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed

motorSpeedA = map(yAxis, 470, 0, 0, 255);

motorSpeedB = map(yAxis, 470, 0, 0, 255);

}

类似的,如果我们向前移动操纵杆的Y轴,数值超过550,我们将设置电机向前移动,并将读数从550到1023转换为PWM值从0到255。如果操纵杆保持在它的中心,电机的速度将为零。接下来,让我们看看如何使用X轴来控制小车左右转动 。

// X-axis used for left and right control

if (xAxis < 470)

{

// Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value

int xMapped = map(xAxis, 470, 0, 0, 255);

// Move to left - decrease left motor speed, increase right motor speed

motorSpeedA = motorSpeedA - xMapped;

motorSpeedB = motorSpeedB + xMapped;

// Confine the range from 0 to 255

if (motorSpeedA < 0) {

motorSpeedA = 0;

}

if (motorSpeedB > 255) {

motorSpeedB = 255;

}

}

首先,需要把X轴的读数转换成0到255之间的速度值。对于向左移动,我们使用这个值来降低左电机速度并增加右电机速度。在这里,由于算术函数,我们使用两个额外的“if”语句来限制电机速度范围从0到255。

机器人小车的左转和右转

同样的方法也适用于向右移动小车。

根据所施加的电压和采用电机本身的不同,在较低的速度下,电机无法启动,并产生嗡嗡声。在我本文的例子中,如果PWM信号的值低于70,电机就无法启动。因此,使用这两个if语句,我实际上把速度限制在70到255之间。最后,发送电机速度控制值或PWM信号到L298N驱动器的使能引脚。

// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)

if (motorSpeedA < 70) {

motorSpeedA = 0;

}

if (motorSpeedB < 70) {

motorSpeedB = 0;

}

analogWrite(enA, motorSpeedA); // Send PWM signal to motor A

analogWrite(enB, motorSpeedB); // Send PWM signal to motor B

最后附上Arduino机器人小车示例的完整代码:

*/

#define enA 9

#define in1 4

#define in2 5

#define enB 10

#define in3 6

#define in4 7

int motorSpeedA = 0;

int motorSpeedB = 0;

void setup() {

pinMode(enA, OUTPUT);

pinMode(enB, OUTPUT);

pinMode(in1, OUTPUT);

pinMode(in2, OUTPUT);

pinMode(in3, OUTPUT);

pinMode(in4, OUTPUT);

}

void loop() {

int xAxis = analogRead(A0); // Read Joysticks X-axis

int yAxis = analogRead(A1); // Read Joysticks Y-axis

// Y-axis used for forward and backward control

if (yAxis < 470) {

// Set Motor A backward

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

// Set Motor B backward

digitalWrite(in3, HIGH);

digitalWrite(in4, LOW);

// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed

motorSpeedA = map(yAxis, 470, 0, 0, 255);

motorSpeedB = map(yAxis, 470, 0, 0, 255);

}

else if (yAxis > 550) {

// Set Motor A forward

digitalWrite(in1, LOW);

digitalWrite(in2, HIGH);

// Set Motor B forward

digitalWrite(in3, LOW);

digitalWrite(in4, HIGH);

// Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed

motorSpeedA = map(yAxis, 550, 1023, 0, 255);

motorSpeedB = map(yAxis, 550, 1023, 0, 255);

}

// If joystick stays in middle the motors are not moving

else {

motorSpeedA = 0;

motorSpeedB = 0;

}

// X-axis used for left and right control

if (xAxis < 470) {

// Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value

int xMapped = map(xAxis, 470, 0, 0, 255);

// Move to left - decrease left motor speed, increase right motor speed

motorSpeedA = motorSpeedA - xMapped;

motorSpeedB = motorSpeedB + xMapped;

// Confine the range from 0 to 255

if (motorSpeedA < 0) {

motorSpeedA = 0;

}

if (motorSpeedB > 255) {

motorSpeedB = 255;

}

}

if (xAxis > 550) {

// Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value

int xMapped = map(xAxis, 550, 1023, 0, 255);

// Move right - decrease right motor speed, increase left motor speed

motorSpeedA = motorSpeedA + xMapped;

motorSpeedB = motorSpeedB - xMapped;

// Confine the range from 0 to 255

if (motorSpeedA > 255) {

motorSpeedA = 255;

}

if (motorSpeedB < 0) {

motorSpeedB = 0;

}

}

// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)

if (motorSpeedA < 70) {

motorSpeedA = 0;

}

if (motorSpeedB < 70) {

motorSpeedB = 0;

}

analogWrite(enA, motorSpeedA); // Send PWM signal to motor A

analogWrite(enB, motorSpeedB); // Send PWM signal to motor B

这就是本文的全部内容。

《Arduino直流电机控制教程》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. DOS call 中的%cd%,当前文件夹演示
  2. public void DeleteT(ListT EntityList) where T : class, new() 这是什么意思
  3. thread local storage
  4. CUDA的global内存访问的问题
  5. php头尾分离,laravel怎么做模板的头尾分离
  6. 作者:​郭海红(1987-),女,中国医学科学院医学信息研究所助理研究员。...
  7. python扩展包rediscluster集群_令人抓狂的redis和rediscluster Python驱动包的安装
  8. SAP License:SAP S/4HANA Cloud介绍
  9. Docker 安装(学习笔记一)
  10. 书还没出,已经在chinapub被虐了
  11. Delphi FastReport组件下载,包含多个版本,自己选择
  12. SeaweedFS 分布式 上传、下载、删除附件公共接口
  13. 【Python】如何实现列表的升序排列
  14. java——html
  15. Leetcode题库1823. 找出游戏的获胜者(约瑟夫环 C实现)
  16. LTE学习笔记之无线资源管理
  17. cocos3D 教程
  18. 计算机卸载一个程序正确操作,卸载一个程序我在电脑里安装了一个一个山西省计算机考试系统21 爱问知识人...
  19. 【总结】MATLAB绘制散点密度图
  20. 免费分享我的匿名邮件群发系统,可匿名发送: 163 126 139 gmail qq 21cn 263 及各类企业级邮件

热门文章

  1. ROM,PROM,EPROM,EEPROM及FLASH存储器的区别
  2. 行列式的计算方法(含四种,看完就会!)
  3. python实战扫码下载_Python实例 一 12306抢票(一)扫码登陆
  4. 学习 《模型思维》-斯科特·佩奇 笔记 9.29
  5. weiphp mysql5.1_weiphp微信公众平台 v4.0 beta
  6. Android键盘的显示和隐藏
  7. matlab实现留一交叉验证,留出法和交叉验证
  8. 关于二极管与三极管的理解——模拟电路基础
  9. 跳楼撞墙挖地道坐热气球:东德人穿越柏林墙的古怪方法
  10. intellij idea中设置mybatis的xml配置文件的背景色