风筝
发表于: 2018-11-7 22:28:49 | 显示全部楼层

在本篇文章中,我们将学习到如何使用Arduino开发板控制直流电机。我们将看看控制直流电机的一些基本技术,然后列举两个例子,通过例子我们将学习到如何使用L298N驱动器和Arduino开发板控制直流电机。我们可以通过简单地控制电机的输入电压来控制直流电机的速度,最常用的方法是使用PWM信号。

DC-Motor-Speed-Control-Input-Voltage.png


PWM直流电机控制

PWM或脉冲宽度调制技术允许我们通过快速打开和关闭电源来调整流向电子设备的电压的平均值。平均电压取决于占空比,或信号开启的时间量与信号在单个时间段内关闭的时间量之间的关系。

PWM-Working-Principle-Pulse-Width-Modulation-How-It-Works.png

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

Arduino-PWM-DC-Motor-Control-Circuit-Diagram.png

注意:Arduino GND和电机电源GND应连接在一起。


H桥直流电机控制

另一方面,为了控制旋转方向,我们只需要反转通过电机的电流方向,最常用的方法是使用H桥。 H桥电路包含四个开关元件、晶体管或MOSFET,电机位于中心,形成类似H的配置。通过同时激活两个特定开关,我们可以改变电流的方向,从而改变电机的旋转方向。

H-Bridge-configuration-How-It-Works.png

因此,如果我们将这两种方法(PWM和H桥)结合起来,我们就可以完全控制直流电机。有许多直流电机驱动器具有这些功能,而L298N就是其中之一。


L298N驱动程序

L298N是一款双H桥电机驱动器,可同时控制两个直流电机的速度和方向。该模块可以驱动电压在5到35V之间的直流电机,峰值电流高达2A。

L298N-Dual-H-Bridge-Motor-Driver.jpg

让我们仔细看看L298N模块的引出线,并解释它是如何工作的。该模块有两个用于电机A和B的螺钉接线端子,另一个用于接地引脚的螺钉接线端子,用于电机的VCC和一个5V引脚,可以是输入或输出。

L298N-Pinout.png

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


我们在这里可以注意到,该IC产生的电压降约为2V。因此,例如,如果我们使用12V电源,电机端子的电压将约为10V,这意味着我们将无法从12V直流电机获得最大速度。

L298N-voltage-drop.png

接下来是逻辑控制输入。 Enable A和Enable B引脚用于启用和控制电机的速度。如果此引脚上有跳线,电机将启用并以最大速度工作,如果我们移除跳线,我们可以将PWM输入连接到此引脚,从而控制电机的速度。如果我们将此引脚连接到地,则电机将被禁用。

L298N-Block-Diagram-Current-Flow-How-It-Works.png

接下来,输入1和输入2引脚用于控制电机A的旋转方向,以及电机B的输入3和4。使用这些引脚,我们实际控制L298N IC内部的H桥开关。如果输入1为低电平且输入2为高电平,则电机将向前移动,反之亦然,如果输入1为高电平且输入2为低电平,则电机将向后移动。如果两个输入相同,无论是低电平还是高电平,电动机都将停止。这同样适用于输入3和4以及电机B。


Arduino和L298N

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

Arduino-and-L298N-Circuit-Diagram-DC-Motor-Control.png

以下是本示例所需的组件:

●    L298N驱动芯片

●    12V高扭矩直流电机

●    Arduino开发板

●    面包板和跳线


Arduino代码

以下是本例中的Arduino代码:

  1. /*  Arduino DC Motor Control - PWM | H-Bridge | L298N  -  Example 01
  2.     by Dejan Nedelkovski, www.HowToMechatronics.com
  3. */
  4. #define enA 9
  5. #define in1 6
  6. #define in2 7
  7. #define button 4
  8. int rotDirection = 0;
  9. int pressed = false;
  10. void setup() {
  11.   pinMode(enA, OUTPUT);
  12.   pinMode(in1, OUTPUT);
  13.   pinMode(in2, OUTPUT);
  14.   pinMode(button, INPUT);
  15.   // Set initial rotation direction
  16.   digitalWrite(in1, LOW);
  17.   digitalWrite(in2, HIGH);
  18. }
  19. void loop() {
  20.   int potValue = analogRead(A0); // Read potentiometer value
  21.   int pwmOutput = map(potValue, 0, 1023, 0 , 255); // Map the potentiometer value from 0 to 255
  22.   analogWrite(enA, pwmOutput); // Send PWM signal to L298N Enable pin
  23.   // Read button - Debounce
  24.   if (digitalRead(button) == true) {
  25.     pressed = !pressed;
  26.   }
  27.   while (digitalRead(button) == true);
  28.   delay(20);
  29.   // If button is pressed - change rotation direction
  30.   if (pressed == true  & rotDirection == 0) {
  31.     digitalWrite(in1, HIGH);
  32.     digitalWrite(in2, LOW);
  33.     rotDirection = 1;
  34.     delay(20);
  35.   }
  36.   // If button is pressed - change rotation direction
  37.   if (pressed == false & rotDirection == 1) {
  38.     digitalWrite(in1, LOW);
  39.     digitalWrite(in2, HIGH);
  40.     rotDirection = 0;
  41.     delay(20);
  42.   }
  43. }
复制代码

代码描述:首先我们需要定义程序所需的引脚和一些变量。 在setup函数部分,我们需要设置引脚模式和电机的初始旋转方向。 在loop函数部分,我们首先读取电位器值,然后将我们从0到1023得到的值映射到PWM信号的0到255之间的值,或者是 PWM信号的0到100%的占空比。 然后使用analogWrite()函数将PWM信号发送到L298N电路板的Enable引脚,该引脚实际驱动电机。


接下来,我们检查是否按下了按钮,如果按下按钮,我们将通过反向设置输入1和输入2状态来改变电机的旋转方向。 按钮将用作切换按钮,每次按下它时,它将改变电机的旋转方向。

跳转到指定楼层
风筝
发表于: 2018-11-10 09:07:18 | 显示全部楼层

使用L298N驱动器实现Arduino智能小车控制

这样,一旦我们学习了以上知识,我们现在就可以制作属于自己的智能小车了。以下是电路原理图:

Arduino-Robot-Car-Control-using-L298N-Driver-Circuit-Schematic.png

在这个电路中只需要两个直流电机、L298N驱动器、Arduino开发板和用于控制的摇杆。使用了三节3.7V锂离子电池串联用于供电,总共可以提供11V电压。我用3毫米厚的胶合板制作底盘,用金属支架将电机安装到底盘上,将轮子连接到电机上,并且在前面安装了一个旋转轮。

Arduino-Robot-Car-DIY-Chassis.jpg


现在让我们来看看Arduino代码部分是如何工作的。

  1. int xAxis = analogRead(A0); // Read Joysticks X-axis
  2. int yAxis = analogRead(A1); // Read Joysticks Y-axis
复制代码

定义这些引脚后,在loop函数中,我们首先读取摇杆X轴和Y轴的值。摇杆实际上由两个电位器组成,它们连接到Arduino的模拟输入引脚,它们的值从0到1023。当摇杆位于其中心位置时,两个电位器或轴的值都在512左右。

Arduino-Robot-Car-Joystick-Movements-Control.png

我们将增加一点容差,将470到550的值视为中心位置。因此,如果我们向后移动摇杆的Y轴并且值低于470,我们将使用四个输入引脚将两个电机旋转方向设置为向后。然后,我们将470到0的递减值转换0到255的递增PWM值,实际上就是电机的速度。

  1. // Y-axis used for forward and backward control
  2.   if (yAxis < 470) {
  3.     // Set Motor A backward
  4.     digitalWrite(in1, HIGH);
  5.     digitalWrite(in2, LOW);
  6.     // Set Motor B backward
  7.     digitalWrite(in3, HIGH);
  8.     digitalWrite(in4, LOW);
  9.     // 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
  10.     motorSpeedA = map(yAxis, 470, 0, 0, 255);
  11.     motorSpeedB = map(yAxis, 470, 0, 0, 255);
  12.   }
复制代码

同样如果我们向前移动操纵杆的Y轴并且值超过550,我们将设置电机向前移动,并将550到1023的读数转换为0到255的PWM值。如果摇杆位于中心位置, 电机速度为零。


接下来,让我们看看如何使用X轴来实现智能小车的左右控制。

  1. // X-axis used for left and right control
  2.   if (xAxis < 470) {
  3.     // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
  4.     int xMapped = map(xAxis, 470, 0, 0, 255);
  5.     // Move to left - decrease left motor speed, increase right motor speed
  6.     motorSpeedA = motorSpeedA - xMapped;
  7.     motorSpeedB = motorSpeedB + xMapped;
  8.     // Confine the range from 0 to 255
  9.     if (motorSpeedA < 0) {
  10.       motorSpeedA = 0;
  11.     }
  12.     if (motorSpeedB > 255) {
  13.       motorSpeedB = 255;
  14.     }
  15.   }
复制代码

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

Arduino-Robot-Car-Left-and-Right-Control.png


使用同样的方法将小车向右移动。


根据所施加的电压和电机本身,在较低的速度下,电机无法开始移动并产生嗡嗡声。 在本例中,如果PWM信号的值低于70,则电机无法移动。因此使用这两个if语句我实际上将速度限制在70到255的范围内。最后我们只发送最终电机速度或 PWM信号到L298N驱动器的使能引脚。

  1. // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  2.   if (motorSpeedA < 70) {
  3.     motorSpeedA = 0;
  4.   }
  5.   if (motorSpeedB < 70) {
  6.     motorSpeedB = 0;
  7.   }
  8.   analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  9.   analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
复制代码

以下是Arduino智能小车示例的完整代码: main.rar (966 Bytes, 下载次数: 39)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1480



手机版|

GMT+8, 2024-4-19 09:50 , Processed in 0.137755 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表