Si tratta di un car robot 2WD, useremo il solito Kit Robot 2 ruote con telaio in plexiglass e 4 Sensori inseguitori di linea TCRT5000.
Vediamo il materiale occorrente:
1 Arduino Uno
1 Motor Shield L293D
1 Kit Robot 2 ruote
4 Sensori inseguitori di linea TCRT5000
2 Led opzionali
Pile 4 stilo AA o 2 pile Litio ricaricabili con porta batteria
4 Distanziale femmina/femmina altezza 20 mm forati e filettati con passo M3. (per fissaggio sensori )
4 Distanziale femmina/femmina altezza 5/8 mm forati e filettati con passo M3. ( per fissaggio Arduino )
cavetti DUPONT Femmina-Femmina lunghezza 20cm circa.
Saldatore stagno
Robot inseguitore di linea è una macchina che segue una linea, nel nostro caso sarà una linea nera tracciata su una superficie chiara con nastro da elettricista nero. Il concetto di lavoro del robot inseguitore di linea è legato alla luce, usiamo il comportamento della luce in una superficie bianca e nera. Quando la luce cade su una superficie bianca viene riflessa a pieno, nel caso invece di superficie nera viene completamente assorbita. Questo comportamento della luce viene utilizzato per gestire i motori del nostro robot inseguitore di linea .
Vediamo il funzionamento del sensore inseguitore di linea:
Una superficie NERA Arduino ottiene sul PIN Una superficie BIANCA Arduino ottiene sul PIN un > livello ALTO (HIGH) 5 Volt un > livello BASSO ( LOW ) 0 Volt
La distanza da terra dei sensori per la linea è importante; fate delle prove con un cartoncino bianco e nero, i 4 sensori quando sono posizionati sopra il cartoncino bianco devono avere i led accesi, mentre posizionati sul nero i led si spengono,.
La sensibilità si può regolare tramite il trimmer che vediamo in foto.
Lo Shield L293D utilizzato per questo progetto non aveva i connettori Pin sulle uscite A0-A5 / Gnd / +5 / , si può risolvere saldando una serie di strip maschio/maschio, per evitare questo passaggio controllate al momento dell'acquisto che disponga di queste uscite con i Pin come quella in foto.
Posizionando i sensori centrali su una linea nera i motori dovrebbero muoversi in avanti. Se un motore gira all'indietro, invertire il cablaggio del motore stesso.
Altro parametro da controllare è la velocità della coppia di motori M1-M2, può essere che un motore abbia un rendimento leggermente inferiore, occorre perciò modificare il valore nella riga #define MAX_SPEED_OFFSET , che ha come riferimento il M2, nel mio caso il M1 aveva rendimento superiore, quindi il valore sarà ( 10 ) in caso opposto sara ( -10 ).
Per queste operazioni può essere utile il codice test motori:
// test motori
#include <AFMotor.h>
AF_DCMotor motor_dc_1(1, MOTOR12_64KHZ); AF_DCMotor motor_dc_2(2, MOTOR12_64KHZ);
void setup() { }
void loop() { motor_dc_1.setSpeed(150); motor_dc_1.run(FORWARD); motor_dc_2.setSpeed(150); motor_dc_2.run(FORWARD); delay( 2000 ); motor_dc_1.setSpeed(0); motor_dc_1.run(RELEASE); motor_dc_2.setSpeed(0); motor_dc_2.run(RELEASE); delay( 4000 ); }
Lo sketch del robot segui linea:
// Robot inseguitore di linea
#include <AFMotor.h>
#define MAX_SPEED 150 // imposta la velocità dei motori DC max #define MIN_SPEED 100 // imposta la velocità dei motori min #define MIN_SPEED_OFF 80 // imposta la velocità dei motori min in curva #define MAX_SPEED_OFFSET 10 // valore per compensare differenza velocità motore1-motore2
bool SensoreSinistra= false ; bool SensoreDestra= false ; bool SensoreCentroSX= false ; bool SensoreCentroDX= false ; boolean DigitalRead(int pinNumber) { pinMode(pinNumber, INPUT); return digitalRead(pinNumber); }
AF_DCMotor motor_dc_1(1, MOTOR12_64KHZ); AF_DCMotor motor_dc_2(2, MOTOR12_64KHZ);
void setup() { }
void loop() { SensoreSinistra = DigitalRead(A0) ; SensoreDestra = DigitalRead(A1) ; SensoreCentroSX = DigitalRead(A2) ; SensoreCentroDX = DigitalRead(A3) ;
if (((SensoreCentroSX == HIGH) && (SensoreCentroDX == HIGH)) && ((SensoreDestra == LOW) && (SensoreSinistra == LOW ))) { motor_dc_1.setSpeed(MAX_SPEED); motor_dc_1.run(FORWARD); motor_dc_2.setSpeed(MAX_SPEED+MAX_SPEED_OFFSET); motor_dc_2.run(FORWARD); } if (((SensoreCentroSX == HIGH) && (SensoreCentroDX == LOW)) && ((SensoreDestra == LOW) && (SensoreSinistra == LOW ))) { motor_dc_1.setSpeed(MIN_SPEED); motor_dc_1.run(FORWARD); motor_dc_2.setSpeed(MAX_SPEED+MAX_SPEED_OFFSET); motor_dc_2.run(FORWARD); }
if (((SensoreCentroDX == HIGH) && (SensoreCentroSX == LOW)) && ((SensoreDestra == LOW) && (SensoreSinistra == LOW ))) { motor_dc_1.setSpeed(MAX_SPEED); motor_dc_1.run(FORWARD); motor_dc_2.setSpeed(MIN_SPEED); motor_dc_2.run(FORWARD); }
if (((SensoreSinistra == HIGH) || (SensoreCentroSX == HIGH)) && ((SensoreDestra == LOW) && (SensoreCentroDX == LOW))) { motor_dc_1.setSpeed(MIN_SPEED_OFF); motor_dc_1.run(BACKWARD); motor_dc_2.setSpeed(MIN_SPEED); motor_dc_2.run(FORWARD); }
if (((SensoreDestra == HIGH) || ( SensoreCentroDX == HIGH)) && ((SensoreSinistra == LOW) && (SensoreCentroSX == LOW))) { motor_dc_1.setSpeed(MIN_SPEED_OFF); motor_dc_1.run(FORWARD); motor_dc_2.setSpeed(MIN_SPEED); motor_dc_2.run(BACKWARD); }
if (((SensoreCentroSX == HIGH) && (SensoreCentroDX == HIGH)) && ((SensoreSinistra == HIGH) && (SensoreDestra == HIGH))) { motor_dc_1.setSpeed(0); motor_dc_1.run(RELEASE); motor_dc_2.setSpeed(0); motor_dc_2.run(RELEASE); delay( 2000 ); motor_dc_1.setSpeed(MIN_SPEED); motor_dc_1.run(FORWARD); motor_dc_2.setSpeed(MIN_SPEED); motor_dc_2.run(BACKWARD); delay( 400 ); } }