ESP32Mini打印机:电机控制模块

0 阅读6分钟

⚙️ ESP32 Mini打印机:电机控制模块

驱动步进电机,实现打印头进退纸、走纸等精确控制
基于四相八拍驱动,支持定时器中断和步进模式


📌 为什么需要电机控制?

热敏打印机需要精确控制纸张的移动:

  • 进纸:将空白纸送入打印位置
  • 走纸:打印过程中逐行移动纸张
  • 退纸:打印完成后吐出纸张

电机控制模块就是打印机的“双腿”,必须平稳、精确、可控

直观理解

就像打印机的“传送带”,电机每转一步,纸张就移动一微米。


一、硬件原理简述

电机类型

本例使用四相步进电机,驱动方式为1-2相励磁(八拍模式),可实现半步控制,提高分辨率和平稳性。

驱动电路

  • 使用四个GPIO直接驱动电机驱动芯片(如ULN2003、DRV8825等)
  • 每个GPIO对应电机的一相:AP、AM、BP、BM
  • 输出高/低电平控制电流方向

引脚定义(示例配置)

// 请根据实际硬件连接修改以下引脚号
#define PIN_MOTOR_AP 25   // A+ 相(原为23,现改为25)
#define PIN_MOTOR_AM 26   // A- 相(原为22,现改为26)
#define PIN_MOTOR_BP 27   // B+ 相(原为21,现改为27)
#define PIN_MOTOR_BM 32   // B- 相(原为19,现改为32)

💡 提示:此处引脚号仅为示例,实际使用时请根据PCB布线或开发板连接情况修改。ESP32的GPIO需避开仅输入引脚(如34~39)和已被占用的引脚。

八拍励磁表

电机旋转一圈需要特定的相序,本例使用八拍表(8个状态,每步进一个状态):

步进位置APAMBPBM说明
00110A相通电,B相通电
10010仅B相通电
21010A相通电,B相通电
31000仅A相通电
41001A相通电,B相通电
50001仅B相通电
60101A相通电,B相通电
70100仅A相通电

每切换一次状态,电机前进半步。循环该表即可持续旋转。


二、代码实现

以下代码实现了基于Ticker定时器的持续旋转和基于阻塞的步进控制。

1. 引脚与定时器定义

#include "Arduino.h"
#include <Ticker.h>

// 用户可根据实际硬件连接修改此处引脚号
#define PIN_MOTOR_AP 25
#define PIN_MOTOR_AM 26
#define PIN_MOTOR_BP 27
#define PIN_MOTOR_BM 32

Ticker timer_motor;          // 定时器对象,用于周期性触发电机步进

2. 八拍励磁表与当前步进位置

uint8_t motor_table[8][4] = {
    {0, 1, 1, 0},   // 状态0
    {0, 0, 1, 0},   // 状态1
    {1, 0, 1, 0},   // 状态2
    {1, 0, 0, 0},   // 状态3
    {1, 0, 0, 1},   // 状态4
    {0, 0, 0, 1},   // 状态5
    {0, 1, 0, 1},   // 状态6
    {0, 1, 0, 0}    // 状态7
};

uint8_t motor_pos = 0;        // 当前步进位置索引(0~7)

3. 定时器回调函数(持续旋转)

void timer_motor_callbackfun() {
    // 根据当前步进位置输出相序
    digitalWrite(PIN_MOTOR_AP, motor_table[motor_pos][0]);
    digitalWrite(PIN_MOTOR_AM, motor_table[motor_pos][1]);
    digitalWrite(PIN_MOTOR_BP, motor_table[motor_pos][2]);
    digitalWrite(PIN_MOTOR_BM, motor_table[motor_pos][3]);

    // 移动到下一步
    motor_pos++;
    if (motor_pos >= 8) {
        motor_pos = 0;        // 循环
    }
}

4. 启动与停止电机(定时器模式)

void motor_start() {
    if (!timer_motor.active()) {
        timer_motor.attach_ms(2, timer_motor_callbackfun);  // 每2ms触发一次,约500Hz步进频率
    }
}

void motor_stop() {
    timer_motor.detach();      // 停止定时器
    // 所有相断电,防止电机发热
    digitalWrite(PIN_MOTOR_AP, 0);
    digitalWrite(PIN_MOTOR_AM, 0);
    digitalWrite(PIN_MOTOR_BP, 0);
    digitalWrite(PIN_MOTOR_BM, 0);
}

直观理解

定时器就像一位严格的指挥官,每隔2ms下令电机前进一步。motor_start 就是“开始行军”,motor_stop 是“原地立正,熄灯”。

5. 步进指定步数(阻塞模式)

void motor_run_step(uint32_t steps) {
    while (steps--) {
        digitalWrite(PIN_MOTOR_AP, motor_table[motor_pos][0]);
        digitalWrite(PIN_MOTOR_AM, motor_table[motor_pos][1]);
        digitalWrite(PIN_MOTOR_BP, motor_table[motor_pos][2]);
        digitalWrite(PIN_MOTOR_BM, motor_table[motor_pos][3]);

        motor_pos++;
        if (motor_pos >= 8) {
            motor_pos = 0;
        }

        delay(2);              // 每步延时2ms,与定时器频率一致
    }
}

核心作用

用于精确控制打印头移动指定的步数(如进纸N步),完成后自动停止。

注意

此函数使用 delay(),会阻塞其他任务,适合短距离移动。长距离移动建议使用定时器模式。

6. 初始化函数

void motor_init() {
    pinMode(PIN_MOTOR_AP, OUTPUT);
    pinMode(PIN_MOTOR_AM, OUTPUT);
    pinMode(PIN_MOTOR_BP, OUTPUT);
    pinMode(PIN_MOTOR_BM, OUTPUT);
    // 初始全部置低,确保电机静止
    digitalWrite(PIN_MOTOR_AP, LOW);
    digitalWrite(PIN_MOTOR_AM, LOW);
    digitalWrite(PIN_MOTOR_BP, LOW);
    digitalWrite(PIN_MOTOR_BM, LOW);
}

三、代码使用示例

void setup() {
    Serial.begin(115200);
    motor_init();
    Serial.println("电机模块初始化完成(引脚已更新)");
}

void loop() {
    // 示例:启动电机持续旋转
    motor_start();
    delay(5000);        // 旋转5秒
    motor_stop();

    delay(1000);

    // 示例:步进200步(约多少圈?取决于电机步距角)
    motor_run_step(200);

    delay(2000);
}

四、代码分析

1. 优点

  • 双模式支持:定时器模式用于持续旋转,步进模式用于精确控制,灵活应对不同场景。
  • 相序表清晰:八拍励磁表用二维数组表示,易于修改和调试。
  • 定时器非阻塞:定时器模式下,电机旋转不占用主循环,可并行处理其他任务。
  • 停止时断电motor_stop 将所有相置低,避免电机发热和功耗浪费。

2. 潜在问题

  • 步进模式阻塞motor_run_step 中使用 delay(2),长时间运行会阻塞系统,不适合与蓝牙、WiFi等实时任务共存。
  • 无加减速控制:突然启动/停止可能导致电机抖动或失步,尤其高速时。
  • 步进频率固定:定时器周期固定为2ms(500Hz),无法动态调整速度。
  • 无电流限制:直接驱动可能超过GPIO驱动能力,需外接驱动芯片。

3. 引脚修改说明

  • 原引脚(23、22、21、19)已替换为 25、26、27、32,仅作为示例。
  • 用户在实际硬件上需根据原理图或PCB设计修改这些宏定义,确保引脚未被其他外设占用(如ADC、触摸、JTAG等)。
  • ESP32的引脚GPIO34~39只能用作输入,不能用于输出,因此需避开。

五、使用总结

关键词/技巧一句话记忆
Ticker硬件定时器,精准触发,不占CPU
八拍励磁表4×8数组,相序全记录,电机旋转靠它
motor_start/stop定时器模式,持续旋转如传送带
motor_run_step步进模式,指哪打哪,精确移动
断电停止停止时所有相拉低,省电又安全
引脚可配置宏定义统一管理,硬件改动只需改一处

六、写在最后

电机控制模块是打印机的“肌肉”,负责纸张的精准移动。通过本文,就学会了:

  • ✅ 四相步进电机的八拍驱动原理
  • ✅ 使用ESP32的Ticker定时器实现非阻塞旋转
  • ✅ 实现精确步进的阻塞函数
  • ✅ 完整的代码结构与使用方法
  • ✅ 如何灵活配置引脚以适应不同硬件