Leggere stringa da seriale

Salve a tutti ragazzi volevo leggere una stringa da seriale ma mi sono bloccato:

void loop(){
  
  while (Serial.available() > 0)
  {
    char recieved = Serial.read();
    comando += recieved; 
      Serial.print(comando);
    if (recieved == '\n')
    {
      Serial.print("Arduino Received: ");
      Serial.print(comando);

       
      
      if(comando.equals("stop"))Stop();
      if(comando.equals("insinistra"))InSinistra();
      if(comando.equals("indestra"))InDestra();
      if(comando.equals("indietro"))Indietro();
      if(comando.equals("avanti"))Avanti();
      if(comando.equals("avsinistra"))AvSinistra();
      if(comando.equals("avdestra"))AvDestra();
      
      comando = "";
    }
     comando = "";
  }
}

Non riesco a farlo funzionare… se scrivo sulla seriale la parola avanti non succede nulla
Grazie

[quote author=roxdragon link=topic=268978.msg1896033#msg1896033 date=1411653995]
...
      
      comando = "";
    }
     comando = "";
  }
}

[/quote] Mi pare che azzeri comando sempre a ogni ricezione di un char, quel comando=""; dopo la graffa prova o toglierlo

Grazie per avermi risposto ma se provo a toglierlo ecco l'output:

aavavaavanavantavanti

Che succede se dal computer arrivano più "avanti"? O se qualcosa rallenta la trasmissione e il tuo programma prende quella pausa come un fine trasmissione?

Dovresti iniziare ad usare un carattere di inizio trasmissione ed uno di fine. E poi perché spedire la stringa intera? Manda un singolo byte che codifica il comando che vuoi eseguire, esempio 0 per avanti, 1 per destra, 2 per sinistra ecc... Mi sembra uno spreco nonché una complicazione mettersi a parsare comandi così lunghi.

Si hai ragione... ma se volessi inviare ad esempio 01? come faccio?

Devi capire come viaggiano i dati sulla seriale. "01" è una stringa composta dai caratteri "0" e "1". Attento: ho scritto "caratteri", non ho scritto numeri. Quindi tu spedisci il carattere "0" ed il carattere "1". 2 byte da inviare. In ricezione, raccogli quanto esce dalla seriale e lo valuti. Oppure potresti voler spedire il "valore" 0 ed il "valore" 1. In questo caso spediresti un byte di valore 0 ed un byte di valore 1. Non più come nel caso precedente i caratteri "0" (ASCII 48) e "1" (ASCII 49"). L'importante è che il trasmettitore ed il ricevitore parlino la stessa lingua. ;)

Generalmente si usa un carattere di inizio trasmissione ed uno di fine, per evitare confusione se casomai ci fossero problemi sul canale ma se hai l'Arduino attaccato al computer, puoi evitare.

Stabilisci quello che si chiama un "protocollo", ossia un "modo" per trasmettere dati. Ad esempio, un prototipo di protocollo potrebbe essere: 1° byte: comando 2° byte: dati aggiuntivi 3° byte: dati aggiuntivi extra

Mi spiego. Mettiamo che stai costruendo un robot ed hai dei motori da pilotare. Un motore sulla ruota destra, un motore sulla ruota sinistra. Tu stabilisci ad esempio che: 0 -> avanti entrambi i motori 1 -> indietro entrambi i motori 2 -> imposta la velocità 3 -> avanti solo il destro 4 -> avanti solo il sinistro ecc...

Come vedi, un caso che richiede parametri extra potrebbe essere il comando 2, che richiederebbe l'informazione aggiuntiva della velocità. Nel caso del comando 0, invece, non servirebbe nessuna info aggiuntiva. Però in questo caso tu devi comunque creare il pacchetto dati includendo sempre TUTTI tanti byte quanti ne richiede il protocollo che hai pensato. E impostare a 0 o a qualunque altro valore i byte non usati, che tanto verrebbero scartati in ricezione.

Quando ricevi, fai il parsing del 1° byte e da lì capisci quanti altri caratteri devi leggere. Tutto il resto viene scartato per la lunghezza del pacchetto. Nel nostro esempio 3 byte devono sempre partire e dopo 3 byte la ricezione capisce che il pacchetto è terminato.

Grazie sei stato molto chiaro…ma non ho ben capito come incorporare tutto a codice…
potresti farmi un esempio banalissimo con due righe senza scrivere tutto il codice?
Grazie ancora

Ho scritto un articolo, tempo fa: http://www.leonardomiliani.com/2013/arduino-invio-seriale-di-dati-da-e-per-il-computer/

Ti può dare spunto. Il codice va scritto in base all'esigenza ed a come vuoi implementare la cosa. In quell'esempio che ti ho linkato ho fatto un parsing classico, come avevi fatto tu, dove mando un numero in formato stringa (quindi ad esempio "150") ma osservando il resto del programma puoi benissimo convertirlo per accettare un byte con valore da 0 a 255.

roxdragon:
Grazie per avermi risposto ma se provo a toglierlo ecco l’output:

aavavaavanavantavanti

Solo per chiarezza. L’output è giusto.
Infatti vedi che comando piano piano “cresce”. Arduino riceve un carattere alla volta e questo carattere viene “accodato” dentro a comando, che quindi cresce. Il tuo fine messaggio è \n e quindi solo quando tutti i char sono arrivati compreso \n allora verifichi quale è il comando e poi lo azzeri.

Bravo, nid, non mi ero messo a scomporre la stringa. effettivamente... aavavaavanavantavanti

a av ava avan avant avanti

:P

Mi inserisco in questo post dato che tratta del mio stesso problema;
Volevo esporre una domanda. Per la ricezione è necessaria una sicronizzazione (temporizzazione)?
Mettiamo il caso che creo un protocollo ex: un carattere di inizio stringa , la mia stringa, e un carattere di fine
Quando arrivo al punto due cioè l’invio completo della stringa lo faccio direttamente senza inviare ogni singolo carattere. nella ricezione però arrivano singolarmente solo che ogni tanto salto qualche carattere…è normale? se inserisco nella lettura un piccolo delay(50) riesco a prendere puntualmente ogni singolo carattere pero naturalmente se faccio l’invio durante il delay saltro quel carattere.

Normalmente io strutturo il ricettore affinché, non appena si accorge della presenza di qualcosa sulla seriale, inizi il parsing dei dati.

Il primo controllo che faccio è: esiste qualcosa sulla seriale? Serial.available(). Se sì, controllo quanti caratteri sono. Questo perché per abitudine mi creo sempre un protocollo per l'invio dei dati, in questo modo escludo già a priori trasmissioni incomplete. Quindi, controllo sempre con Serial.available quanti caratteri ci sono. Se non sono quanti ho stabilito, vuol dire che per un problema nella trasmissione o qualcosa è andato perso o mi sono inserito a metà di un invio. In questo caso, svuoto il buffer di ricezione, ed esco. Se invece ho il quantitativo di caratteri giusti, inizio ad esaminarli dal primo, che può essere o meno il byte di inizio trasmissione (a seconda di come ho impostato il protocollo, ma generalmente lo uso). Se non è il byte di inizio trasmissioni, scarto tutti i dati ed esco. se è il byte, continuo prelevando i caratteri, che devono essere in numero stabilito, compreso il carattere terminatore. Se il carattere terminatore non c'è, scarto tutto. Se c'è, passo ad analizzare i dati. Per i casi più complessi, inserisco anche un CRC per il controllo di cosa ho spedito.