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.
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:
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 |
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) | 3 | 11 |
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:
HIGH
o LOW
sui pin 12 e 13In 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.
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 |
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.
/* 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); }
/* 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); } }
Torna all'indice.