Start Elkretssimulator


Driva stegmotor

Vi får en stegmotor snurra med arduino. Först lite teori.

En stegmotor består enkelt uttryckt av en snurrande magnet eller en järnkärna. Runt om sitter elektromagneter vilka magnetiseras enligt ett mönster som driver runt axeln med magneten eller järnkärnan. Det finns en hel del varianter på konstruktion och en del varianter på metod att driva stegmotorer. Här är några.



Unipolär eller Bipolär

Elektromagneterna, som de används, i en stegmotor bygger på att du kan vända den magnetiska polartiteten. För att åstadkomma detta kan man antingen vända på den elektriska polariteten på en lindning (bipolär stegmotor) eller så kan man när man bygger motorn lägga in en mittenanslutning i lindningen som ger dig möjlighet välja en kopparlindning som ger dig magnetisk polaritet åt ena eller andra hållet (unipolär stegmotor). Beroende på vilken av dessa lindningar som strömsätts i den unipolära elektromagneten så får man sedan en elektromagnet med den ena eller andra polariteten.

Den bipolära har 4 trådar ut och elektroniken måste alltså klara av att vända på polariteten. Elektronik för en unipolär stegmotor är vanligtvis enklare att konstruera. En 5-trådars unipolär stegmotor har en gemensam anslutning (plus). Elektroniken kommer sedan "sänka" (minus) för den elektromagnet som önskas aktiveras.

En 6-trådars unipolär kan användas som en 4-trådars bipolär genom att man helt enkelt struntar i 2 av trådarna eller som en 5-trådars unipolär genom att man virar ihop 2 av trådarna.



Några exempel på stegmotorer

Nedan några exempel på stegmotorer och anslutningar. Det kan i princip se ut hur som helst. Titta i dokumenteringen på den stegmotor du köpt. Det viktiga är att sortera upp dem i A+, A- och B+ och B- samt vilka som är gemensamma om det är 5 eller 6 ansluntingar.

Typ Exempel A+ Acom A- B+ Bcom B-
Bi 4 Nema 16 Svart Grön Röd Blå
Bi 4 Orange Blå Röd Gul
Uni 5 BYJ48 Rosa Röd Orange Gul Röd Blå
Uni 6 Nema 23 Svart Gul Grön Röd Vit Blå

Nedan klippt ur datablad. Överst stegsekvens (mer om det längre ner) och under hur lindningarna sitter och deras färg.



Bipolär med 4 anslutningar

Vi måste här vända på polariteten för att driva runt stegmotorn. Stegmotorn är enklare konstruera men drivelektroniken lite mer komplicerat.



Observera att ovan bilder enbart är en något förenklad modell. I verkligheten ser en stegmotor inte sällan ut som nedan inuti. Tack vare en finurlig kugg-konstruktion tickar rotorn fram små steg vid varje förändring av elektromagneterna. (Nedan snurrar av händelse åt andra hållet mot ovan)



Unipolär med 5 anslutningar

Nu behöver vi inte vända på polariteten längre. Vi behöver bara flytta drivningen (-) till de lindningar vi vill magnetisera. Drivelektroniken blir enklare men stegmotorn blir mer komplicerad.



Metoder driva runt stegmotorn

Vid sidan om att identifiera hur stegmotorn är konstruerad så måste man välja någon metod att driva runt den.

Fullsteg

En elektromagnet åt gången magnetiseras.



Halvsteg

Genom att varannat steg elektrifiera 2 elektromagneter skapas ett mellanläge, vilket ger dubbelt så många steg.



Mikrosteg

Mikrosteg är en teknik där man stegvis flyttar magnetiseringen mellan två lindningar. På så vis åstadkommer man ett antal virtuella steg mellan två magneter. Mikrosteg kräver därför en ganska avancerad drivelektronik.

Exempel på fullsteg med 2 faser

Genom att magnetisera 2 magneter åt gången får vi samma upplösning som ett vanligt fullsteg, men starkare vridmoment. Det är intutivt på något sätt eftersom 2 aktiva magneter bör vara starkare tillsammans än 1 magnet, eller hur?



Stegsekvensen

Arbetet att driva runt stegmotorn handlar alltså om att aktivera elektromagneterna i stegmotorn enligt ett mönster som driver runt axeln. Denna aktivering kan göras på flera olika sätt.

Jag har en stegmotor här (en 5-trådars unipolär stegmotor BYJ48) som enligt dokumenteringen kan drivas runt med hjälp av nedanstående sekvens. Detta kallas fullsteg.

Fullsteg



I detta fall skall man upprepande mata ut mönstret 1000, 0100, 0010, 0001, ... (eller i omvänd ordning beroende på riktning) med lämplig hastighet på de digitala portar som matchar stegmotorns 4 lindningar.

Det finns som sagt något som heter halvsteg (beskrivet ovan) och det innebär att man lägger in ett steg mitt-i-mellan två elektromagneter i motorn genom att magnetisera båda elektromagneterna samtidigt.

Halvsteg


Vilket också kan visualiseras såhär:


Vi ska alltså upprepande mata ut mönstret 1000, 1100, 0100, 0110, 0010, 0011, 0001, 1001, ... (eller i omvänd ordning beroende på riktning) med lämplig hastighet på de digitala portar som matchar stegmotorns 4 lindningar.

Halvsteg ger en jämnare gång på stegmotorn men till priset att vridmomentet blir lägre.

Vilken riktning stegmotorn snurrar beror helt på i vilken ordning dessa sekvenser matas ut till stegmotorn.

Driva stegmotorn

Strömmen på utgångarna på en mikrokontroller räcker inte för att driva en stegmotor så det behövs någon form av effektsteg här. Typiskt är det någon krets t.ex. ULN2803 eller ULN2003 som ligger mellan mikrokontrollern och stegmotorn enligt nedan.





Men det går även att konstruera detta effektsteg med t.ex. BC547 transistorer t.ex. enligt nedan.


När man tittar på ovanstående schema och även det med ULN2803, så kan man få intrycket att signalen inverteras och att man därför måste skicka in en inverterad signal för att det skall bli "rätt". Att signalen inverteras stämmer, men det blir rätt ändå. Lindningarnas gemensamma anslutning på stegmotorn går till 5 eller 12 volt, så det är just när lindningens andra anslutning "nollas" (sänks) som den blir aktiv (flyter en ström). Så en hög signal in betyder fortfarande att elektromageten i stegmotorn är aktiv och vice versa.

Programmet - med riktning och fartreglering

Uppkoppling

Först kanske ska sägas att eftersom stegmotorn 28BYJ48 har en växellåda så snurrar axeln ut ganska långsamt. Detta är därför kanske inte den mest visuella stegmotorn för att se vad som händer. Men strunt i den detaljen nu! (Men det är bra att veta att det existerar en växellåda annars kanske du undrar varför det går så långsamt)

Koden nedan bör fungera för vilken stegmotor som helst som är unipolär med 4 magneter (5 trådar).

Nedan kod kan ställas in så att den antingen kör fullsteg (FULLSTEP) eller halvsteg (HALFSTEP). De digitala utgångarna 8-9-10-11 kopplas till IN1-IN2-IN3-IN4. För att reglera hastigheten kopplas en potentiometers mittenutgång till pinne 1 och de andra pinnarna på potentiometern till GND resp. 5V (det blir en spänningsdelare som kan regleras från 0-5V).



Om ovan bild och text är lite otydlig, här kommer en bild till.


28BYJ48

Observera att stegmotorn använd här ser ut som nedan. Vi avfyrar sedan elektromagneterna i denna enligt följande för fullsteg; 1000, 0100, 0010, 0001 där lindningarna är BRGO (Blå-Rosa-Gul-Orange) och 1000, 1100, 0100, 0110, 0010, 0011, 0001, 1001 för halvsteg.



Användning

Funktionen är sådan att när potentiometern står i mitten så står stegmotorn stilla. Vrider man åt ena eller andra hållet snurrar stegmotorn medurs eller moturs och hastigheten beror på hur mycket man vrider åt ena eller andra håller.

Funktion

En timer-interrupt sätts med en väntetid som beror på vad potentiometer står på. Beroende på om potentiometern befinner sig på vänster eller höger halva (dvs utsignalen blir mer eller mindre än 512 (alltså halva 1024 som är full signal på analog ingång)) så sätts även rotate till +1 eller -1.

För varje steg (interrupt-avbrott) räknas fasen upp eller ner och börjar om i andre änden. Dvs 0-1-2-3-0-1-2-3-0-1-2 osv. eller vice versa och vi skriver sedan ut värdet på stegmotorns lindningar enligt tabellerna halfStep eller fullStep beroende på vad som är önskvärt.

Vi ändrar enbart interruptet om vi har vridit lite på potentiometern, därför sparar jag lastPotValue (senaste värdet). Värdet från A/D -omvandlaren rör sig alltid lite så därför jämför jag med en viss tröskel (3).

#define HALFSTEP 1
#define FULLSTEP 2

int stepMode = HALFSTEP;

int POT = 1;    // Potentiometer (fart)
int IN1 = 8;    // Blå - 28BYJ48 pin 1
int IN2 = 9;    // Rosa - 28BYJ48 pin 2
int IN3 = 10;   // Gul - 28BYJ48 pin 3
int IN4 = 11;   // Orange - 28BYJ48 pin 4

int halfStep[8] = {
	B01000, 
	B01100, 
	B00100, 
	B00110, 
	B00010, 
	B00011, 
	B00001, 
	B01001};

int fullStep[4] = {
	B01000, 
	B00100, 
	B00010, 
	B00001};

int phase = 0;
int rotate = 1;
int potValue;
int lastPotValue;

void setup() 
{
  Serial.begin(9600); 
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  
  potValue = analogRead(POT);
  setupInterrupt(potValue);
}

void setupInterrupt(int potValue)
{
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A =  16000 - abs(potValue-512)*30; 
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
  TIMSK1 |= (1 << OCIE1A);
  sei();      
}

ISR(TIMER1_COMPA_vect)
{
  setOutput(phase);
  phase += rotate;

  if(stepMode == HALFSTEP)
  {
    phase%=8;
    if(phase<0)
    phase = 7;
  }
  if(stepMode == FULLSTEP)
  {
    phase%=4;
    if(phase<0)
    phase = 3;
  }

  potValue = analogRead(POT);
  if(abs(potValue - lastPotValue) > 3)
  {
    Serial.println(potValue);    
    if(potValue>512)
      rotate = 1;
    else
      rotate = -1;
    lastPotValue = potValue;    
    setupInterrupt(potValue);
  }  
}

void setOutput(int out)
{
  if(stepMode == HALFSTEP)
  {
    digitalWrite(IN1, bitRead(halfStep[out], 0));
    digitalWrite(IN2, bitRead(halfStep[out], 1));
    digitalWrite(IN3, bitRead(halfStep[out], 2));
    digitalWrite(IN4, bitRead(halfStep[out], 3));
  }
  if(stepMode == FULLSTEP)
  {
    digitalWrite(IN1, bitRead(fullStep[out], 0));
    digitalWrite(IN2, bitRead(fullStep[out], 1));
    digitalWrite(IN3, bitRead(fullStep[out], 2));
    digitalWrite(IN4, bitRead(fullStep[out], 3));
  }  
}

void loop()
{

}