Robot a due ruote autonomo con batteria e sensore ad ultrasuoni

Questo articolo è il proseguimento del precedente, consente di staccare il robot dal cavo usb e lo rende autonomo di muoversi. Lo sketch presente in questo articolo è una versione base che può essere ulteriormente migliorato: ad es. si può collegare un sensore di temperatura per fare una misura corretta della distanza fatta con gli utlrasuoni; il sensore di distanza (ad ultrasuoni) può essere montato su un servomotore che ruota ed aiuta a determinare meglio la direzione da prendere; si possono montare più sensori ad ultrasuoni … Lo sketch è stato programmato in modo che se il robot incontra un ostacolo, torna indietro, ruota e poi prosegue.

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);
  • 1 BREADBOARD;
  • 1 ARDUINO UNO R3:
  • 1 TAVOLETTA NERA;
  • 1 CAVO USB;
  • 1 clip;
  • 1 pezzo di nastro biadesivo “Dual Lock 3M”;
  • 1 porta pile con 4 pile (non incluse nel kit);
  • 1 sensore ad ultrasuoni (ho sostituito il componente presente nel kit con HC-SR04 più affidabile);

Posizionare il sensore ad ultrasuoni tra i pin a14 e a17 della breadboard in modo che il sensore guardi avanti e sia posizionato al centro.

Prendere 3  cm di “Dual Lock 3M” ed incollarlo una parte sul fondo delle batterie e l’altra parte a metà della struttura portante nera.

Il sensore ad ultrasuoni ha 4 pin:

  • a14 (pin vicino la ruota destra): VCC – va collegato a 5 V (sul morsetto +) con un cavo rosso;
  • a15: TRIG – va collegato al pin 6;
  • a16: ECHO – va collegato al pin 5;
  • a17 (pin vicino la ruota sinistra): GND – va messo a terra (ground) con un cavo nero.

ATTENZIONE: prima di attivare il codice, posizionare l’interruttore su OFF ed assicurarsi che non sia su un tavolo o una posizione da cui possa cadere.

Il codice per lo sketch è il seguente (ma può essere ulteriormente migliorato mediante dei test):

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

// variabili per la misura delle distanze
const int trigPin = 6;
const int echoPin = 5;
int switchPin = 7; // interruttore per accendere e spegnere il robot
float distance = 0; // variabile in cui verrà scritta la distanza misurata dal sensore
int backupTime = 700; // tempo, in millisecondi, utilizzato dal robot per tornare indietro quando incontra un ostacolo
int turnTime = 350; // tempo, in millisecondi, utilizzato dal robot per svoltare quando incontra un ostacolo

/**************/
void setup()
{
pinMode(trigPin, OUTPUT); // questo pin invia impulsi ad ultrasoni dal sensore di distanza
// questo pin rileverà quando gli impulsi riflessi torneranno indietro.
// In questo modo dal tempo e dalla velocità del suono è possibile ricavare la distanza.
pinMode(echoPin, INPUT);
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
Serial.print(“Verso l’infinito!”); // test della connessione seriale
}

/**/
void loop()
{
// RILEVA LA DISTANZA CON IL SENSORE
distance = getDistance();
Serial.print(“Distanza: “);
Serial.print(distance);
Serial.println(” cm”);
if(distance < 7){ // se si rileva un ostacolo a 7 cm di distanza
// viene stampato sul monitor seriale (ciò serve soltanto per testare il robot)
Serial.print(” “);
Serial.print(“BACK!”);
}
// legge l’interruttore sullo switchPin e se è basso (interruttore chiuso)
if(digitalRead(7) == LOW)
{ // cioè l’interruttore è ON
if(distance < 7){ // se si rileva un ostacolo
// si ferma per 0,2 s, torna indietro e gira

// fermati per un momento
  rightMotor(0);
  leftMotor(0);
  delay(200);
  // torna indietro
  rightMotor(-100);
  leftMotor(+100);
  delay(backupTime);
  // cambia direzione
  rightMotor(100);
  leftMotor(+100);    
  delay(turnTime);
  // vai avanti
  rightMotor(100);
  leftMotor(-100);
}else{                         // se nessun ostacolo è rilevato, vai avanti
  Serial.print(" ");
  Serial.print("Moving...");
  rightMotor(100);
  leftMotor(-100);
}

} else{ // se l’interruttore è spento, stai fermo
//stop the motors
rightMotor(0);
leftMotor(0);
}

delay(100); // aspetta 0,1 s
}
/**/
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
}

// invia un impulso ultrasonico lungo 10ms
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// usa il comando pulsein per vedere quanto tempo impiega l’impulso a rimbalzare sul sensore
echoTime = pulseIn(echoPin, HIGH);

calculatedDistance = echoTime * 0.01715; // calcola la distanza dell’oggetto che riflette l’impulso (metà del tempo di rimbalzo moltiplicato per la velocità del suono)
// 343 m/s che vuol dire anche 0,0343 cm/microsecondi
// s = 0,0343 * t/2 = 0,01715 * t

return calculatedDistance; // restituisce la distanza calcolata
}

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.