Skocz do zawartości

Kurs budowy robotów - #4 - pierwsze programowanie


Komentator

Pomocna odpowiedź

Cześć! 😉

Zad 4.3 - Działa, ale nie do końca tak jak należy...

Robot rozpędza się, po czym staje na około 1 sekundę. Następnie cała sekwencja zwalniania i ponownego rozpędzania zachodzi tak jak należy i znowu się zatrzymuje.

Pomożecie? 😉 Wstawiam kod do wglądu:

#define L_DIR 4
#define L_PWM 5
#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() {
for  (int i=50; i<PWM_MAX; i++) {
  leftMotor(i);
  rightMotor(-i);
  delay(50);
}
for (int i=PWM_MAX; i>=50; i--) {
 leftMotor(i);
 rightMotor(-i);
 delay(50);
}
}

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

Cześć wszystkim!

Ta część poradnika w końcu dała tą frajdę której spodziewałem się w kursie budowy robotów. Super sprawa. Załączam moje testy metod odpowiedzialnych za napęd:

pierwszy

drugi

trzeci

Rozwiązanie zadania 4_2,  tutaj efekt w praktyce. Kod niestety nadpisałem robiąc następne zadanie. Po wykonaniu wszystkich ruchów dodałem zatrzymanie na 10s bo sam się nie mogłem połapać kiedy jest koniec 🙂

A tutaj nagranie zadania 4_3, a poniżej kod:

#define PWM_MAX 165

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

void setup()
{
  pinMode(L_PWM, OUTPUT);
  pinMode(L_DIR, OUTPUT);
  pinMode(R_PWM, OUTPUT);
  pinMode(L_DIR, OUTPUT);
}

int currentValue = 0;
int delta = 5;

void loop()
{

  leftMotor(currentValue);
  rightMotor(-currentValue);

  delay(250);
  
  currentValue += delta;

  if(currentValue >= 100 || currentValue <= 0)
  {
    delta = -delta;
    currentValue += delta;
  }
  
}

void leftMotor(int v)
{
  if(v < 0)
  {
    v = map(abs(v), 0, 100, 0, PWM_MAX);
    digitalWrite(L_DIR, 1);
    analogWrite(L_PWM, v);
  }
  else
  {
    v = map(v, 0, 100, 0, PWM_MAX);
    digitalWrite(L_DIR, 0);
    analogWrite(L_PWM, v);
  }
}

void rightMotor(int v)
{
  if(v < 0)
  {
    v = map(abs(v), 0, 100, 0, PWM_MAX);
    digitalWrite(R_DIR, 1);
    analogWrite(R_PWM, v);
  }
  else
  {
    v = map(v, 0, 100, 0, PWM_MAX);
    digitalWrite(R_DIR, 0);
    analogWrite(R_PWM, v);
  }
}

void stopMotors()
{
  analogWrite(L_PWM, 0);
  analogWrite(R_PWM, 0);
}

 

  • 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

@olum widzę że jednak udało Ci się złożyć robota i programy działają bardzo ładnie 🙂 

7 godzin temu, olum napisał:

Rozwiązanie zadania 4_2,

Fajnie, acz etap "obrót o 360°" przypomina bardziej piruet z kilkukrotnym obrotem 😄 

7 godzin temu, olum napisał:

A tutaj nagranie zadania 4_3

A tu działa bardzo ładnie, powodzenia w kolejnych zadaniach!

Edytowano przez Gieneq
  • Lubię! 2
Link do komentarza
Share on other sites

@leepa79 Czy mógłbyś jednak pomóc na czym polega ta poprawka ? Nie mogę wymyślić dlaczego następuje przerwa pomiędzy rozpędzaniem i hamowaniem.

Pierwsza metoda , którą opisałeś działa bez pudła ( też tak to rozwiązałem ) ale nadal mnie frapuje dlaczego nie działa przy wykorzystaniu funkcji zewnętrznej

Link do komentarza
Share on other sites

@leepa79 Czy mógłbyś podpowiedzieć jaką zmianę zrobiłeś żeby zlikwidować ten 1 sek przestój pomiędzy rozpędzaniem i zwalnianiem ?

Nie mogę znaleźć błędu 

Dnia 8.01.2017 o 10:38, leepa79 napisał:

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

 

Link do komentarza
Share on other sites

@DeryKwiat niezbyt rozumiem o co chodzi. Piszesz o jakiś opóźnieniach to może masz na myśli ten fragment gdzie robot się rozpędza:

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

 

Link do komentarza
Share on other sites

Chodzi mi o to co sam napisałeś pod programem

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

Link do komentarza
Share on other sites

@DeryKwiat bo w programie jest taki kwiatek:

void loop(){
 turnMotor1();
}

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

Czyli mamy tu taki przebieg piłokształtny - prędkość narasta... i od zera (zatrzymuje się i znowu narasta).

Możliwe że pierwsze kilka iteracji nie powoduje ruchu robota. Zmień PWM_MIN i sprawdź czy jest lepiej.

Link do komentarza
Share on other sites

Widzę że chcesz mi pomóc to tym razem przesyłam zawartość programu i efekt na filmiku. Nie rozumiem dlaczego występuje gwałtowne zatrzymanie na około 1 sek pomiędzy narastaniem prędkości i następuje skok do prędkości MAX i łagodne wyhamowanie. Miała być właśnie taka piła od Min do MAX i z powrotem do min.

#define L_PWM 5
#define L_DIR 4
#define R_PWM 6
#define R_DIR 9
#define PWM_MAX 165
int n = 0;
int k = 0;
int s = 0;
void setup() 
{
  Serial.begin(115200);                                      //Konfiguracja pinow od mostka H
  pinMode(L_DIR, OUTPUT);
  pinMode(R_DIR, OUTPUT);
  pinMode(L_PWM, OUTPUT);
  pinMode(R_PWM, OUTPUT);
}

void loop() 
 {
  
  Serial.print (" k = ");
  Serial.print(k);

     for ( n=5 ; n <= PWM_MAX ; n = n+5 )
      {
        leftMotor(n);                      // Rozpędzanie silników
        rightMotor(-n); 
        delay(500);                        // co 0,5 sek zmiana prędkości
      }
      
     for( n = PWM_MAX ; n >= 5 ; n = n-5 )
       {
        leftMotor(n);                     // hamowanie silników
        rightMotor(-n);                    
        delay(500);                       // co 0,5 sek zmiana prędkości
       }
   }

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
}

Robot.zip

Edytowano przez Gieneq
Link do komentarza
Share on other sites

@DeryKwiat faktycznie podejrzane.

Widzę tu jeden błąd, porównaj funkcję i wywołanie:

V = map(V, 0, 100, 0, PWM_MAX);
for( n = PWM_MAX ; n >= 5 ; n = n-5 )
       {
        leftMotor(n); 

Funkcja przyjmuje wartości od 0 do 100 które skaluje na 0 do PWM_MAX. A w pętli iterujesz do PWM_MAX, które jest większe od 100.

Funkcja map() nie ma żadnych zabezpieczeń więc przeskalowała tę wartość:

long map(long x, long in_min, long in_max, long out_min, long out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Funkcja analogWrite() jest już zabezpiecozna:

void analogWrite(uint8_t pin, int val)
{
	// We need to make sure the PWM output is enabled for those pins
	// that support it, as we turn it off when digitally reading or
	// writing with them.  Also, make sure the pin is in output mode
	// for consistenty with Wiring, which doesn't require a pinMode
	// call for the analog output pins.
	pinMode(pin, OUTPUT);
	if (val == 0)
	{
		digitalWrite(pin, LOW);
	}
	else if (val == 255)
	{
		digitalWrite(pin, HIGH);
	}

ale argument ma 8 bitów (0-255), a jak dałeś coś większego to zmienna się obróciła i zaczęła liczyć od 0. Spróbuj zmienić zakres iteracji i powinno działać. Możesz też spróbować wykorzystać fakt przepełniania zmiennej do animacji piłokształtnej, a stosując funkcję abs() zrobić ładny trójkąt.

Edytowano przez Gieneq
  • Lubię! 1
  • Pomogłeś! 1
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.