Puntata II: Creazione sketch per la macchinina.
Salve a tutti prima di tutto vorrei fare una premessa di seguito troverete solo le parti principali dello sketch di Arduino. Per avere il codice intero cliccate qui .
Benvenuti alla seconda puntata del tutorial per costruire una macchinina che si autopiloti, ma che può anche essere pilotata da manuale tramite applicazione Android. In questa puntata andremo a vedere come creare lo sketch ovvero il programma che verrà eseguita dalla nostra scheda Arduino.
Partiamo subito col dire che il programma è suddiviso in funzioni, le funzioni principali sono:
- setup(): La funzione setup è una funzione base di arduino che viene eseguita una volta solo all’ accensione della scheda, qui di solito viene inizializzato il programma, definendo modalità dei pin, creazione di comunicazioni seriali ecc..
- loop(): La funzione loop è la seconda funzione base di arduino. A differenza della prima questa viene eseguita in modo infinito ovvero una volta che arriva al suo termine essa riparte la sue esecuzione dall’inizio
- automatico(): Questa funzione ha il compito di gestire la vettura in modo che non abbia collisioni con ostacoli cambiando rotta prima che vi si schianti.
- manuale(): Questa funzione serve per pilotare i motori, ovvero serve per pilotare i 2 motori che andranno a muovere la nostra macchinina. Questa funzione entra in gioco soltanto quando andremo a pilotare la vettura tramite applicazione android
- sch04(): Funzione che ci restituisce la distanza dell’ ostacolo in cm (centimetri);
setup()
Come precedentemente detto qui andremo a inizializzare i pin di arduino e la comunicazione seriale.
void setup() {
pinMode(key,OUTPUT);//key per il bluetooth serve per configuralo
pinMode(btLed,OUTPUT);//notifica la ricezione di qualcosa
digitalWrite(key,HIGH);//attiva key ma serve solo in fase iniziale
//inizializzazione porta seriale definendo il baud
Serial.begin(38400);
Serial.println("Type AT commands!");
// SoftwareSerial "com port"
mySerial.begin(38400);
}loop()
Come detto prima il loop è una funzione che viene ripetuta ogni volta che viene completata. Qui c’è la gestione delle priorità tra manuale e automatico (dando la precedenza al comando in manuale) e la letture dallo stream del bluetooth.
la funzione commandToInt() è una funzione scritta da me che ci trasforma il comando in carattere in un numero intero, invece la funzione StrToInt() è una funzione che trasforma una stringa con un valore numerico in numero intero. Queste funzioni le troverete nel link a inizio pagina insieme al resto del codice dell’ intero progetto
void loop(){
// legge se il bluetooth è avviabile
if (mySerial.available())
{
digitalWrite(btLed,HIGH); // accende led rosso
while(mySerial.available()){
//leggo i valori ricevuti dal bluetooth
command += (char)mySerial.read();
}
Icommand=commandToInt(command);//converte comando in int
Serial.println(Icommand);
Serial.println(command);
switch (Icommand){
case 1:
partenza = true;//flag per la partenza
break;
case 2:
partenza = false;//flag per lo stop
break;
case -1:
if (partenza){
//converte la stringa in intero
Idirection=StrToInt(command);
manuale(Idirection);
}
else{stopAuto();}//ferma la macchinina
break;
}
command = ""; // svuoto la variabile
}
else{
//nessun segnale da bluetooth
digitalWrite(btLed,LOW); //spengo il led
if (partenza)
automatico();
else
stopAuto();
}
/* manda l' input scritto dall' utente al bluetooth per comando
* AT i comandi AT servono per configurare il bluetooth*/
if (Serial.available()){
delay(10); // The DELAY!
mySerial.write(Serial.read());
}
//delay di sincronizzazione con l' app
delay(100);
}//chiuso loopAutomatico()
Nella funzione Automatico vengono gestite le collisioni. Il suo funzionamento è semplice, esso fa partire la macchinina in avanti e fa una misura dell’ ostacolo tramite la funzione sch04() che ritorna la distanza in centimetri. Poi fa un piccolo controllo se l’oggetto si trova a una distanza inferiore di 20 cm esso si ferma e fa marcia indietro per 0,3 secondi poi esegue una misurazione sia a destra che a sinistra e con un altro controllo verifica dove ha più spazio per far manovra e cambiare direzione.
void automatico (){
Serial.println("AUTOMATICO");
long front,left,right;
//richiamo la funzione del sensore, ritorna la distanza in cm
front = sch04(TRIG1,ECHO1);
delay(100);
motor1.setSpeed(205); //imposto velocità
motor2.setSpeed(235); //imposto velocità
motor1.run(FORWARD); //parametro->direzione
motor2.run(FORWARD);
if(front<20){
while(stato){
motor1.run(BACKWARD);
motor2.run(BACKWARD);
delay(300);
left=sch04(TRIG2,ECHO2);
delay(100);
right=sch04(TRIG3,ECHO3);
delay(100);
if(left>right){
//giro a destra e continuo la marcia
motor1.run(BACKWARD);
motor2.run(FORWARD);
delay(500);
stato=false;
}
else{
if(left<right){
//giro a sinistra e continuo la marcia
motor1.run(FORWARD);
motor2.run(BACKWARD);
delay(500);
stato=false;
}
else{stato=true;}
}
}
}
stato=true;
}// chiuso automaticomanuale (int direct)
Questa funzione consiste tutto in uno switch. infatti tramite android noi manderemo alla nostra scheda Arduino un valore tra uno e otto (1-8), questi valori corrispondono rispettivamente a una direzione che può intraprendere la nostra macchina. Come si nota dal codice non viene usato nessun sensore per controllare la distanza con l’ ostacolo, infatti quando si è manuale la macchina diventa completamente “cieca”. “FRONT” e tutte le altre direzioni sono delle costanti intere. Il parametro che inseriamo in questa funzione è il valore della direzzione letto con il bluetooth.
void manuale(int direct){
Serial.println("MANUALE");
switch (direct){
case FRONT: //3
motor1.setSpeed(205);
motor2.setSpeed(240);
motor1.run(FORWARD);
motor2.run(FORWARD);
break;
case LEFT_FRONT: //2
motor1.setSpeed(120);
motor2.setSpeed(235);
motor1.run(FORWARD);
motor2.run(FORWARD);
break;
case LEFT: //1
motor1.setSpeed(175);
motor2.setSpeed(195);
motor1.run(BACKWARD);
motor2.run(FORWARD);
break;
case BOTTOM_LEFT: //8
motor1.setSpeed(120);
motor2.setSpeed(235);
motor1.run(BACKWARD);
motor2.run(BACKWARD);
break;
case BOTTOM: //7
motor1.setSpeed(205);
motor2.setSpeed(235);
motor1.run(BACKWARD);
motor2.run(BACKWARD);
break;
case RIGHT_BOTTOM: //6
motor1.setSpeed(235);
motor2.setSpeed(135);
motor1.run(BACKWARD);
motor2.run(BACKWARD);
break;
case RIGHT: //5
motor1.setSpeed(175);
motor2.setSpeed(195);
motor1.run(FORWARD);
motor2.run(BACKWARD);
break;
case FRONT_RIGHT: //4
motor1.setSpeed(235);
motor2.setSpeed(135);
motor1.run(FORWARD);
motor2.run(FORWARD);
break;
default://il bluetoothj ha avito qualche problema e ha ricevuto un valore non corretto
Serial.println("errore di codice");
break;
}
}//chiuso manualesch04 (int trigPin, int echoPin)
Come valore in ingresso gli andremo a metterci il pin del trig e dell’ echo del sensore che vorremo utilizzare. Questa funzione invia un segale alto per 10 microsecondi poi attiva il pin echo in input e con la funzione pulseIn misura la durata dell’ impulso restituendoci quanto tempo chi ha messo il segnale ad arrivare fino all’ ostacolo e tornare indietro. La funzione microsecondsToCentimeters trasforma il tempo impiegato dal segnale in una distanza espressa in centimetri.
long microsecondsToCentimeters(long microseconds){
//la velocità del suono è 340 m/s o 29 millisecondi per centimetro.
// nel calcolo viene diviso per 2 perché il la distanza rilevata è pari allo spazioe dell' andata e del ritorno del suono
return microseconds / 29 / 2;
}
//fnzione per trovare la distanza
long sch04(int trigPin, int echoPin ){
long duration, cm;
//emissione del suono
pinMode(trigPin, OUTPUT);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//ricezione del suono
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
//conversione del tempo in spazio
cm = microsecondsToCentimeters(duration);
//feedback su monitor seriale
switch (trigPin){
case TRIG2:
Serial.print("left");
break;
case TRIG1:
Serial.print("front");
break;
case TRIG3:
Serial.print("right");
break;
}
Serial.print(cm);
Serial.print("cm");
Serial.println();
//ritorno il valore
return cm;
}Qui si conclude la seconda puntata di questo progetto, vi invito a commentare se vi serve aiuto o non vi è chiaro qualche passaggio. A breve uscirà la terza puntata, dove andremo a parlare del Software lato Android dove andremo a pilotare la nostra vettura progettata con arduino in modalità manuale. Inoltre vi invito, se vi siete persi il primo tutorial, a riprenderlo: Puntata I: Costruzione hardware con Arduino.


Lascia un commento
Devi essere connesso per inviare un commento.