Difference between revisions of "Arduino - Een servo"
(→Het programma) |
|||
| Line 34: | Line 34: | ||
<pre> | <pre> | ||
| − | int servoPin=9; | + | int servoPin=9; // servo op pin digitale IO pin 9 |
| − | int potPin=0; | + | 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 | + | int minPulse=50; // microsecondes hoog voor minimale arm-stand |
| − | int | + | 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) | + | 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.
|
| 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
|
| 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

