Il mio primo robot a due ruote

Questo articolo è il proseguimento del precedente e consentirà di pilotare un robot a due ruote tramite la tastiera del computer; i comandi verranno inseriti nel monitor seriale dello sketch di arduino. Verranno utilizzati alcuni elementi presenti in SparkFun Inventor’s Kit for Arduino UNO:

  • 1 INTERRUTTORE (SWITCH): apre/chiude un circuito; se l’interruttore è chiuso il circuito si attiverà;
  • 2 MOTORI DC, 2 RUOTE e 1 CHIP MOTOR DRIVER (TB6612FNG) : tale chip
  • 1 BREADBOARD
  • 1 ARDUINO UNO R3
  • 1 TAVOLETTA NERA
  • 1 CAVO USB
  • 1 clip
  • 1 pezzo di nastro biadesivo “Dual Lock 3M”

Dopo aver fatto tutti i collegamenti previsti nel precedente articolo, tagliare 3 – 3,5 cm di “Dual Lock 3M” ed incollarlo una parte sulla ruota ed una parte sulla struttura portante. Fare lo stesso per l’altra ruota:

Si osservi che, per comodità di montaggio, un motore è stato montato al contrario. Ciò vuol dire che quando il robot a due ruote dovrà andare dritto, un motore dovrà essere pilotato in un verso e l’altro in verso opposto.
Il robot, avendo solo due ruote, penderà nella parte posteriore dove verrà collegata una clip:

Per controllare il robot a due ruote, bisognerà inserire un comando tramite il monitor seriale. Scrivendo

  • a 20: il robot andrà avanti di 20 cm
  • i 30: il robot andrà indietro di 30 cm
  • d 45: il robot ruoterà di 45°
  • s 90: il robot ruoterà a sinistra di 90°

Il codice da utilizzare sarà il eseguente:

/*SparkFun Inventor’s Kit
Circuit 5B – Remote Control Robot
Questo sketch consente di controllare il robot a due ruote inviando
dei comandi di movimento e di direzione attraverso il monitor seriale*/

// La ruota sinistra è controllata dal canale A, la ruota destra dal canale B
// Controllare i collegamenti delle ruote
const int AIN1 = 13;     // pin1 di controllo del motore A (ruota sinistra)
const int AIN2 = 12;     // pin2 di controllo del motore A
const int PWMA = 11;  // controlla la velocità del motore A
const int BIN1 = 8;       // pin1 di controllo del motore B  (ruota destra)
const int BIN2 = 9;       // pin1 di controllo del motore B
const int PWMB = 10;  // controlla la velocità del motore B
int switchPin = 7;          // interruttore per accendere e spegnere il robot
// numero di millisecondi che il robot impiega a fare circa 1 cm; dipende dall’attrito delle ruote con il pavimento.
const int driveTime = 26;
// Questo valore va settato sperimentalmente. Si scrive “a 100” nel Monitor seriale, si misura la distanza percorsa dal robot e si fa la proporzione:
// 26 : misura = x : 100 => x = 2600/misura. Tale valore si setta in driveTime
const int turnTime = 3;        // numero di millisecondi necessario per ruotare di 1 grado;
// se nella porta seriale si indica d 45, il robot ruota di 45° a destra;
// tale valore va settato sperimentalmente, dipende dall’attrito con il pavimento.
String botDirection;           // verso di spostamento del robot;
String distance;               // distanza da percorrere

/**************************************/
void setup()
{
  pinMode(switchPin, INPUT_PULLUP);   //set this as a pullup to sense whether the switch is flipped  // setta i pin come output
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(PWMA, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  Serial.begin(9600);           //inizializza la comunicazione con la porta seriale
  //prompt the user to enter a command
  Serial.println(“Scrivi il tipo di movimento, spazio, distanza da percorrere (cm) e premi invio.”);
  Serial.println(“a = avanti, i = indietro”);
  Serial.println(“Esempio: a 50”);
  Serial.println(“va avanti di 50 cm”);
  Serial.println(“Oppure scrivi il tipo di rotazione e l’angolo di rotazione.”);
  Serial.println(“d = ruota a destra, s = ruota a sinistra”);
  Serial.println(“Esempio: d 90”);
  Serial.println(“ruota a destra di 90°”);
Serial.println(“—————————————“);
}

/*******************************************/
void loop()
{
// legge l’interruttore sullo switchPin e se è basso (interruttore chiuso)
if(digitalRead(7) == LOW)
{  // cioè l’interruttore è ON
   if (Serial.available() > 0)    // se l’utente ha inserito un comando
    {
// legge il primo comando (prima dello spazio) cioè il verso del robot : a avanti, i indietro
     botDirection = Serial.readStringUntil(‘ ‘);
// legge il secondo comando sulla distanza/rotazione: d destra, s sinistra
distance = Serial.readString();    
      // stampa il comando ricevuto
      Serial.print(botDirection);                      
      Serial.print(” “);                               
      Serial.println(distance.toInt());                
      if(botDirection == “a”)                 // se l’utente inserisce a (avanti)
      {
        rightMotor(200);                      // setta la velocità del motore destro
        leftMotor(-200);                       // setta la velocità del motore sinistro
// la distanza viene trasformata in un tempo e i motori proseguono per il tempo indicato
       delay(driveTime * distance.toInt()); 
      }
     else if(botDirection == “i”)     // se l’utente inserisce i (indietro)
      {
       rightMotor(-200);          // setta la velocità del motore destro
       leftMotor(+200);           // setta la velocità del motore sinistro
// la distanza viene trasformata in un tempo e i motori proseguono per il tempo indicato
       delay(driveTime * distance.toInt());
      }
     else if(botDirection == “d”)                      // se si deve ruotare a destra
      {
       rightMotor(-255);     // setta la velocità del motore destro
       leftMotor(-255);        // setta la velocità del motore sinistro
       delay(turnTime * distance.toInt()); 
      }
     else if(botDirection == “s”)                    // se si deve ruotare a sinistra
      {
       rightMotor(255);     // setta la velocità del motore destro
       leftMotor(+255);      // setta la velocità del motore sinistro
       delay(turnTime * distance.toInt());      
      }
     rightMotor(0);        // ferma il motore destro
     leftMotor(0);          // ferma il motore sinistro
    }
  }
  else // l’interruttore è OFF
  {
      rightMotor(0);                                  // ferma il motore destro
      leftMotor(0);                                   // ferma il motore sinistro
  }
}

/***********************************/
void rightMotor(int motorSpeed)  // funzione che guida il motore destro
{
  if (motorSpeed > 0)                                 // se il motore destro deve andare avanti
  {
    digitalWrite(BIN1, HIGH);                         //set pin 1 to high
    digitalWrite(BIN2, LOW);                          //set pin 2 to low
  }
  else if (motorSpeed < 0)                            // se il motore destro deve andare indietro
  {
    digitalWrite(BIN1, LOW);                          //set pin 1 to low
    digitalWrite(BIN2, HIGH);                         //set pin 2 to high
  }
  else                                                // se il motore va fermato
  {
    digitalWrite(BIN1, LOW);                          //set pin 1 to low
    digitalWrite(BIN2, LOW);                          //set pin 2 to low
  }
analogWrite(PWMA, abs(motorSpeed)); // avvia il motore (se motorSpeed è diverso da 0)
}

/*********************************/
void leftMotor(int motorSpeed)                        // funzione che guida il motore sinistro
{
  if (motorSpeed > 0)                                 // se il motore sinistro deve andare avanti
  {
    digitalWrite(AIN1, HIGH);                         //set pin 1 to high
    digitalWrite(AIN2, LOW);                          //set pin 2 to low
  }
  else if (motorSpeed < 0)                            // se il motore sinistro deve andare indietro
  {
    digitalWrite(AIN1, LOW);                          //set pin 1 to low
    digitalWrite(AIN2, HIGH);                         //set pin 2 to high
  }
  else                                                // se il motore va fermato
  {
    digitalWrite(AIN1, LOW);                          //set pin 1 to low
    digitalWrite(AIN2, LOW);                          //set pin 2 to low
  }
  analogWrite(PWMB, abs(motorSpeed));                 // avvia il motore
}

Prof. Vito Egidio Mosca
Imparare la Fisica

Pubblicato da impararelafisica

Come è bello conoscere tante cose e non saperne altre, ma è ancora più bello scoprirne delle nuove anche se già scoperte da altri. Mosca Vito Egidio, Docente di Matematica e Fisica, Liceo Scientifico. Vincitore del Premio Antonella Bastai Prat 2009 dell'AIF. Vincitore del Premio Antonella Bastai Prat 2016 dell'AIF.