Skocz do zawartości

Kurs budowy robotów - #4 - pierwsze programowanie


Komentator

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

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ń

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

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

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

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

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

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

Link do komentarza
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);
}

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

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.