Grupa uczniów mimo ferii i soboty wybrała się do szkoły. Pod wodzą ks. Dyrektora młodzi adepci programowania i technicznego dłubania budowali platformę jeżdżąca do eksperymentów z jeżdżącymi robotami. Udało się skończyć jedną – reszta w zaawansowanej formie. Gotowy jest też program, który jeszcze wymaga sporo poprawek, ale dzięki temu będzie można dobrze zrozumieć jego działanie.
Robot działa w oparciu o ośmiobitowy mikrokontroler (w postaci Arduino, ale to zwykła ATmega328). Posiada czujnik ultradźwiękowy dzięki któremu rozpoznaje przeszkody. Program zajmuje 5 730 bajtów czyli niecałe 18% pamięci mikrokontrolera. Sporo miejsca na dodatkowe pomysły.
Kod programu:
//podłaczenia - od tego zaczynamy:
//silnik lewy piny 3 i 4
//silnik prawy piny 7 i 8
//czujnik ultradzwiękowy trig pin 11 echo pin 12
//serwo pin 9
#include <Servo.h> //dopinamy bibliotekę z obsługą serwomechanizmu
// —————————————–silniki i czujnik
int silnik_lewy[] = {3, 4}; //do tablicy z pinami lewego silnika
int silnik_prawy[] = {7, 8}; //do tablicy z pinami prawego
// ultradzwiekowy czyli czujnik na głowie robota
int trig = 11; // pin wyzwolenia
int echo = 12; // pin odpowiedzi
int czas, odleglosc_lewa, odleglosc,odleglosc_prawa; //czas trwania impulsu, pomiary stron. Po prostu definicja wykorzystywanych później zmiennych
Servo myservo; //definicja serwa czyli szyi robota – tworzymy obiekt
// ————————————–ustawienia
void setup() {
Serial.begin(9600); //przydaje się do debugowania – port szeregowy
// do silników
int i;
for(i = 0; i < 2; i++){
pinMode(silnik_lewy[i], OUTPUT); //piny lewego jako wyjście
pinMode(silnik_prawy[i], OUTPUT); //piny prawego jako wyjście
}
// ustalenie co z czym jesli chodzi o ultradzwiękowy – wysyłanie i
//odbiór sygnału
pinMode(trig, OUTPUT); //do czujnika ultradzwiękowego – wyzwolenie wyjście
pinMode(echo, INPUT); //do czujnika ultradzwiękowego – odpowiedz wejście
myservo.attach(9); //pin sygnału serwa
}
// ————————————————–glówna petla
void loop() {
silniki_stop(); //funkcje określone na końcu skryptu, które obsługują silniki – patrz koniec skryptu - uwaga silniki_stop tutaj tylko po to żeby nam robot na biurku nie ruszył. Później trzeba zahaszować
delay(20);
Odleglosc_pomiar();//robot zaczyna ostrożnie od pomiaru przed nim
Serial.println(odleglosc);
Serial.println(odleglosc_lewa);
if(odleglosc<=17){ //odebrał pomiar przodu jeżeli trochę krótko (równo lub mniej niż 17)
Odleglosc_prawa(); //zerka w prawo
Odleglosc_lewa(); //zerka w lewo
myservo.write(90); //pozycja serwa srodek po spojrzeniu – serwo ma obrót – 0-180 stopni
//tutaj mając odległości program podejmuje decyzję co do - skrętu lub jazdy do przodu
if(odleglosc_lewa>=odleglosc_prawa){ //ktora odleglosc wieksza do podjecia decyzji
zakret_lewo(); //lepiej w lewo jeżeli więcej cm
delay(550);
}
else{ //odwrotnie z wolnym polem
zakret_prawo(); //lepiej w prawo jeżeli więcej cm
delay(550);
}
}
else{//nie zaszedł warunek odleglosc wieksza niz zakladana
jazda_przod(); //zaiwania do przodu
}
}
// ———————————————–definicja jazdy – definicja silników według tabeli prawdy mostka H
//własne funkcje zaczynaja się od void
void silniki_stop(){ //funkcja zatrzymująca silniki - wszędzie niski stan
digitalWrite(silnik_lewy[0], LOW);
digitalWrite(silnik_lewy[1], LOW);
digitalWrite(silnik_prawy[0], LOW);
digitalWrite(silnik_prawy[1], LOW);
delay(25);
}
void jazda_przod(){ //funkcja oba silniki naprzód
digitalWrite(silnik_lewy[0], HIGH);
digitalWrite(silnik_lewy[1], LOW);
digitalWrite(silnik_prawy[0], HIGH);
digitalWrite(silnik_prawy[1], LOW);
}
void jazda_tyl(){ //funkcja oba silniki w tył
digitalWrite(silnik_lewy[0], LOW);
digitalWrite(silnik_lewy[1], HIGH);
digitalWrite(silnik_prawy[0], LOW);
digitalWrite(silnik_prawy[1], HIGH);
}
void zakret_lewo(){ //jeden silnik tył, drugi przód
digitalWrite(silnik_lewy[0], LOW);
digitalWrite(silnik_lewy[1], HIGH);
digitalWrite(silnik_prawy[0], HIGH);
digitalWrite(silnik_prawy[1], LOW);
}
void zakret_prawo(){ //jeden silnik przód, drugi tył
digitalWrite(silnik_lewy[0], HIGH);
digitalWrite(silnik_lewy[1], LOW);
digitalWrite(silnik_prawy[0], LOW);
digitalWrite(silnik_prawy[1], HIGH);
}
//definicja pomiarow czujnika ultradzwiękowego
void Odleglosc_pomiar(){ //pomiar przodu bez ruchu serwa na boki
delay(50);
digitalWrite(trig, HIGH);
delayMicroseconds(1000);
digitalWrite(trig, LOW);
czas = pulseIn(echo, HIGH);
odleglosc = (czas/2) /29.1;
Serial.println(odleglosc);
}
void Odleglosc_lewa(){ //pomiar lewej strony z ruchem serwa
myservo.write(160); //obrrót serwa w lewo
delay(1000);
delay(50);
digitalWrite(trig, HIGH);
delayMicroseconds(1000);
digitalWrite(trig, LOW);
czas = pulseIn(echo, HIGH); //wysyła impuls
odleglosc_lewa = (czas/2) /29.1; //wynik w cm
}
void Odleglosc_prawa(){ //pomiar prawej strony z ruchem serwa
myservo.write(20); //obrót serwa w prawo
delay(1000);
delay(50);
digitalWrite(trig, HIGH); //wysyła impuls
delayMicroseconds(1000);
digitalWrite(trig, LOW);
czas = pulseIn(echo, HIGH);
odleglosc_prawa = (czas/2) /29.1; //wynik w cm
}