Sincronizzazione seriale c++ vs arduino

Salve a tutti

sto cercando di inviare dei dati via seriale, da un programma c++ ad un arduino. In un programma dove inviava la stringa di dati (per semplicità "SAAAQ") ogni volta che premevo invio, l'arduino riceveva perfettamente senza disturbi... facendomi stampare ogni volta la stringa che riceveva,ottenevo:

SA
SAA
SAAA
SAAAQ

e fin qui perfetto.

Il problema è invece in un programma che elabora 30 volte a secondo dei dati ed una volta pronti richiama la funzione di invio che è settata a 19200 di baudrate, dall'altra parte l'arduino anche lui settato a 19200 di baudrate controlla ogni 50 ms che ci sia il dato (if SerialAvailable ...). Inviando continuamente SAAAQ
l'arduino riceve :

SA
SAA
SAAA
SAAAQ
SAAAQ
SA
SAA
SAAA
SAAAQ
SAAAQ
SA
SAA
SAAA
SAAAQ
SAAAQ
SA
SAA
SAAA
SAASQ
SAASS
SAASSS
SAASSSS
SAASSSSS
SAASSSSSQ
SS
SSS
SSSS
SSSSA
SSSSAS
SSSSASS
SSSSASSS
SSSSASSSQ
SSSSASSSSSSSS
SSSSASSSSSSSSS
SSSSASSSSSSSSSS
SSSSASSSSSSSSSSS

periodicamente ... se provo con un serial.flush dopo la lettura da seriale impazzisce e legge strani caratteri...

Sapreste consigliarmi i vari settaggi da configurare al fine di una corretta trasmissione seriale
Ringrazio anticipatamente.

baudrate 19200 vuol dire che ogni secondo spedisce ca 2000Byte. Uno ogni mezzo ms.
30 volte 5 caratteri che sono 150 carattei al secondo non dovrebbe essere un problema.
Se fai un controllo ogni 50 ms se ci sono nuovi dati vuol dire che ...
non so dire niente di sicuro se non vedo il codice.
Ci spedisci il codice lato arduino?
Ciao Uwe

Grazie per la risposta!

il codice parte c++(che riguarda la trasmissione seriale):

void Serialout(int v)    
{       
	int fd; // File descriptor for the port 
	fd = open(PORT, O_RDWR | O_NOCTTY | O_NDELAY);
  	if (fd == -1)
	{
		perror("open_port: Unable to open /dev/ttyUSB0 - ");
	}
 	else
	{
	  std::ostringstream oss;
 	  int a,b,c;
	  v=111; // Per semplicità inviamo 111 che codificato tramite la funzione assegna corrisponde a "AAA"

         // inizio assegnazione numeri a lettere //

	  if (v<=50 && v>=0)
		v=50;
	 else if (v>255)
		v=255;
	 else if (v<-255)
		v=255;
	  a= v/100;
	  if (a!=0)
		b=(v%100);
	  b= b/10;
	  if (b!=0)
		c =(v%10);

               // fine assegnazione numeri lettere ////
               // Tre casi d'invio la struttura rimane sempre la stessa //
	  if(a==0 && b==0)
	      {
                printf( "  %c  Q\n",assegna(v));
		oss <<"S"<< assegna(v)<< "Q";
		fcntl(fd, F_SETFL, 0);
		int n = write(fd,oss.str().c_str(),3); // funzione d'invio
                if (n < 0)
		fputs("write() of 9 bytes failed!\n", stderr);
               }
	      if(a==0 && b!=0)
	      {
            	printf( "  %c %c Q\n",assegna(b),assegna(c));
		oss <<"S"<<assegna(b) <<assegna(c)<< "Q";
		fcntl(fd, F_SETFL, 0);
		int n = write(fd,oss.str().c_str(),4);   // funzione d'invio
                if (n < 0)
		fputs("write() of 9 bytes failed!\n", stderr);
               }
	        if(a!=0 && b!=0)
	       {
                printf( " %c %c %c Q\n", assegna(a),assegna(b),assegna(c));
		oss <<"S"<< assegna(a)<<assegna(b) <<assegna(c)<< "Q";
		fcntl(fd, F_SETFL, 0);                
		int n = write(fd,oss.str().c_str(),5);
                if (n < 0)
		fputs("write() of 9 bytes failed!\n", stderr);
                }
	          // sleep(0.010);
	 }
	struct termios options;   	// Get the current options for the port...
 	tcgetattr(fd, &options);    	// Set the baud rates to 19200...
 	cfsetispeed(&options, BAUDRATE);
 	cfsetospeed(&options, BAUDRATE);    	// Enable the receiver and set local mode...   
 	options.c_cflag |= (CLOCAL | CREAD);  	// Set the new options for the port...
 	tcsetattr(fd, TCSANOW, &options);
 	close(fd); 
}

Questo codice invia una serie di lettere precedute dal carattere S e terminati dal carattere Q se invio Serialout(111) lui invia SAAAQ

Il codice parte arduino:

//DEFINIZIONE PIN ARDUINO
[...]
// VARIABILI LETTURA SERIALE
char s[25]={"Z0Z0q\0"};
char ct;
int i=0,j,k,z=0,v;
int inizio,segno;
[...]
//VARIIABILI PER INTERVALLI DI TEMPO
long previousMillis = 0, previousMillis6=50;
#define interval 50          //INTERVALLO CALCOLO VELOCITA'
#define interval6 45         //INTERVALLO LETTURA STRINGA prima 50
[...]
//SETUP INZIALE PORTE ARDUINO
void setup() {
  // Definizioni porte e BaudRate
  Serial.begin(19200);
}

int converti(char z)  // converte lettere in numeri
{
 int x;
 if (z=='A')
 x=1;
 if (z=='B')
 x=2; 
 if (z=='C')
 x=3;
 if (z=='D')
 x=4;
 if (z=='E') 
 x=5;
 if (z=='F')
 x=6;
 if (z=='G') 
 x=7;
 if (z=='H')
 x=8;
 if (z=='I')
 x=9;
 if (z=='J')
 x=0;
 return x;
}
// CICLO LOOP
void loop()
{
   //LETTURA STRINGA    
  if (millis() - previousMillis6 > interval6)  // interval 6 è settato a 50 ms anche previousmillis6 a 50 ms
  {     
    previousMillis6 = millis();
  
    if (Serial.available() > 0) 
    {   
      // salva quel che è arrivato nella variabile char s
      ct=char(Serial.read()); 
      if (((ct-'0'>=0) && (ct-'0')<=9) || (ct-'A'>=0) && (s[j]-'A')<=26)
      {
        s[i] = ct;
        i++;
      }
      for (z=0;z<=i;z++)
      Serial.print(s[z]);
      Serial.print("\n");
      
     if (s[i-1]=='Q')  // se la stringa ricevuta è terminata da Q 
      {      
      
      if (s[0]=='S')   //se la strinfa è preceduta da S
       { 
        velrichiesta1=0;
        velrichiesta2=0;
        for (v=1;(s[v]-'A'>=0) && (s[v]-'A')<=11  ;v++)
          {
            // Questa è la porzione di codice che si occupa della decodifica//////
            velrichiesta1=velrichiesta1*10 + (converti(s[v]));
          }
         velrichiesta2=velrichiesta1;       
         velrichiesta1=-velrichiesta1;
         //Serial.print(velrichiesta1);
       }
       i=0;
      }// Q
   } 
}

Ok capito l'inghippo.
Tu controlli se é disponibile un byte sulla seriale.
Leggi un byte e controlli se i caratteri trasmessi sono ta 0 e 9 e tra A e qualcosa che non so perché hai scritto "(s[j]-'A')<=26"
" if (((ct-'0'>=0) && (ct-'0')<=9) || (ct-'A'>=0) && (s[j]-'A')<=26) "
Se é un carattere ammesso lo aggiungi alla stringa e stampi tutta la stringa fin quel momento aquisita.
Poi fai un controllo se alla prima posizione é un S e all' ultima appena aquisita un Q e se sí fai un ulteriore elaborazione (che per l'analisi non é pertinente) e metti l'indice della stringa alla posizione Zero.

Il numero di caratteri trasmessi é sempre costante?
Il carattere di inizio e fine stringa sono sempre quelli?

Ciao Uwe

l'ultima condizione (ct-'A'>=0) && (s[j]-'A')<=26) 6 serve per dire che è compresa tra [A Z] (ascii)

il numero di caratteri non è costante può variare da 3 a 5.
I caratteri d'inizio e fine sono sempre S e Q per la nostra applicazione (in realtà ho tagliato altre porzioni di codice dove eseguivano altre analisi in base alla prima lettera della stringa che riceveva ma per il programma in questione invio solo comandi del tipo SQ o SQ o SQ ).

gepp:
l'ultima condizione (ct-'A'>=0) && (s[j]-'A')<=26) 6 serve per dire che è compresa tra [A Z] (ascii)

Ho capito che volevi scrivere quello, ma hai veramente scritto quello??

È giusto

(s[j]-'A')<=26)

non dovrebbe essere

(ct-'A'<=26)

Variabile "ct"??

Ciao Uwe

j'ai compris... in effetti ora che ci penso perché non ho scritto s[j]-'A' invece di ct-'A'?
Domani effettuo la sostituzione che al momento non ce l'ho sotto mano, ma non credo che sia dovuto a questo il problem, cioè possibile che questa disattenzione comprometta l'intera ricezione...? ok la smetto con le domande retoriche ahah XD

Non sapendo che valore ha j e per questo non sapendo che valore é s[j] non so risponderti.
Puoi potenzialmente leggere qualsiasi numero e percui potrebbe essere "l' errore".
Ciao Uwe

ho modificato la condizione
e per un invio continuo della stringa SAAAQ ottengo:

SA
SAA
SAAA
SAAAQ
SAAAQA
SA
SAA
SAAA
SAAAQ
SAAAQA
SA
SAA
SAAA
SAAAQ
SAAAQA
SA
SAA
SAPA
SAPPQ
SAPPQ
SAPPSA
SAPPSAA
SAPPSAAQ
SAPPSAAA
SAPPSAAAQ
SA
SAP
SAAP
SAAAS
SAAAQA
SA
SA
SAA
SAAA
SAAQQ
SA
SAA
SAAQ
SAAAQ
SAAAQA
SA
SAA
SASA
SASSQ
SASSSA
SASSSSA
SASSSSSA
SASSSSSAQ
SASSSSSAS
SASSSSSASS©
SASSSSSASSS
SASSSSSASSyR2Rs

in genere come viene fatto il protocollo di trasmissione seriale tra un arduino ed un computer? vengono introdotti dei ritardi ?

In teoria l'UART (la comunicazione seriale) è implementata in hardware quindi non dovrebbe richiederebbe nessuna sincronizzazione da parte software.

ok risolto era un problem di sincronizzazione se da programma c++ i dati venivano inviati ogni secondo invece di 50 ms, la ricezione -> perfetta!
Ora la frequenza d'invio è di 3send/sec e funziona! XD
vi ringrazio per le risposte!