Difference between revisions of "Arduino - Een servo"

From SPAD-it Wiki
Jump to: navigation, search
(Het programma)
(Uitleg)
Line 67: Line 67:
  
 
===Uitleg===
 
===Uitleg===
 +
Allereerst wordt aangegeven aan welke digitale pin de servo hangt en aan welke analoge pin de potmeter van de joystick zit. Daarna worden de details van de servo-besturing opgegeven. Dit zijn de duur van de cyclus (20ms = 20000 microseconde), 50 microseconde voor de minimale puls en 2500 microseconde voor de maximale puls. De ''setup()'' is in dit geval buitegewoon simpel en stelt alleen de servo-pin in als output. Ook de ''loop()'' functie is vrij eenvoudig. Hij leest de analoge waarde van de potPin en zet dat getal meteen om in een floating point getal tussen 0 en 1. Daarna stuurt het die waarde 10 keer achter elkaar naar de functie ''setServoPulse()''. Dit duurt bij elkaar dus 10 cycli en dus 0,2 seconde. Het komt erop neer dat de analoge waarde 5 keer per seconde wordt gemeten, waarna de servo met de nieuwe waarde wordt aangestuurd.
  
 +
De functie ''setServoPulse()'' doet het echte werk. Maar ook deze functie is relatief eenvoudig. Hij berekent de pulsebreedte. Bij ''arm_stand=0'' moet daar ''minPulse'' uit komen en ''maxPulse'' bij ''arm_stand=1''. Dat doet de berekening op de eerste regel. Daarna wordt de uitgang op ''servoPin'' hoog gemaakt. Dan volgt een wachttijd van ''pulseBreedte'' (in microsecondes), wordt ''servoPin'' laag gemaakt en wacht de functie de resterende tijd van de cyclus. Elke aanroep van ''setServoPulse()'' voert dus precies een cyclus uit.
  
 
===Beetje spelen===
 
===Beetje spelen===

Revision as of 11:32, 1 February 2018

Een servo is een mechanisch element dat een as heeft die in bepaalde mate kan draaien. Heel vaak wordt aan de as van de servo een arm bevestigd die met de as meebeweegt. Daarmee kun je bijvoorbeeld het roer van een modelschip besturen of het stuur van een modelauto. Naast toepassingen in de modelbouw hebben servo's talloze andere toepassingen, zoals de cruisecontrol van een auto en het hoogteroer van vliegtuigen. Van binnen heeft een servo een motor die via een aantal tandwielen de stand van de as bediend. Die tandwielen zorgen voor vertraging, maar vergroten de kracht van de servo. Daarnaast wordt de stand van de as gemeten, doorgaans met een potmeter, waarmee de stand van de arm wordt omgezet in een spanning. Door elektronische terugkoppeling wordt die spanning, en dus de positie van de arm, geregeld naar gelang het inputsignaal. Dit mechanisme brengt wel met zich mee dat dit soort servo's relatief veel stroom verbruiken. In feite hebben zowel het inputsignaal als de meting van de stand van de arm steeds kleine afwijkingen, waardoor de elektronica continu zal proberen om de positie te verbeteren. Het gevolg is dat de motor bijna continu wordt aangestuurd en de servo relatief veel stroom verbruikt. Toch moet dat stroomverbruik ook niet worden overdreven; kleine servo's kunnen nog altijd rechtstreeks op een Arduino worden aangesloten.

Uiteraard werken verschillende servo's op verschillende spanningen, maar servo's hebben ook andere belangrijke karakteristieken. Zo hebben ze een maximaal draaibereik en leveren ze een beperkte maximale kracht. Ook de snelheid waarmee ze van het ene uiterste naar het andere uiterste kunnen bewegen kan een belangrijk kenmerk zijn. Als je een servo aanschaft is het altijd verstandig om te onderzoeken of jouw servo voldoet voor jouw specifieke toepassing. Naast dit soort analoge servo's bestaan er tegenwoordig overigens ook digitale servo's. Die hebben uiteraard een andere interne werking en worden ook anders aangestuurd. Hier gaat het echter over analoge servo's.


Servo.jpg
Een typische servo voor de modelbouw met drie aansluitdraden: zwart/bruin=0V, rood=5V, geel/oranje=input

Door een servo aan te sluiten op een Arduino kunnen we de servo met een programma netjes laten bewegen. We kunnen dan natuurlijk ook die servo besturen met een [[joystick die ook op de Arduino wordt aangesloten. We sluiten daarom tegelijk een joystick en een servo aan op de Arduino en maken een programma waarmee de servo met de joystick wordt bestuurd.

Input signaal

Het inputsignaal heeft typisch de vorm van een puls-breedte-modulatiesignaal. De stand van de arm correspondeert dan met de pulsbreedte. Helaas is het niet zo dat we daarmee de PWM mogelijkheden van Arduino kunnen gebruiken. Servo's gebruiken namelijk een basisfrequentie van 50Hz, terwijl de frequentie van het PWM signaal van Arduino veel hoger ligt (afhankelijk van de versie). Daar komt bij dat de minimale en maximale stand van de arm niet overeenkomen met een duty cycle van 0 en 100%, maar meer in de buurt komt van 2,5% tot 12,5%. De arm van de servo kan dus helemaal naar links worden gestuurd met een signaal dat afwisselend 0,5ms hoog en 19,5ms laag is. De arm staat helemaal naar rechts met een signaal dat afwisselend 2,5ms hoog en 17,5ms laag is. Merk op dat de cyclus steeds 20ms duurt. Dit komt neer op 50 cycli per seconde, ofwel 50Hz. Deze details kunnen per type servo overigens wat afwijken.

Ondanks dat we niet direct PWM kunnen gebruiken, kunnen we een servo toch direct aansluiten op een digitale poort van Arduino en een programma maken dat de servo netjes laat bewegen. We moeten de pulse-breedte modulatie dan zelf programmeren.

De schakeling

Extra benodigdheden:

  • 1 5V servo
  • 8 joystick module
Servo schakeling.png
Schakeling met servo en joystick

Het programma

int servoPin=9;    // servo op pin digitale IO pin 9
int potPin=0;      // potmeter op analoge pin A0
int cyclus=20000;  // microsecondes van de hele PWM cyclus => 50Hz
int minPulse=50;   // microsecondes hoog voor minimale arm-stand
int maxPulse=2500; // microsecondes hoog voor maximale arm-stand

void setServoPulse(float arm_stand)       // dient continu te worden aangeroepen
// arm-stand 0 => helemaal links
// arm-stand 1 => helemaal rechts
{
  int pulseBreedte = (int)minPulse + arm_stand*(maxPulse-minPulse); // berekening duur pulse, als geheel getal
  digitalWrite(servoPin,HIGH);            // signaal naar HIGH
  delayMicroseconds(pulseBreedte);        // wacht pulseWidth
  digitalWrite(servoPin,LOW);             // signaal naar LOW
  delayMicroseconds(cyclus-pulseBreedte); // wacht de rest van de cyclus tijd
}

void setup()
{
  pinMode(servoPin,OUTPUT);
}

void loop()
{
  float potVal=(float)analogRead(potPin)/1024;  // stand van de pot, omgezet naar getal tussen 0 en 1
  for(int i=0;i<=10;i++)   // elke keer 10 cycli => duurt 0,2 seconde
  {
    setServoPulse(potVal);                      // dient continu te worden aangeroepen
  }
}

Uitleg

Allereerst wordt aangegeven aan welke digitale pin de servo hangt en aan welke analoge pin de potmeter van de joystick zit. Daarna worden de details van de servo-besturing opgegeven. Dit zijn de duur van de cyclus (20ms = 20000 microseconde), 50 microseconde voor de minimale puls en 2500 microseconde voor de maximale puls. De setup() is in dit geval buitegewoon simpel en stelt alleen de servo-pin in als output. Ook de loop() functie is vrij eenvoudig. Hij leest de analoge waarde van de potPin en zet dat getal meteen om in een floating point getal tussen 0 en 1. Daarna stuurt het die waarde 10 keer achter elkaar naar de functie setServoPulse(). Dit duurt bij elkaar dus 10 cycli en dus 0,2 seconde. Het komt erop neer dat de analoge waarde 5 keer per seconde wordt gemeten, waarna de servo met de nieuwe waarde wordt aangestuurd.

De functie setServoPulse() doet het echte werk. Maar ook deze functie is relatief eenvoudig. Hij berekent de pulsebreedte. Bij arm_stand=0 moet daar minPulse uit komen en maxPulse bij arm_stand=1. Dat doet de berekening op de eerste regel. Daarna wordt de uitgang op servoPin hoog gemaakt. Dan volgt een wachttijd van pulseBreedte (in microsecondes), wordt servoPin laag gemaakt en wacht de functie de resterende tijd van de cyclus. Elke aanroep van setServoPulse() voert dus precies een cyclus uit.

Beetje spelen

Verdiepende opdrachtjes

Navigatie