Skocz do zawartości

Podwozie robota 4x4


Pomocna odpowiedź

Projekt powstał jako rozwinięcie prostego jeździka solarnego ( dwa panele słoneczne, dwa silniki rama z dużego klocka ala duplo) który miał problem z pokonywaniem  nierówności.

Założenia

Stworzenie budżetowej platformy jezdnej mogącej poruszać się swobodnie po typowym  mieszkaniu - pokonywać przeszkody typu próg czy gruby dywan. Walidacją założenia  będzie możliwość pokonywania przeszkód o wysokości około 1 cm.

Układ mechaniczny

Aby było możliwe pokonywanie nierówności, koła muszą być maksymalnie niezależne -  amortyzowane. Próby [teoretyczne] opracowania zawieszenia trwały w sumie kilka  miesięcy. Żaden z pomysłów nie był tani a jednocześnie obiecujący (prosty).  Natomiast podczas spożywania ptysi z biedronki (francuskie ptysie nadziewane kremem o  smaku waniliowym z sosem z czekoladowym) zauważyłem że pudełko jest wytrzymałe ale  jego rogi da się dość elastycznie wyginać. Po nawierceniu 8 dziur i przykręceniu  silników z kołami okazało się że efekt jest obiecujący.

IMG_20190127_171352.thumb.jpg.26ef106896ea2fe0fd9606589ad9177c.jpgIMG_20190127_171344.thumb.jpg.78b4e7d56eb02d286e178e4c9ac9ef5b.jpg

Elektronika

Sercem układu jest Arduino Pro Mini 328 3V3 (3V3 bo docelowo będzie zasilane z starej  baterii od telefonu) poza tym jest wystarczające. Silnikami steruje DRV8833 - pierwszy kanał na dwa silniki z prawej strony i drugi  kanał na dwa silniki z lewej strony. UWAGA trzeba pamiętać o polach lutowniczych  pozwalających ograniczyć prąd! Komunikacja odbywa się jednokierunkowo - z telefonu do arduino. Ja użyłem Bluetooth  BLE HM-10 bo taki miałem ale może być jakiś inny.

IMG_20190102_234443.thumb.jpg.2e7f8c6e212c43c1bcc5423bdae3a8b6.jpgP1278002.thumb.JPG.555516cea1ded214948e2e90593c1037.JPG

 

Schemat bardzo poglądowy

Program
Jako bazy użyłem przykładu SerialEvent https://www.arduino.cc/en/Tutorial/SerialEvent Dodałem obsługę przycisku włączającego i wyłączającego pojazd (ruch pojazdu). Obsługa sterowania na podstawie akcelerometru:

  • Oś y - prawo lewo ( 123 na wprost [110-136]; 250 max prawo; 0 max lewo)
  • Oś z - speed (0-255) wsteczny max 140; przód max 255 - środek 195, bezład [ 200-230 ]
/*
akcelerometr:
1 - (x)
2 - (y) prawo lewo ( 123 na wprost [110-136]; 250 max prawo; 0 max lewo )
3 - (z) speed (0-255) wsteczny max 140; przód max 255 - srodek 195, bezład [ 200-230 ]
PWM 9 i 6
*/

//PWM
int BIN_1 = 9;
int BIN_2 = 8;
//PWM
int AIN_1 = 6;
int AIN_2 = 5;
int MAX_PWM_VOLTAGE = 240;
float MAX_PWM_VOLTAGE_FLOAT = 240.00;
float PWM_VOLTAGE_PERCENT = MAX_PWM_VOLTAGE_FLOAT/100;


float PWM_VOLTAGE_A;
float PWM_VOLTAGE_B;

String inputString = "";         // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

String speed = "";
String direction = "";

int speed_int = 215;
int direction_int = 123;

int tmp_speed_int = 0;
int tmp_direction_int = 0;

bool remote = false;

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);

    pinMode(BIN_1, OUTPUT);
    pinMode(BIN_2, OUTPUT);
    pinMode(AIN_1, OUTPUT);
    pinMode(AIN_2, OUTPUT);


    // delay just in case bluetooth module needs time to "get ready"
    //delay(100);

    //Serial.println("setup complete");
    //--prevMillis = millis();

    digitalWrite(BIN_2, LOW);
    digitalWrite(AIN_2, LOW);
    analogWrite(BIN_1, 0);
    analogWrite(AIN_1, 0);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {

    if (inputString.substring(0,6) == "remote"){
      if(remote == true){
        remote = false;
        digitalWrite(LED_BUILTIN, LOW);
      } else {
        remote = true;
        digitalWrite(LED_BUILTIN, HIGH);
      }
    }

    if (inputString.substring(0,1) == "2"){
      direction = inputString.substring(2);
      direction_int = direction.toInt();
    }

    if (inputString.substring(0,1) == "3"){
      speed = inputString.substring(2);
      speed_int = speed.toInt();
    }

]

    if((remote == true) && (speed_int > 230)){
      
          //26-50 pomnozone razy dwa daje ponad 50%, przy niższej mocy silniki nie pracują
          tmp_speed_int = speed_int-205;
          tmp_speed_int = tmp_speed_int*2;

          PWM_VOLTAGE_A = PWM_VOLTAGE_PERCENT*tmp_speed_int;
          PWM_VOLTAGE_B = PWM_VOLTAGE_PERCENT*tmp_speed_int;

          if((direction_int >= 110 ) && (direction_int <= 136 )){
            digitalWrite(BIN_2, LOW);
            digitalWrite(AIN_2, LOW);
          } else if (direction_int < 110){
            digitalWrite(BIN_2, LOW);
            digitalWrite(AIN_2, HIGH);
          } else if (direction_int > 136){
            digitalWrite(BIN_2, HIGH);
            digitalWrite(AIN_2, LOW);
          }
          
          
          analogWrite(BIN_1, (int)PWM_VOLTAGE_B);
          analogWrite(AIN_1, (int)PWM_VOLTAGE_A);
    } else if((remote == true) && (speed_int < 200)){
      //26-50 pomnozne razy dwa daje ponad 50%, przy niższej mocy silniki nie pracują
      tmp_speed_int = speed_int-230;
      tmp_speed_int = tmp_speed_int*-2;

      if((direction_int >= 110 ) && (direction_int <= 136 )){
            PWM_VOLTAGE_A = PWM_VOLTAGE_PERCENT*tmp_speed_int;
            PWM_VOLTAGE_B = PWM_VOLTAGE_PERCENT*tmp_speed_int;
          } else if (direction_int < 110){
            PWM_VOLTAGE_A = 0;
            PWM_VOLTAGE_B = PWM_VOLTAGE_PERCENT*tmp_speed_int;
          } else if (direction_int > 136){
            PWM_VOLTAGE_A = PWM_VOLTAGE_PERCENT*tmp_speed_int;
            PWM_VOLTAGE_B = 0;
          }
          
          
          digitalWrite(BIN_2, HIGH);
          digitalWrite(AIN_2, HIGH);
          analogWrite(BIN_1, (int)PWM_VOLTAGE_B);
          analogWrite(AIN_1, (int)PWM_VOLTAGE_A);
    } else {
      digitalWrite(BIN_2, LOW);
      digitalWrite(AIN_2, LOW);
      analogWrite(BIN_1, 0);
      analogWrite(AIN_1, 0);
    }

    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}


/*
  Serial Event example

  When new serial data arrives, this sketch adds it to a String.
  When a newline is received, the loop prints the string and clears it.

  A good test for this is to try it with a GPS receiver that sends out
  NMEA 0183 sentences.

  NOTE: The serialEvent() feature is not available on the Leonardo, Micro, or
  other ATmega32U4 based boards.

  created 9 May 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/SerialEvent
*/

/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();


    //Serial.println(inChar);
    
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}


Podsumowanie

Pojazd pokonuje przeszkody o wysokości ponad 1 centymetra - więc cel został  osiągnięty. Natomiast sterowanie nie jest optymalne - docelowo będę zmieniał na skręt  realizowany jako obrót wokół własnej osi (naprzemienny kierunek silników z prawej i  lewej strony).


Do budowy platformy wykorzystano:

  • 4 * silnik DC + koło
  • 1 * sterownik silników DC DRV8833
  • 1 * Arduino Pro Mini 328 3V3
  • 1 * Bluetooth BLE HM-10 (może być każdy BT [slave])
  • 2 * koszyczek na cztery AA
  • 8 * akumulator AA (najlepsze IMHO enleopy)
  • 1 * Breadboard 170
  • 1 * zestaw kabli
  • 1 * śrubki z nakrętkami z LeroyMerlin
  • 1 * pudełko po francuskich ptysiach nadziewanych kremem o smaku waniliowym z sosem z  czekoladowym - na wszelki wypadek zaopatrzyłem się w 3 dodatkowe pudełka 😉

Sterowanie odbywa się z smartfonu przy użyciu aplikacji RoboRemoFree.

50940792_2109475486031833_2748521749359362048_n.thumb.jpg.2f4ce4e49314d41dfe2d4e679169d425.jpg

Do programowania Arduino Pro Mini konieczne jest użycie konwertera USB do RS232TTL.

  • Lubię! 1
Link to post
Share on other sites

Podoba Ci się ten projekt? Zostaw pozytywny komentarz i daj znać autorowi, że zbudował coś fajnego!

Masz uwagi? Napisz kulturalnie co warto zmienić. Doceń pracę autora nad konstrukcją oraz opisem.

Właśnie zaakceptowałem Twój opis, możesz go teraz zgłosić do akcji rabatowej umieszczając link w temacie zbiorczym. Dziękuję za przedstawienie ciekawego projektu, zachęcam do prezentowania kolejnych DIY oraz aktywności na naszym forum 🙂

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

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.