Stappenmotor draait niet

In mijn eerste poging tot het aansturen van een stappenmotor loop ik tegen het probleem aan dat hij niet gaat draaien.

Mijn opstelling bestaat uit:
- Arduino UNO
- Stappenmotor sanyo denki 103H546-0440 (datasheet: http://www.robotstorehk.com/micromouse/doc/103H546-0440.pdf)
- ULN2004AG

Schema:
http://www.maze-online.nl/Stappenmotor_test.jpg

Arduino script:

c code:


int motorSpeed = 4;

void setup() {                
  pinMode(3, OUTPUT);  
  pinMode(4, OUTPUT);  
  pinMode(5, OUTPUT);  
  pinMode(6, OUTPUT);  
}

void loop() {
  
  digitalWrite(4, LOW);   
  digitalWrite(5, LOW);   
  digitalWrite(6, HIGH);   
  digitalWrite(7, HIGH); 
  delay(motorSpeed);
  digitalWrite(4, HIGH);   
  digitalWrite(5, LOW);   
  digitalWrite(6, LOW);   
  digitalWrite(7, HIGH);
  delay(motorSpeed);
  digitalWrite(4, HIGH);   
  digitalWrite(5, HIGH);   
  digitalWrite(6, LOW);   
  digitalWrite(7, LOW);
  delay(motorSpeed);
  digitalWrite(4, LOW);   
  digitalWrite(5, HIGH);   
  digitalWrite(6, HIGH);   
  digitalWrite(7, LOW); 
  delay(motorSpeed);
}

Waardoor kan het komen dat deze opstelling niet werkt zoals ik dat voor ogen zou hebben?

Je maakt telkens twee uitgangen hoog. Probeer het eerst door de uitgangen één voor één hoog te maken. En dan liefst in de juiste volgorde, en niet te snel.

Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)

Klopt, zal het vanavond eens proberen, echter wordt in de datasheet aangegeven dat het er steeds twee moeten zijn of zie ik dat verkeerd?

Je kan wel tussenstappen nemen: eerste uitgang hoog, dan eerste en tweede samen, vervolgens enkel de tweede, dan de tweede en de derde, enz...
Een situatie, waar altijd twee wikkelingen gestuurd worden, lijkt me hoogst ongebruikelijk.

Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)

Thanks, hij doet het nu wel. Zelfs met een delay van 1.

Wanneer ik nu de delay op 0 zet, blijft hij stilstaan. Betekend dit dat de stappenmotor dit niet trekt?

En dan nog een kleine vraag: hoe laat ik hem nu in de tegengestelde richting draaien?

c code:


int myMotorSpeed = 1;

void setup() {                
  pinMode(4, OUTPUT);  
  pinMode(5, OUTPUT);  
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT);  
}

void loop() {
  
   runStep(1,0,0,0, myMotorSpeed);
   runStep(1,1,0,0, myMotorSpeed);
   runStep(0,1,0,0, myMotorSpeed);
   runStep(0,1,1,0, myMotorSpeed);
   runStep(0,0,1,0, myMotorSpeed);
   runStep(0,0,1,1, myMotorSpeed);
   runStep(0,0,0,1, myMotorSpeed);
   runStep(1,0,0,1, myMotorSpeed);
  
}

void runStep(int pin4, int pin5, int pin6, int pin7, int motorSpeed){
  digitalWrite(4, pin4);   
  digitalWrite(5, pin5);   
  digitalWrite(6, pin6);   
  digitalWrite(7, pin7);
  delay(motorSpeed);
}
Arco

Special Member

Het lijkt me nogal logisch dat het zonder delay niet werkt, dat kan de motor mechanisch niet bijbenen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

hoe laat ik hem nu in de tegengestelde richting draaien?

Door de volgorde om te draaien.

Wat het toerental betreft: dat wordt voor een groot deel beperkt door het inductieve karakter van de wikkelingen. Er bestaan verschillende truuken om een hogere snelheid te halen, maar de beste resultaten ga je halen met een echte stepper-driver.

Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)

Nog afgezien van de inductie en voedingsspanning, is een delay van 1 nog steeds een stapfrequentie van maar 1kHz, terwijl een delay van 0 een veel hogere frequentie wordt (waarschijnlijk vele kHz).

@pros: het is helemaal niet ongebruikelijk om steeds 2 spoelen tegelijk te bekrachtigen (zie full-step, half-step, wave-step patronen), maar dan natuurlijk niet de 2 spoelen die een middenaftakking delen, zoals de TS doet in het eerste voorbeeld. Deze 2 spoelen geven natuurlijk een tegengesteld koppel, waardoor er niets gebeurd.

@TS: voor de duidelijkheid: om te motor de andere kant op te laten draaien, moet je hetzelfde patroon aanbieden, maar dan is omgekeerde volgorde. Als je van dat patroon (de eerste 4 parameters van je Runstep functie) nu een array maakt, waarbij je het stapnummer meegeeft als argument, kun je vooruit door steeds 1 bij het stapnummer op te tellen, en achteruit door er steeds 1 vanaf te trekken. Je moet er natuurlijk wel voor zorgen dat je niet buiten de lengte van de array komt, bijvoorbeeld door de index steeds bitwise te AND'en met 0x07.

Volgens mij klopt je stappenpatroon trouwens niet, zie hierboven; je bekrachtigd nu 2 spoelen die tegengesteld in de motor zitten.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Of gebruikt een atxmega die heeft daar waveform generator functie voor, die kan hardwarematig steppers aansturen. Ik ga mijn reprap aansturing daarmee bouwen.

Maar met gewoon pwm kom je ook al eind. Zijn aantal documenten te vinden die goed uitleggen hoe microsteps werken en hoe je de resolutie kan verhogen en resonantie verlagen.

Je zult nu wel niet zoveel trekkracht overhouden met je aansturing door maar 1 poort hoog te maken. Krijgt dan hele schokkerige wave aansturing die heel veel herrie maakt en weinig kracht heeft. Moet nu gewoon verder naar volle stappen of gelijk naar halve stappen. Uiteindelijk zou je bij microstaps moeten uitkomen met acceleratie controller met stroom meting. Dan zullen je motor's relatief stil zijn en volle kracht en resolutie zonder schokken.

Volle stappen.
1010
0110
0101
1001

Zonder al te veel moeite kan je al halve stappen doen.
1000
1010
0010
0110
0100
0101
0001
1001

http://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Drive.png/440px-Drive.png

Hier nog wat leesvoer, is nog veel meer over te vinden.
http://ww1.microchip.com/downloads/en/AppNotes/00822a.pdf

Tja, je begint met een stappenmotor met vaste voedingsspanning, zonder PWM, en een blokvormig stappenpatroon.

Vervolgens ga je stroom meten, PWM'en om die stroom te regelen vanaf een hogere voedingsspanning, sinusvormige stromen sturen voor microstepping, uiteindelijk nog de stroom voorspellen en vergelijken met de werkelijkheid om de rotorpositie te kunnen volgen, en voor je het weet kom je gewoon uit bij sensorless field-oriented control voor een permanente magneet motor, die toevallig geen 3 fasen in ster geschakeld heeft.

Stappenmotoren en borstelloze DC of permanente magneet synchrone motoren liggen helemaal niet zover uit elkaar, alleen de manier van wikkelen en het aantal poolparen verschilt.

Maar het lijkt me handig om de TS eerst hiermee te laten spelen, tenslotte heeft het net voor het eerst een stappenmotor zelf laten draaien. Daarbij is een simpele sturing voor veel toepassingen goed genoeg.

@TS: dat voelt goed he? Ik kan me nog herinneren (zo'n 15 jaar geleden, denk ik) dat ik voor het eerst zo'n ding aan de gang kreeg. Dat was nog de tijd dat je die dingen volop in printers vond, en er genoeg oude 5.25" floppydrives waren om ze uit te slopen. Tegenwoordig worden ze een beetje zeldzaam, er zijn nog maar weinig apparaten waar leuke steppers in zitten.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Thanks iedereen

@pros: Het omdraaien van draairichting is inmiddels gelukt, logisch ook !

@peter79: Ik zal me er binnenkort eens in verdiepen. Had al een aantal 3d-printers bekeken. Leuk speelgoed, maar nog net iets te hoog gegrepen vermoed ik.

@SparkyGSX: Vooral de combinatie met programmeren boeit me. De fysieke aansluiting is alleen wat lastiger :)

Deze stappenmotor heb ik een paar jaar geleden voor een euro of 7 gekocht. Helaas weet ik niet meer waar. Hebben jullie een idee waar je voor relatief weinig een dergelijk stappenmotor vandaan kan halen?

Lambiek

Special Member

Vraag of ze bij een computer bedrijf een oude printer hebben, daar zitten er een paar in.

Als je haar maar goed zit, GROETEN LAMBIEK.

Zorg ook dat je je outputs met een pulldown weerstand zet.

Edit: geloof dat ik een jaar of 10 te laat ben onderhand ;)

[Bericht gewijzigd door Zylar op maandag 16 januari 2012 22:07:47 (78%)

Bij samenkopen komen ze soms wel langs (o.a. de actie van Niels). In de printers van de afgelopen 5-8 jaar of zo zitten ze vaak al niet meer, daarin zijn ze vervangen door DC motoren met encoders op de motor of met lineaire encoders (transparant kunststof met heel fijn patroon van lijntjes).

In echt oude printers (vooral de dot-matrix printers) zitten nog wel leuke stappers, maar die heeft zelfs de kringloopwinkel nauwelijks meer, en op rommelmarkten en zo vind je ze ook bijna niet meer terug. Hooguit nog een keer zo'n Star LC-10 of LC-20, omdat die dingen echt onverwoestbaar waren.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

@Zylar: Waar moet deze weerstand precies komen? ik vermoed tussen poort 8 van de ULN2004AG en de GND van de Arduino right?

Is het tevens verstandig om tussen de output poorten van de Arduino en de input poorten van de ULN2004AG pullup weerstanden te plaatsen?

Lambiek

Special Member

die weerstanden zijn niet echt nodig, maar kan ook geen kwaad.

De ULNxxxx heeft intern een weerstand van 10K5, dus tussen je arduino en de ULN hoeft het niet.

Edit:

Op 18 januari 2012 08:53:13 schreef vMaze:
@Zylar: Waar moet deze weerstand precies komen? ik vermoed tussen poort 8 van de ULN2004AG en de GND van de Arduino right?

En zeker niet daar.
Als je weerstanden wilt plaatsen, zet ze dan over de poorten waar je motor aanhangt. Weerstanden van 1K bijv, maar nodig is het niet.

[Bericht gewijzigd door Lambiek op woensdag 18 januari 2012 09:47:15 (55%)

Als je haar maar goed zit, GROETEN LAMBIEK.

Ik dacht eigenlijk idd 10k weerstandjes aan de uitgangspoortjes, omdat arduino zelf geen interne pulldown heeft? weet het niet zeker hoor, ben er geen expert in.

Lambiek

Special Member

Nee dat hoeft niet, je maakt je poort hoog en laag die is dus gedefinieerd. En als je daar weerstanden aan wil hangen kan dat beter nog hoger 22 of 47K bijv.

Als je haar maar goed zit, GROETEN LAMBIEK.

Dat is niet helemaal waar; als de controller in een reset blijft hangen (bijvoorbeeld omdat je die aan het programmeren of debuggen bent) zijn de I/O pinnen hoog impedant.

De ULN2003 heeft echter interne pull-down weerstanden aan zijn ingangen, waardoor het niet nodig is die extern te plaatsen.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Ah inderdaad SparkyGSX, de ULN2004A zit inderdaad intern al met 20,7K naar grnd.

@lambiek, het ging idd niet om de arduino maar om de darlingtons,deze zijn wat gevoeliger voor ESD enzo.

Lambiek

Special Member

Wat heeft ESD hier mee te maken?.

Als je haar maar goed zit, GROETEN LAMBIEK.

Ik heb de weerstanden achterwege gelaten. Voor beginners die interesse hebben om relatief eenvoudig een stappen motor aan te sturen, dit programma kan je gebruiken om een stappen motor via serial naar links en rechts te laten draaien met de L en R toets.

Op deze manier maakt hij het minste lawaai ;)

Het idee is om twee stappen motoren erbij te scharrelen en een soort robotarm te bouwen.

c code:

// Config
int myMotorSpeed   = 2;
int steps = 10;
int offsetSlowdown = 6;
// int accelerationStart = 10;

char sinput;
int motorSpeed;

void setup() {                
  Serial.begin(9600);
  pinMode(4, OUTPUT);  
  pinMode(5, OUTPUT);  
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT);   
}

void loop() {
    
  if(Serial.available() > 0){
      sinput = Serial.read();
      
      Serial.println(sinput);
      
      
      if(sinput == 'r'){
        motorSpeed = myMotorSpeed;
        for(int o = 0; o < steps; o++){
          if(o > offsetSlowdown && o < steps){
            motorSpeed++;
            
          }
          runRightStep(motorSpeed);
        }
      }
      
       if(sinput == 'l'){
        motorSpeed = myMotorSpeed;
        for(int o = 0; o < steps; o++){
          if(o > offsetSlowdown && o < steps){
            motorSpeed++;
          
          }
          runLeftStep(motorSpeed);
        }
      }
      motorSpeed = myMotorSpeed;
      Serial.flush();
      delay(5);
  } 
}

void runRightStep(int motorSpeed){
   runStep(1,1,0,0, motorSpeed);
   runStep(0,1,0,0, motorSpeed);
   runStep(0,1,1,0, motorSpeed);
   runStep(0,0,1,0, motorSpeed);
   runStep(0,0,1,1, motorSpeed);
   runStep(0,0,0,1, motorSpeed);
   runStep(1,0,0,1, motorSpeed);
   runStep(1,0,0,0, motorSpeed);
}

void runLeftStep(int motorSpeed){
  runStep(1,0,0,0, motorSpeed);
  runStep(1,0,0,1, motorSpeed);
  runStep(0,0,0,1, motorSpeed);
  runStep(0,0,1,1, motorSpeed);
  runStep(0,0,1,0, motorSpeed);
  runStep(0,1,1,0, motorSpeed);
  runStep(0,1,0,0, motorSpeed);
  runStep(1,1,0,0, motorSpeed);
}

void runStep(int pin4, int pin5, int pin6, int pin7, int motorSpeed){
  digitalWrite(4, pin4);   
  digitalWrite(5, pin5);   
  digitalWrite(6, pin6);   
  digitalWrite(7, pin7);
  delay(motorSpeed);
}