Skocz do zawartości

Kurs budowy robotów - #5 - omijanie przeszkód


Komentator

Pomocna odpowiedź

html_mig_img
Jeśli wszystko poszło zgodnie z planem, to w tej chwili każdy powinien mieć przed sobą złożonego robota, który potrafi już jeździć. Pora, aby nasz pojazd zaczął widzieć otoczenie!Podczas tej części kursu wykorzystamy proste czujniki przeszkód. Dzięki nim robot będzie mógł poruszać się sprawnie po nieznanym terenie!

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.

Link do komentarza
Share on other sites

Problem. Gdy wgram program w którym robot ma jechać, wszystko jest ok, oprócz tego, że zamiast jechać prosto dopóki w coś nie huknie, to co jakiś czas sam skręca, cofa, po prostu żyje własnym życiem, jakby czujnik za dużo "widział". Jak wgram pierwszy program, wyświetla tylko jak wcisnę, jakby w programie bylo coś nie tak.

Link do komentarza
Share on other sites

ZombiZiomek, niestety z Twojego opisu ciężko wywnioskować, co tak naprawdę się dzieje. Napisałeś, że "Jak wgram pierwszy program, wyświetla tylko jak wcisnę" mógłbyś opisać to jaśniej? Czy na pewno poprawnie podłączyłeś czujniki, czyli do masy (GND) oraz pinu opisanego jako A1/A0?

Link do komentarza
Share on other sites

Coś w tym co mówi ZombiZiomek. Na pinach A0 i A1 zachowuje się jak na przeszkodzie, czyli cały czas chce cofać. Sprawdzę jeszcze co się dzieje, ale po wpięciu do pinów A4 i A5 działa dobrze.

__________

Komentarz dodany przez: Treker

Problem rozwiązany, przyczyna: wgrywanie zmienionego programu z błędem (pominięcie konfiguracji wejść w trybie INPUT_PULLUP).

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Teraz to się 'rozjechaliśmy' w zeznaniach z kolegą Ziomkiem 🙂 Bo ja też juz nie wiem o co chodzi. Jak naciska się dźwignię to ma wyświetlać "wykryto przeszkodę". Przewody wg opisu w lekcji nie mają znaczenia jaki kolor gdzie.

U mnie sprawdzałem czy pin A0 i A1 działają na innych czujnikach - jest ok. Na krańcówkach nie. Ale na tę chwilę nie drążę tematu. Mam podłączone do A4 i A5 i wszystko chodzi dobrze. Pewnie jakaś drobnostka i wyjdzie z czasem.

Teraz dołączyłem czujniki odległości i krańcówki:

#define L_SIDE_SENSOR A5
#define R_SIDE_SENSOR A4
#define BUZZER 10

#define trigPin 7
#define echoPin 8
#define trigPin1 12
#define echoPin1 13

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

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);
 pinMode(trigPin1, OUTPUT);
 pinMode(echoPin1, INPUT);

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

void loop() {
 //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;

 //Pomiar odleglosci
 long czas1, dystans1;
 digitalWrite(trigPin1, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin1, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin1, LOW);
 czas1 = pulseIn(echoPin1, HIGH);
 dystans1 = czas1 / 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 || dystans1 < 15) {
   stopMotors();
   delay(150);
   leftMotor(-45);
   rightMotor(-45);
   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);
   delay(700);
   leftMotor(50);
   rightMotor(10);
   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);
   delay(700);
   leftMotor(10);
   rightMotor(50);
   delay(800);
   //Koniec warunku wracamy do jazdy prosto
 }
}

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
}

A efekt mamy taki:

Światło trochę słabe, ale będzie jeszcze inna okazja żeby nagrać lepszej jakości film 😉

Link do komentarza
Share on other sites

Coś w tym co mówi ZombiZiomek. Na pinach A0 i A1 zachowuje się jak na przeszkodzie, czyli cały czas chce cofać. Sprawdzę jeszcze co się dzieje, ale po wpięciu do pinów A4 i A5 działa dobrze.

Jak wygląda sprawa z programem testowym z UARTem, co dzieje się, gdy czujniki wpięte są po A0 i A1?

Chodzi o to, że info "wykryto przeszkodę..." wyświetla się tylko jak wcisnę dzwignię.

Czyli wszystko jest poprawnie, jakiego innego działania się spodziewałeś?

W tym tygodniu nie ma mnie na miejscu, więc dostęp do swojego zestawu będę miał dopiero w środę/czwartek. Jednak tym razem sprawdzałem wszystko na dwóch shieldach i tak samo jak poprzednio nie miałem żadnych problemów, więc wierzę, że to jakaś drobnostka, którą uda się rozwiązać zdalnie. Jeszcze sprawdźcie dla pewności, czy Wasze obie krańcówki mają dolutowane przewody do wyjść NO i C.

Link do komentarza
Share on other sites

A więc tak - programy z lekcji działają dobrze. UART pokazuje dobrze informacje, program z samymi krańcówkami też działa dobrze na pinach A0/A1. Problem jest u mnie kiedy dołączam czujniki odległości. Teraz dołączyłem do powyższego programu buzzer żeby również słyszeć co się dzieje 😉

Po włączeniu robota buzzer wyje, a koła zachowują się jak po wjechaniu na przeszkodę(krańcówki na pinach A0/A1).

Przepiąłem też ten jeden czujnik z tego pinu 13, ale nie dało to efektu. I myślałem, że to może być jakiś błąd w programie (chociaż tam nic skomplikowanego nie ma, prawie jak zabawa z diodami 🙂 ), ale po przełączeniu krańcówek na piny A4/A5 wszystko działa zgodnie z oczekiwaniami - tak ja powyższym filmie.

Aktualny program:

https://create.arduino.cc/editor/leepa79/b7a68158-227e-4a15-86ce-8046ece39291/preview

Teraz w oczekiwaniu na kolejną lekcję spróbuję podłączyć oświetlenie na robocie, które włącza się w ciemności coś na wzór "Kurs Arduino – #4" 🙂 trzeba też będzie pomyśleć o jakimś lepszym zasilaniu.

Link do komentarza
Share on other sites

Strzelam, że nie włączone pull-upy w procku 🙂

Zastrzelony 🙂 tak czułem, że to jakaś drobnostka. Jak sprawdzałem na A0/A1 kiedy działało korzystałem z aplikacji Arduino. Na 'Arduino Create' miałem błąd tzn nie dopisałem hmmm czegoś 😳 i tak się zapętliłem. Wielkie dzięki. Piwo się należy bo teraz długo będę pamiętał żeby wpierw takie rzeczy sprawdzać.

ED

Aktualna wersja programu poprawiona 🙂

#define L_SIDE_SENSOR A1
#define R_SIDE_SENSOR A0
#define BUZZER 10

#define trigPin 7
#define echoPin 8
#define trigPin1 12
#define echoPin1 13

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

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);
 pinMode(trigPin1, OUTPUT);
 pinMode(echoPin1, INPUT);

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

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

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

void loop() {

 //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;

 //Pomiar odleglosci
 long czas1, dystans1;
 digitalWrite(trigPin1, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin1, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin1, LOW);
 czas1 = pulseIn(echoPin1, HIGH);
 dystans1 = czas1 / 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 || dystans1 < 15) {
   stopMotors();
   delay(150);
   leftMotor(-45);
   rightMotor(-45);
   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
 }
}

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
}
Link do komentarza
Share on other sites

leepa79, super, że działa - teraz czekamy w takim razie na informację od ZombiZiomek. Na przyszłość prośba, aby zaczynać od programów, które są w artykułach. Jeśli ktoś zgłasza, że coś nie działa, to zakładam, że postępuje zgodnie z poradnikami. W związku z tym doszukuje się od razu problemów w sprzęcie, sprawdzam różne wersje, angażuje w to inne firmy np. Botland, czy MSX'a. Rozumiem, że podczas nauki mogą zdarzać się różne problemy, ale postępowanie zgodnie z instrukcjami z artykułów naprawdę wszystko ułatwia (każdej ze stron) 😉

Link do komentarza
Share on other sites

Może warto zbudować jakąś bazę programów testowych? Nie żeby od razu wgrywamy i robot jeździ hurra, tylko malutkie kawałki kodu sprawdzające po kolei każdy fragment sprzętu, każde połączenie i jasno raportujące ew. problem. Wtedy każdy budujący mógłby skupić się na bardzo małym kawałku swojego robota i tylko tam szukać błędu. A w razie gdyby coś przestało działać miałby zawsze pod ręką wzorce kodu, które weryfikują poprawność.

A wypuszczenie pierwszej serii sprzętu do ludzi to chyba najgorszy czas. Gdy jeszcze nie ma 100% zaufania do poprawności wszystkich szczegółów (bo poprawki w ostatniej chwili, bo terminy, bo montaż, bo elementy, pakowanie, wysyłka itd..), wtedy każde nawet niewinne pytanie jeży włosy na głowie i stawia na nogi cały zespół. Nie zazdroszczę, Treker 🙂

A my zaraz będziemy puszczać serię kilkunastu tysięcy urządzeń.. Stanowiska testowe pod parą, ludzie pościągani, obrazy się kompilują, sobie też nie zazdroszczę 🙂

Link do komentarza
Share on other sites

Może warto zbudować jakąś bazę programów testowych?

Może i warto tylko... z doświadczenie powiem (i nie dotyczy to problemów z tego kursu - piszę ogólnie), że sporo osób idzie w zaparte mówiąc, że uruchamia dokładnie takie programy, jak powinno, a dopiero później się okazuje, że "oj jednak zmieniłem 1 linijkę"...

A wypuszczenie pierwszej serii sprzętu do ludzi to chyba najgorszy czas.

Robiliśmy oczywiście prototypy i to kilka. Przed ostatecznym montażem serii sprawdziliśmy też dokładnie finalną wersję. U mnie ten robot jeździł już na wszystkie możliwe strony, w każde możliwej konfiguracji - szansa na błąd jest praktycznie zerowa... Jednak tak jak pisałem wcześniej, każdą zgłoszenie "usterki" traktujemy poważnie i od razu przeprowadzamy dodatkowe testy. Sam wiesz jak to jest przy swoich produktach 😉

Link do komentarza
Share on other sites

"Robiliśmy oczywiście prototypy i to kilka. Przed ostatecznym montażem serii sprawdziliśmy też dokładnie finalną wersję. U mnie ten robot jeździł już na wszystkie możliwe strony, w każde możliwej konfiguracji - szansa na błąd jest praktycznie zerowa"

Nie mam żadnych wątpliwości, że tak właśnie zrobiliście. Inaczej przedsięwzięcie nie miałoby żadnych szans powodzenia. Niemniej jednak od serii prototypowej do produkcji seryjnej i potem do wyrobu u klienta jest jeszcze kilka miejsc w których można się potknąć. Choćby ktoś założył taśmę z innymi opornikami na podajnik czy cała seria PCB na delikatnie słabsze metalizacje w przelotkach itd itd. Ale nie chciałem wcale złowieścić a wręcz przeciwnie, trzymam kciuki i naprawdę szacun za inicjatywę.

A ludzie chętnie wgrywają gotowe programy, szczególnie w sytuacjach podbramkowych, gdy coś nie działa i nie wiedzą dlaczego. Takie potwierdzenie poprawności działania sprzętu byłoby dobrym punktem odniesienia nawet podczas niesienia pomocy:

Puściłeś test numer 7? Diodka zamrugała 3 razy? Nie? No to szukaj błędu w czujniku. Tak? To masz problem w kodzie, pokaż go. Przynajmniej wiemy wtedy na czym stoimy.

  • Lubię! 1
Link do komentarza
Share on other sites

Właściwie w tym wypadku takim programem testowym był odczyt z czujników przez UART. Działało dobrze dlatego czułem, że gdzieś coś przeoczyłem. Najgorsze u początkujących (w tym u mnie) jest sytuacja, w której kopiuje się część kodu. W programie, w którym wklepywałem ręcznie (na pinach A4/A5) działało dobrze, a w drugim oknie kod 'wpisywałem' metodą kopiuj wklej i boom - coś nie działa. Trzeba odejść od takich nawyków od początku 🙂

Link do komentarza
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!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.