Problemi con Serial e Stringheeee !!!

Stavo provando a ricevere un messaggio via serial, "appenderlo" a una stringa e ritornare la stringa via serial; solo che non funziona.
Il codice che ho scritto è questo e di fianco a ogni comando di reinvio al pc ho scritto il risultato che esce sulla console.

void setup() {
  Serial.begin(9600);
}
String stringOne = "";
void loop() {
   if (Serial.available()>0){
   int a=Serial.read();  //riceve input es. 2
   Serial.write(a);   //ritorna input -->2
   Serial.println();  //a capo
   Serial.println(a);   //ritorna input -->50
   stringOne += String(a);    //Stringa = stringa + input
   //Serial.write(stringOne);  //se si toglie commento da errore
   Serial.println(stringOne);  //ritorna stringa vuota+input --> 50
   stringOne = String(13);     //Stringa diventa 13
   Serial.println(stringOne); //ritorna stringa --> 13
   }
}

Quello che ho notato è che se uso il write il testo ritorna tale e quale mentre se uso il print/println il testo mi viene restituito come codificato in ASCII (es. 1-->49) tuttavia se uso
Serial.print(1) quello che mi esce a video è 1 e non 49.
Allo stesso modo se dichiaro una variabile già con un valore mi verrà restituito giusto mentre se la "aggiorno tramite il Serial.read()" poi me lo restituirà in ASCII
es.

int a=13
Serial.println(a) // restituisce 13
int b=Serial.read()
Serial.println(b) // restituisce--> valore immesso in ASCII

A me sembrano uguali... :frowning: :frowning:

Avete qualche consiglio? che le pagine di referenza per read() print() ecc. non mi sono state troppo di aiuto :disappointed_relieved:
Francesco

Il metodo print, se non specifichi la codifica, stampa in formato ACII

Quindi 49 al posto di 1 perché 49 è il codice ASCII del carattere "1".

Invece write stampa il valore binario e dipende da cosa gli hai dato in pasto:

Quindi se converti in stringa poi stampi una stringa, quindi "1" resta "1"

ho sperimentato molto e sono riuscito a capire abbastanza bene dove era l'errore, che penso di poter ricondurre a come leggevo il read(), infatti mi sembra di aver capito che usando int a=Serial.read se inviavo ad es. 1 a diventava uguale a 49 e quindi l'errore era già li, mentre io pensavo che a sarebbe stata uguale a 1 e che poi l'errore fosse nel print()

grazie comunque per la risposta

ora che ho capito come vengono letti i dati ho un altro problema sempre legato alle stringhe anche se in questo casi il colpevole è un ciclo while:

void setup() {
  Serial.begin(9600);
}
String stringOne = "";
void loop() {
  if (Serial.available()){
    while (Serial.available()>0){
      char a=Serial.read(); 
      stringOne += String(a);   
      Serial.println(stringOne);  
    }
      Serial.println("Finito!!!");
      stringOne = "";
  }
}

Secondo la mia logica questo codice dovrebbe:

  • controllare se ci sono byte disponibili da leggere
  • se si, finchè ce ne sono eseguire il codice all'interno di while
  • una volta letti tutti i byte il ciclo while dovrebbe fermarsi e io mi ritroverei con una stringa composta dai vari byte
  • Uscito dal ciclo while stampare "Finito!!!" e riazzerare la stringa per una prossima lettura
  • Riprendere a looppare finche non vi siano di nuovo dei byte da leggere

Nella mia idea il ciclo while dovrebbe interrompere il loop() fino a sua conclusione.

Invece come risultato (avendo inviato "ciao") ottengo:

c
Finito!!!
i
Finito!!!
a
Finito!!!
o
Finito!!!

quindi ripete ogni volta tutto il loop fregandosene di ripetere prima il while.

Cosa sbaglio??? :cold_sweat: :cold_sweat: :cold_sweat:

aggiungendo println(Serial.available()) che da quello che ho letto nelle referenze dovrebbe restituire il numero di bytes disponibili da leggere mi esce(con lo stesso input di prima) sempre 1 invece di 4...3...2...1...interruzione.

è possibile che l'errore con il ciclo while sia causato da questo problema? come posso risolverlo?
Francesco

ho risolto da solo :grin: :grin: mettendo un delay di 10 ms, forse basta anche meno, da quello che ho capito una volta che il while finiva e ricontrollava il numero di byte disponibili il byte successivo non era ancora arrivato e quindi il while pensava di aver finito.
è giusta come idea o sbaglio? 8)

Prova aumentando la velocità dell porta seriale. Forse a 9600 baud il buffer di ricezione si riesce a svuotare tra un byte e l'altro.

leo72:
Forse a 9600 baud il buffer di ricezione si riesce a svuotare tra un byte e l'altro.

In che senso fa in tempo a svuotarsi? :cold_sweat: :cold_sweat:

Esiste un buffer di ricezione, è un array in cui vengono memorizzati i caratteri man mano che arrivano dalla seriale.
Serial.available() restituisce i caratteri presenti e Serial.read() estrae il primo disponibile.
Mettiamo che stiano arrivando 2 caratteri, se tu ne prelevi uno e leggi subito dopo lo stato del buffer prima che arrivi il 2°, sicuramente il buffer lo troverai vuoto ed il ciclo uscirà. Aumentando la velocità di spedizione, forse riesci a far arrivare entrambi i caratteri prima che venga letta la disponibilità dopo il prelevamento del 1°.

Sono test che devi condurre. Prova a mettere 57600 (sia su trasmettitore che su Arduino) e guarda un po'.