Robot con sens. Ultrasuoni e IR evita ostacoli

Ciao a tutti,
circa un anno fa, insieme all’aiuto prezioso del forum, ho realizzato un piccolo robot evita ostacoli utilizzando due sensori IR e due sensori Ultrasuoni. questo particolare robot lo vorrei usare per passare i pavimenti con i panni antistatici in giro per casa. Ho quindi sviluppato tutti componenti con l’aiuto di una stampante 3D eseguito tutti i collegamenti tra arduino nano sensori e driver per i motori passo passo.
Tutto funziona perfettamente tranne che per una zona ceca al quale vorrei risolvere utilizzando un semplice microswitch.

Volevo avere un suggerimento su come modificare lo sketch utilizzando il pin 12 (LAMA; al quale cambierò il nome) per il microswitch il quale richiamerà i comando di “retromarcia”.

Di seguito lo sketch:

#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 LAMA 12        //rele di controllo motore lama
#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;

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(LAMA, OUTPUT);
  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() {
  
  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) && (rilevamentoS == HIGH && times==0)) { //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)) {//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)) {//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)) {//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
  
}

Grazie mille a tutti

Ciao,
Ho modificato lo sketch aggiungendo il microswich di cui vi avevo parlato in precedenza…
Secondo voi può andare?
Volevo avere delle certezze prima di effettuare dei cambiamenti al robot.

#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  //rele di controllo motore lama
#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) && (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
  
}

Grazie Mille

Ciao! Non voglio entrare in merito al codice ma proporre una riflessione sul il problema, funzione del robot.

A mio avviso un robot evita ostacoli e un robot "aspirapolvere", dovrebbero funzionare con due algoritmi diversi.

Un robot evita ostacoli, mi muovo se trovo un ostacolo cambio direzione.

Un robot aspirapolvere, percorro tutta la superficie della stanza, se trovo un ostacolo mi sposto per poi tornare al percorso programmato.

Secondo me un robot evita ostacoli diviene del tutto casuale che riesca a coprire la superficie di una stanza.

Ciao,

Capisco che probabilmente l’idea di utilizzare tale robot per passare un panno elettrostatico in giro per una stanza evitando ostacoli non sia l’ideale, sia per il consumo non ottimale delle risorse della batteria che per l’efficienza del lavoro… ma siccome sono un vero neofita di Arduino e programmazione ho voluto creare un progetto, se pur inutile per qualcuno, che mi incentivi ad informarmi, sbagliare, rimediare ai miei errori, confrontandomi con gli altri per imparare sempre cose nuove divertendomi nel tempo libero.

Tornando al progetto ho effettuato i collegamenti del microswich al pin 12 con una resistenza di pull up di 10Kohm e successivamete ho caricato il programma su Arduino; le funzionalità standard precedenti alla modifica dello sketch funzionano perfettamente mentre per quanto riguarda il microswich, quando viene chiuso e invio i 5V al pin 12 di Arduino, i motori si fermano fino a che non riapro il circuito del medesimo.

Sicuramente ho sbagliato a compilare qualcosa sullo sketch.

Qualche suggerimento?

Grazie Mille a tutti.

#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) && (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
 
}

Ciao,
dopo aver capito il significato di “||” e “&&” ed il funzionamento di “if” e “else” sono riuscito nel mio intento.

#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) && (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)) {//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)) {//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)) {//se entrambi i sensori rilevano un ostacolo
      Serial.print("\nOstacoli laterali: Retromarcia!");
     
        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!

     }
     if(val == HIGH) { //Microswich frontale rileva ostacolo
      Serial.print("\nOstacolo frontale: Retromarcia!");
     
         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
 
}

Grazie a tutti.

//se entrambi i sensori rilevano un ostacolo
e
//Microswich frontale rileva ostacolo
fanno lo stesso retromarcia, cambia solo la frase

    if( ((rilevamentoS == LOW || times > 0) && (rilevamentoD == LOW || timed > 0)) || val==HIGH) 
    { //se entrambi i sensori rilevano un ostacolo OR Microswich frontale rileva ostacolo
      if(val == HIGH)  
        Serial.print("\nOstacolo frontale: Retromarcia!");
      else
        Serial.print("\nOstacoli laterali: Retromarcia!");
      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!
    }

P.S. Nell'IDE usa CTRL+T che indenta meglio il codice, lo rende più leggibile

Grazie,
molto interessante.

:slight_smile:

Un'altra piccola idea:
se dichiari 2 variabili byte, con valori 0/1 OSTACOLO/LIBERO, puoi assegnargli un valore usando if in linea

const byte OSTACOLO=1;
const byte LIBERO=0;
byte sensSX=LBERO;
byte sensDX=LIBERO;
...
  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 sinistr

  sensSX=(rilevamentoS == LOW || times > 0 ? OSTACOLO : LIBERO);   // if in linea del C
  sensDX=(rilevamentoD == LOW || timed > 0 ? OSTACOLO : LIBERO);   // if in linea del C
...
  if( (sensSX==OSTACOLO && sensDX==OSTACOLO) || val==HIGH)
  { //se entrambi i sensori rilevano un ostacolo OR Microswich frontale rileva ostacolo

e i vari test negli if diventano un pò più semplici/leggibili