Arduino Forum

International => Italiano => Software => Topic started by: dinopaolo on Apr 07, 2019, 10:50 pm

Title: AtMega2560 e il buffer in ingresso da seriale
Post by: dinopaolo on Apr 07, 2019, 10:50 pm
Al momento non ho capito perchè stringhe in ingresso diverse e consecutive vengono catturate fino all'asterisco, mentre stringhe uguali consecutive catturano la stringa completa oltre l'asterisco.
Questo indipendentemente dalla lunghezza della stringa.
Dino


Queste le stringhe in ingresso:
$$GPRMC,023405.00,A,1827.23072,N,06958.07877,W,1.631,33.83,230613,,,A*42 (con CRC verificato)
$GPRMC,123456789A123456789B*XX    (CRC a caso)

Questa l'uscita:
SeriaìSerial communication initialized
il buffer: $GPRMC,023405.00,A,1827.23072,N,06958.07877,W,1.631,33.83,230613,,,A*42

 il CRC in HEX: 42
il buffer: $GPRMC,023405.00,A,1827.23072,N,06958.07877,W,1.631,33.83,230613,,,A*
 il CRC in HEX: 42
il buffer: $GPRMC,023405.00,A,1827.23072,N,06958.07877,W,1.631,33.83,230613,,,A*42

 il CRC in HEX: 42
il buffer: $GPRMC,023405.00,A,1827.23072,N,06958.07877,W,1.631,33.83,230613,,,A*42

 il CRC in HEX: 42
il buffer: $GPRMC,123456789A123456789B*
 il CRC in HEX: 64
il buffer: $GPRMC,123456789A123456789B*XX

 il CRC in HEX: 64
il buffer: $GPRMC,123456789A123456789B*XX

 il CRC in HEX: 64
il buffer: $GPRMC,123456789A123456789B*XX

 il CRC in HEX: 64
=========================================


Code: [Select]

// Sample sentences to XOR
//$GPRMC,135847.198,A,4424.5162,N,00816.1586,E,0.00,0.00,020307,,*0A
//$GPRMC,023405.00,A,1827.23072,N,06958.07877,W,1.631,33.83,230613,,,A*42
//$GPRMC,123456789A123456789B*XX


const byte buff_size = 80; // buffer size must be a constant variable
char buffer[buff_size];
byte index = 0;   // declare all variables that will hold numbers less than '255' as 'byte' data type, because they require only '1-byte' of memory ('int' uses 2-bytes).
byte start_with = 0;
byte end_with = 0;
byte CRC = 0;
boolean data_end = false; // Here we will keep track of EOT (End Of Transmission).

void setup(){
  Serial3.begin(38400);
  Serial.begin(9600);
  Serial.println("Serial communication initialized"); // Print to serial port so we know its working.
  delay (2000);
}

void loop(){

  while (Serial3.available() > 0){
    char inchar = Serial3.read();
    buffer[index]  = inchar;
    if( inchar == '$'){
      start_with = index;
    }
    if (inchar == '*')  {
      end_with = index;
    }
    index++;

    if((inchar == '\n') || (inchar == '\r') || (index >= buff_size-1)){ // if 'new line' or 'carriage return' is received then EOT.
      index = 0;
      data_end = true;
    }
  }

  if (data_end == true){
    for (byte x = start_with+1; x<end_with; x++){ // XOR every character in between '$' and '*'
      CRC = CRC ^ buffer[x] ;
    }
  }

  if(CRC > 0){
    Serial.print("il buffer: ");
    Serial.println(buffer);
    Serial.print(" il CRC in HEX: ");
    Serial.println(CRC,HEX); // print calculated CS in HEX format.
    CRC = 0;                 // reset CRC variable
    data_end = false;        // Reset EOF so we can process more incoming data.
   
 //   Serial.print(" il CRC dopo: ");
 //  Serial.println(CRC,HEX);
   
    memset(buffer,'\0',buff_size-1);      // empty array
//    memset(buffer,0,sizeof(buffer));
    start_with, end_with =0;            // reset
  }
}
Title: Re: AtMega2560 e il buffer in ingresso da seriale
Post by: uwefed on Apr 07, 2019, 11:49 pm
non controlli ancora il limite del indice per non andare oltre il limite.
Ciao Uwe
Title: Re: AtMega2560 e il buffer in ingresso da seriale
Post by: dinopaolo on Apr 08, 2019, 08:03 am
Uwe, è scritto qui (ma non ho verificato se agisce in modo corretto)

Code: [Select]
if((inchar == '\n') || (inchar == '\r') || (index >= buff_size-1)){ // if 'new line' or 'carriage return' is received then EOT.
      index = 0;
      data_end = true;
    }
Title: Re: AtMega2560 e il buffer in ingresso da seriale
Post by: uwefed on Apr 08, 2019, 09:26 am
Scusami, non lo avevo visto.

Code: [Select]
while (Serial3.available() > 0){
    char inchar = Serial3.read();
    buffer[index]  = inchar;
    if( inchar == '$'){
      start_with = index;
    }
    if (inchar == '*')  {
      end_with = index;
    }
    index++;

    if((inchar == '\n') || (inchar == '\r') || (index >= buff_size-1)){ // if 'new line' or 'carriage return' is received then EOT.
      index = 0;
      data_end = true;
    }
  }

Non credo che funzioni.
Cosí quando arriva un NL o CR o il buffer é pieno non vai alla decodifica della stringa ma sovrascrivi il buffer finché ci sono dati che arrivano dalla seriale.
D' altra parte se il modulo non Ti da abbastanza velocemente dati sulla seriale e il buffer della seriale si svuolta  ( Serial3.available() diventa zero) decodifichi una stringa parziale che poi in seguto cancelli. Forse sarebbe meglio ripensare alla funzionalitá / logica di questa parte di sketch.
Ciao Uwe
Title: Re: AtMega2560 e il buffer in ingresso da seriale
Post by: dinopaolo on Apr 08, 2019, 11:12 am
Scusate, non lasciatevi distrarre dal problema del superamento dello spazio allocato nell'array, che, considerando che la lunghezza massima del messaggio NMEA è di 82 caratteri e la sua frequenza 1 secondo, posso risolvere aumentando le demensioni dell'array, ma giustamente da verificare eventuali (improbabili) problemi di buffer della seriale.

Ho usato uno sketch raccolto in rete, e vedo che dovrà essere ripensato, ad esempio: prima scaricare il messaggio, e poi estrarre i dati e/o verificare il CRC, ma....

Cortesemente mi sapete spiegare quanto evidenziato nel post iniziale?
Dino
Title: Re: AtMega2560 e il buffer in ingresso da seriale
Post by: fabpolli on Apr 08, 2019, 11:56 am
Rivedere è da rivedere, nel frattempo se vuoi toglierti il dubbio a cui fai riferimento nel tuo post iniziale metti messaggi di debug in ogni if (quando setti l'inizio, la fine della stringa da analizzare, quando esci dal while di Serial3.available, quando entri nell'if per calcolare il CRC, ecc.) in mod da tracciare ciò che avviene e tentare di capire il flusso.