Vogliamo realizzare un robot che sia in grado di seguire autonomamente un percorso indicato da una linea nera. Useremo del nastro isolante nero per disegnare il tracciato su un banco di colore chiaro e tre sensori a infrarosso per rilevare la presenza della linea nera e correggere la direzione. Il robot consiste in:
Il risultato finale è quello mostrato nel video:
Scopo | realizzare un veicolo robot che segua un tracciato a piacere indicato da una riga nera |
---|---|
Componenti | telaio con ruote e motoriduttori, Arduino Motor Shield, 3 sensori IR TCRT5000, 4 batterie stilo da 1,5 Volt |
Il Motor Shield Arduino si monta sopra la scheda Arduino e permette di collegare un motore elettrico alla scheda 1). Il componente principale dello shield, l'integrato L298, è in grado di comandare due motori in continua o un motore passo-passo grazie a due ponti H2). Allo shield possono essre collegati motori da 5 a 12 Volt con correnti fino a 2 Ampère.
Lo shield utilizza 8 pin della scheda Arduino; noi ne useremo solo 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 shield3).
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 veicolo perché le due ruote devono potersi muoversi in maniera indipendente - avanti e indietro e con velocità diverse - per cambiare direzione.
Le caratteristiche principali dei motori in continua sono:
Il motore si aziona applicando tensione e ruota a una velocità proporzionale al valore di tensione applicato. Per cambiare direzione bisogna invertire il verso la tensione.
Il movimento del motore viene trasmesso al carico - in questo caso le ruote - attraverso un albero motore. Più precisamente viene trasmessa una potenza meccanica che corrisponde al prodotto tra la velocità di rotazione e la coppia (la “spinta” ovvero qualcosa che ha un effetto simile a quello della forza nei 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)4).
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 tra i motori montati sul telaio e le ruote è posto un riduttore, un sistema ad ingranaggi che trasmette potenza meccanica riducendo la velocità, 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 (giri al minuto) |
corrente senza carico | 190 mA |
corrente massima | 250 mA |
L'algoritmo che permette al robot di seguire la linea è molto semplice. I tre sensori sono in grado di distinguere la linea nera (che riflette poco) dal piano su cui è disegnato il tracciato (che riflette il raggio infrarosso). I motori vengono comandati considerando che:
La figura seguente illustra il funzionamento dell'algoritmo (il segno giallo indica che il sensore ha rilevato la linea).
Nel programma si terrà conto anche di casi anomali; ad esempio se tutti i sensori sono attivi (o disattivi) significa che non è stata individuata la linea.
/* Progetto finale: robot che segue una linea * I due motori vengono comandati in base ai tre sensori a infrarosso * montati sulla parte frontale. Se quello centrale è sulla linea * il veicolo procede dritto, se la linea viene rilevata sui sensori * laterali il veicolo curva per riportare la linea al centro * * 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; // pin digitali collegati ai tre sensori (sinistro, centrale, destro) int IRs = 4; int IRc = 5; int IRd = 6; // lettura sensori bool lineaS, lineaD, lineaC; void setup() { // imposto i pin dei motori come uscite pinMode(dirD, OUTPUT); pinMode(dirS, OUTPUT); pinMode(velD, OUTPUT); pinMode(velS, OUTPUT); // marcia avanti per entrambi i motori digitalWrite(dirD, HIGH); digitalWrite(dirS, HIGH); // imposto i pin dei sensori come ingressi pinMode(IRs, INPUT); pinMode(IRd, INPUT); pinMode(IRc, INPUT); // serial debug Serial.begin(9600); } void loop() { // leggo i tre sensori (HIGH = linea nera) lineaS = digitalRead(IRs); lineaD = digitalRead(IRd); lineaC = digitalRead(IRc); Serial.print(lineaS); Serial.print(lineaC); Serial.println(lineaD); // linea non rilevata (tutto nero) -> alt if (lineaS && lineaD && lineaC){ Serial.println("tutto nero"); analogWrite(velD, 0); analogWrite(velS, 0); } // linea non rilevata (tutto bianco) -> alt else if (!lineaS && !lineaD && !lineaC) { Serial.println("tutto bianco"); analogWrite(velD, 0); analogWrite(velS, 0); } // linea al centro -> dritto else if (lineaC && !lineaS && !lineaD) { Serial.println("linea al centro"); analogWrite(velD, 200); analogWrite(velS, 200); } // linea a sinistra -> gira a sinistra else if (lineaS && !lineaC && !lineaD) { Serial.println("linea a sinistra"); analogWrite(velD, 200); analogWrite(velS, 100); } // linea a destra -> gira a destra else if (lineaD && !lineaC && !lineaS) { Serial.println("linea a destra"); analogWrite(velD, 100); analogWrite(velS, 200); } // piccolo ritardo per permettere al controllo di intervenire delay(10); }
Torna all'indice.