La Comunicazione Seriale

 

 

Documentazione:

Areduino Reference
 
 

 

Arduino è munito di una porta seriale, mediante USB, Che permette di comunicare con altri dispositii esterni ed in particolare con il PC. Si possono ricevere ed inviare dati da Pc e verso Pc. Oppure, più semplicemente, si può usare il Monitor seriale, un interfaccia tipo terminale compresa nell'IDE di Arduino.

In questa sede riporteremo alcuni esempi di comunicazione seriale per comprenderne il funzionamento.

Un primo esempio riguarda l'invio di una stringa ad Arduino e il suo reinvio tramite Monitor seriale:

 

 

Nella casella di testo in alto, si possono scrivere dei dati che con il tasto invia vengono spediti ad Arduino. Nello spazio sottostante abbiamo la visualizzazione dei dati in arrivo da Arduino. Importante notare i pulsanti in basso a destra. Con il primo possiamo scegliere se i dati che inviamo debbano essere seguiti da un CR(carriage return), NL(new line), entrambi NL+CR o nulla (nessun fine riga). Questi sono caratteri non stampabili che indicano la fine della riga di dati. Io preferisco inserire un solo ritorno carrello CR (carattere Ascii 13) per indicare la fine della riga. In questo esempio abbiamo inviato una stringa "hx23456" un primo carattere 'h' seguito da un'altro carattere che potrà essere o 'm' o 'x' poi dei numeri. Il codice è in attesa dell'invio della sequenza di caratteri (stringa), qundo ciò avviene legge il primo carattere se è un 'h' procede a leggere il carattere successivo e lo conserva nella variabile sec. Poi prosegue a leggere i successivi caratteri che va via via accumulando nella stringa str. Quando incontra un carattere CR (Ascii 13) termina la lettura. Se il secondo carattere era un 'm' allora invierà sulla com il messaggio Minimo: 23456 se invece sec era un 'x' rimanderà indietro il messaggio Massimo:: 23456.

 

  byte cmd,sec,tch; 
  String str;
  
  void setup(){   
     Serial.begin(115200);
     cmd=0;
  } 
  
  void loop(){
       str="";
    if (Serial.available()>0) cmd = Serial.read();//leggi il primo       
    switch (cmd) {      
      case 'h':
      if (Serial.available()>0)  sec = Serial.read();//leggi il secondo
            
      while(true){//Cicla--------------
       if (Serial.available()>0)  tch = Serial.read(); 
        if(tch!=13){//se diverso da ritorno carrello
           str+=char(tch);//accumula nella stringa                                                       
         }else{//se invece è un ritorno carrello
          if(sec=='m'){//se il secondo carattere era una 'm'
            Serial.print("Minimo "); Serial.println(str);  
          }else if(sec=='x'){//se il secondo carattere era una 'x'
            Serial.print("Massimo "); Serial.println(str); 
          }
          break;
         }        
      }//End while -------------------
           
        break;         
     }//fine switch 
     cmd=0;
     delay(10);//non togliere
  } 

 

  • Attivare la comunicazione mediante l'istruzione:  Serial.begin(115200); l'argomento indica il baudrate, (numero di dati al secondo) normalmente è 9600 ma io lo imposto a 115200 baud/sec. Questo valore corrisponde a bps ossia bit per secondo.
  • Si entra nel loop, si verifica se ci sono dati in arrivo mediante  if (Serial.available()>0)
  • se ce ne sono si procede con la lettura del primo byte disponibile cmd = Serial.read();
  • mediante uno switch si controlla il primo carattere se questo corrisponde a un 'h' allora si procede alla lettura del secondo byte
  • mediante il ciclo while si estraggono uno alla volta gli altri byte  che vengono accumulati entro la stringa str. Notare la conversione di byte in char, necessaria per inserire i dati nella stringa
  • quando si incontra il byte con valore 13 significa che la stringa è terminata e si interrompe il ciclo while con un break;

Considerazioni importanti da fare sono:

  • Ricordarsi di azzerare la variabile cmd
  • Assolutamente importante aggiungere un'attesa delay(10) per quanto riguarda i millisecondi fare delle prove. Se non si aggiunge un ritardo la cosa non funziona. O meglio si ha un anomala ripetozione di dati. Evidentemente bisogna dare il tempo di elaborarli con cura.

Ora proviamo ad articolare un pochino la cosa. Faremo in modo che i dati dopo le prime due lettere siano esclusivamente numeri. O meglio anche se si inseriranno numeri misti a lettere solo i numeri verranno prelevati:

 

  byte cmd,sec,tch; 
  String str;
  long pot;
  void setup(){   
     Serial.begin(115200);
     cmd=0;
     pot=0;
  } 
  
  void loop(){
    str="";
    if (Serial.available()>0) cmd = Serial.read();//leggi il primo       
    switch (cmd) {      
      case 'h':
      if (Serial.available()>0)  sec = Serial.read();//leggi il secondo           
      while(true){//Cicla--------------
       if (Serial.available()>0)  tch = Serial.read(); 
        if(tch!=13){//se diverso da ritorno carrello
          if(tch>47 && tch<58){  //se è un numero
             pot = (pot * 10) + (tch - 48);//forma il numero
          }
        }else{//se invece è un ritorno carrello
          str=String(pot);
          if(sec=='m'){//se il secondo carattere era una 'm'
            Serial.print("Minimo "); Serial.println(pot);  
          }else if(sec=='x'){//se il secondo carattere era una 'x'
            Serial.print("Massimo "); Serial.println(pot); 
          }
          break;    
        }                   
       }//End while ------------------- 
        break;        
     }
     cmd=0;
     delay(10);//non togliere
  } 

 

Se diverso da ritorno carrello allora controlliamo che sia un numero. I numeri nel codice ASCII vanno da 48 (0) a 57 (9) quindi solo i codici ASCII (contenuti nel byte letto) compresi tra questi valori saranno dei numeri. if(tch>47 && tch<58). Segue un semplice algoritmo che costruisce il numero intero. Facciamo un esempio, immaginiamo che il numero sia 234 il primo sarà 2 prendiamolo e moltiplichiamolo per 10 avremo 20 se a questo sommiamo il secondo numero avremo 23. Moltiplichiamo 23 per 10 avremo 230 + il terzo numero 4 avremo 234 ed ecco il nostro numero ricostruito.

Attenzione importante utilizzare la variabile pot del tipo giusto. Se usiamo pot come int ricordatevi che un int ha valori che vanno da 32.767 a -32.768 per cui se inseriamo numeri maggiori di 32767 questi diventeranno negativi e tutto salta. Se pensate di dover inviare numeri di maggiori dimensioni utilizzare un long che va da 2.147.483.647 a -2.147.483.648.