Skocz do zawartości
Komentator

Kurs budowy robotów - #6 - Światłolub (sterowanie latarką)

Pomocna odpowiedź

html_mig_img
Gdy Arduino nie było jeszcze popularne, dużo początkujących szukało poradników opisujących budowę robotów bez mikrokontrolerów.Popularnym wyborem był wtedy światłolub, czyli robot, który jechał w kierunku światła. W praktyce oznaczało to możliwość zdalnego sterowania za pomocą latarki!

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Udostępnij ten post


Link to post
Share on other sites

Zadanie 6.1 - oczywiście w moim, pokrętnym, stylu 🙂 Zdradzę Wam sekret - staram się wykonać zadania tylko z pomocą tych kursów, tzn. mam przygotowane materiały do nauki, ale póki kursy trwają staram się korzystać tylko z nich. Książki po kursie 🙂 Chociaż ostatnio miałem problem przy kursie Arduino II z default: w case: 🙂 bo nie było przykładu na lekcji. Chyba czas na posiłkowanie się źródłami zewnętrznymi bo po napisaniu tego zadania przed oczami pojawił mi się mem z kotkiem "Andrzej to jeb... 🙂 Zatem przedstawiam kod:

#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165

#define R_LIGHT_SENSOR A0
#define L_LIGHT_SENSOR A1
#define BUZZER 10

#define LED 13

int bip = 0; //Zmienna na potrzeby 'bipania'

void setup() {
 //Konfiguracja pinow od mostka H
 pinMode(L_DIR, OUTPUT);
 pinMode(R_DIR, OUTPUT);
 pinMode(L_PWM, OUTPUT);
 pinMode(R_PWM, OUTPUT);

 pinMode(LED, OUTPUT); //Konfiguracja LED

 //Konfiguracja pozostalych elementow
 pinMode(BUZZER, OUTPUT);
 digitalWrite(BUZZER, 0); //Wylaczenie buzzera   
}

void loop() {
 int odczytLewy = analogRead(L_LIGHT_SENSOR);
 int odczytPrawy = analogRead(R_LIGHT_SENSOR);
 int roznica = odczytLewy - odczytPrawy;
 migLed();
 stopMotors();

 while (odczytPrawy < 600 || odczytLewy < 600 ){
   if (bip < 3){
     BUZZASTER();
     bip++;
     }else{
     JAZDA();
   }
 }
}

void leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   analogWrite(L_PWM, V); //Ustawienie predkosci    
 }
}

void rightMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
}

void migLed() {
   digitalWrite(LED, 1);
   delay(200);
   digitalWrite(LED, 0);
   delay(200);
}

void BUZZASTER() {
 digitalWrite(BUZZER, 1);
 delay(500);
 digitalWrite(BUZZER, 0);
 delay(500);
}
//Jazde wrzucilem tu zeby miec czysto w loop podczas 'wymyslania' zadania domowego :)
void JAZDA(){
 int odczytLewy = analogRead(L_LIGHT_SENSOR);
 int odczytPrawy = analogRead(R_LIGHT_SENSOR);
 int roznica = odczytLewy - odczytPrawy;
 if (roznica > 50) { //Jesli obliczona roznica jest wieksza
   leftMotor(30); //To skręcamy w prawo
   rightMotor(-30);  
 } else if (roznica < -50){ //Jesli obliczona roznica jest mniejsza
   leftMotor(-30); //To skręcamy w lewo
   rightMotor(30);    
 } else {
   //W pozostałych przypadkach jedziemy prosto
   leftMotor(30);
   rightMotor(30);        
 }
}

i film

Udostępnij ten post


Link to post
Share on other sites

leepa79, dałbym sobie rękę uciąć, że odpisywałem na Twoją wiadomość... i teraz nie miałbym czym pisać artykułów... Robot radzi sobie bardzo ładnie. Faktycznie program napisany trochę pokrętnie, ale ważne, że działa! Główna zmiana jakąś bym wprowadził, to przeniesienie procedury startowej do funkcji setup(), bo ten kod z założenia powinien wykonać się tylko raz.

A jak idzie innym programowanie światłolubów?

Przy okazji niestety muszę powiedzieć, że "coś mnie bierze", a wolę się nie rozchorować na najbliższe 2 tygodnie, więc musiałem sobie trochę dziś odpuścić i nie zdążyłem dorobić wszystkich zdjęć do kolejnego artykułu. Nie chcę publikować wybrakowanego, więc będzie drobna zmiana w kalendarzu publikacji. Postaram się od razu ustalić terminy wszystkich pozostałych artykułów. Będę informował o postępach 😉

Udostępnij ten post


Link to post
Share on other sites

Światłolub otrzymał dodatkowe 'oczy'. Czujnik odległości HC-SR04 i krańcówki z poprzedniej lekcji.

#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165

#define trigPin A4
#define echoPin A3

#define L_SIDE_SENSOR 7
#define R_SIDE_SENSOR A2

#define R_LIGHT_SENSOR A0
#define L_LIGHT_SENSOR A1
#define BUZZER 10
#define LED 13

#define ROZNICA_MIN -300
#define ROZNICA_MAX 300

int bip = 0; //Zmienna na potrzeby 'bipania'



void setup() {
 //Konfiguracja pinow od mostka H
 pinMode(L_DIR, OUTPUT);
 pinMode(R_DIR, OUTPUT);
 pinMode(L_PWM, OUTPUT);
 pinMode(R_PWM, OUTPUT);

 //Konfiguracja pinów HC-SR04
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);

 //Konfiguracja pinow od czujnikow
 pinMode(L_SIDE_SENSOR, INPUT_PULLUP);
 pinMode(R_SIDE_SENSOR, INPUT_PULLUP);

 //Konfiguracja pozostalych elementow
 pinMode(BUZZER, OUTPUT);
 digitalWrite(BUZZER, 0); //Wylaczenie buzzera   

 pinMode(LED, OUTPUT);

 randomSeed(analogRead(5)); //Inicjalizacja generatora
}

void loop() {

int odczytLewy = analogRead(L_LIGHT_SENSOR);
int odczytPrawy = analogRead(R_LIGHT_SENSOR);
int roznica = odczytLewy - odczytPrawy;

migLed(); //Miganie diody przed jazda
stopMotors();

while (odczytPrawy < 600 || odczytLewy < 600 ){//Kiedy mocniejsze swiatlo
//Bipnij 3 razy
if (bip < 3){
BUZZASTER();
bip++;

}else{

 int odczytLewy = analogRead(L_LIGHT_SENSOR);
 int odczytPrawy = analogRead(R_LIGHT_SENSOR);
 int roznica = odczytLewy - odczytPrawy;

 //Pomiar odleglosci
 long czas, dystans;
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 czas = pulseIn(echoPin, HIGH);
 dystans = czas / 58;

 //W przod
   leftMotor(50);
   rightMotor(50);

 int los = random(5, 20) * 10; //Dodajemy losowo od 50 do 200 ms obrotu

 //Jesli przeszkoda 
 if (dystans < 15) {
   stopMotors();
   delay(150);
   leftMotor(-40);
   rightMotor(-40);
   delay(500);
   leftMotor(-35);
   rightMotor(35);
   delay(140+los);
 }

 if (digitalRead(L_SIDE_SENSOR) == LOW) {
   //Jesli przeszkoda po lewej stronie
   //Jedz do tylu i w prawo
   leftMotor(-40);
   rightMotor(-40);
   digitalWrite(BUZZER, 1);
   delay(700);
   leftMotor(50);
   rightMotor(10);
   digitalWrite(BUZZER, 0);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }

 if (digitalRead(R_SIDE_SENSOR) == LOW){
   //Jesli przeszkoda po prawej stronie
   //Jedz do tylu w lewo
   leftMotor(-40);
   rightMotor(-40);
   digitalWrite(BUZZER, 1);
   delay(700);
   leftMotor(10);
   rightMotor(50);
   digitalWrite(BUZZER, 0);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }


 if (roznica < ROZNICA_MIN) { //Jeśli roznica mniejsza od dopuszczalnej
   roznica = ROZNICA_MIN; //To ustaw najmniejszą dopuszczalną wartość
 } else if (roznica > ROZNICA_MAX) { //Jeśli różnica większa od dopuszczalnej
   roznica = ROZNICA_MAX; //To ustaw największą dopuszczalną wartość
 }

 //Przeliczenie odczytow z czujnikow na zmiane predkosci silnikow
 int zmianaPredkosci = map(roznica, ROZNICA_MIN, ROZNICA_MAX, -45, 45);

 //Dodajemy lub odejmujemy wyliczoną zmianę od prędkosci bazowej
 leftMotor(30+zmianaPredkosci);
 rightMotor(30-zmianaPredkosci);
 }
}
}

void leftMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 0); //Kierunek: do przodu
   analogWrite(L_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(L_DIR, 1); //Kierunek: do tyłu
   analogWrite(L_PWM, V); //Ustawienie predkosci    
 }
}

void rightMotor(int V) {
 if (V > 0) { //Jesli predkosc jest wieksza od 0 (dodatnia)
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 0); //Kierunek: do przodu
   analogWrite(R_PWM, V); //Ustawienie predkosci 
 } else {
   V = abs(V); //Funkcja abs() zwroci wartosc V  bez znaku
   V = map(V, 0, 100, 0, PWM_MAX);
   digitalWrite(R_DIR, 1); //Kierunek: do tyłu
   analogWrite(R_PWM, V); //Ustawienie predkosci    
 }
}

void stopMotors() {
 analogWrite(L_PWM, 0); //Wylaczenie silnika lewego
 analogWrite(R_PWM, 0); //Wylaczenie silnika prawego
} 

void migLed() {
digitalWrite(LED, 1);
delay(200);
digitalWrite(LED, 0);
delay(200);
}

void BUZZASTER() {
digitalWrite(BUZZER, 1);
delay(500);
digitalWrite(BUZZER, 0);
delay(500);
}

i film

Teraz jest samodzielnym zwierzakiem 😉

Udostępnij ten post


Link to post
Share on other sites

leepa79, super - miło widzieć, że ciągle rozwijasz robota 🙂

Udostępnij ten post


Link to post
Share on other sites

Dzień dobry, mam problem z czujnikami światła. W trakcie sprawdzania wartości przez UART, mimo tych samych warunków, zachowują się zupełnie inaczej. Dla prawego czujnika cały czas wykazywana jest wartość około tysiąca przy normalnym świetle, a przy lewym wartość zero, przy takim samym świetle. Nie wiem jak mam sobie poradzić z tym problemem. 

Udostępnij ten post


Link to post
Share on other sites

@juk3n czy gdy zamienisz czujniki miejscami (podłączenie na płytce) to nadal uzyskujesz złe wyniki na tym samym czujniki? 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Treker  sytuacja jest taka sama, tylko wartości zmieniły się miejscami 

Udostępnij ten post


Link to post
Share on other sites

@juk3n w takim razie faktycznie trafił Ci się uszkodzony czujnik 😞 Przepraszam za kłopot, dawno nie było już takiej sytuacji. Zgłoś reklamację w Botlandzie - na pewno szybko wymienią uszkodzony element. W między czasie możesz zająć się innymi częściami kursu.

Alternatywnie, jeśli masz lutownicę, to możesz spróbować poprawić luty fotorezystora i sprawdzić miernikiem gdzie "znika" sygnał z czujnika. Jednak to tylko taka sugestia, jeśli masz czas i ochotę samemu to zweryfikować (zepsuć bardziej i tak Ci się nie uda) 😉

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Napisz odpowiedź...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...