直流电机简介及利用L298N控制
直流电机简介及利用L298N控制
本文将详细介绍直流电机的工作原理以及如何使用Arduino和L298N驱动器来控制直流电机的速度和方向。通过本教程,你将掌握直流电机的基本知识,并能够独立完成电机控制的硬件连接和软件编程。
直流电机简介
直流电机引脚排列
直流电机通常有两根电线:
- 正极线:通常为红色
- 负极线:通常为黑色
直流电机的工作原理
以12V直流电机为例:
- 当正极线连接12V,负极线连接GND时,电机顺时针方向以最大速度旋转
- 当负极线连接12V,正极线连接GND时,电机逆时针方向以最大速度旋转
通过改变电源极性可以控制电机的旋转方向。在实际应用中,我们通过编程来实现这一控制。
使用Arduino控制直流电机
控制直流电机包括两个因素:速度和方向。Arduino可以生成PWM信号,但其输出的电压和电流不足以直接驱动直流电机。因此,我们需要使用硬件驱动器来放大信号并控制电机的方向。
注意事项:
- 本教程适用于所有直流电机,12V直流电机仅作为示例。
- 即使是5V直流电机,也需要使用驱动器,因为Arduino引脚无法提供足够的电流。
L298N驱动器简介
L298N驱动器可以同时独立控制两个直流电机,称为电机A和电机B。它有13个引脚:
L298N驱动器引脚排列
通用引脚:
VCC引脚:为电机供电,电压范围5V至35V
GND引脚:公共接地引脚,需要连接到GND(0V)
5V引脚:为L298N模块供电,可以由Arduino的5V供电
电机A引脚(通道A):
ENA引脚:用于控制电机A的速度
IN1 & IN2引脚:用于控制电机A的旋转方向
OUT1 & OUT2引脚:连接到电机A
电机B引脚(通道B):
ENB引脚:用于控制电机B的速度
IN3 & IN4引脚:用于控制电机B的旋转方向
OUT3 & OUT4引脚:连接到电机B
L298N驱动器具有两种输入电源:
- 一种用于直流电机(VCC和GND引脚):5V至35V
- 一种用于L298N模块的内部操作(5V和GND引脚):5V至7V
使用L298N驱动器控制直流电机的速度
通过向L298N的ENA引脚生成PWM信号来控制直流电机的速度:
- 将Arduino引脚连接到L298N的ENA引脚
- 使用
analogWrite()
函数生成PWM信号
analogWrite(ENA_PIN, speed); // speed是介于0到255之间的值
速度值介于0到255之间。如果速度为0,电机停止;如果速度为255,电机以最大速度旋转。
使用L298N驱动器控制直流电机的方向
电机的旋转方向可以通过对IN1和IN2引脚施加逻辑HIGH/LOW来控制:
IN1 引脚 | IN2 引脚 | 方向 |
---|---|---|
LOW | LOW | 电机A停止 |
HIGH | HIGH | 电机A停止 |
HIGH | LOW | 电机A顺时针旋转 |
LOW | HIGH | 电机A逆时针旋转 |
控制电机A顺时针旋转:
digitalWrite(IN1_PIN, HIGH);
digitalWrite(IN2_PIN, LOW);
控制电机A逆时针旋转:
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, HIGH);
停止直流电机旋转
有两种方法可以停止直流电机:
- 将速度控制为0
- 将IN1和IN2引脚设置为相同值(LOW或HIGH)
将速度控制为0:
analogWrite(ENA_PIN, 0);
将IN1和IN2引脚设置为相同值:
digitalWrite(IN1_PIN, LOW);
digitalWrite(IN2_PIN, LOW);
或
digitalWrite(IN1_PIN, HIGH);
digitalWrite(IN2_PIN, HIGH);
使用L298N驱动器控制直流电机
接线图
在接线前请拆下L298N模块上的所有三个跳线。
Arduino代码
以下代码实现:
- 加速直流电机
- 改变方向
- 减速直流电机
- 停止电机
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor
*/
// 常量不会改变
const int ENA_PIN = 9; // Arduino引脚连接到L298N的EN1引脚
const int IN1_PIN = 6; // Arduino引脚连接到L298N的IN1引脚
const int IN2_PIN = 5; // Arduino引脚连接到L298N的IN2引脚
// setup函数在你按下复位或供电时运行一次
void setup() {
// 初始化数字引脚为输出
pinMode(ENA_PIN, OUTPUT);
pinMode(IN1_PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
}
// loop函数会无限循环运行
void loop() {
digitalWrite(IN1_PIN, HIGH); // 控制电机A顺时针旋转
digitalWrite(IN2_PIN, LOW); // 控制电机A顺时针旋转
for (int speed = 0; speed <= 255; speed++) {
analogWrite(ENA_PIN, speed); // 控制速度
delay(10);
}
delay(1000); // 在顺时针方向以最大速度旋转1秒
// 改变方向
digitalWrite(IN1_PIN, LOW); // 控制电机A逆时针旋转
digitalWrite(IN2_PIN, HIGH); // 控制电机A逆时针旋转
delay(1000); // 在逆时针方向以最大速度旋转1秒
for (int speed = 255; speed >= 0; speed--) {
analogWrite(ENA_PIN, speed); // 控制速度
delay(10);
}
delay(1000); // 停止电机1秒
}
快速步骤:
- 卸下L298N模块上的所有三个跳线。
- 复制上述代码并使用Arduino IDE打开。
- 单击Arduino IDE上的“上传”按钮,将代码上传到Arduino。
- 你将看到:
- 直流电机加速并以最大速度旋转1秒
- 直流电机的方向改变
- 直流电机以最大速度反向旋转1秒
- 直流电机降速
- 直流电机停止1秒
- 上述过程重复运行。
使用L298N驱动器控制两个直流电机
以下代码使直流电机无限旋转,并在触动两个限位开关中的一个时改变方向:
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-dc-motor-limit-switch
*/
#include <ezButton.h>
#define DIRECTION_CCW -1
#define DIRECTION_CW 1
#define ENA_PIN 7 // Arduino引脚连接到L298N的EN1引脚
#define IN1_PIN 6 // Arduino引脚连接到L298N的IN1引脚
#define IN2_PIN 5 // Arduino引脚连接到L298N的IN2引脚
ezButton limitSwitch_1(A0); // 创建连接到A0引脚的ezButton对象
ezButton limitSwitch_2(A1); // 创建连接到A1引脚的ezButton对象
int direction = DIRECTION_CW;
int prev_direction = DIRECTION_CW;
void setup() {
Serial.begin(9600);
limitSwitch_1.setDebounceTime(50); // 设置消抖时间为50毫秒
limitSwitch_2.setDebounceTime(50); // 设置消抖时间为50毫秒
// 初始化数字引脚为输出
pinMode(ENA_PIN, OUTPUT);
pinMode(IN1_PIN, OUTPUT);
pinMode(IN2_PIN, OUTPUT);
digitalWrite(ENA_PIN, HIGH); // 最大速度
digitalWrite(IN1_PIN, HIGH); // 控制电机A顺时针旋转
digitalWrite(IN2_PIN, LOW); // 控制电机A顺时针旋转
}
void loop() {
limitSwitch_1.loop(); // 必须先调用loop()函数
limitSwitch_2.loop(); // 必须先调用loop()函数
if (limitSwitch_1.isPressed()) {
direction *= -1; // 改变方向
Serial.println(F("The limit switch 1: TOUCHED"));
}
if (limitSwitch_2.isPressed()) {
direction *= -1; // 改变方向
Serial.println(F("The limit switch 2: TOUCHED"));
}
if (prev_direction != direction) {
Serial.print(F("The direction -> "));
if (direction == DIRECTION_CW) {
Serial.println(F("CLOCKWISE"));
digitalWrite(IN1_PIN, HIGH); // 控制电机A顺时针旋转
digitalWrite(IN2_PIN, LOW); // 控制电机A顺时针旋转
} else {
Serial.println(F("ANTI-CLOCKWISE"));
digitalWrite(IN1_PIN, LOW); // 控制电机A逆时针旋转
digitalWrite(IN2_PIN, HIGH); // 控制电机A逆时针旋转
}
prev_direction = direction;
}
}