Silniki krokowe to kluczowy element w projektach robotycznych i elektronicznych. Oferują precyzyjną kontrolę pozycji bez enkoderów, ale ich integracja z Arduino bywa kłopotliwa (drgania, utrata kroków, brak obrotów). Poniżej znajdziesz krótką teorię, poprawne sposoby podłączenia oraz sprawdzone rozwiązania typowych problemów – z działającymi przykładami kodu.

Zasada działania silnika krokowego

Silnik krokowy pracuje dzięki sekwencyjnemu zasilaniu cewek, co tworzy przesuwające się pole magnetyczne „ciągnące” wirnik o stały kąt. W trybie pełnokrokowym jest to zwykle 1,8° (200 kroków/obrót). W trybie półkroku kąt maleje do 0,9°, a przy mikrokrokach – nawet do 1/16 lub 1/32 kroku (np. A4988, DRV8825), co zapewnia płynniejszy ruch i niższy hałas.

Pozycja jest znana w otwartej pętli sterowania – o ile dostarczysz prawidłową sekwencję impulsów. Dlatego poprawne zasilanie, sterownik i timing są krytyczne.

  • pełny krok – najwyższy moment, większy hałas i rezonans przy średnich prędkościach;
  • półkrok – kompromis: lepsza płynność, mniejsze drgania kosztem nieco niższego momentu;
  • mikrokrok – bardzo płynny ruch i cicha praca, wymaga sterownika (np. A4988, DRV8825).

Podłączenie silnika krokowego do Arduino

Arduino nie zasila bezpośrednio uzwojeń – zawsze użyj sterownika. Najpopularniejsze są dwa scenariusze: tani unipolarny 28BYJ‑48 z modułem ULN2003 oraz bipolarne NEMA 17 ze sterownikiem A4988/DRV8825 (STEP/DIR).

Porównanie najczęściej spotykanych konfiguracji:

Silnik Sterownik Piny sterujące Zasilanie Uwagi
28BYJ-48 (unipolarny) ULN2003 IN1, IN2, IN3, IN4 → piny cyfrowe 5 V (osobne od Arduino, wspólna masa) sterowanie sekwencją cewek; dobry do małych obciążeń
NEMA 17 (bipolarny) A4988 / DRV8825 STEP, DIR (+ MS1–MS3 do mikrokroków) 12–24 V (silnik), 5 V (logika), wspólna masa mikrokroki, wyższe prądy, ustawienie prądu przez Vref

Przykład: 28BYJ‑48 + ULN2003 (pełny krok)

Poniższy kod realizuje prostą sekwencję pełnokrokową IN1→IN2→IN3→IN4. Zwróć uwagę na poprawną deklarację tablicy oraz przypisania do pinów:

#define IN1 8
#define IN2 9
#define IN3 10
#define IN4 11

const uint8_t stepSequence[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};

void setCoils(uint8_t s[4]) {
digitalWrite(IN1, s[0]);
digitalWrite(IN2, s[1]);
digitalWrite(IN3, s[2]);
digitalWrite(IN4, s[3]);
}

void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}

void loop() {
// kierunek do przodu
for (int i = 0; i < 4; i++) {
setCoils((uint8_t*)stepSequence[i]);
delay(5); // im mniejsze opóźnienie, tym szybciej
}
// aby zmienić kierunek, przejdź po tablicy wstecz
}

Przykład: NEMA 17 + A4988 (mikrokroki, AccelStepper)

W tej konfiguracji używasz tylko dwóch pinów: STEP i DIR. Biblioteka AccelStepper doda rampy prędkości i znacznie ograniczy utratę kroków:

#include <AccelStepper.h>

// A4988: STEP=2, DIR=3
AccelStepper stepper(AccelStepper::DRIVER, 2, 3);

const int stepsPerRev = 200; // 1,8°/krok bez mikrokroków

void setup() {
stepper.setMaxSpeed(1200); // kroki/s
stepper.setAcceleration(600); // kroki/s^2
}

void loop() {
// obróć o jeden pełny obrót, zatrzymaj, wróć
stepper.moveTo(stepsPerRev);
stepper.runToPosition();
delay(300);
stepper.moveTo(0);
stepper.runToPosition();
delay(300);
}

Typowe problemy z ruchem silnika krokowego

Jeśli silnik nie pracuje prawidłowo, najczęściej winne są zasilanie, sekwencja, prędkość lub prąd fazy. Sprawdź poniższe symptomy i wskazówki:

  • brak ruchu lub tylko drgnięcia – nieaktywny sterownik, błędne okablowanie lub brak wspólnej masy; sprawdź napięcie logiki i zasilanie silnika;
  • utrata kroków – zbyt wysoka prędkość bez akceleracji; wirnik nie nadąża i „ślizga się” po polu;
  • drgania i rezonans – pełny krok przy prędkościach około 1/3 maksimum; spada moment i rośnie hałas;
  • nadmierny hałas lub przegrzewanie – zbyt wysoki prąd faz; błędnie ustawione Vref lub brak mikrokroków;
  • nierówny obrót – błędna kalibracja kroków/obrót lub przełożenia; dla NEMA 17 zwykle 200 kroków/obrót, a przy mikrokrokach przemnażaj tę wartość.

Dodatkowo zweryfikuj: pary cewek w silniku bipolarnym, luźne przewody, zakłócenia EMI oraz blokujące opóźnienia w kodzie.

Rozwiązywanie problemów – krok po kroku

1. Diagnoza sprzętowa

Zacznij od podstawowych testów i pomiarów:

  • zmierz napięcia – multimetr na pinach zasilania sterownika; logika 5 V, zasilanie silnika zgodnie ze specyfikacją;
  • zidentyfikuj pary cewek – w silniku bipolarnym znajdź pary przewodów (miernikiem ciągłości) i podłącz je poprawnie do A/B;
  • testuj bez obciążenia – odłącz paski/śruby; jeśli silnik rusza płynnie „na luzie”, szukaj problemów mechanicznych;
  • użyj INPUT_PULLUP przy przyciskachpinMode(BTN, INPUT_PULLUP); ogranicza fałszywe wyzwolenia;
  • chłodzenie sterownika – radiator i przewiew obniżają temperaturę i zapobiegają zadziałaniu zabezpieczeń termicznych.

2. Optymalizacja prędkości i akceleracji

Silnik potrzebuje rampy przyspieszania/hamowania, zwłaszcza przy większych obciążeniach. Poniżej minimalny przykład z AccelStepper do płynnego ruchu:

#include <AccelStepper.h>
AccelStepper s(AccelStepper::DRIVER, 2, 3);

void setup() {
s.setMaxSpeed(1500); // kroki/s
s.setAcceleration(800);
}

void loop() {
static long target = 0;
if (s.distanceToGo() == 0) {
target = (target == 0) ? 3200 : 0; // np. 16x mikrokroki: 200*16
s.moveTo(target);
}
s.run(); // nie blokuje, generuje rampę i kroki w czasie
}

3. Włącz mikrokroki i ustaw prąd

Mikrokroki wyraźnie zmniejszają drgania i hałas. Ustaw MS1–MS3 (A4988) lub M0–M2 (DRV8825) zgodnie z dokumentacją, a następnie wyreguluj Vref pod prąd znamionowy silnika. Orientacyjna zależność dla A4988: Imax ≈ Vref / (8 × Rsense). Zawsze zaczynaj od niższych wartości i kontroluj temperaturę.

4. Sterowanie przyciskami i czujnikami

Tak możesz dodać sterowanie kierunkiem przyciskami oraz regulację prędkości potencjometrem (A4988 + AccelStepper):

#include <AccelStepper.h>
#define STEP_PIN 2
#define DIR_PIN 3
#define BTN_L 4
#define BTN_R 5
#define POT_AIN A0

AccelStepper st(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
const int stepsPerRev = 200; // bez mikrokroków

void setup() {
pinMode(BTN_L, INPUT_PULLUP);
pinMode(BTN_R, INPUT_PULLUP);
st.setMaxSpeed(1200);
st.setAcceleration(600);
}

void loop() {
// regulacja prędkości potencjometrem (kroki/s)
long spd = map(analogRead(POT_AIN), 0, 1023, 100, 2000);
st.setMaxSpeed(spd);

// ruch inkrementalny przy przytrzymaniu przycisków
if (digitalRead(BTN_L) == LOW) st.move(-stepsPerRev / 10); // mały krok w lewo
if (digitalRead(BTN_R) == LOW) st.move( stepsPerRev / 10); // mały krok w prawo

st.run();
}

5. Zaawansowane triki

W trudniejszych przypadkach pomocne będą dodatkowe praktyki:

  • rampowanie prędkości w całym cyklu ruchu (start, przelot, hamowanie),
  • odwracanie kierunku przez zmianę DIR lub odwrócenie sekwencji,
  • konfiguracje wielosilnikowe z DRV8825/TMC i wspólnym zegarem kroków,
  • diagnostyka w czasie rzeczywistym przez Serial.print() stanu kroków i docelowej pozycji.

Dla szybkiej diagnozy możesz skorzystać z poniższej ściągi problem–przyczyna–naprawa:

Problem Przyczyna Rozwiązanie
Brak ruchu Błędne okablowanie, brak wspólnej masy Sprawdź piny i masę; zweryfikuj pary cewek i zasilanie
Utrata kroków Start bez rampy, zbyt duża prędkość Użyj AccelStepper i akceleracji; obniż prędkość maksymalną
Drgania Pełny krok przy średnich prędkościach Włącz mikrostepping 1/8–1/16; podnieś napięcie zasilania w granicach sterownika
Nierówny obrót Zła kalibracja kroków/obrót Ustal poprawne stepsPerRevolution i przełożenia
Przegrzewanie Za wysoki prąd faz Skoryguj Vref, dodaj radiator i przewiew

Praktyczne projekty i wskazówki

W robotyce silniki krokowe napędzają ramiona, wózki liniowe i głowice drukarek 3D. Zawsze testuj najpierw przy niskiej prędkości, a następnie stopniowo zwiększaj, obserwując temperaturę i dźwięk.

Unikaj sterowników mostkowych ogólnego przeznaczenia (np. L298N) do precyzyjnego sterowania – postaw na A4988/DRV8825/TMC. Dla większych jednostek (np. NEMA 23) zastosuj wydajny zasilacz 24 V, odpowiednio ustaw prąd i zadbaj o chłodzenie.