2.4 Servo motors
Stundas uzdevums: Izprast Servo motora darbības principu, pievienot to mikrokontrolierim un uzrakstīt programmu, kas ļauj fiziski kontrolēt motora leņķi, izmantojot potenciometra kloķi.
Datorika 7. klase (D.7.1.1., D.7.4.2., D.7.6.1.)70 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~15 min) - pieslēdz servo motora trīs vadus · 2. uzdevums (~20 min) - liec motoram griezties pa trim leņķiem · 3. uzdevums (~25 min) - vadi motora leņķi ar potenciometru. Papildu uzdevumu sāc tikai tad, ja pārējie trīs ir gatavi.
Pirms sāc: atver tinkercad.com un jaunu Circuit projektu - noderēs arī 2.3 stundas potenciometra slēgums, jo to izmantosi 3. uzdevumā.
Teorija: Kas ir Servo motors un kā ar to "sarunāties"?
Atšķirībā no parastajiem motoriem (kā ventilatoriem), kas griežas uz riņķi nepārtraukti, Servo motors ir īpašs – tam var pateikt precīzu leņķi (parasti no 0° līdz 180°), un tas turēs šo pozīciju. Tas ir ideāli piemērots robotu rokām, stūres mehānismiem un durvju slēdzenēm.
- Trīs vadi: Servo motoram ir 3 vadi. Sarkanais iet uz 5V (strāva), brūnais/melnais iet uz GND (mīnuss), bet dzeltenais/oranžais ir "Signāla" vads, kas jāsavieno ar Arduino pinu.
- C++ Bibliotēkas: Lai pašiem nebūtu jāraksta sarežģīts matemātiskais kods motora vadībai, programmētāji izmanto gatavas "bibliotēkas". Koda pašā sākumā jāieraksta
#include <Servo.h>. - Objekta izveide: Tāpat kā mainīgajam, mums jādod motoram vārds, ierakstot
Servo mansMotors;. - Map() funkcija: Mūsu potenciometrs dod datus no 0 līdz 1023, bet motors saprot tikai leņķus no 0 līdz 180. Lai šos skaitļus automātiski proporcionāli pārveidotu, C++ valodā ir maģiskā komanda
map(vērtība, no_min, no_max, uz_min, uz_max).
Praktiskie uzdevumi
1. uzdevums -
Pieslēdz servo motora trīs vadus
Beigās tavs servo motors būs pareizi savienots ar strāvu un 9. portu.
- Izveido jaunu Tinkercad projektu ar Arduino un maketo plati.
- Savieno 5V ar sarkano (+) līniju un GND ar melno (-) līniju.
- Ievelc darba laukumā komponenti "Micro Servo".
- Savieno motora vadu "Ground" ar melno (-) līniju.
- Savieno vadu "Power" ar sarkano (+) līniju.
- Savieno vadu "Signal" ar Arduino 9. portu un iekrāso to oranžu.
Gatavs, kad: no motora iet tieši trīs vadi un signāla vads beidzas 9. portā.
2. uzdevums -
Liec motoram griezties pa trim leņķiem
Beigās motora ass pati staigās starp 0, 90 un 180 grādiem.
- Ieraksti koda pašā augšā rindu
#include <Servo.h>. - Ieraksti zem tās rindu
Servo mansMotors;. - Ieraksti funkcijā
setup()rindumansMotors.attach(9);. - Ieraksti funkcijā
loop()rindasmansMotors.write(0);undelay(1000);. - Pievieno tādu pašu pāri leņķim 90 un vēl vienu leņķim 180.
- Palaid simulāciju un vēro motora asi.
Gatavs, kad: motors bez apstājas atkārto trīs pozīcijas, katrā pastāvot vienu sekundi.
3. uzdevums -
Vadi motora leņķi ar potenciometru
Beigās motora ass sekos tavai rokai, kad griezīsi kloķi.
- Pievieno potenciometru: malējās kājas pie 5V un GND, vidējo pie A0.
- Izdzēs no
loop()iepriekšējā uzdevuma rindas. - Ieraksti rindu
int klokis = analogRead(A0);. - Pievieno rindu
int lenkis = map(klokis, 0, 1023, 0, 180);. - Pievieno rindas
mansMotors.write(lenkis);undelay(15);. - Palaid simulāciju un lēnām pagriez kloķi.
- Pieraksti vienu secinājumu: ko dara funkcija
map().
Gatavs, kad: kloķa galos motors stāv 0 un 180 grādos un pa vidu seko kloķim bez raustīšanās.
Papildu uzdevums - Motora vadība ar divām pogām
Ja pamatdarbs ir gatavs, nomaini kloķi pret divām pogām, kas griež asi pa soļiem.
- Pievieno divas pogas ar
INPUT_PULLUPpie portiem 2 un 3. - Ieraksti virs
setup()rinduint pozicija = 90;. - Uzraksti nosacījumu: ja nospiesta 2. poga,
pozicija = pozicija - 10;. - Uzraksti otru nosacījumu: ja nospiesta 3. poga,
pozicija = pozicija + 10;. - Pievieno abos zaros
delay(100);, lai leņķis nelec pārāk ātri. - Pievieno cikla beigās
mansMotors.write(pozicija);.
Gatavs, kad: katrs pogas piespiediens pagriež asi tieši par vienu soli, nevis aizgriež to līdz galam.
Biežākās kļūdas (un kā tās labot):
- Kods uzrāda kļūdu pie vārda "Servo": Tu aizmirsi koda augšā ierakstīt
#include <Servo.h>vai uzrakstīji "servo" ar mazo burtu. C++ atšķir lielos un mazos burtus! - Motors simulācijā "dreb" vai raustās: Tu aizmirsi
loop()beigās pievienotdelay(15);. Ja komandas nāk tūkstošiem reižu sekundē, motors nespēj tikt līdzi un sāk vibrēt. - Map funkcija nestrādā pareizi: Pārbaudi mainīgo nosaukumus un to, vai tiešām lieto
map(). Ja motoram sūti potenciometra vērtību (0-1023) tiešā veidā, tas saprot tikai 0-180 un apstāsies galā. - Kods nekompilējas, un kļūda rāda uz mainīgā vārdu: Mainīgo nosaukumos nedrīkst lietot garumzīmes un mīkstinājuma zīmes. Raksti
klokis, neviskloķis, unlenkis, nevisleņķis.
Koda piemērs (map() no 0-1023 uz 0-180 - grūtākā daļa)
// Grūtākā vieta: potenciometrs dod 0..1023, bet servo saprot tikai 0..180.
// Bez map() motors jau pie ceturtdaļas kloķa aizgriežas līdz galam un apstājas.
// map(vērtība, no_min, no_max, uz_min, uz_max)
// map(512, 0, 1023, 0, 180) -> 90 grādi (tieši pa vidu)
#include <Servo.h> // Pievieno Servo bibliotēku
Servo mansMotors; // Izveido motora objektu
int potPin = A0; // Potenciometra ports
void setup() {
// Pievieno motoru 9. portam
mansMotors.attach(9);
}
void loop() {
// 1. Nolasa potenciometra stāvokli (0 līdz 1023)
int klokaStavoklis = analogRead(potPin);
// 2. Pārveido šos datus leņķu skalā (0 līdz 180)
int motoraLenkis = map(klokaStavoklis, 0, 1023, 0, 180);
// 3. Pasaka motoram fiziski pagriezties uz šo leņķi
mansMotors.write(motoraLenkis);
// 4. Pagaida, lai motors pabeidz kustību
delay(15);
}
map() rindu, ass aizgriežas līdz galam jau pie neliela kloķa pagrieziena un tālāk nekustas.