controllo robot con arduino

ciao a tutti ho fatto un programma per comandare (tramite comandi da tastiera) un robot a 2 ruote (dicendogli direzione e velocità) tramite arduino e il chip L298P.
questo è il sorgente del programma

int E1 = 6;   //controllo potenza motore
int M1 = 7;  //controllo direzione motore
int E2 = 5;                         
int M2 = 4;                           
int value = 125;
int cmd;
int ciclo=0;

void setup() 
{
  Serial.begin(9600);
  pinMode(M1, OUTPUT);   
  pinMode(M2, OUTPUT); 
} 

void loop() 
{
  if(ciclo == 0) {  //mostra i comandi solo all'inizio e quando viene premuto Stop
    Serial.println(">> COMANDI ROBOT <<\n w - Avanti \n d - Destra \n a - Sinistra \n s - Indietro \n e - Ruota Destra \n q - Ruota Sinistra \n altro - Stop");
    Serial.println(" + - Aumenta Velocita'(+5)");
    Serial.println(" - - Diminuisci Velocita'(-5)");
    Serial.println("// Velocita' impostata //");
    Serial.println(value);
    ciclo++;  
  }
  
  if (Serial.available() > 0) {
    cmd = Serial.read();
    Serial.flush();
    
    switch(cmd) {
      
      case 'w': {  //Avanti
        digitalWrite(M1, LOW);    //imposta direzione rotazione motore
        digitalWrite(M2, LOW);
        analogWrite(E1, value);   //Controllo velocità PWM
        analogWrite(E2, value);   
        delay(100);
        Serial.println("\nAVANTI");
      } break;
      
      case 'd': {  //Destra
        digitalWrite(M1, LOW);
        analogWrite(E1, value);   
        analogWrite(E2, '0');
        delay(100);
        Serial.println("\nDESTRA");
      } break;
    
      case 'a': {  //Sinistra
        digitalWrite(M2, LOW);
        analogWrite(E2, value);   
        analogWrite(E1, '0');
        delay(100);
        Serial.println("\nSINISTRA");
      } break;
      
      case 's': {  //Indietro
        digitalWrite(M1, HIGH);
        digitalWrite(M2, HIGH);
        analogWrite(E2, value);   
        analogWrite(E1, value);
        delay(100);
        Serial.println("\nINDIETRO");
      } break;
      
      case 'q': {  //Ruota Sinistra
        digitalWrite(M1, HIGH);
        digitalWrite(M2, LOW);
        analogWrite(E1, value);   
        analogWrite(E2, value);
        delay(100);
        Serial.println("\nRUOTA SINISTRA");
      } break;
      
      case 'e': {  //Ruota Destra
        digitalWrite(M1, LOW);
        digitalWrite(M2, HIGH);
        analogWrite(E1, value);   
        analogWrite(E2, value);
        delay(100);
        Serial.println("\nRUOTA DESTRA");
      } break;
      
      case '+': {  //aumenta la velocità di 5
        if(value > 250) {
          Serial.println("\nERRORE: non e' più possibile aumentare la velocita'");         
          delay(100);
        }
        else {
          value = value + 5;
          Serial.println(value);
          delay(100);
        }
      } break;
      
      case '-': {  //aumenta la velocità di 5
        if(value <= 5) {
          Serial.println("\nERRORE: non e' più possibile diminuire la velocita'");
          delay(100);
        }
        else {
          value = value - 5;
          Serial.println(value);
          delay(30);
        }
      } break;
      
      default: {  //Stop
        analogWrite(E1, 0);   
        analogWrite(E2, 0);
        delay(100);
        Serial.println("\nSTOP\n");
        ciclo = 0;
      } break;
      
    } //fine switch
  } //fine if
   
} //fine loop

il programma funziona bene infatti riesco a comandare bene il robot usando gli appositi tasti, solo che ho 2 problemi che non riesco a capire perchè si verificano.

  • il primo problema è che a volte il robot si ferma da solo senza che io gli dia il comando per fermarsi (come se nello sfitch entrasse da solo nel default (che è il caso in cui il robot si deve fermare)), invecie altre volte è come se riniziasse da capo il sorgente, perchè mi reimposta la velocità dei motori che ho dato di default.
    esempio: premo '+' aumento la velocità del robot quindi da 125 iniziale arriva a 130, do il comando 'w' il robot va avanti, dopo un po si ferma, come risposta sul serial monitor mi da STOP (quindi è entrato nel caso "default") e mi da tutta la lista di comandi che posso dare al robot e la velocità impostata dei motori è rimasta a 130 quindi non è cambiata; ridò il comando 'w' dopo un po si riferma, mi ridà tutta la lista dei comandi possibili, ma la velocità impostata non è più 130 ma è tornata quella di default 125 (come se avesse letto nuonamente tutto il sorgente dall'inizio)
  • il secondo problema è che a volte non mi prende più nessun comando, ad esempio il robot sta andando dritto gli do il comando di fermarsi (o di girare a destra, o qualsiasi altro comando), ma il robot non risponde e continua ad andare dritto, unica soluzione per fermarlo è staccare il cavo USB in modo da togliergli l'alimentazione.

come mai si verificano questi problemi?? come posso risolvere??
spero di essere stato chiaro nell'esposizione dei problemi, in caso contrario chiedete pure maggiori info.
grazie in anticipo

EDIT: adesso provo a modificare il programma al posto di fermarlo con qualsiasi tasto gli dico che si deve fermare con 'h', perchè non vorrei che arrivassero al serial monitor dei comandi che non essendo di nessuno dei casi precedenti entrano nel default e quindi lo fanno fermare

ora il sorgente è questo l'ho modificato un po

int E1 = 6;   //controllo potenza motore
int M1 = 7;  //controllo direzione motore
int E2 = 5;                         
int M2 = 4;                           
int value = 125;
int cmd;
int ciclo=0;

void setup() 
{
  Serial.begin(9600);
  pinMode(M1, OUTPUT);   
  pinMode(M2, OUTPUT); 
} 

void loop() 
{
  if(ciclo == 0) {  //mostra i comandi solo all'inizio e quando viene premuto Stop
    Serial.println(">> COMANDI ROBOT <<\n w - Avanti \n d - Destra \n a - Sinistra \n s - Indietro \n e - Ruota Destra \n q - Ruota Sinistra \n altro - Stop");
    Serial.println(" + - Aumenta Velocita'(+5)");
    Serial.println(" - - Diminuisci Velocita'(-5)");
    Serial.println("// Velocita' impostata //");
    Serial.println(value);
    ciclo++;  
  }
  
  else {
    if (Serial.available() > 0) {
      cmd = Serial.read();
      Serial.flush();
    
      switch(cmd) {
      
        case 'w': {  //Avanti
          digitalWrite(M1, LOW);    //imposta direzione rotazione motore
          digitalWrite(M2, LOW);
          analogWrite(E1, value);   //Controllo velocità PWM
          analogWrite(E2, value);   
          delay(100);
          Serial.println("\nAVANTI");
        }  break;
      
        case 'd': {  //Destra
          digitalWrite(M1, LOW);
          analogWrite(E1, value);   
          analogWrite(E2, '0');
          delay(100);
          Serial.println("\nDESTRA");
        } break;
    
        case 'a': {  //Sinistra
          digitalWrite(M2, LOW);
          analogWrite(E2, value);   
          analogWrite(E1, '0');
          delay(100);
          Serial.println("\nSINISTRA");
        } break;
      
        case 's': {  //Indietro
          digitalWrite(M1, HIGH);
          digitalWrite(M2, HIGH);
          analogWrite(E2, value);   
          analogWrite(E1, value);
          delay(100);
          Serial.println("\nINDIETRO");
        } break;
      
        case 'q': {  //Ruota Sinistra
          digitalWrite(M1, HIGH);
          digitalWrite(M2, LOW);
          analogWrite(E1, value);   
          analogWrite(E2, value);
          delay(100);
          Serial.println("\nRUOTA SINISTRA");
        } break;
      
        case 'e': {  //Ruota Destra
          digitalWrite(M1, LOW);
          digitalWrite(M2, HIGH);
          analogWrite(E1, value);   
          analogWrite(E2, value);
          delay(100);
          Serial.println("\nRUOTA DESTRA");
        } break;
      
        case '+': {  //aumenta la velocità di 5
          if(value > 250) {
            Serial.println("\nERRORE: non e' più possibile aumentare la velocita'");         
            delay(100);
          }
          else {
            value = value + 5;
            Serial.println(value);
            delay(100);
          }
        } break;
      
        case '-': {  //aumenta la velocità di 5
          if(value <= 5) {
            Serial.println("\nERRORE: non e' più possibile diminuire la velocita'");
            delay(100);
          }
          else {
            value = value - 5;
            Serial.println(value);
            delay(100);
          }
        } break;
      
        case 'h': {  //Stop
          analogWrite(E1, 0);   
          analogWrite(E2, 0);
          delay(100);
          Serial.println("\nSTOP\n");
          ciclo = 0;
        } break;
      
      }  //fine switch
    }  //fine if
  }  //fine else
   
}  //fine loop

con queste modifiche mi sembra di aver risolto il problema che a volte si fermava da solo, però dopo qualche minuto di utilizzo del robot, ha smesso nuovamente di seguire i comandi, non sono sicuro al 100% ma mi sembra che il problema che a volte smette di seguire i comandi si verifica dopo che gli modifico la velocità dei motori
potete aiutarmi??

Puoi prendere uno spunto da qui:

e

:wink:

ho modificato nuovamente il sorgente del robottino e adesso sembra non darmi più nemmeno il problema che smette di rispondere ai comandi dati da pc.
secondo me il problema era che a volte si incasinava nel caso in cui si aumentava e diminuiva la velocità; quindi al posto di aumentare/diminuire la velocità dei motori del 5% alla volta ho dato 4 velocità preimpostate (35%, 50%, 75%, 100%).
ecco il nuovo sorgente

int E1 = 6;   //controllo potenza motore
int M1 = 7;  //controllo direzione motore
int E2 = 5;                         
int M2 = 4;                           
int value = 128;  //velocità motori
int cmd;  //comando inserito
int ciclo=0;  //ciclo

void setup() 
{
  Serial.begin(9600);
  pinMode(M1, OUTPUT);   
  pinMode(M2, OUTPUT); 
} 

void loop() 
{
  if(ciclo == 0) {  //mostra i comandi solo all'inizio e quando viene premuto Stop
    Serial.println(">> COMANDI ROBOT <<\n w - Avanti \n d - Destra \n a - Sinistra \n s - Indietro \n e - Ruota Destra \n q - Ruota Sinistra \n 0 - Stop");
    Serial.println(" 1 - Velocita' 35/100");
    Serial.println(" 2 - Velocita' 50/100");
    Serial.println(" 3 - Velocita' 75/100");
    Serial.println(" 4 - Velocita' 100/100");
    Serial.println("// Velocita' impostata //");
    Serial.println(value);
    ciclo++;  
  }
  
  else {
    if (Serial.available() > 0) {
      cmd = Serial.read();
      Serial.flush();
    
      switch(cmd) {
      
        case 'w': {  //Avanti
          digitalWrite(M1, LOW);    //imposta direzione rotazione motore
          digitalWrite(M2, LOW);
          analogWrite(E1, value);   //Controllo velocità PWM
          analogWrite(E2, value);   
          delay(100);
          Serial.println("\nAVANTI");
        }  break;
      
        case 'd': {  //Destra
          digitalWrite(M1, LOW);
          analogWrite(E1, value);   
          analogWrite(E2, '0');
          delay(100);
          Serial.println("\nDESTRA");
        } break;
    
        case 'a': {  //Sinistra
          digitalWrite(M2, LOW);
          analogWrite(E2, value);   
          analogWrite(E1, '0');
          delay(100);
          Serial.println("\nSINISTRA");
        } break;
      
        case 's': {  //Indietro
          digitalWrite(M1, HIGH);
          digitalWrite(M2, HIGH);
          analogWrite(E2, value);   
          analogWrite(E1, value);
          delay(100);
          Serial.println("\nINDIETRO");
        } break;
      
        case 'q': {  //Ruota Sinistra
          digitalWrite(M1, HIGH);
          digitalWrite(M2, LOW);
          analogWrite(E1, value);   
          analogWrite(E2, value);
          delay(100);
          Serial.println("\nRUOTA SINISTRA");
        } break;
      
        case 'e': {  //Ruota Destra
          digitalWrite(M1, LOW);
          digitalWrite(M2, HIGH);
          analogWrite(E1, value);   
          analogWrite(E2, value);
          delay(100);
          Serial.println("\nRUOTA DESTRA");
        } break;
      
        case '1': {  //velocità 1 = 35%
          value = 89;
          Serial.println(value);
        } break;
      
        case '2': {  //velocità 2 = 50%
          value = 128;
          Serial.println(value);
        } break;
        
        case '3': {  //velocità 2 = 75%
          value = 192;
          Serial.println(value);
        } break;
        
        case '4': {  //velocità 2 = 100%
          value = 255;
          Serial.println(value);
        } break;
      
        case '0': {  //Stop
          analogWrite(E1, 0);   
          analogWrite(E2, 0);
          delay(100);
          Serial.println("\nSTOP\n");
          ciclo = 0;
        } break;
      
      }  //fine switch
    }  //fine if
  }  //fine else
   
}  //fine loop

ora che il controllo manuale del robot sembra funzionare passo a farlo muovere automaticamente facendogli seguire una riga nera su sfondo bianco, usando 2 fotoresistenze per fargli vedere la differenza del colore.
in questo modo dovrei riuscire a fargli seguire un percorso disegnato con una riga nera