[ARDUINO] Oko Cyklopa – ultradźwiękowy „radar” do lokalizacji obiektów
List. 4. Fragment programu sortujący wyniki pomiaru
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
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
if(TIME1<=TIME2) { if (TIME1<=TIME3) { dx=5; } else { dx=15; } } else { if(TIME2<=TIME3) { dx=-15; } }
List. 7. Pętla główna programu
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