List. 4. Fragment programu sortujący wyniki pomiaru
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
if(A<=B) { if(A<=C) { A; } else { C; } } else { if(B<=C) { B; } } |
Podczas analizy schematu napotkałem kluczowy problem. Pierwotnie urządzenie miało być zasilane z wykorzystaniem stabilizatora napięcia zamontowanego na płytce startowej Arduino Leonardo. Jednak wykorzystany w projekcie silnik serwo potrzebował większej mocy niż mógł dostarczyć stabilizatora. Powodowało to znaczne spadki napięcia w układzie, co skutkowało zerowaniem się mikrokontrolera. Aby zabezpieczyć układ przed spadkami napięcia, wykorzystałem układ zasilający step-down, który stał się równoległym źródłem napięcia dla silnika serwo oraz Arduino. Na rysunku 4 znajduje się ostateczny schemat urządzenia.
Rys. 4. Schemat elektryczny finalnego urządzenia
Pamiętając o estetycznym programowaniu zostały przygotowane bloki funkcyjne realizujące główne zadania. Pierwszy realizuje pobranie oraz analizę danych z czujników ultradźwiękowych (listing 5 i listing 6), natomiast drugi blok główny kieruje pracą serwomechanizmu (listing 7).
List. 5. Fragment programu odpowiedzialny za pomiar odległości
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void pomiar_odleglosci () { // impuls 10 uS inicjalizujacy - patrz dokumentacja digitalWrite(TX1, HIGH); delayMicroseconds(10); digitalWrite(TX1, LOW); TIME1 = pulseIn(RX1, HIGH); digitalWrite(TX2, HIGH); delayMicroseconds(10); digitalWrite(TX2, LOW); TIME2 = pulseIn(RX2, HIGH); digitalWrite(TX3, HIGH); delayMicroseconds(10); digitalWrite(TX3, LOW); TIME3 = pulseIn(RX3, HIGH); } |
List. 6. Fragment programu sortujący wartości odczytane przez czujniki
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
if(TIME1<=TIME2) { if (TIME1<=TIME3) { dx=5; } else { dx=15; } } else { if(TIME2<=TIME3) { dx=-15; } } |
List. 7. Pętla główna programu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
void loop() { pomiar_odleglosci(); // szerokość odbitego impulsu w uS podzielone przez // 58 to odleglosc w cm - patrz dokumentacja Serial.print(" Czujnik 1: "); TIME1=TIME1/58; Serial.print(TIME1); Serial.print(" Czujnik 2: "); TIME2=TIME2/58; Serial.print(TIME2); Serial.print(" Czujnik 3: "); TIME3=TIME3/58; Serial.println(TIME3); if(TIME1<=TIME2) { if (TIME1<=TIME3) { dx=0; } //w przypadku śledzenia obiektu przez oko frontowe brak reakcji else { dx=15; } //w przypadku wykrycia obiektu przez oko prawe obrót w prawo } else { if(TIME2<=TIME3) { dx=-15; } //w przypadku wykrycia obiektu przez oko lewe obrót w lewo } pos=pos+dx; //zabezpieczenie przed osiągnięciem przez silnik wartości skrajnych if(pos>170) { pos=170; } else { if(pos<10) { pos=10; } } Serial.println(pos); myservo.write(pos); // ustawienie silnika serwo w pozycji "pos" delay(70); } |
Opisywany projekt jest przeznaczony przede wszystkim dla początkujących oraz średnio-zaawansowanych adeptów robotyki. Pozwala zdobyć doświadczenie w dziedzinie wykorzystania czujników ultradźwiękowych w różnych konfiguracjach portów. Realizując ten projekt (fotografia 5) zyskujemy umiejętności wykorzystania silników serwo, które dzięki swej precyzji często są obowiązkowym punktem kolejnych projektów.
Fot. 5. Widok zmontowanego urządzenia