Indice

Progetto finale: un veicolo radiocomandato

Vogliamo comandare un veicolo con un radiocomando sfruttando due schede Arduino che comunicano via radio. Il veicolo è quasi lo stesso utilizzato nel progetto finale 2013/2014, ma privo del sensore ad ultrasuoni e dotato invece di uno shield wireless per la comunicazione via radio.

vista inferiore del telaio: motori, riduttori, ruote e cavi di alimentazione

La struttura del veicolo è costituita da un telaio in plastica che supporta:

Il radiocomando è realizzato su breadboard ed è dotato di quattro pulsanti per la marcia avanti, indietro, a destra e a sinistra. Sia il veicolo che il radiocomando montano uno shield con un modulo wireless Xbee per la comunicazione via radio.

Il risultato finale è questo:

Progetto: un robot esploratore

Scopo realizzare un veicolo e il relativo radiocomando
Componenti veicolo telaio con ruote e motoriduttori, Arduino Motor Shield, Xbee Shield 4batterie stilo da 1,5 Volt
Componenti radicomando breadboard, quattro pulsanti, quattro resistenze da 15 kΩ, Xbee Shield

Approfondimento sull'hardware : il motor shield Arduino

Arduino Motor Shield R3

Il Motor Shield Arduino si monta sopra la scheda Arduino e permette di collegare un motore alla scheda. Il componente principale dello shield è l'integrato L298 che contiene due ponti H con i quali comandare due motori in continua o un motore passo-passo. Si possono collegare motori da 5 a 12 Volt che assorbono una corrente fino a 2 Ampère. Per alimentare la scheda, lo shield e i due motori useremo quattro batterie stilo per un totale di 6 Volt.

Lo shield utilizza 8 pin della scheda Arduino; noi ne useremo quattro, in particolare:

funzione pin (motore A) pin (motore B)
direzione (avanti/indietro) 12 13
velocità (tensione al motore) 311

NB lo shield usa anche i pin A0 e A1 per misurare le correnti e i pin 8 e 9 per l'arresto rapido dei motori; se si vuole utilizzare ad altro scopo questi pin occorre tagliare i rispettivi collegamenti sul retro dello shield1).

Comandare due motori in continua è molto semplice:

Approfondimento sull'hardware : il motore in continua

In questo progetto utilizzeremo due motori in continua per muovere il robot. Le due ruote devono muoversi in maniera indipendente - avanti e indietro e con velocità diverse - per far cambiare direzione al robot.

motore in continua, fonte sparkfun.com

Le caratteristiche principali dei motori in continua sono:

Il motore si aziona applicando tensione e la sua velocità è proporzionale al valore di tensione applicato. Per invertire la direzione è sufficiente invertire la tensione.

Il movimento del motore viene trasmesso al carico - in questo caso le ruote - attraverso l'albero. Più precisamente viene trasmessa una potenza meccanica che corrisponde al prodotto tra la velocità di rotazione e la coppia (la “spinta” o meglio l'equivalente della forza dei moti rettilinei):

`P=C cdot omega`

dove P è la potenza in Watt (W), C la coppia in Newton per metro (Nm) e ω la velocità in radianti al secondo (rad/s)2).

Nel nostro caso non è possibile collegare direttamente le ruote all'albero perché i motori sono costruiti per girare molto velocemente - ad esempio a 1000 giri al minuto (rpm) - e le ruote girerebbero troppo velocemente. Per questo i motori montati sul telaio sono equipaggiati con un riduttore, un sistema ad ingranaggi che trasmette potenza meccanica riducendo la veocità, più o meno come il cambio di un'automobile o di una bicicletta.

I due motoriduttori (motore più riduttore) montati sul telaio hanno queste caratteristiche:

tensione massima 4,5 Volt in continua
velocità massima senza carico 10 rpm
corrente senza carico 190 mA
corrente massima 250 mA

Approfondimento sull'hardware: lo shield Xbee

Xbee Shield

L'Xbee Shield si monta sopra la scheda Arduino (sopra il Motor shield nel veicolo) e permette di stabilire una connessione wireless con altre schede o con altri dispositivi compatibili con il protocollo ZigBee (un protocollo wireless diverso dal WiFi o dal Bluetooth di computer e smartphone). Sullo shield è montato un modulo wireless Xbee S2 della Digi International che gestisce la comunicazione via radio con altri dispositivi ZigBee. La vasta gamma di funzionalità offerta da questi moduli rende il loro utilizzo piuttosto complesso; noi ci limiteremo ad utilizzarne due già configurati (si fa da PC con un apposito software). Il risultato è che le due schede Arduino potranno comunicare tra loro con una semplice connessione seriale come quella del monitor seriale quando la scheda è collegata col cavo USB.

Schema elettrico radiocomando

schema elettrico del radiocomando

sketch veicolo

/* Progetto finale: veicolo radiocomandato
 * Questo sketch va caricato sulla scheda Arduino del veicolo
 * I due motori vengono comandati in base ai dati ricevuti via seriale:
 * 'a' -> avanti (i due motori vanno alla stessa velocità)
 * 'i' -> indietro (i due motori vanno indietro alla stessa velocità)
 * 'd' -> destra (motore destro più lento del sinistro)
 * 's' -> sinistra (motore sinistro più lento del destro)
 *
 * Nome:
 * Creato il:
 */
 
// pin che controllano la direzione del motore destro e sinistro
// valori: HIGH = avanti, LOW = indietro
int dirD = 12;
int dirS = 13;
 
// pin PWM che controllano la velocità del motore destro e sinistro
// valori: da 0 (motore fermo) a 255 (massima velocità)
int velD = 3;
int velS = 11;
 
// numero di byte da leggere ricevuti via seriale 
int numByte;
 
// dato ricevuto dalla seriale (un byte)
int byteRicevuto;
 
void setup(){
  // imposto i pin dei motori come uscite
  pinMode(dirD, OUTPUT);
  pinMode(dirS, OUTPUT);
  pinMode(velD, OUTPUT);
  pinMode(velS, OUTPUT);
  // imposto la comunicazione seriale
  Serial.begin(9600);
}
 
void loop(){
  // controllo quanti byte di dati sono stati ricevuti via seriale
  numByte = Serial.available();
  // se il numero è zero non sono stati ricevuti dati, se è uno o più
  // posso leggere i dati un byte per volta dal primo all'ultimo ricevuto
  if(numByte > 0){
    // leggo un byte
    byteRicevuto = Serial.read();
    // comando i due motori in base al carattere ricevuto da seriale:
    // a = avanti, i = indetro, d = destra, s = sinistra
    if(byteRicevuto == 'a'){
      //  marcia avanti
      digitalWrite(dirD, HIGH);
      digitalWrite(dirS, HIGH);
      analogWrite(velD, 255);
      analogWrite(velS, 255);
    }
    else if(byteRicevuto == 'i'){
      // marcia indietro
      digitalWrite(dirD, LOW);
      digitalWrite(dirS, LOW);
      analogWrite(velD, 255);
      analogWrite(velS, 255);
    }
    else if(byteRicevuto == 'd'){
      // gira a destra
      digitalWrite(dirD, HIGH);
      digitalWrite(dirS, HIGH);
      analogWrite(velD, 100);
      analogWrite(velS, 255);
    }
    else if(byteRicevuto == 's'){
      // gira a sinistra
      digitalWrite(dirD, HIGH);
      digitalWrite(dirS, HIGH);
      analogWrite(velD, 255);
      analogWrite(velS, 100);
    }
    else{
      // arresta i motori (dato ricevuto non valido)
      analogWrite(velD, 0);
      analogWrite(velS, 0);
    }
  }
  // arresta i motori se non sono stati ricevuti dati
  else{
    analogWrite(velD, 0);
    analogWrite(velS, 0);
  }
  // piccolo ritardo
  delay(10);
}

sketch radiocomando

/* Progetto finale: veicolo radiocomandato
 * Questo sketch va caricato sulla scheda Arduino del radiocomando
 * Invio un comando al veicolo tramite seriale. 
 * I comandi (semplici caratteri) sono:
 * 'a' -> avanti 
 * 'i' -> indietro 
 * 'd' -> destra 
 * 's' -> sinistra 
 *
 * Nome:
 * Creato il:
 */
 
// pin collegati ai quattro pulsanti
int avanti = 2;
int indietro = 3;
int destra = 4;
int sinistra = 5;
 
void setup(){
  // imposto i pin dei pulsanti come ingressi
  pinMode(avanti, INPUT);
  pinMode(indietro, INPUT);
  pinMode(destra, INPUT);
  pinMode(sinistra, INPUT);
  // imposto la comunicazione seriale
  Serial.begin(9600);
}
 
void loop(){
  // controllo lo stato dei pulsanti e invio il carattere corrispondente
  if(digitalRead(avanti) == HIGH){
    Serial.print('a');
    delay(10);
  }
  else if(digitalRead(indietro) == HIGH){
    Serial.print('i');
    delay(10);
  }
  else if(digitalRead(destra) == HIGH){
    Serial.print('d');
    delay(10);
  }
  else if(digitalRead(sinistra) == HIGH){
    Serial.print('s');
    delay(10);
  }
}

Osservazioni

Torna all'indice.

1)
nel nostro caso i pin per la frenatura non sono utilizzati nel programma e risultano scollegati (di default i pin sono impostati come ingressi ad alta impedenza); nello shield invece una resistenza di pull-down disabilita l'arresto rapido
2)
spesso la velocità è espressa in giri al minuto (rpm) anche se non è l'unità di misura prevista dal Sistema Internazionale