Programmering og koding

Trinnmotor med Arduino: styr fart, retning og posisjon

Trinnmotor 28BYJ-48 med ULN2003-driverkort ved siden av en Arduino-skisse med Stepper-biblioteket som dreier akselen fram og tilbake

Styrer du en trinnmotor med Arduino, bestemmer du nøyaktig hvor langt akselen skal gå, hvor fort og hvilken vei, uten noen sensor på motoren. Programmet teller trinn, og hvert trinn er en fast vinkel. Guiden bruker den lille 28BYJ-48-motoren med ULN2003-driver og et Arduino Uno R4 WiFi og er delt i tre nivåer: én omdreining fram og tilbake, fart med potensiometer og retning med knapp, og til slutt et lite prosjekt som går til vinkelen du skriver inn.

Kort forklartKoble IN1 til IN4 på driveren til pinne 8 til 11, og gi driveren 5 V fra en egen adapter. GND på adapteren og på Arduinoen skal være koblet sammen. Opprett motoren med Stepper motor(2048, 8, 10, 9, 11);: 2048 trinn per omdreining og pinnene i rekkefølgen IN1, IN3, IN2, IN4. Hold farten mellom 4 og 12 RPM, og slå av spolene når motoren står stille, ellers blir den varm.

Slik virker 28BYJ-48 og ULN2003

En trinnmotor har spoler rundt en magnetisk rotor. Får spolene strøm i en bestemt rekkefølge, trekker de rotoren ett lite trinn videre om gangen. Antallet trinn bestemmer vinkelen, tiden mellom trinnene bestemmer farten, og rekkefølgen bestemmer retningen. Arduinoen styrer altså posisjonen ved å telle, ikke ved å måle.

Trinnmotoren 28BYJ-48 med driverkort er unipolar: den har fire spolehalvdeler med en felles rød ledning til 5 V. Databladene for 28BYJ-48 oppgir trinnvinkelen 5,625° og viser trinnsekvensen for halvtrinn, som vinkelen hører til. Det gir 64 halvtrinn per runde inne i motoren, og girkassen girer ned 64:1. På akselen blir det 64 × 64 = 4096 halvtrinn eller 2048 fulle trinn per omdreining, rundt 0,18° per fullt trinn. Giret gjør motoren presis og gir den nok kraft til lette oppgaver, men gjør den også langsom.

EgenskapVerdiHva det betyr for deg
Spenning5 VDriveren skal ha 5 V, ikke 12 V
Spolemotstand50 ΩRundt 0,1 A per spole, opptil 0,2 A med to spoler på
Girforhold64:12048 fulle trinn eller 4096 halvtrinn per omdreining
Holdemoment på akselen0,03 Nm (0,3 kg·cm)Nok til en peker, en ventil eller en lett dreieskive, ikke til hjulene på en robotbil
Startfrekvens uten lastover 600 HzHvor fort motoren kan starte rett fra stillstand
Maksimal frekvens uten lastover 1000 HzHvor fort den kan gå når den allerede er i gang
Kontakt5-polet JST XHGår bare én vei inn i driverkortet

Driverkortet har brikken ULN2003A med sju Darlington-transistorer, som kobler en spole til jord når inngangen er høy. En pinne på Uno R4 WiFi tåler bare 8 mA, mens en spole trekker rundt 100 mA og en inngang på ULN2003A trenger rundt 1 mA ifølge TIs datablad. Arduinoen gir altså bare signalet, og brikken tar seg av motorstrømmen. Kortet bruker fire av de sju kanalene, og fire lysdioder viser hvilke spoler som har strøm.

Merkingen VCC, GND og IN1 til IN4 står på baksiden. Forfra, på siden med brikken, sitter VCC ytterst nærmest monteringshullet, så kommer GND og IN1 til IN4. Har du det blå driverkortet med IN1 til IN7, bruker du IN1 til IN4 på samme måte.

Koble trinnmotoren til Arduino Uno R4 WiFi

Strøm: egen 5 V-forsyning og felles GND

Arduino anbefaler egen strømforsyning til trinnmotorer, og databladet for Uno R4 WiFi sier at motorer skal ha ekstern forsyning. Motoren trekker opptil rundt 0,2 A, og en USB-port på en PC er ifølge Arduino vanligvis begrenset til 500 mA, som motoren må dele med kortet. Bruk derfor en stabilisert 5 V-adapter med DC-plugg 5,5/2,1 mm og en DC-kontaktmodul med to VCC- og to GND-pinner. Arduinoen får strøm og program over USB-C som vanlig.

GND på adapteren og GND på Arduinoen kobles sammen, fordi signalene på pinne 8 til 11 måles mot GND. Pluss-sidene skal aldri kobles sammen.

Før du kobler til: koble aldri adapterens VCC til 5V-pinnen på Arduinoen. Produktsidene oppgir ikke polariteten, så mål med et multimeter at VCC på DC-modulen gir +5 V mot GND før driveren får strøm. Guiden om multimeter, oscilloskop og USB-tester viser hvilket utstyr som holder til slike målinger.

Koblingen steg for steg

  1. Sett motorpluggen i den hvite kontakten på driverkortet. Den går bare én vei.
  2. Koble strømmen til driveren med to hunn-hunn-ledninger: VCC på DC-modulen til VCC på driveren, og GND til GND.
  3. Lag felles jord med en hunn-hann-ledning fra den andre GND-pinnen på DC-modulen til GND på Arduinoen, pinnen mellom AREF og 13 i den øverste rekken.
  4. Koble signalene med fire hunn-hann-ledninger: IN1 til pinne 8, IN2 til 9, IN3 til 10 og IN4 til 11.
  5. Kontroller og slå på: mål VCC, sett adapteren i stikkontakten og koble til slutt USB-C til PC-en.
Koblingstegning: pinne 8 til 11 på Uno R4 WiFi går til IN1 til IN4 på ULN2003, 5 V fra DC-modulen til driveren og felles GND til Arduinoen.
Koblingen for nivå 1, med driverkortet sett forfra (merkingen står på baksiden) og bare en del av Uno R4 WiFi, sett ovenfra. Pinne 8 til 11 går til IN1 til IN4, og driveren får 5 V fra adapteren via DC-modulen. Den svarte ledningen fra DC-modulen til GND på Arduinoen gir felles jord; pluss-siden kobles bare til driveren.
DriverkortUno R4 WiFiMotorledningPlass i Stepper(…)
IN1pinne 8blå (1)1.
IN2pinne 9rosa (2)3.
IN3pinne 10gul (3)2.
IN4pinne 11oransje (4)4.
VCCikke tilkoblet, får 5 V fra adapterenrød (5), felles
GNDGND, felles med adapteren

Nivå 1: én omdreining fram og tilbake

Nivå 1: nybegynner. Tid: rundt 20 minutter. Du trenger et Arduino Uno R4 WiFi med en USB-C-kabel for data, trinnmotoren med driverkort, 5 V-adapteren og DC-modulen, to hunn-hunn- og fem hunn-hann-ledninger. Alle tre ledningstypene finnes i ledningssettet med 140 koblingsledninger, og flere lengder ligger under koblingsledninger. Du trenger verken loddebolt eller koblingsbrett ennå.

Stepper-biblioteket følger med Arduino IDE 2 og installeres ved første oppstart. Mangler det, søker du etter «Stepper» i Library Manager. Er Arduino IDE nytt for deg, viser guiden om Arduino-programmering for nybegynnere hvordan du velger kort og port og laster opp en skisse. Denne skissen bygger på Arduinos eksempel «stepper_oneRevolution»:

#include <Stepper.h>

// 2048 fulle trinn per omdreining på akselen (32 x 64)
const int STEG_PER_OMDREINING = 2048;

// Rekkefølgen er IN1, IN3, IN2, IN4: pinne 8, 10, 9 og 11
Stepper motor(STEG_PER_OMDREINING, 8, 10, 9, 11);

void setup() {
  motor.setSpeed(8);     // 8 RPM: 7,5 sekunder per omdreining
  Serial.begin(9600);
}

void loop() {
  Serial.println("En omdreining fram");
  motor.step(STEG_PER_OMDREINING);    // positivt tall: én vei
  delay(1000);

  Serial.println("En omdreining tilbake");
  motor.step(-STEG_PER_OMDREINING);   // negativt tall: andre vei
  delay(1000);
}
  • Stepper motor(2048, …) forteller biblioteket hvor mange trinn det er i én omdreining. Med feil tall blir både fart og vinkel feil.
  • setSpeed(8) setter farten i omdreininger per minutt (RPM), og bare hele tall er mulig. Biblioteket regner ut ventetiden mellom trinnene, her rundt 3,7 ms.
  • step() blokkerer: programmet blir stående på denne linjen til alle trinnene er tatt, i nivå 1 i 7,5 sekunder. Med et negativt tall går motoren motsatt vei.
  • Under delay(1000) har de to siste spolene fortsatt strøm. Motoren holder posisjonen, men bruker strøm. Nivå 2 viser hvordan du slår dem av.

Hvorfor rekkefølgen 8, 10, 9, 11?

I kildekoden til Stepper-biblioteket har pinne 1 og 2 i parentesen alltid motsatt nivå, og det samme gjelder pinne 3 og 4. Biblioteket regner altså med at de to første styrer hver sin ende av den ene spolen, og de to siste den andre. Ifølge databladet er blå og gul de to endene av én spole, og rosa og oransje den andre. Driverkortet fører IN1 til blå, IN2 til rosa, IN3 til gul og IN4 til oransje. Da blir den riktige rekkefølgen IN1, IN3, IN2, IN4, altså 8, 10, 9, 11. Skriver du 8, 9, 10, 11 som i Arduinos eget eksempel, får motoren strømmen i feil rekkefølge, og den rister eller summer på stedet.

Koblingsskjema: pinne 8 til 11 via ULN2003A til spolehalvdelene blå, rosa, gul og oransje; spole A er blå og gul, spole B rosa og oransje.
Hver motorledning går til én spolehalvdel. Stepper-biblioteket gir pin 1 og 2 motsatte signaler, og det samme gjelder pin 3 og 4. Blå og gul er de to endene av den ene spolen, rosa og oransje av den andre, og derfor står pinnene i rekkefølgen 8, 10, 9, 11.

Prøv selv: bytt ut STEG_PER_OMDREINING med STEG_PER_OMDREINING / 4 i begge step()-linjene. Da går motoren en kvart runde, 90°, fram og tilbake.

Hvis det ikke virker: lyser ingen av lysdiodene på driveren, mangler 5 V eller felles GND. Blinker de, men akselen bare rister, er rekkefølgen i koden eller ledningene til IN1 til IN4 feil. Starter Arduinoen på nytt når motoren går, får motoren trolig strøm fra USB i stedet for fra adapteren.

Nivå 2: fart med potensiometer og retning med knapp

Nivå 2: viderekommen. Tid: rundt 30 minutter. Du bygger videre på nivå 1 og trenger i tillegg et koblingsbrett, ett potensiometer på 10 kΩ, én trykknapp og seks hann-hann-ledninger. Alt dette ligger i startpakken for Uno R4 WiFi sammen med kortet. Et løst koblingsbrett med 830 hull og andre størrelser finner du under koblingsbrett og prototyping.

Potensiometeret får strøm fra Arduinoen, ikke fra adapteren: ytterbeina går til 5V og GND på kortet og midtbeinet til A0, så målingen følger referansen til analoginngangen. GND går til minusskinnen på koblingsbrettet, og derfra med korte ledninger til potensiometeret og knappen. Knappen kobles mellom pinne 2 og GND og bruker den interne pull-up-motstanden: pinnen leser HIGH når knappen er sluppet og LOW når den er trykket. Motoren og driveren er koblet som i nivå 1.

Koblingstegning: potensiometer mellom 5V og GND med midtbeinet til A0, og trykknapp fra pinne 2 til GND på et koblingsbrett under Uno R4 WiFi.
Tillegget for nivå 2. Motoren og driveren fra nivå 1 er ikke tegnet. Potensiometeret ligger mellom 5V og GND på Arduinoen med midtbeinet til A0, og knappen går fra pinne 2 til minusskinnen. Knappen kobles på skrå, slik at signalet alltid går gjennom bryteren.
#include <Stepper.h>

const int STEG_PER_OMDREINING = 2048;
Stepper motor(STEG_PER_OMDREINING, 8, 10, 9, 11);  // IN1 IN3 IN2 IN4

const int KNAPP = 2;       // knapp mellom pinne 2 og GND
const int MAKS_RPM = 12;   // toppfart med potensiometeret

int retning = 1;           // 1 eller -1
int knappStatus = HIGH;    // stabil tilstand etter prellfilteret
int forrigeLest = HIGH;
unsigned long sistEndret = 0;

void setup() {
  pinMode(KNAPP, INPUT_PULLUP);
}

void loop() {
  // Retning: bytt ved hvert nye trykk, med 50 ms prellfilter
  int lest = digitalRead(KNAPP);
  if (lest != forrigeLest) sistEndret = millis();
  if (millis() - sistEndret > 50 && lest != knappStatus) {
    knappStatus = lest;
    if (knappStatus == LOW) retning = -retning;
  }
  forrigeLest = lest;

  // Fart: potensiometeret gir 0 til MAKS_RPM
  int rpm = map(analogRead(A0), 0, 1023, 0, MAKS_RPM);
  if (rpm > 0) {
    motor.setSpeed(rpm);
    motor.step(retning * 4);   // fire trinn, så sjekk igjen
  } else {
    slippSpoler();             // 0: stopp og spar strøm
  }
}

void slippSpoler() {
  for (int pin = 8; pin <= 11; pin++) {
    digitalWrite(pin, LOW);
  }
}
  • motor.step(retning * 4) tar fire trinn om gangen. Fordi step() blokkerer, leser programmet knappen og potensiometeret mellom hver lille bevegelse, slik Arduinos dokumentasjon anbefaler.
  • if (rpm > 0) er nødvendig: setSpeed() deler på farten, og med 0 ville programmet ha delt på null.
  • Prellfilteret godtar en ny knappetilstand først når den har vært stabil i 50 ms, som i Arduinos eksempel «Debounce». Uten det kan ett trykk bytte retning flere ganger.
  • slippSpoler() setter alle fire inngangene lave når potensiometeret står på null, så motoren står uten strøm og holder seg kald.

Hvor fort kan motoren gå? Databladet oppgir at den uten last starter på over 600 Hz og holder følge opp til over 1000 Hz, men ikke om det gjelder hele eller halve trinn. Regnet som halvtrinn, som trinnvinkelen gjelder for, blir det omtrent 9 RPM fra stillstand og knapt 15 RPM i fart. Derfor går nivå 1 med 8 RPM, og potensiometeret stopper på 12 RPM. Øk farten gradvis: starter eller snur motoren i full fart, kan den hoppe over trinn.

FartFulle trinn per sekundTid per omdreiningKommentar
4 RPM13715 sRolig, sterkest
8 RPM2737,5 sTrygg startfart, brukt i nivå 1
12 RPM4105 sToppen på potensiometeret
15 RPM5124 sNær grensen, prøv uten last

Prøv selv: legg til Serial.begin(9600); i setup() og skriv ut rpm i loop(), eller sett MAKS_RPM til 15 og finn farten der akselen begynner å stoppe opp når du holder lett i den.

Hvis det ikke virker: står motoren stille hele tiden eller går den alltid på toppfart, går A0-ledningen til et ytterbein i stedet for midtbeinet. Bytter ikke retningen, er knappen koblet med to bein som alltid er koblet sammen. Flytt ledningen til beinet på skrå overfor, slik guiden for nybegynnere viser.

Nivå 3: gå til en bestemt vinkel med halvtrinn og myk start

Nivå 3: avansert. Tid: rundt 60 minutter. Du bruker oppkoblingen fra nivå 2. Potensiometeret brukes ikke, og knappen setter nullpunktet. Fest en peker av papp eller tape på akselen, og legg en enkel gradskive av papir under, så ser du hvor nøyaktig motoren treffer.

Nå skriver du trinnsekvensen selv i stedet for å bruke biblioteket. Det gir halvtrinn med 4096 trinn per omdreining, en loop() som aldri blokkerer, og en myk start: motoren tåler høyere fart når den allerede går, så programmet starter rolig og øker farten i løpet av de første 200 trinnene. Tabellen er halvtrinnssekvensen fra databladet, skrevet med IN1 først. Hver rad gir strøm til én eller to spoler:

TrinnIN1 (blå)IN2 (rosa)IN3 (gul)IN4 (oransje)
0på
1påpå
2på
3påpå
4på
5påpå
6på
7påpå
// Nivå 3: vinkelstyring med halvtrinn, myk start og nullpunkt
const int PINNER[4] = {8, 9, 10, 11};  // IN1, IN2, IN3, IN4
const int KNAPP = 2;                   // setter nullpunktet

// Halvtrinn (1-2-fase): kolonnene er IN1, IN2, IN3 og IN4
const byte SEKVENS[8][4] = {
  {1, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0},
  {0, 0, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 0, 1}
};

const long HALVTRINN = 4096;          // per omdreining på akselen
const unsigned long START_US = 3000;  // start: 333 trinn per sekund
const unsigned long TOPP_US = 1200;   // topp: 833 trinn per sekund
const long RAMPE = 200;               // trinn med akselerasjon

long posisjon = 0;    // halvtrinn siden oppstart
long nullpunkt = 0;   // posisjonen som er 0 grader
long start = 0;       // der bevegelsen begynte
long mal = 0;         // der motoren skal stoppe
unsigned long sistTrinn = 0;
bool spolerPa = false;

void setup() {
  for (int i = 0; i < 4; i++) pinMode(PINNER[i], OUTPUT);
  pinMode(KNAPP, INPUT_PULLUP);
  skriv(0);              // trekk rotoren inn på rad 0
  delay(200);
  slippSpoler();
  Serial.begin(9600);
  Serial.println("Skriv 0 til 359, eller +5 og -5 for små steg");
}

void loop() {
  if (Serial.available() > 0) lesKommando();

  if (digitalRead(KNAPP) == LOW && posisjon == mal) {
    nullpunkt = posisjon;
    Serial.println("Nullpunkt satt");
    delay(300);
  }

  if (posisjon != mal) {
    if (micros() - sistTrinn >= intervall()) {
      sistTrinn = micros();
      posisjon += (mal > posisjon) ? 1 : -1;
      skriv(posisjon);
      spolerPa = true;
    }
  } else if (spolerPa) {
    slippSpoler();
    Serial.print("Står på ");
    Serial.print(vinkelNa());
    Serial.println(" grader");
  }
}

void lesKommando() {
  String linje = Serial.readStringUntil('\n');
  linje.trim();
  if (linje.length() == 0) return;
  if (posisjon != mal) {
    Serial.println("Vent til motoren står stille");
    return;
  }
  long tall = linje.toInt();
  start = posisjon;
  if (linje[0] == '+' || linje[0] == '-') {
    mal = posisjon + tall * HALVTRINN / 360;   // relativt
  } else {
    long her = modulo(posisjon - nullpunkt);
    long diff = modulo(tall * HALVTRINN / 360) - her;
    if (diff > HALVTRINN / 2) diff -= HALVTRINN;   // korteste vei
    if (diff < -HALVTRINN / 2) diff += HALVTRINN;
    mal = posisjon + diff;
  }
}

unsigned long intervall() {
  long gatt = labs(posisjon - start);   // trinn siden start
  long igjen = labs(mal - posisjon);    // trinn igjen til målet
  long n = (gatt < igjen) ? gatt : igjen;
  if (n >= RAMPE) return TOPP_US;
  return START_US - (START_US - TOPP_US) * n / RAMPE;
}

void skriv(long trinn) {
  int rad = (trinn % 8 + 8) % 8;   // virker også for negative tall
  for (int i = 0; i < 4; i++) {
    digitalWrite(PINNER[i], SEKVENS[rad][i] ? HIGH : LOW);
  }
}

void slippSpoler() {
  for (int i = 0; i < 4; i++) digitalWrite(PINNER[i], LOW);
  spolerPa = false;
}

long modulo(long x) {              // gir 0 til HALVTRINN - 1
  return (x % HALVTRINN + HALVTRINN) % HALVTRINN;
}

long vinkelNa() {                 // avrundet til hele grader
  long g = modulo(posisjon - nullpunkt) * 360 + HALVTRINN / 2;
  return (g / HALVTRINN) % 360;
}
Flytskjema for vinkelstyringen: en kommando gir nytt mål, knappen setter nullpunktet, og motoren tar et halvtrinn når rampeintervallet har gått.
Slik går skissen i nivå 3 rundt: loop() venter aldri, men sjekker om det har kommet en kommando, om knappen er trykket og om det er tid for neste halvtrinn. Når målet er nådd, slås spolene av.

Slik virker de viktigste linjene:

  • PINNER står i vanlig rekkefølge, 8, 9, 10, 11. Tabellen bestemmer selv hvilken spole som får strøm, så du trenger ikke å bytte om 9 og 10 her.
  • skriv(0) i setup() gir strøm til rad 0 i 0,2 sekunder. Da står rotoren garantert der programmet tror den står, før den første bevegelsen.
  • posisjon teller alle halvtrinn siden oppstart, og skriv() velger rad ut fra resten etter deling på 8. (trinn % 8 + 8) % 8 trengs fordi % gir negativt svar for negative tall i C++.
  • nullpunkt husker hvilken posisjon som er 0°. Knappen flytter bare nullpunktet, ikke telleren, så spolerekkefølgen brytes aldri.
  • if (micros() - sistTrinn >= intervall()) tar ett trinn bare når nok tid har gått, ellers går loop() videre. Det er tidsstyring som med millis(), bare i mikrosekunder.
  • intervall() lager rampen: 3000 µs mellom trinnene i starten, ned mot 1200 µs etter 200 trinn, og omvendt før målet. n er avstanden til nærmeste ende av bevegelsen, så korte bevegelser når aldri toppfarten.
  • Ved start er 333 halvtrinn per sekund under startfrekvensen i databladet, og 833 i fart er under maksimal frekvens. Toppfarten tilsvarer rundt 12 RPM.
  • I lesKommando() regner diff ut den korteste veien. Står pekeren på 350° og du skriver 10, går den 20° fram, ikke 340° tilbake. Tall med + eller - foran gir en relativ bevegelse.
  • readStringUntil('\n') leser én linje fra Serial Monitor. Velg «New Line» nederst i vinduet, ellers venter funksjonen ett sekund før den gir opp.
  • Ved målet slår slippSpoler() av spolene, og vinkelen skrives ut. Kommandoer som kommer mens motoren går, avvises, så den aldri snur brått i full fart.

Slik bruker du vinkelstyringen

  1. Last opp skissen og åpne Serial Monitor med 9600 baud og «New Line».
  2. Juster pekeren med +5 og -5, eller +1 for finjustering, til den står på 0-merket på gradskiven.
  3. Trykk på knappen for å sette nullpunktet. Serial Monitor svarer «Nullpunkt satt».
  4. Skriv en vinkel, for eksempel 90, 180 eller 270, og sjekk at pekeren treffer merket.
  5. Test nøyaktigheten: skriv +3600, ti omdreininger, og se om pekeren treffer samme merke. Forskyver den seg like mye hver runde, justerer du HALVTRINN litt for ditt eksemplar. Hopper den uregelmessig, mister motoren trinn, og da må du senke farten.

Prøv selv: lag en dreieskive for produktbilder som stopper åtte ganger per runde. Send +45 åtte ganger med en pause imellom, eller legg en løkke i loop() som gjør det samme når du trykker på knappen.

Hvis det ikke virker: hopper pekeren litt når den starter, er lasten for tung eller farten for høy. Øk START_US og TOPP_US, eller la spolene stå på når en last trekker i akselen. Går det ett sekund før Serial Monitor svarer på hver kommando, er linjeslutt satt til «No Line Ending».

Varme, strøm og nøyaktighet

Stepper-biblioteket lar de to siste spolene stå på når step() er ferdig. Motoren holder da posisjonen, men bruker rundt 0,2 A hele tiden og blir varm. Databladet tillater en temperaturøkning på under 40 K i drift, så det er normalt at den er varm å ta på. Står motoren mest stille, slår du av spolene som i nivå 2 og 3. Motorens selvholdende moment og friksjonen i girkassen holder en lett peker på plass, men en last som trekker, krever strøm på spolene.

Programmet vet bare hvor mange trinn det har sendt. Holdes motoren igjen eller går den for fort, hopper den over trinn uten at noen merker det, og etter et strømbrudd vet programmet ikke hvor akselen står. Må prosjektet finne posisjonen selv ved oppstart, kjører du motoren mot en endebryter og setter nullpunktet der.

Trinnmotor, servo eller DC-motor?

MotorHva du styrerPosisjonPasser tilMellom motor og Arduino
Trinnmotor 28BYJ-48Fart, retning og posisjon ved å telle trinnHele omdreininger, ingen sensorPeker, dreieskive, ventil, lett løftULN2003 og fire pinner
Mikroservo MG90SVinkel fra 0 til 180°Innebygd måling av vinkelenSpjeld, arm, griper, låsIngen driver, én signalpinne
DC-motor med girFart og retningIngen uten encoderHjul, vifte, pumpeH-bro eller MOSFET

Trenger du bare en vinkel innenfor en halv runde, er en servo enklere og raskere: mikroservoen MG90S går 60° på 0,1 s ved 4,8 V, mens trinnmotoren bruker over 0,8 s ved 12 RPM. Til hjul og pumper passer en DC-motor, og guiden om L298N, MOSFET og PWM for DC-motorer viser hvilken driver du trenger.

Kort om servo: MG90S med samme potensiometer

En servo har motor, gir og vinkelmåler i samme hus og går selv til vinkelen du ber om. Den brune ledningen går til GND, den røde til +5 V og den oransje til signalpinnen. Ifølge Arduinos servoguide kan en mikroservo trekke opptil 800 mA når den belastes eller blokkeres, så den røde ledningen skal til adapteren, ikke til 5V-pinnen. Sett adapterens VCC og GND på strømskinnene på koblingsbrettet, koble GND på Arduinoen til minusskinnen og den oransje ledningen til pinne 6. Arduino anbefaler også en kondensator, for eksempel på 100 µF, mellom pluss og minus nær servoen, med minusstripen mot GND. Skissen er Arduinos eksempel «Knob» med pinne 6, så trinnmotoren kan stå tilkoblet:

#include <Servo.h>

Servo servo;

void setup() {
  servo.attach(6);   // oransje signalledning til pinne 6
}

void loop() {
  int vinkel = map(analogRead(A0), 0, 1023, 0, 180);
  servo.write(vinkel);   // servoen går selv til vinkelen
  delay(15);
}

Brummer servoen og presser mot en av endene, begrenser du området, for eksempel til map(…, 0, 1023, 10, 170).

Vanlige spørsmål

Hvor mange trinn har 28BYJ-48 per omdreining?

2048 fulle trinn eller 4096 halvtrinn på akselen, ut fra trinnvinkelen 5,625° og girforholdet 64:1. Stepper-biblioteket bruker fulle trinn, så du skriver 2048 der.

Kan jeg gi motoren strøm fra 5V-pinnen på Arduinoen?

Det anbefales ikke. Arduino råder til egen forsyning for trinnmotorer, og databladet for Uno R4 WiFi sier det samme om motorer. Fra USB deler motoren strømmen med kortet, mens adapteren har nok til både trinnmotor og servo.

Hvorfor summer motoren uten å gå rundt?

Nesten alltid fordi pinnene står i rekkefølgen 8, 9, 10, 11 i Stepper(…). Bruk 8, 10, 9, 11. Er rekkefølgen riktig, er farten trolig for høy: senk den til 8 RPM og prøv igjen.

Kan jeg bruke ULN2003-driveren til en NEMA 17-motor?

Nei. En NEMA 17-trinnmotor er bipolar med fire ledninger og trenger en H-bro eller en egen trinnmotordriver, for eksempel en TMC2209-driver med step- og dir-innganger. ULN2003 kan bare trekke strøm til jord og passer til unipolare motorer som 28BYJ-48.

Kan jeg styre flere trinnmotorer samtidig?

Ja, men hver motor trenger sin egen driver og fire pinner, og forsyningen må tåle rundt 0,2 A per motor. Med Stepper-biblioteket venter programmet på én motor om gangen. Skriv koden som i nivå 3, med én teller og ett mål per motor, eller bruk biblioteket AccelStepper, som du finner i Library Manager.

Kilder og videre lesing

Trinn, spoler, farger og frekvenser er kontrollert mot databladet for 28BYJ-48, driverbrikken mot TIs datablad for ULN2003A, og strømrådene mot databladet for Uno R4 WiFi og Arduinos side om trinnmotorer. Rekkefølgen 8, 10, 9, 11 følger av kildekoden til Stepper-biblioteket, og servodelen bygger på Arduinos servoguide.

Guiden om transistorer forklarer hvordan transistorene i ULN2003A virker som brytere. Flere motorer finner du blant trinnmotorene og servomotorene i butikken.

Alle guider

Produkter omtalt i denne guiden

Produktene som brukes og sammenlignes i guiden, med pris og lagerstatus.