【教程】基于 ESP32 与 LN298N 的电动推杆控制

【教程】基于 ESP32 与 LN298N 的电动推杆控制

给大家分享一个项目案例,结合 ESP32 开发板、LN298N 电机驱动模块以及带有编码器(霍尔编码器)的推杆,实现对推杆运动的精准控制。实现了推杆的前进、后退、速度控制,还添加了根据目标行程自动控制的功能函数,并能实时反馈电机当前的行程位置。

1.电推杆参数

下图:带霍尔编码器的电推杆

具有六根线:

LN298N

LN298N参数如下图所示;

ESP32

ESP32用的是S2系列,这里就不再出图了。

接线

具体接线步骤

1. 电源连接

外部电源与 LN298N:

将外部电源(如 12V 或 24V 直流电源,需根据推杆电机的额定电压选择)的正极连接到 LN298N 模块的 +12V 或相应的电源输入引脚(确保电源电压在 LN298N 的工作范围内),负极连接到 GND 引脚。这为 LN298N 模块和推杆电机提供电力。

LN298N 与推杆电机:

把 LN298N 模块的输出引脚 OUT1 和 OUT2 连接到推杆电机的两个接线端(电机的正负极)。若电机需要反转功能,可通过控制 OUT1 和 OUT2 的电平来实现。

ESP32 电源:ESP32 可通过 USB 线连接到电脑或使用合适的电源模块供电。同时,将 ESP32 的 GND 引脚与 LN298N 模块的 GND 引脚相连,确保共地。

2. 控制信号连接

ESP32 与 LN298N:

方向控制:将 ESP32 的 GPIO 引脚(如 GPIO18 和 GPIO19)分别连接到 LN298N 模块的 IN1 和 IN2 引脚。通过控制这两个引脚的电平高低,可以改变电机的转动方向。

速度控制:把 ESP32 具有 PWM 功能的引脚(如 GPIO25)连接到 LN298N 模块的 ENA 引脚。通过调整 PWM 信号的占空比,可以控制电机的转速。

ESP32 与编码器:

编码器信号 A:将编码器的信号线 A(通常为蓝色线)连接到 ESP32 的 GPIO16 引脚。该信号用于检测电机的旋转状态和方向。

编码器信号 B:把编码器的信号线 B(通常为白色线)连接到 ESP32 的 GPIO17 引脚。与信号 A 配合,可实现更精确的位置检测和速度计算。

编码器电源:编码器的电源正极(通常为黄色线)连接到 ESP32 的 3.3V 引脚(若编码器工作电压兼容 3.3V),负极(通常为绿色线)连接到 ESP32 的 GND 引脚。

关于行程的计算

参考官方文档

BMMINI系列推杆采用双通道AB相增量式磁编码器。输出为两路正交90°方波(如下图所示),分辨率7线即电机旋转一圈输出7个脉冲。如果想知道每个脉冲位移多少,那么就用丝杠的导程÷(编码器线数×减速比),就可以得到每脉冲位移是多少毫米;编码器使用非接触磁感应技术,不存在机械磨损,从而具有超长的使用寿命和稳定性,可靠性极强。

关于速度

若输入电源电压为 12V,PWM 信号占空比为 78.4%,那么电机两端的平均电压约为 0.784×12V=9.408V,电机转速与平均电压的关系,直流电机的转速和其两端的电压大致成正比。在其他条件不变的情况下,电机两端的平均电压越高,电机的转速就越快;反之,平均电压越低,转速越慢。所以,通过调整 ESP32 输出的 PWM 信号的占空比,就能改变 LN298N 输出到电机的平均电压,进而实现对电机转速的控制。

总结:最大速度8mm/s,如果占空比是78.4%,那么实际速度是V=8X78.4%

代码

// 定义LN298N控制引脚

const int in1 = 18;

const int in2 = 19;

const int enA = 25;

// 定义编码器引脚

const int encoderA = 16;

const int encoderB = 17;

// 编码器脉冲计数

volatile long encoderCount = 0;

// 每脉冲对应的位移,需根据实际参数调整

// 假设获取到的丝杠导程为L毫米,减速比为R

// 需替换为实际的丝杠导程和减速比

const float lead = 2; // 示例丝杠导程,单位:毫米

const float reductionRatio = 100; // 示例减速比

// 根据公式计算每脉冲对应的位移

const float displacementPerPulse = lead / (7 * reductionRatio);

// 中断服务函数

void IRAM_ATTR handleEncoder() {

int stateA = digitalRead(encoderA);

int stateB = digitalRead(encoderB);

if (stateA == stateB) {

encoderCount++;

} else {

encoderCount--;

}

}

// 功能函数,控制推杆移动到目标行程

void movePusher(int speed, float targetDistance) {

long targetPulses = targetDistance / displacementPerPulse;

long initialCount = encoderCount;

long currentPulses;

int direction;

if (targetPulses > 0) {

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

direction = 1;

} else {

digitalWrite(in1, LOW);

digitalWrite(in2, HIGH);

direction = -1;

targetPulses = -targetPulses;

}

analogWrite(enA, speed);

while (1) {

currentPulses = abs(encoderCount - initialCount);

float currentDistance = currentPulses * displacementPerPulse;

Serial.print("Current position: ");

Serial.print(currentDistance);

Serial.println(" mm");

float initialDistance = initialCount * displacementPerPulse;

Serial.print("Initial position: ");

Serial.print(initialDistance);

Serial.println(" mm");

if (currentPulses >= targetPulses) {

break;

}

delay(10);

}

// 停止电机

digitalWrite(in1, LOW);

digitalWrite(in2, LOW);

analogWrite(enA, 0);

}

void setup() {

Serial.begin(115200);

// 设置LN298N控制引脚为输出模式

pinMode(in1, OUTPUT);

pinMode(in2, OUTPUT);

pinMode(enA, OUTPUT);

// 初始化电机停止

digitalWrite(in1, LOW);

digitalWrite(in2, LOW);

analogWrite(enA, 0);

// 设置编码器引脚为输入模式

pinMode(encoderA, INPUT_PULLUP);

pinMode(encoderB, INPUT_PULLUP);

// 附加中断服务函数

attachInterrupt(digitalPinToInterrupt(encoderA), handleEncoder, CHANGE);

}

void loop() {

// 推杆后退,速度200,目标行程 -50mm

movePusher(200, 50);

delay(5000);

// // 推杆前进,速度200,目标行程 50mm

movePusher(200, -50);

delay(5000);

}

以上就可以实现带霍尔编码器的电推杆的控制了!如有疑问可以发邮件联系我

dnddn@foxmail.com

🌸 相关推荐

Surface换电池多少钱?
正规365网址是多少

Surface换电池多少钱?

📅 07-26 👀 1245
鼓的成语
aa365备用网址

鼓的成语

📅 07-18 👀 8984
ADCK镜头系列及其ADL低光摄影镜头的特点和优点
正规365网址是多少

ADCK镜头系列及其ADL低光摄影镜头的特点和优点

📅 07-01 👀 1428