Difference between revisions of "Arduino - Een servo"

From SPAD-it Wiki
Jump to: navigation, search
(Het programma)
Line 34: Line 34:
  
 
<pre>
 
<pre>
int servoPin=9;     // servo op pin digitale IO pin 9
+
int servoPin=9;   // servo op pin digitale IO pin 9
int potPin=0;       // potmeter op analoge pin A0
+
int potPin=0;     // potmeter op analoge pin A0
int cyclus = 20000; // microsecondes van de hele PWM cyclus => 50Hz
+
int cyclus=20000; // microsecondes van de hele PWM cyclus => 50Hz
int min = 50;       // microsecondes hoog voor minimale arm-stand
+
int minPulse=50;   // microsecondes hoog voor minimale arm-stand
int max = 2500;     // microsecondes hoog voor maximale arm-stand
+
int maxPulse=2500; // microsecondes hoog voor maximale arm-stand
  
 
void setServoPulse(float arm_stand)      // dient continu te worden aangeroepen
 
void setServoPulse(float arm_stand)      // dient continu te worden aangeroepen
Line 44: Line 44:
 
// arm-stand 1 => helemaal rechts
 
// arm-stand 1 => helemaal rechts
 
{
 
{
   pulseBreedte = (int)min + arm_stand*(max-min); // berekening duur pulse, als geheel getal
+
   int pulseBreedte = (int)minPulse + arm_stand*(maxPulse-minPulse); // berekening duur pulse, als geheel getal
 
   digitalWrite(servoPin,HIGH);            // signaal naar HIGH
 
   digitalWrite(servoPin,HIGH);            // signaal naar HIGH
 
   delayMicroseconds(pulseBreedte);        // wacht pulseWidth
 
   delayMicroseconds(pulseBreedte);        // wacht pulseWidth
Line 59: Line 59:
 
{
 
{
 
   float potVal=(float)analogRead(potPin)/1024;  // stand van de pot, omgezet naar getal tussen 0 en 1
 
   float potVal=(float)analogRead(potPin)/1024;  // stand van de pot, omgezet naar getal tussen 0 en 1
   for(int i=0;i<=10;i++)
+
   for(int i=0;i<=10;i++)   // elke keer 10 cycli => duurt 0,2 seconde
 
   {
 
   {
 
     setServoPulse(potVal);                      // dient continu te worden aangeroepen
 
     setServoPulse(potVal);                      // dient continu te worden aangeroepen

Revision as of 11:19, 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

Beetje spelen

Verdiepende opdrachtjes

Navigatie