Il sito per chi ama smanettare con Arduino, Raspberry Pi & Co.
Condividi:
Notifiche
Cancella tutti

Robot evita ostacoli con sens. Ultrasuoni e Infrarosso non vede pulsante paraurti anteriore

   RSS

0

Ciao a tutti,

Per cominciare mi presento dicendo di essere un vero neofita di Arduino, non tanto per quanto riguarda la parte elettronica ma bensì per quella riguardante la programmazione. Per me usare Arduino è un passa tempo divertente dove posso mettermi alla prova creando progetti e confrontarmi con gli altri per imparare sempre cose nuove.

Tempo fa, partendo da un progetto visto su internet, ho creato un robot evita ostacoli utilizzando due sensori Infrarosso e due sensori Ultrasuoni. Due motori passo passo muovono il robot in accordo con le informazioni dei sensori evitando gli ostacoli. Tutto funziona perfettamente se no fosse per un unico punto cieco sulla parte frontale; per i muri laterali ed ostacoli voluminosi non ci sono problemi, ma, per esempio, la gamba di una sedia dritta sul muso del robot si.

Per ovviare a tale problema ho pensato ad un semplice paraurti al quale ho montato un piccolo microswitch il quale dovrebbe attivare la parte dello sketch riguardante la retromarcia invece, quando il microswitch chide il circuito e invia i 5V al pin 12 di Arduino (ovviamente collegato con un pull up) i motori si fermano.

Sicuramente ho sbagliato qualcosa nello sketch ma non riesco a capire dove.

Grazie mille.

#define DIRD 2 //direzione motore destra
#define STEPD 3 //pin di step motore destra
#define IRD 4 //sensore IR a destra
#define ECHOD 5 //echo sensore destro
#define TRIGERD 6 //triger sensore destro
#define DIRS 7 //direzione motore sinistra
#define STEPS 8 //pin di step motore sinistra
#define IRS 9 //sensore IR sinistra
#define ECHOS 10 //echo sensore sinistro
#define TRIGERS 11 //triger sensore sinistro
#define SWFRONTALE 12 //microswitch paraurti frontale
#define PASSI 80 //durata del movimento generale 8 * 100 (ritorno) = 800 passi per 1/2 giro ritorno = 200 per un giro completo
#define RETRO 8000 //durata della retromarcia
#define ROTAZIONE 4000 //durata della rotazione

long timed=0;//misura sensore destro
long times=0;//misura sensore sinistro

int rilevamentoD = HIGH;
int rilevamentoS = HIGH;

int ritorno = 200; //durata della rotazione senza controllare nuovamente (variabile perche nel programma il robot potra adattarlo in base alle condizioni)
int velo=10; //velocita movimento da 1 a 100 ritardo step successivi
int i;
int val = 0;

void setup()
{
Serial.begin(9600); //inizio della trasmissione seriale (serve soprattutto a noi per capire a che punto del programma si trova)
Serial.print("Mi sono acceso correttamente.");
delay(500);

pinMode(DIRD, OUTPUT);
pinMode(STEPD, OUTPUT);
pinMode(IRD, INPUT);
pinMode(DIRS, OUTPUT);
pinMode(STEPS, OUTPUT);
pinMode(IRS, INPUT);
pinMode(SWFRONTALE, INPUT);
pinMode(TRIGERD, OUTPUT);
pinMode(TRIGERS, OUTPUT);
pinMode(ECHOD, INPUT);
pinMode(ECHOS, INPUT);

digitalWrite(TRIGERD,LOW); //inizializzo basso destro
digitalWrite(TRIGERS,LOW); //inizializzo basso sinistro

}

void loop() {
val = digitalRead(SWFRONTALE);

ultraRead_D(); //la funzione imposta la variabile timed
ultraRead_S(); //la funzione imposta la variabile times

rilevamentoD = digitalRead(IRD); //rileva la condizione del sensore destro
rilevamentoS = digitalRead(IRS); //rileva la condizione del sensore sinistro

if((rilevamentoD == HIGH && timed==0 && val == LOW) && (rilevamentoS == HIGH && times==0 && val == LOW)) { //se sentrambi non rilevano ostacoli
Serial.print("\nVia libera!");

step(true, false, PASSI,velo); //ATTENZIONE: i motori sono opposti sullo stesso asse quindi le rotazioni in senso discorde manderanno avanti o indietro il robot!

}
else {
if((rilevamentoD == LOW || timed > 0 ) && (rilevamentoS == HIGH && times==0) && (val == LOW)) {//se il sensore destro rileva un ostacolo
Serial.print("\nOstacolo a destra!");

step(false, false, PASSI,velo); //ATTENZIONE: i motori sono opposti sullo stesso asse quindi le rotazioni in senso concorde faranno ruotare il robot!

}
if((rilevamentoS == LOW || times > 0 ) && (rilevamentoD == HIGH && timed==0) && (val == LOW)) {//se il sensore sinistro rileva un ostacolo
Serial.print("\nOstacolo a sinistra!");

step(true, true, PASSI,velo); //ATTENZIONE: i motori sono opposti sullo stesso asse quindi le rotazioni in senso concorde faranno ruotare il robot!

}
if((rilevamentoS == LOW || times > 0) && (rilevamentoD == LOW || timed > 0) && (val == HIGH)) {//se entrambi i sensori rilevano un ostacolo
Serial.print("\nRetromarcia!");

step(false, true, RETRO,velo); //ATTENZIONE: i motori sono opposti sullo stesso asse quindi faranno indietreggiare il robot!
step(false, false, ROTAZIONE,velo); //ATTENZIONE: i motori sono opposti sullo stesso asse quindi le rotazioni in senso concorde faranno ruotare il robot!

}
}
}

void step(boolean dirAttualeD, boolean dirAttualeS, int steps,int velo) {//velo 1 ... 100
digitalWrite(DIRD, dirAttualeD); //invia al driver destro la direzione attuale
digitalWrite(DIRS, dirAttualeS); //invia al driver sinistro la direzione attuale
for(int i=0; i<steps; i++) {//ATTENZIONE: durante il ciclo non controlla i sensori!
digitalWrite(STEPD, HIGH);
digitalWrite(STEPS, HIGH);
delayMicroseconds(3200/velo);//doppio ritardo fra step min 32uS puo' essere abbassato fino a 8uS
digitalWrite(STEPD, LOW);
digitalWrite(STEPS, LOW);
delayMicroseconds(3200/velo);//doppio ritardo fra step min 32uS puo' essere abbassato fino a 8uS
}
}

void ultraRead_S() {

digitalWrite(TRIGERS,HIGH);//impulso di triger al sensore
delayMicroseconds(10);//temporizzo a 10uS
digitalWrite(TRIGERS,LOW);

/*misuro impulso uscita con timeout a 2000 limito la massima distanza a 25cm circa
*e riduco il tempo di misurazione altrimenti il timeout della pulsin sarebbe 1S
*in questo modo otterò misure fina a 25cm oppure 0 se la distanza è > 25cm per
*tanto sarà molto semplice testare il sensore con if distanza > 0 ostacolo da evitare*/

times=pulseInLong(ECHOS,HIGH,2000);
//misura l' impulso alto su echo se > 1mS restituisce 0 e torna dopo 1mS

}


void ultraRead_D() {

digitalWrite(TRIGERD,HIGH);//impulso di triger al sensore
delayMicroseconds(10);//temporizzo a 10uS
digitalWrite(TRIGERD,LOW);

/*misuro impulso uscita con timeout a 2000 limito la massima distanza a 25cm circa
*e riduco il tempo di misurazione altrimenti il timeout della pulsin sarebbe 1S
*in questo modo otterò misure fina a 25cm oppure 0 se la distanza è > 25cm per
*tanto sarà molto semplice testare il sensore con if distanza > 0 ostacolo da evitare*/

timed=pulseInLong(ECHOD,HIGH,2000);
//misura l' impulso alto su echo se > 1mS restituisce 0 e torna dopo 1mS

}


Condividi:

Entra nel forum

Hai un nuovo progetto in mente ma hai dei dubbi su come realizzarlo? Vuoi condividere la tua conoscenza da maker con gli altri? Registrati nella nostra community e potrai chiedere fare la tua domanda o rispondere e condividere la tua conoscenza in internet.