← До всіх проєктів
Автоматизація Початковий

Кроковий двигун 28BYJ-48: точні повороти без бібліотек

Найдешевший кроковий двигун із драйвером ULN2003. Пишемо власний неблокуючий напівкроковий драйвер, керуємо кутом і швидкістю командами з Serial. Основа для жалюзі, годівниць і поворотних платформ.

Складність
Початковий
Час
1 h
Категорія
Автоматизація

Чим кроковий двигун кращий за сервопривід

Сервопривід повертається лише на 180°, а кроковий — на будь-який кут у будь-який бік, скільки завгодно обертів, із точністю до кроку. 28BYJ-48 з вбудованим редуктором 1:64 дає близько 4096 напівкроків на оберт (≈0.09° на крок) і помітний крутний момент — достатньо, щоб крутити ролету чи дозатор.

Компоненти

  • ESP32 DevKit
  • Двигун 28BYJ-48 (5 В) + плата драйвера ULN2003 (зазвичай продаються комплектом)
  • Живлення 5 В ≥ 500 мА

Підключення

ULN2003 ESP32
IN1 GPIO 19
IN2 GPIO 18
IN3 GPIO 5
IN4 GPIO 17
+ / − 5V / GND

Двигун підключається до білого роз'єму на платі драйвера. Земля драйвера й ESP32 — спільна.

Як крутиться кроковик

Усередині чотири обмотки. Вмикаючи їх по черзі, ми «тягнемо» ротор по колу. Напівкроковий режим чергує одну та дві ввімкнені обмотки — 8 фаз на цикл: так рух плавніший, а кроків удвічі більше.

Код

const int PINS[4] = {19, 18, 5, 17};   // IN1..IN4

// Напівкрокова послідовність: біт 3 → IN1 ... біт 0 → IN4
const uint8_t SEQ[8] = {
  0b1000, 0b1100, 0b0100, 0b0110,
  0b0010, 0b0011, 0b0001, 0b1001
};
const long STEPS_PER_REV = 4096;

long position = 0;             // поточна позиція в кроках
long target = 0;               // куди їдемо
int phase = 0;
unsigned long stepIntervalUs = 1500;
unsigned long lastStepUs = 0;

void applyPhase(uint8_t mask) {
  for (int i = 0; i < 4; i++) {
    digitalWrite(PINS[i], (mask >> (3 - i)) & 1);
  }
}

void setRpm(float rpm) {
  rpm = constrain(rpm, 1.0f, 15.0f);   // 28BYJ-48 пропускає кроки понад ~15 об/хв
  stepIntervalUs = 60000000.0 / (rpm * STEPS_PER_REV);
  Serial.printf("Speed: %.1f rpm (%lu us/step)\n", rpm, stepIntervalUs);
}

void handleCommand(String cmd) {
  cmd.trim();
  if (cmd.startsWith("rpm ")) {
    setRpm(cmd.substring(4).toFloat());
  } else if (cmd == "home") {
    target = 0;
  } else if (cmd.length()) {
    float degrees = cmd.toFloat();       // «90», «-180», «720»
    target += lround(degrees * STEPS_PER_REV / 360.0);
    Serial.printf("Moving to %ld\n", target);
  }
}

void setup() {
  Serial.begin(115200);
  Serial.setTimeout(20);
  for (int p : PINS) pinMode(p, OUTPUT);
  setRpm(10);
  Serial.println("Commands: <degrees> | rpm <1-15> | home");
}

void loop() {
  if (Serial.available()) handleCommand(Serial.readStringUntil('\n'));

  if (position != target && micros() - lastStepUs >= stepIntervalUs) {
    lastStepUs = micros();
    int dir = target > position ? 1 : -1;
    phase = (phase + dir + 8) % 8;
    applyPhase(SEQ[phase]);
    position += dir;

    if (position == target) {
      applyPhase(0);    // знімаємо струм — двигун не грітиметься
      Serial.printf("Arrived at %ld (%.1f°)\n", position, position * 360.0 / STEPS_PER_REV);
    }
  }
}

Перевірка

Відкрийте Serial Monitor (115200, «Newline») і надсилайте:

Команда Дія
90 повернути на 90° за годинниковою стрілкою
-360 один повний оберт у зворотний бік
rpm 5 змінити швидкість
home повернутися в нульову позицію

Чотири світлодіоди на платі ULN2003 показують, які обмотки зараз увімкнені — зручно для налагодження.

Нюанси

  • Точне число кроків. Реальний редуктор — не рівно 1:64, а ≈1:63.68, тому точніше STEPS_PER_REV = 4076. Для жалюзі різниця неважлива, для годинника — суттєва.
  • Утримання. Ми знімаємо струм після зупинки, щоб двигун не грівся. Якщо навантаження може провернути вал (вертикальна ролета), залишайте обмотки ввімкненими.
  • Нуль після перезавантаження невідомий. Для абсолютного позиціонування додайте кінцевий вимикач і процедуру homing при старті.
  • Потрібно більше сили чи швидкості — беріть NEMA17 з драйвером A4988/TMC2209.

Ідеї

  • Автоматичні жалюзі: відкрити на світанку, закрити на заході сонця (NTP + розрахунок часу).
  • Поворотний стіл для 360°-фото товарів: крок, пауза, знімок.
  • Годівниця з дозатором-шнеком.