Programma Robot Line Follower

Questo è il primo topic che apro quindi scusatemi se ho sbagliato sezione :grin:
Ho visto che nel forum ci sono altri topic riguardanti i robot line follower, ma nessuno di questi rispondeva alle mie domande.

Per la tesina di maturità volevo portare un robot line follower comandato da Arduino Uno rev3.
I componenti che ho usato sono:

  • Pololu QTR-8A (uso solo 5 sensori: 2,3,4,5,6)
  • 2 motori cc (3-6V)
  • ponte H L293DNE (quello nel kit di Arduino)
  • Arduino Uno ovviamente :smiley:

Sotto è allegato lo schema elettrico fatto con fritzing e con fidocad.

Io non ne so mezza di programmazione, ma comunque ho tentato di fare un programmino che segua la logica di funzionamento del robot...
Praticamente se il robot tende ad andare a sinistra della linea nera il motore che comanda la ruota destra dovrebbe rallentare. Stessa cosa accade a destra, ma stavolta è il motore di sinistra che rallenta. Più sensori escono dalla linea nera più il motore rallenta, fino a fermarsi.

Nel programma ho usato la funzione while... è la più appropriata? O è meglio usare if...else?
Altra cosa molto importante, non ho capito molto come utilizzare analogWrite. Sul sito spiega come usarlo con un potenziometro o una fotocellula, ma non con una serie di sensori... E io non l'ho capito :frowning:

Mancheranno sicuramente parti importanti, quindi riempitemi di consigli!

Grazie in anticipo per tutte le risposte! :slight_smile:

Schema elettrico fritzing OK.JPG|x

Schema robot line follower (V e GND corr.jpg

Robot_Line_Follower_clean.ino (2.94 KB)

So che non bisogna fare il cosidetto "bump", ma una risposta mi sarebbe molto utile...
Grazie a chi ci proverà :smiley:

Hm, intanto certamente non userei i while ma le if() (o meglio if().. else if() ...). Poi non mi è ben chiaro, vista la prima condizione ("(sx2 > 510) && (dx2 > 510)") la linea da seguire è larga almeno come l'intera strip Pololu?

La soluzione a mio avviso migliore sarebbe quella di calcolare, dati i valori letti dai sensori, un valore che rappresenti l'indicazione di quanto è spostata la linea, calcolato dando un "peso" ad ogni sensore.

Una cosa di questo tipo (non ho provato il codice, sto per andare a letto ma volevo darti una mano;-)):

...
int sx2 = analogRead(sx2Pin);
int sx = analogRead(sxPin);
int c = analogRead(cPin);
int dx = analogRead(dxPin);
int dx2 = analogRead(dx2Pin);

long posLeft = (long)sx2 * 10 + (long)sx * 2 + (long)c/2;
long posRight = (long)c/2 + (long)dx *2 + (long)dx2 *10;

Le variabili posLeft e posRight indicano quanto la linea è "esterna" rispetto ai lati sinistro e destro
Poi ti fai qualche test mandando su console seriale i valori "pos" che ricavi con le varie posizioni della linea rispetto al centro del sensore del robot, e con questi modifichi eventualmente i valori dei pesi (qui ho usato 2 per quelli vicini al centro e 10 per quelli estremi) quindi li usi per comandare i motori, dopo averli normalizzati in base ai valori massimi, ossia una cosa del tipo:

posLeft = map(posLeft, 0, 12800, 0, 255);
posRight = map(posRight, 0, 12800, 0, 255);
int motLeft = 255 - posRight;
int motRight = 255 - posLeft;
analogWrite(enable1Pin, motLeft);
analogWrite(enable2Pin, motRight);

PS: noterai che non ho messo alcune "if" né "while", e che la velocità del motore di sinistra è determinato dalla posizione della linea dal lato destro e viceversa, ossia quando la riga è più a destra che a sinistra sarà il motore sinistro ad accelerare e quello destro a rallentare, e viceversa.
E per fare un robot che "scappa" dalla linea invece di inseguirla, ti basta invertire questi due fattori...

Beh vado a letto, tu prova e fammi sapere. Ciao!