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 przyciskach –
pinMode(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.