Vogliamo realizzare un robot esploratore capace di muoversi autonomamente ed evitare gli ostacoli cambiando direzione quando ne incontra uno. Per rilevare gli ostacoli useremo un sensore a ultrasuoni; per muovere il robot due motori pilotati dalla scheda Arduino con il motor shield Arduino.
La struttura del robot è costituita da un telaio in plastica che supporta:
Il risultato finale è questo:
Scopo | realizzare un robot esploratore che evita gli ostacoli |
---|---|
Componenti | telaio con ruote motori e riduttori, arduino motor shield, 4batterie stilo da 1,5 Volt, sensore a ultrasuoni HC-SR04 |
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 |
/* * Progetto Finale: un robot esploratore che evita gli ostacoli * Il robot si muove autonomamente: procede con una traiettoria * rettilinea finché non incontra un ostacolo (rilevato con un * sensore a ultrasuoni), quindi cambia direzione * * Nome Studente: * Creato il: data */ // pin collegati a trigger ed echo del sensore a ultrasuoni int pinTrig = 4; int pinEcho = 5; // durata dell'impulso echo in microsecondi unsigned long durata; // distanza dell'ostacolo in centimetri int distanza; // timeout della funzione pulseIn() in assenza di impulso echo unsigned long timeout = 100000; // pin direzione e velocità del motore sinistro int pinDirS = 13; int pinVelS = 11; // pin direzione e velocità del motore destro int pinDirD = 12; int pinVelD = 3; void setup(){ // imposto i pin del sensore pinMode(pinTrig, OUTPUT); pinMode(pinEcho, INPUT); // imposto i pin del motore sinistro pinMode(pinDirS, OUTPUT); pinMode(pinVelS, OUTPUT); // imposto i pin del motore destro pinMode(pinDirD, OUTPUT); pinMode(pinVelD, OUTPUT); } void loop(){ // RILEVAMENTO OSTACOLO // impulso di 10us dalla scheda al pin trigger del sensore digitalWrite(pinTrig, HIGH); delayMicroseconds(10); digitalWrite(pinTrig, LOW); // calcolo la durata dell'impulso echo inviato dal sensore durata = pulseIn(pinEcho, HIGH, timeout); // converto la durata dell'impulso in distanza in centimetri distanza = durata / 58; // MARCIA DEL ROBOT // cambia direzione se l'ostacolo è a meno di 15 centimetri // (distanza 0 significa nessun ostacolo) if(distanza != 0 && distanza < 15){ // va indietro a sinistra per un secondo digitalWrite(pinDirS, LOW); digitalWrite(pinDirD, LOW); analogWrite(pinVelS, 255); analogWrite(pinVelD, 100); delay(1000); } // altrimenti va dritto else { digitalWrite(pinDirS, HIGH); digitalWrite(pinDirD, HIGH); analogWrite(pinVelS, 255); analogWrite(pinVelD, 255); } // breve ritardo tra una misura e l'altra delay(100); }
analogWrite(pin, valore)
dove pin è uno dei 6 pin digitali con modulazione PWM (3, 5, 6, 9, 10, 11) e valore è un numero compreso tra 0 e 255, dove 255 corrisponde a 5 Volt Torna all'indice.