Mikrokontrolér ATtiny – ovládanie servomotorov

Mikrokontrolér ATtiny je malý a ľahký čip s ôsmimi vývodmi. Nás zaujíma hlavne verzia v puzdre DIL, ktorá má vývody s rozstupom 0,1’’ čiže 2,54 mm. Šikovný kutil si poradí aj s variantom v puzdre pre plošnú montáž WIDE s rozstupom vývodom 0,05’’ čiže 1,27 mm. Prívlastky „malý“ a „ľahký“ sú ideálne nielen pre tvorcov miniatúrnych konštrukcií, ale aj pre modelárov. Preto ukážeme ako pomocou ATtiny45, alebo ATtiny85 ovládať servomotory.

Príklady sú vo videu:

https://youtu.be/L8TJfrWYxjo

Servomotory využívajú modelári a konštruktéri robotov. Servo je k riadiacej jednotke pripojené pomocou troch vodičov. Na červenom vodiči je kladné napájacie napätie, na čiernom (niekedy hnedom) vodiči je zem a na oranžový vodič sa privádzajú signály. Oranžový vodič je vo vnútri serva pripojený na riadiacu elektroniku, nemá veľký prúdový odber, takže ho môžete pripojiť priamo na port.

Ovládanie servomotorov pomocou modelárskeho diaľkového ovládania

Uhol natočenia, prípadne otáčky kontinuálneho serva sa ovládajú pomocou PWM, čiže pulzne šírkovej modulácie. Frekvencia impulzov privádzaných na oranžový vodič je 50 Hz, čo je čas trvania periódy 20 ms. Uhol natočenia sa ovláda šírkou impulzu. U klasického modelárskeho serva je šírka pulzu 0.5 až 2.5 ms a tejto hodnote zodpovedá uhol natočenia0°až 180, prípadne 0 – 270 stupňov, podľa konštrukcie serva. Kontinuálne servomotory fungujú tak, že zmenou šírky impulzov sa mení rýchlosť otáčania.

Našou úlohou je teda generovať PWM signál s periódou 20ms a šírkou impulzu pravouhlého signálu v rozsahu 1 až 2ms.Opakovacia frekvencia impulzov je 50 Hz. ATtiny má podporu PWM na výstupoch PB0, PB1, PB3 a PB4, túto funkcionalitu však využiť nemôžete, pretože frekvencia PWM impulzov je 500 Hz avšak my na ovládanie serva potrebujeme 50 Hz. Naprogramovať mikroprocesor na taktovacej frekvencii 8 MHz aby generoval signál 50 Hz s premenlivou šírkou impulzov nie je zložité.

Zabudovať maličký mikrokontrolér aj do menších modelov nie je problém

Pre servo pripojené na výstupe PB0 (PIN 5) môžeme vytvoriť kód, ktorý nastaví servo do strednej polohy (šírka impulzov 1 ms )a následne ho impulzmi so šírkou 2.5 ms pretočí do krajnej polohy.

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

void loop()
{
for(int i = 0; i<20; ++i) // pod dobu 20 cyklov čiže 400 ms
{ 
digitalWrite(PB0, HIGH);
delayMicroseconds(1000);// šírka impulzu 1 milisekunda
digitalWrite(PB0, LOW);
delay(19);// medzera medzi impulzami 19 ms
}
delay(1000);
for(int i = 0; i<20; ++i) // pod dobu 20 cyklov
{
digitalWrite(PB0, HIGH);
delayMicroseconds(2500); // šírka impulzu 2,5 milisekundy
digitalWrite(PB0, LOW);
delay(19); // medzera medzi impulzami 19 ms
}
delay(1000);
}

Pri využití vhodného synchrónneho časovania môžete bez problémov generovať PWM signály aj na viacerých pinoch.

Jednoduchšie sa vám bude obsluha servomotorov programovať pomocou knižnice SoftwareServo.

Jednoduchý kód, ktorý pootočí hriadeľ serva o 30 stupňov. Riadiaci signál servomotora je rovnako ako v predchádzajúcom príklade pripojený na výstupe PB0 (PIN 5)

#include 
SoftwareServo servo;

void setup()
{
servo.attach(0);// priradenie na pin 0 ATtiny
}

void loop()
{
servo.write(30); delay(300);
SoftwareServo::refresh();
servo.write(0); delay(300);
SoftwareServo::refresh();
}

V ďalšom príklade sa servo natáča z jednej krajnej polohy do druhej


#include 
SoftwareServo servo;
int uhol = 0;// pozicia serva

void setup()
{
servo.attach(0);// priradenie na pin 0 ATtiny
}

void loop()
{
for(uhol = 0; uhol <= 180; uhol += 1) // od 0 do 180 stupnov po jednom stupni { servo.write(uhol); // servo na pozíciu vpremennej uhol delay(15); // pauza na pootočenie SoftwareServo::refresh(); // odporúča autor knižnice } delay (20);// pauza na prepnutie smeru for(uhol = 180; uhol>=0; uhol-=1) // opačný pohyb o 180 stupnov
{
servo.write(uhol);
delay(15);
SoftwareServo::refresh();
}
delay(20);
}

Ukážeme aj príklad na ovládanie dvoch servomotorov. Pre jednoduchosť sa bude pohybovať v danom čase vždy iba jedno servo

#include 
SoftwareServo servo;
SoftwareServo servo2;
int uhol = 0; // pozicia serva

void setup()
{
servo.attach(0); // priradenie na pin 0 ATtiny
servo2.attach(1);
}

void pohybServa2()
{
servo2.write(30); delay(300); SoftwareServo::refresh();
servo2.write(0); delay(300);SoftwareServo::refresh();
}

void loop()
{
for(uhol = 0; uhol <= 180; uhol += 1) // od 0 do 180 stupnov po jednom stupni { servo.write(uhol); delay(15); SoftwareServo::refresh(); } pohybServa2(); for(uhol = 180; uhol>;=0; uhol-=1) // opačný pohyb o 180 stupnov
{
servo.write(uhol); delay(15); SoftwareServo::refresh();
}
pohybServa2();
}

Prípadne môžete vyskúšať knižnicu PrecisionServo

Príklad použitia:


#include 
const int servoPin = 0;
PrecisionServo* servo;

void setup()
{
ServoManager::setup(1);
servo = ServoManager::createServo(servoPin);
servo->;setSetting(SERVO_MEDIUM_ENDPOINT);
}

void loop()
{
servo->;setTarget(0);
ServoManager::waitUntilFinished();

servo->;setTarget(180);
ServoManager::waitUntilFinished();
}

Převzato z webu Nextech se souhlasem autora.