Skocz do zawartości
Komentator

Kurs budowy robotów - #4 - pierwsze programowanie

Pomocna odpowiedź

qbeczek, cieszę się, że już wszystko działa 🙂

Może w takim razie to samo rozwiąże problem kolegi ZombiZiomek? Spróbuj odkręcić i jeszcze raz założyć wtyczki na kable od silników. Pamiętaj, aby wewnątrz złącza znajdował się odsłonięty kawałek przewodu, a nie izolacja.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Prawie jak Colobot: motor(30,-30); tylko chwytaka brak 😉

Udostępnij ten post


Link to post
Share on other sites

ZombiZiomek, super, cieszę się, że wszystko jest dobrze 🙂

buchbuch, przyznam, że nigdy nie grałem... Chyba najwyższa pora 😉

Udostępnij ten post


Link to post
Share on other sites

Witam,
Pozdrawiam autora Trekera - super kursy - świetny opis i grafika.

Sam dzisiaj walczyłem z brakującą zworką polecam rozwiązanie stara płyta główna od komputera - jest ich kilka można wykorzystać.

Miałem problem z niedziałającym prawym silnikiem - już byłem pewny że nie działa

wielokrotne próby nic nie pomagały. Liczy się dokładność patrząc z boku należy precyzyjnie zamieść nie osłonięty izolacją przewód we wtyczce i dokręcić. Najczęstsze błędy to przewód przykręcony z izolacją oraz przewód nie przymocowany - nie widać tego błędu przez ograniczoną przestrzeń

Udostępnij ten post


Link to post
Share on other sites

Zadanie 4.3 można oczywiście zrobić kilkoma sposobami. U mnie najszybciej tą drogą:

#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);
}

void loop(){
 turnMotor1();
}

void turnMotor1() {
 for (int i = 50; i < 165; i++){
   digitalWrite(L_DIR, 0);
   analogWrite(L_PWM, i);
   digitalWrite(R_DIR, 1);
   analogWrite(R_PWM, i);
   delay(100);
 }
 for(int i = 165; i >= 50; i--){
   digitalWrite(L_DIR, 0);
   analogWrite(L_PWM, i);
   digitalWrite(R_DIR, 1);
   analogWrite(R_PWM, i);
   delay(100);
 }
}

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

Zadanie 4.2 to świetna zabawa - nie daję kodu bo zadanie rozbudowałem i dostosowałem do warunków w mojej kuchni 🙂

PS. Ja również nie miałem zworki, ale w garażu mam kilka starych dysków więc nie ma problemu. Reszta działa (na tym etapie) super. Tylko bieżnik w jednym kole obróciłem żeby poślizgów nie było 🙂

PS1. Kot mój nie reaguje na robota. Może to być związane z tym, że jest głuchy...

Udostępnij ten post


Link to post
Share on other sites
Pozdrawiam autora Trekera - super kursy - świetny opis i grafika.

Dzięki za miłe słowa 🙂 Nie sądziłem, że z tymi złączami może być tyle problemów (a to już 3 taki przypadek). Zaktualizowałem właśnie artykuły i dodałem uwagi na temat izolacji. Jeśli chodzi o zworki, to faktycznie płyty główne (i stare dyski) są dobrym źródłem takich elementów. Oczywiście, jeśli ktoś nie znajdzie zworki, to ją doślemy - proszę takie osoby o kontakt na PW.

Zadanie 4.3 można oczywiście zrobić kilkoma sposobami. U mnie najszybciej tą drogą:

Działa dobrze, więc super, ale mnie trochę zaskoczyłeś 😃

Dlaczego zakomentowałeś przygotowane funkcje left/rightMotor?

Wystarczyło przecież je zostawić i wewnątrz for'a wydawać komendy:

leftMotor(i);
rightMotor(-i);

Pamiętaj też o stałej PWM_MAX warto z niej korzystać, bo za jakiś czas zapomnisz skąd te 165 się wzięło wewnątrz pętli 😉

Udostępnij ten post


Link to post
Share on other sites

Teraz mam tak:

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

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

void loop(){
 turnMotor1();
}

void turnMotor1() {
 for (int i = PWM_MIN; i < PWM_MAX; i++){
   leftMotor(i); 
   rightMotor(-i);
   delay(100);
 }

 for(int i = PWM_MAX; i >= PWM_MIN; i--){
   leftMotor(i); 
   rightMotor(-i);
   delay(100);
 }
}

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
}

Ale nie działa tak jak myślałem 🙂 Po rozpędzeniu się do max zatrzymuje się na około 1 sek. Z min do rozpędzania przechodzi płynnie. Czegoś jeszcze nie widzę?

ED - ok znalazłem winowajce 🙂 nie wrzucam, bo nie chcę psuć innym zabawy 🙂 naprawdę drobna poprawka

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dodaliśmy jeszcze do artykułów nową grafikę - mam nadzieję, że teraz nikt nie będzie miał już problemów z mocowaniem przewodów w złączach:

robot_zlacze_izolacja-650x219.png

Udostępnij ten post


Link to post
Share on other sites

Ja w ramach czekania na kolejną lekcję wróciłem na chwilkę do lekcji z Arduino (Kurs Arduino – #9 – Czujnik odległości HC-SR04, funkcje) i dodałem do naszego robota właśnie czujnik odległości. Z jednym nie było kłopotu, zresztą z dwoma też nie było trudno (chyba - patrz dalej). Program:

#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);
}

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);
   delay(200);

 //Jesli przeszkoda 
 if (dystans < 25 || dystans1 < 25) {
   stopMotors();
   delay(150);
   leftMotor(-45);
   rightMotor(-45);
   delay(500);
   leftMotor(-35);
   rightMotor(35);
   delay(470);
 }
}

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
}

I nasuwają się dwa pytania:

1.) Czy będą dostępne w sprzedaży dodatkowe elementy konstrukcji? Coś np. takiego bym mógł 'elegancko' zamocować inne czujniki takie jak ten użyty powyżej. Teraz na szybko zamocowałem za pomocą gumki recepturki 🙂

2.) Czy dobrze użyłem sumy łącząc dwa warunki w pomiarze odległości? Pierwszy raz zastosowałem dwa te same czujniki w jednym projekcie i pewny nie jestem. Temat był poruszony w Kursie Arduino lekcja 10, ale był ledwo liźnięty więc proszę o rady.

Docelowo czujnik będzie jeden. Na bokach planuję krańcówki.

Udostępnij ten post


Link to post
Share on other sites

Kolejny odcinek jest już dostępny (Kurs budowy robotów – #5 – omijanie przeszkód),
więc wygaszam kilka poprzednich postów, aby w przyszłości nie wprowadzać innych w błąd 🙂

leepa79, tak, planujemy dodatkowe elementy konstrukcyjne ze sklejki do tego kolejne moduły (np. bardziej zaawansowane czujniki). Prawdopodobnie stanie się tak po zakończeniu kursu (w marcu), aby nie robić teraz zamieszania. Wtedy wraz z każdym nowym produktem będą pojawiały się nowe artykuły 🙂 Jeśli ktoś ma pomysły lub sugestie czego brakuje, to zapraszam na PW, chętnie przeczytam wszystkie sugestie.

Czy dobrze użyłem sumy łącząc dwa warunki w pomiarze odległości? Pierwszy raz zastosowałem dwa te same czujniki w jednym projekcie i pewny nie jestem. Temat był poruszony w Kursie Arduino lekcja 10, ale był ledwo liźnięty więc proszę o rady.

Wszystko wygląda dobrze - robot wykona instrukcje, które są wewnątrz warunku, gdy jeden lub drugi czujnik coś wykryje.

Zastanawia mnie tylko, dlaczego dodałeś tutaj opóźnienie:

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

Bez niego działanie programu również powinno być poprawne 😉

Udostępnij ten post


Link to post
Share on other sites

Ok 'delay' usunięty 🙂 dzięki za radę.

Mam jeszcze jedno pytanie tutaj i lecę do następnej lekcji.

Rozumiem, że podczas jazdy dioda miga ponieważ jeden z czujników podłączony mam do pinu 13? Przeszkadza to coś (jakiś wew. proces) lub będzie przeszkadzało w przyszłości kiedy program będzie bardziej rozbudowany?

Udostępnij ten post


Link to post
Share on other sites
Rozumiem, że podczas jazdy dioda miga ponieważ jeden z czujników podłączony mam do pinu 13? Przeszkadza to coś (jakiś wew. proces) lub będzie przeszkadzało w przyszłości kiedy program będzie bardziej rozbudowany?

Dioda świeci, ponieważ tak jak napisałeś, jest ona na stałe podłączona do pinu nr 13. Raczej nie powinno wprowadzać to chyba problemów - zresztą najłatwiej sprawdzisz to w praktyce patrząc na zachowanie robota 😉

Udostępnij ten post


Link to post
Share on other sites

Czy ktoś bawił się może z obrotami tego potwora? U mnie to działa tak sobie więc chciałbym się dowiedzieć czy ktoś sobie z tym poradził i może mógłby dać jakąś podpowiedź jak to zrobić.

Aby zrobić obrót w miejscu o zadany kąt napisałem poniższą funkcyjkę. Drogę obrotu wyliczyłem z uwzględnieniem rozstawu osi a współczynnik a (wsp_a) z przeliczenia prędkości (zadawanej w skali 0 do 100) i pokonywanej fizycznie drogi. Ze względu na nieidelaność układów trzeba było te współczynniki trochę dostroić (eksperymentalnie). Efekt działania dla prędkości V=40 umieściłem na filmiku. Nie jest idealnie. Dla wyższych prędkości trochę się to rozsypuje (głównie ze względu na szybkie zatrzymanie pojazdu i jego skoki).

Nie wiem czy w ogóle dobrze się zabieram do tego problemu. Czy ma ktoś może jakieś sugestie w tym temacie?

Pozdrawiam.

void obrotkat(int K,int V){
 float czas_obrotu;
 float droga_obrotu=33.0*K/360.0;
 float wsp_a=0.56;
 // jak + to obrot w prawo
 // jak - to obrot w lewo
 leftMotor(V);
 rightMotor(-V);
 V=abs(V);
 czas_obrotu=(droga_obrotu*1000)/(wsp_a*V);
 delay(czas_obrotu);
}

Udostępnij ten post


Link to post
Share on other sites

Raf11, tak jak pisałem podczas jednej z części kursu - bez odpowiednich dodatkowych czujników (enkoderów) nie jesteśmy w stanie kontrolować faktycznej drogi pokonywanej przez robota. Tyczy się to zarówno jazdy prosto, jak i precyzyjnych obrotów. Próba dobierania współczynników jest dobra, ale prędzej czy później całość się "rozjedzie". Pamiętaj, że już samo rozładowywanie się baterii podczas jazdy może tutaj dużo namieszać. Temat wykonywania obrotów o konkretny kąt, to coś, czym zajmuj się konstruktorzy robotów typu MicroMouse i często zajmuje im to długie godziny. Jak na tego robota i możliwości Arduino, to udało Ci się uzyskać dobre wyniki 🙂

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!

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