ROS2+智能导航小车 2024年5月24日 · 18 分钟
ROS2进阶 -- 硬件篇第三章第四节 -- ESP32 DEVKIT_V1通过PID实现霍尔编码电机的速度控制,使用A4950驱动板
基于 A4950 驱动板与 PID 算法,实现 ESP32 对霍尔编码电机的闭环速度控制
第四节我们的任务是使用ESP32 DEVKIT_V1通过PID实现霍尔编码电机的速度控制,使用A4950驱动板
参考资料:
零件说明:ROS2进阶 – 硬件篇第一章 – 使用ESP32,树莓派5,ROS2 从零组装一台差速控制的机器人 环境配置:ROS2进阶 – 硬件篇第二章 – 使用 ESP32 DEVKIT_V1 开发板基于 Arduino IDE 的环境搭建教程 windows / ubuntu 双系统安装 视频讲解:第七节:ESP32通过PID实现霍尔编码电机的速度控制
使用本章内容时请提前将代码esp32_ros2_robot下载好
1. 本节需要准备的东西
ESP32,A4950,前面用到的电机(需要重新接线),电源, Arduino IDE

本节所使用的代码为:07-esp32_Motor_Velocity_PID_Control
2. 电路图
先将esp32通过USB连接到电脑上,然后将ESP32,A4950,电机,电源按照下图连接

实物连接如下:

3. 代码
motor_driver.h
// 左边电机转动方向控制位 引脚
// 左边电机转动方向控制位 引脚
#define Back_Left_D1 12
#define Back_Left_D1_B 13
// 右边电机转动方向控制位 引脚
// 右边电机转动方向控制位 引脚
#define Back_Right_D1 14
#define Back_Right_D1_B 27
void Init_Motors()
{
pinMode(Back_Left_D1, OUTPUT);
pinMode(Back_Left_D1_B, OUTPUT);
pinMode(Back_Right_D1, OUTPUT);
pinMode(Back_Right_D1_B, OUTPUT);
}
void setSpeeds(int m1Speed, int m2Speed)
{
// 控制左侧电机
if(m1Speed > 0)
{
analogWrite(Back_Left_D1, m1Speed);
analogWrite(Back_Left_D1_B, LOW);
}
else
{
analogWrite(Back_Left_D1, LOW);
analogWrite(Back_Left_D1_B, -m1Speed);
}
// 控制右侧电机
if(m2Speed > 0)
{
analogWrite(Back_Right_D1, m2Speed);
analogWrite(Back_Right_D1_B, LOW);
}
else
{
analogWrite(Back_Right_D1, LOW);
analogWrite(Back_Right_D1_B, -m2Speed);
}
}
Serial_A4950T_PWM_velocity_test.ino
#include "motor_driver.h"
// A pair of varibles to help parse serial commands (thanks Fergs)
int arg = 0;
int index_ = 0;
// Variable to hold an input character
char chr;
// Variable to hold the current single-character command
char cmd;
// Character arrays to hold the first and second arguments
char argv1[16];
char argv2[16];
// The arguments converted to integers
long arg1;
long arg2;
/* Clear the current command parameters */
void resetCommand() {
cmd = 0 ; //NULL;
memset(argv1, 0, sizeof(argv1));
memset(argv2, 0, sizeof(argv2));
arg1 = 0;
arg2 = 0;
arg = 0;
index_ = 0;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
setSpeeds(0,0);
}
void loop() {
while (Serial.available() > 0)
{
// Read the next character
chr = Serial.read();
// Terminate a command with a CR
if (chr == 13) // '\r'
{
if (arg == 1)
argv1[index_] = 0 ;//NULL;
else if (arg == 2)
argv2[index_] = 0; //NULL;
Serial.print(cmd);
Serial.print(" ");
Serial.print(atoi(argv1));
Serial.print(" ");
Serial.println(atoi(argv2));
setSpeeds(atoi(argv1),atoi(argv2));
resetCommand();
}
// Use spaces to delimit parts of the command
else if (chr == ' ')
{
// Step through the arguments
if (arg == 0) arg = 1;
else if (arg == 1)
{
argv1[index_] = NULL;
arg = 2;
index_ = 0;
}
continue;
}
else
{
if (arg == 0)
{
// The first arg is the single-letter command
cmd = chr;
}
else if (arg == 1)
{
// Subsequent arguments can be more than one character
argv1[index_] = chr;
index_++;
}
else if (arg == 2)
{
argv2[index_] = chr;
index_++;
}
}
}
}
4. 运行代码
在Arduino打开代码

选择开发板和端口号

点击验证和上传按钮,此时还没有输出,我们打开串口监视器,右侧选择换行和回车都是
然后键入==m 100 100==
这个时控制左右电机转速的
注:当这个值过小时,驱动板输出给电机的电压会不够,此时带不动电机,电机会发出响声,我这个电机如果输入50以下的值时会出现这种情况

5. 视频调试过程如下
总结:
第三章到此共4小节,基本完成了ESP32上需要接入的板子,测试没问题后可以将前面几节的板子都接在esp32上,整理线路,后续的章节我们将进行上位工控机的配置与安装。

