A12. Servot - matpi/EmbeddedSystemsUTU GitHub Wiki
Servo on eräälainen vaihteistolla varustettu sähkömoottori, joka tietää oman asentonsa. Servoa voidaan siis ohjata tarkasti johonkin tiettyyn asentoon jossa se pyrkii pysymään. Servojen käyttöä varten on arduino-ohjelmassa valmis servo-kirjasto. Servo tietää mihin asentoon sen pitää mennä, kun sen ohjauspinniin syötetään pulssi. Kun pulssi on 75 mikrosekuntia, servo kääntyy toiseen äärilaitaan. Toiseen äärilaitaan servo kääntyy tyypillisesti 225 mikrosekunnin pulssilla. Arduinon kirjasto hoitaa nämä pulssitukset automaattisesti ohjelman taustalla. Sillä voidaan ohjata 12 servoa yhtäaikaisesti. Arduino Mega kehitysalustaa ja PWM pulssitusta käytettäessä voidaan ohjata jopa 48 servoa yhtä aikaa.
Tavanomaisen servon liike vaihtelee yleensä 0 ja 180 asteen välillä. Ohjelmakoodissa arvo 0 saa servon liikkumaan toiseen ääriasentoon, arvo 90 keskelle ja arvo 180 toiseen ääriasentoon. Erityisesti mikroservoissa liike saattaa kuitenkin olla pienempi. Käyttäessäsi mikroservoa aseta tämän vuoksi aluksi servon toisen ääripään maksimiarvo pienemmäksi kuin 180 (esim. 165). Tällöin myös servon keskiasennon arvo on pienempi kuin 90.
Servo kytketään siten että :
-
ruskeaan tai mustaan reunassa olevaan johtimeen kytketään maa/GND
-
punaiseen johtimeen kytketään 5v-virta
-
reunassa tai keskellä olevaan valkoiseen, keltaiseen tai oranssiin johtimeen kytketään arduinon output pinni, jolla servoa ohjataan
Pienet servot voi testikäytössä liittää suoraan Arduinon +5 Volttiin.
Isommalle servolle tai useammalle pikkuservolle kannataa kytkeä oma virtalähde, koska ne vievät virtaa enemmän kuin Arduino pystyy antamaan. Silloin Arduinon ja servon virtalähteen maat on kytkettävä yhteen.
Seuraava koodi heiluttelee yhtä servoa asennosta toiseen. Arvot on tässä koodissa asetettu pienille servoille sopiviksi:
#include <Servo.h>
Servo ekaServo; // luodaan servo-objekti nimeltä ekaServo
void setup()
{
ekaServo.attach(9); //käynnistää ekaServo nimisen servo-objektin pinnissä 9
ekaServo.write(77); // asettaa servon keskelle, 90 asteen kulmaan
delay(1000); // servolle pitää antaa aikaa liikkua
}
void loop()
{
ekaServo.write(0); // käskee servon toiseen äärilaitaan, 0-asteen kulmaan
delay(1000);
ekaServo.write(161); // käskee servon vastakkaiseen äärilaitaan, 180 asteen kulmaan
delay(1000);
ekaServo.write(77); // takaisin keskelle ja odotellaan 5 sekuntia
delay(5000);
}
On olemassa myös 360 astetta kääntyviä eli ympäri pyöriviä (continuous rotation) servoja. Tällaisia servoja käytetään esim. robottiauton moottoreina tai muissa jatkuvaa pyörimisliikettä hyödyntävissä sovelluksissa. Esim. Parallax valmistaa tällaisia servoja http://www.parallax.com/sites/default/files/downloads/900-00008-Continuous-Rotation-Servo-Documentation-v2.2.pdf. Myös tavallisesta servosta voi tehdä ympäri pyörivän. Netin keskustelufoorumeilta löytyy ohjeita tähän: esimerkkinä http://www.ruuvipenkki.fi/foorumi/viewtopic.php?f=15&t=66
Ympäri pyörivän servon kytkeminen arduinoon tapahtuu samalla tavalla kuin tavanomaisen servon kytkentä. Pyörimissuunnan vaihto tapahtuu koodin avulla. Nyt on vain etsittävä koodin parametrejä vaihtamalla ja/tai potentiometristä säätämällä servon nollakohta, jossa servo pysyy paikallaan. Käskyllä ekaServo.write(90) eli käskyn parametrilla 90 servon pitäisi pysyä paikallaan. Nollakohdan ylittävä tai alittava arvo saa servon pyörimään jompaan kumpaan suuntaan. Servomoottorin huonona puolena on, että se tarvitsee jatkuvan ohjausvirran.
Kokeile oheista koodia: tämän koodin avulla servon pitäisi pysyä kahdeksan sekuntia paikallaan ja pyörähtää sitten yhden sekunnin ajan toiseen suuntaan. Sen jälkeen servon tulisi taas pysyä kahdeksan sekuntia paikallaan ja sitten pyöriä yhden sekunnin ajan vastakkaiseen suuntaan. Jos servo on jatkuvassa pienessä liikkeessä myös oletetun tauon aikana, käännä varovasti pienen ruuvitaltan kärjellä servon sisällä olevaa trimmeriä jompaan kumpaan suuntaan. Säädä trimmeri sellaiseen asentoon, että servo pysyy paikallaan ohjelman mukaisesti.
#include <Servo.h>
Servo ekaServo; // luodaan servo-objekti nimeltä ekaservo
void setup()
{
ekaServo.attach(9); //käynnistää ekaservo nimisen servo-objektin pinnissä 9
}
void loop()
{
ekaServo.write(90); // käskee servon pysyä paikallaan
delay(8000);
ekaServo.write(80); // käskee servon pyöriä toiseen suuntaan
delay(1000);
ekaServo.write(90); // käskee servon pysyä paikallaan
delay(8000);
ekaServo.write(100); // käskee servon pyöriä vastakkaiseen suuntaan
delay(1000);
}
Yritä luoda kytkentä, jossa ultraäänianturi toimii etäisyysmittarina, ja saa ympäri pyörivän servon pyörimissuunnan muuttumaan tietyllä etäisyydellä. Kokeile tätä ensin yhdellä servolla ja sitten kahdella servolla. Kun saat tehtävän ratkaistua, mieti kuinka tehtävää voisi soveltaa itse liikkuvaan robottiautoon, joka osaa väistää esteitä.
#include <Servo.h>
int echoPin = 11; // Määritellään, mihin Arduino pinniin echoPin yhdistetään
int trigPin = 12; // Määritellään, mihin Arduino pinniin trigPin yhdistetään
long kesto = 0; // Määritellään long-tyyppinen muuttuja nimeltä kesto
long matka = 0; // Määritellään long-tyyppinen muuttuja nimeltä matka
Servo ekaServo; // luodaan servo-objekti nimeltä ekaservo
Servo tokaServo;
void setup()
{
ekaServo.attach(9); //käynnistää ekaservo nimisen servo-objektin pinnissä 9
tokaServo.attach(8); //käynnistää ekaservo nimisen servo-objektin pinnissä 9
Serial.begin (9600); // Avataan sarjaliikenne tietokoneelle nopeudella 9600 bps
pinMode(trigPin, OUTPUT); // Määritellään trigPin outputiksi
pinMode(echoPin, INPUT); // Määritellään echoPin inputiksi
}
void loop()
{
ultra(); // Määritellään ultra -niminen fuktio
Serial.println(matka); //"Serial.println" komento vaihtaa riviä tulostuksen jälkeen
if (matka > 50)
{
delay(10);
ekaServo.write(100); // käskee servon liikkua eteen päin
tokaServo.write(80); // käskee servon liikkua eteen päin
delay(100);
}
else if(matka < 50)
{
peruuta();
}
}
void ultra() // Kutsutaan ultra
{
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
kesto = pulseIn(echoPin, HIGH);
matka = kesto/58.2; // Muuttujan matka arvo muutetaan senttimetreiksi ko. kaavalla
return;
}
void peruuta()
{
ekaServo.write(80); // käskee servon liikkua eteen päin
tokaServo.write(80); // käskee servon liikkua eteen päin
delay(3000);
return;
}