problema mega 2560 e Serial.print

ciao a tutti, ho un problema con il mio codice per effetuare una serial.print con arduino mega 2560 il programma non da errori di compilazione ma dopo alcuni secondi si blocca come se il buffer della seriale fosse pieno. aprendo il serial monitor noto che prima di bloccarsi i dati iniziano a rallentare e ad arrivare a “scatti”.
utilizzo IDE 1.0.5 su win 7. ho provato a cambiare 4 PC e 6 arduino ma il problema persiste, presumo quindi che non sia un problema hardware. sicuramente ho dimenticato di specificare qualcosa, vi chiedo perdono e vi ringrazio in anticipo.

il codice è questo e dovrebbe essere usato per controllare un robot cingolato tramite “telecomando” (arduino):

int occupaspazio[100];
int velocita1=0;//velocita motore1
int velocita2=0; //velocita motore2
int Slide; //potenziometro lineare per velocità
int Joistick1;//Joistick1
int Joistick2;//Joistick2
int VJ1=520;//vecchia lettura Joistick1
int VJ2=505;//vecchia lettura Joistick2
char direzione1='w';//direzione motore1
char direzione2='y';//direzione motore2

void setup() {
  Serial.begin(19200);
}

void loop() {  
  
  Joistick1= analogRead(A2);
  Joistick2= analogRead(A3);
  Slide= analogRead (A1);//0-1023
  Slide=map(Slide,0,1023,0,255);
  
  if (Joistick1!=VJ1){
    VJ1=Joistick1; //se la lettura cambia valore

  if (Joistick1==520){ //motore 1 fermo
    velocita1=0;
    direzione1='w';  
  }

  else if (Joistick1>520){ //motore 1 avanti
    velocita1 = map(Joistick1, 505, 1023, 0, Slide);
    direzione1='w';    
  }

  else if (Joistick1<520){//motore 1 indietro
    velocita1 = map(Joistick1, 505, 0, 0, Slide);
    direzione1='x';
  }
  //stampa
    Serial.print(direzione1);
    Serial.print('v');
    Serial.print(velocita1);
    Serial.print('#');
}

  
  if (Joistick2!=VJ2){
    VJ2=Joistick2;
    
  if (Joistick2==505){ //motore 1 fermo
    velocita2=0;
    direzione2='y';  
  }

  else if (Joistick1>520){ //motore 1 avanti
    velocita2 = map(Joistick1, 505, 1023, 0, Slide);
    direzione2='y';    
  }

  else if (Joistick1<520){//motore 1 indietro
    velocita2 = map(Joistick1, 505, 0, 0, Slide);
    direzione2='z';
  }
  
    Serial.print(direzione2);
    Serial.print('V');
    Serial.print(velocita2);
    Serial.print('#');
  }

}

facendo dei test ho notato che aggiungento una analogRead ad un loop che esegue solo Serial.print il programma dopo alcuni secondi di esecuzione rallenta notevolmente il tempo di scrittura sul serial monitor ed iniza a lavorare con tempi di latenza abbastanza alti. Questo mi porta a pensare che la serie di analogRead presenti nel mio programma entrano in "conflitto" con le Serial.print. Come posso risolvere?
grazie mille.

perchè non vai a capo ogni tanto e scrivi sulla stessa riga?
a parte che è difficile leggere i debug così, ma poi saturi la linea e si inchioda.

perchè in realtà questo è il codice che deve far comunicare i due arduino, per leggerli si riesce con un po di fatica, sono solo 4 caratteri: direzione(avanti o indietro), motore (uno o due), velocità (da 0 a 255) e # per la chiusura.

ahhh non è un debug che vuoi fare, è una trasmissione seriale, però così saturi il buffer e poi si inchioda tutto
in questo caso devi usare un SerialWrite per trasmettere e potresti usare uno char di "\n" per terminare l'istruzione invece di #

prova così

Serial.print(direzione2);
    Serial.print('V');
    Serial.print(velocita2);
    Serial.print('\n');

dall'altra parte avrai

char c = serial.read();
if  c == '\n' .........................

ho provato anche con la serial.write che manda un byte alla volta, l'unica differenza è che ci mette un po di piu a bloccarsi, circa il doppio del tempo ma poi inevitabilmente si blocca. non so piu dove poter cercare il problema...

ho modificato il post sopra rileggilo :smiley:

Hai provato come test di aumentare il baudrate? oppure di aggiungere un delay per spedire meno dati?

Ciao Uwe

ho provato con baud rate di 9600, 19200 e 57600 ma il risultato è lo stesso (con 57600 si blocca prima, mentre con 9600 impiega un paio di secondi in più). ho provato a inserire delay nel setup e a inizio loop ma il risultato è lo stesso. ho provato anche con la procedura d'emergenza ma non sembra essere colpa di arduino.

@pablos: ho provato come mi hai consigliato con

Serial.write(direzione2);
    Serial.write('V');
    Serial.print(velocita2);
    Serial.write('\n');

ma non da risultati...
il problema è nato da un giorno all'altro senza cambiare una virgola nel programma, quindi non saprei neanche dove cercare...

Potresti dirmi in che stato sono i LED "RX" e "TX" della scheda, quando si blocca la trasmissione?

il problema è nato da un giorno all'altro senza cambiare una virgola nel programma, quindi non saprei neanche dove cercare...

prima di risponderti ho caricato il tuo shetch sulla mia Mega e sulla DUE (ero curioso di capire cosa dicevi) :slight_smile:
in effetti va a rallentare fino a inchiodarsi anche a me in entrambe le shede. Però mettendo lo '\n' non succede più.
Se tu usavi il simbo '#' per far intendere all'arduino slave che la stringa di ricezione è terminata puoi cambiarlo con un "a capo", non dimenticare che nella comunicazione serial va usato anche il flush.

pablos:
in effetti va a rallentare fino a inchiodarsi anche a me in entrambe le shede. Però mettendo lo '\n' non succede più.

Non sono a casa per delle prove, ma da quel che dici è la tua prima diagnosi, ossia che è il monitor seriale che collassa perché crea in memoria una stringa lunghissima per contenere tutto quel che gli arriva su una singola riga. Sarebbe da vedere se usando un altro terminale il problema si presenta lo stesso oppure no.

ok vado per ordine:
@leo72: il led TX è costantemente acceso (prima di bloccarsi lampeggia molto velocemente a causa dei 19200 baud e quando si blocca resta fisso), per il problema dei terminali non credo poichè ho testato il programma anche tra due arduino senza il terminale e il problema rimane, inoltre ho testato il programma su 4 terminali diversi (tra cui due pc da gaming “spinto”) e il problema persiste.

@pablos: ho ricontrollato il programma che avevo modificato dopo il tuo consiglio e mi sono accorto che avevo solo sotituito il serial.print con il serial.write, ora provo a fare dei test con \n, secondo te quindi è quello il problema? e la serial.flush avevo provato a metterla a fine loop ma in quel caso inviava solo valori di 0, ovvero inviava tutto correttamente ma con velocità 0 (es. wv0#).

grazie mille a tutti per le risposte!!

ho appena provato con lo \n e ora sembra non bloccarsi piu (l’ho lasciato andare per un paio di minuti e non si è bloccato), sorge però un altro problema: sembra che la seriale non riesca ad inviare con la stessa velocità di lettura dei potenziometri (joistick), da monitor seriale prima che cambino i valori ed escano quelli corrispondenti all’attuale stato del joistick passano circa 15/20 secondi, questo gap è abbastanza alto considerando che il programma verrà usato per controllare un rover e che dovrà essere “appesantito” con la parte relativa ai sensori.

borgo:
ok vado per ordine:
@leo72: il led TX è costantemente acceso (prima di bloccarsi lampeggia molto velocemente a causa dei 19200 baud e quando si blocca resta fisso), per il problema dei terminali non credo poichè ho testato il programma anche tra due arduino senza il terminale e il problema rimane, inoltre ho testato il programma su 4 terminali diversi (tra cui due pc da gaming "spinto") e il problema persiste.

Se il led TX si blocca acceso significa che si satura il buffer seriale del chippino 16U2 usato come convertitore USB/seriale. Troppi dati spediti senza che riescano ad uscire verso il computer.
Il fatto di non spezzare la riga causa pian piano un rallentamento in ricezione da parte del terminale che poi fa andare in blocco il chip convertitore.