Seriale che perde caratteri...

Ciao a tutti, devo ricavare una stringa dalla seriale e questa mi perde puntualmente dei caratteri.
Il codice è questo.

...
  int i, serAva;
  if (Serial.available()>0){
    delay(5);
    serAva = Serial.available();
    for (i=0; i<serAva; i++){   
      delay(6);
      tmp += (char)Serial.read();
    }
  }
  if (tmp!=""){
    inviare = true;
    Serial.println("Finito il buffer");
  }
  if (inviare){
    Serial.print("Inviato");
    Serial.println(msg);
//// blablabla parte che invia i dati
}

Sulla seriale ricevo:

*scrivendo ciaoooo*
Finito il buffer
Inviatociaoo

Finito il buffer
Inviatooo

Spezza il messaggio in due! E senza il delay perde il primo carattere! Mentre se ci metto un Serial.print() per fare il debug nel for funziona tutto >.<
Mi prende per i fondelli?

Grazie a tutti!

Ciao Guglio,
ma la variabile msg come e dove è inizializzata?

che spezza il messaggio è normale, in realtà viene spezzato in caratteri, e non c'è modo che in automagico ricomponga il tutto da solo :grin: devi farti il codice da te.

i caratteri scomparsi potrebbero esse a causa di quei delay, poi senza vedere il resto del codice...

if (Serial.available()>0){
    delay(5);
    serAva = Serial.available();
    for (i=0; i<serAva; i++){   
      delay(6);
      tmp += (char)Serial.read();
    }
  }

fallo

    serAva = Serial.available();
    for (i=0; i<serAva; i++){   
      tmp += (char)Serial.read();
    }

molto meglio, no?

Il codice intero è questo... (è c'è anche la variabile msg che avevo tagliato prima)
I delay gli ho messi perchè pensavo/speravo servissero a far "arrivare" i byte :disappointed_relieved:

#include <VirtualWire.h>

void setup()
{
  Serial.begin(9600);	  // Debugging only
  Serial.println("setup");
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);	 // Bits per sec
}
String conferma;
boolean da_confermare = false;
boolean inviare = false;
String tmp = "";
void loop()
{
  int i, serAva;
  if (Serial.available()>0){
    serAva = Serial.available();  // Read number of input bytes
    for (i=0; i<serAva; i++){   
      tmp += (char)Serial.read();
    }
  }
  if (tmp!=""){
    inviare = true;
    Serial.println("Finito il buffer");
  }

  if (inviare){
    Serial.print("Inviato");
    char msg[30];
    tmp.toCharArray(msg, sizeof(msg));
    Serial.println(msg);
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx();
    inviare = false;
    //Calcolo stringa conferma:
    conferma = tmp.substring(1,2);
    conferma += tmp.substring(0,1);
    conferma += "k";
    Serial.print("Conferma aspettata: ");
    Serial.println(conferma);
    tmp = "";
  }


  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen))//Non-blocking
  {	
    int i;
    Serial.println("Conferma in arrivo:");
    for (i = 0; i < buflen; i++)
    {
      Serial.print(buf[i]);
    }
    Serial.println();
  }
}

E' il codice del nodo collegato al pc, spedisce la stringa ricevuta via RF agli arduini sparsi per la casa e controlla la stringa di conferma (manca ancora il controllo con reinvio)

Buttando dentro la stringa 10u1654 (A nodo 1, da nodo 0, azione Update orario, valore 16:54) nel serial leggo questo:

setup
Finito il buffer
Inviato1
Conferma aspettata: 1k
Finito il buffer
Inviato0u1654
Conferma aspettata: u0k

Cioè ha spedito via l' 1 da solo e poi tutto il resto!! Non ha senso!

Buahahahah, penso d'aver trovato il problema! Ho portato i baud a balla (115200) e il problema è sparito, quindi pare che i delay fossero effettivamente necessari, cioè l'arduino esegue il ciclo e non è ancora arrivato il carattere successivo quindi pensa sia finita la trasmissione... possibile?

Guarda il mio Topic qualche post sotto al tuo. Se non ho capito male è perchè dalla versione 1.0 dell'IDE la trasmissione è diventata Asincrona, in pratica non aspetta che sia finita prima di passare all'istruzione successiva.

Probabilmente se provi ad eseguire lo stesso sketch con una versione dell'IDE come la 023 il problema si risolve. A me è andata così!

Cioè ha spedito via l' 1 da solo e poi tutto il resto!! Non ha senso!

certo che ha senso! la seriale spedisce un caratte per volta, quindi a seconda di quanto velocemente leggi puoi trovarti solo uno o mille caratteri. mettere un delay e aspettrsi di leggere la stringa intera non è una soluzione valida perchè potrebbe esserci un errore di trasmissione, o un disturbo o potresti leggere dei dati parzialmente, oppure potrebbe riempirsi il buffer della seriale.

per il "problema" detto da legolas, si può risolvere mettendo una Serial.flush(), che in pratica blocca il codice finchè la trasmissione non è effettuata completamente.

cioè l'arduino esegue il ciclo e non è ancora arrivato il carattere successivo quindi pensa sia finita la trasmissione... possibile?

assolutamente no, come detto la seriale lavora carattere per carattere, quindi ogni carattere è una nuova trasmissione. se vuoi puoi crearti del codice per fare in modo tale da creare un protocollo che supporti trasmissione di più caratteri alla volta (un sistema "a pacchetti")