Comandare Arduino tramite seriale RS232 (USART) (Lezione 9)
Con la periferica UART è possibile leggere e/o trasferire informazioni ad Arduino. Nel post lettura segnale analogico, abbiamo visto un esempio di come leggere un segnale analogico e stampare il suo valore sul terminale video.
Molto spesso per interagire con un sistema si richiede il trasferimento di informazioni, sotto forma di variabili alfanumeriche codificate. In base ai dati trasferiti, possiamo prevedere l’esecuzioni di particolari funzioni, per esempio: richiedere informazioni, configurazioni, attivare particolari processi, ricevere delle informazioni per il debug del software e hardware ecc..
Da quanto indicato in precedenza è evidente che avere un’interfaccia di comunicazione con il nostro sistema è di fondamentale importanza, per un sistema come Arduino la soluzione più semplice è quella di utilizzare la porta UART perché già integrata sulla board ed è facilmente configurabile con l’ambiente di sviluppo.
Comandare Arduino tramite seriale RS232
Come nello stile di questo sito, svolgeremo un esercizio didattico, molto semplice e istruttivo che fornisce le basi poter utilizzare il sistema anche per applicazioni più complesse,
Nell’esempio, tramite la seriale inviamo un comando per accendere o spegnere i tre diodi LED RGB. Inoltre, ho inserito dopo lo stantment if la stampa su monitor seriale di una frase per rilevare la corretta esecuzione del software in un particolare punto del codice, se per un nostro errore, il sistema non esegue l’istruzione di stampa sul terminale, possiamo eseguire un’analisi per l’individuazione dell’errore, limitata quella ristretta aerea di codice. Per codici che hanno migliaia di righe, questa soluzione e’ molto utile per l’individuazione degli errori.
Vi consiglio di utilizzare questa tecnica, molto spesso vi aiuterà a risolvere problemi che possono essere presenti nel vostro codice sorgente, tecnica usata anche da chi ha un’esperienza decennale.
Possiamo leggere tre numeri interi, inviati tramite la UART, con un valore compreso tra 0 e 100, dove 0 corrisponde a LED spento e 100 massima intensità luminosa. Il valore inserito, per ogni colore, setterà la la modulazione dei PWM (vedi articolo PWM ) connessi ai tre pins del LED RGB.
//Definiamo i pins const int ROSSO = 11; const int VERDE = 10; const int BLU = 9; void setup() { Serial.begin(9600); //Impostiamo la seriale alla velocità di 9600 Serial.setTimeout(10); //impostiamo il timeout sulla lettura della seriale //Set pins as outputs pinMode(ROSSO, OUTPUT); pinMode(VERDE, OUTPUT); pinMode(BLU, OUTPUT); // Impostiamo le uscite a valore alto, per spegnere i tre diodi LEDS all'accensione digitalWrite(ROSSO, HIGH); digitalWrite(VERDE, HIGH); digitalWrite(BLU, HIGH); } void loop() { // con questa istruzione controlliamo se ci sono dei dati disponibile // nel buffer della seriale if (Serial.available() > 0) { int val1 = Serial.parseInt(); // legge i primo valore e lo converte in un numero intero int val2 = Serial.parseInt(); // se non ci sono dei dati che possono essere convertiti int val3 = Serial.parseInt(); // esce per timeout Serial.println("ROSSO: " + String(val1) + "%"); Serial.println("VERDE: " + String(val2) + "%"); Serial.println("BLU: " + String(val3) + "%"); // se nella seriale ci sono ancora dei dati che non possono essere convertiti li cancella while (Serial.available()) { Serial.read(); } //impostiamo un costrain, da 0 a 100 int val1c = constrain(val1,0,100); int val2c = constrain(val2,0,100); int val3c = constrain(val3,0,100); // rimappa i valori con numeri compresi tra 0 e 255 int rval = map(val1c,0,100,255,0); int vval = map(val2c,0,100,255,0); int bval = map(val3c,0,100,255,0); //settiamo la luminosità dei didodi LEDs analogWrite(ROSSO, rval); analogWrite(VERDE, vval); analogWrite(BLU, bval); //riportiamo i valori in percentuale sulla seriale Serial.println("ROSSO: " + String(val1c) + "%"); Serial.println("VERDE: " + String(val2c) + "%"); Serial.println("BLU: " + String(val3c) + "%\n"); } }
Analizziamo il codice
- digitalWrite(ROSSO, HIGH); impostiamo l’uscita a valore alto per spegnere il dido LED rosso.
- digitalWrite(VERDE, HIGH); impostiamo l’uscita a valore alto per spegnere il dido LED verde.
- digitalWrite(BLU, HIGH); impostiamo l’uscita a valore alto per spegnere il dido LED blu.
- if (Serial.available() > 0) se è presente un dato nella seriale lo leggiamo
- int val1 = Serial.parseInt(); il seguente comando bloccherà l’esecuzione della prossima istruzione fino a quando non riceverà un numero intero (per il tempo impostato nell’istruzione Serial.setTimeout(10); ) mentre, tutti gli altri caratteri nuova linea o spazio saranno cancellati.
- Serial.println(“ROSSO: ” + String(val1c) + “%”); Stampiamo i valori letti, per verificare se abbiamo inserito i numeri interi correttamente
- while (Serial.available()) { Serial.read(); } se per errore, verranno digitati più di tre valori interi queste istruzione provvederà a cancellare il contenuto dei registri della UART.
- int val1c = constrain(val1,0,100); il valore letto è valido solo se compreso tra 0 e 100.
- int rval = map(val1c,0,100,255,0); il numero intero letto dalla seriale è mappato in un valore compreso tra 0 e 255, perché il PWM del microcontrollore di Arduino Uno ha una risoluzione di 8 bit.
- analogWrite(RED, rval); I valori mappati sono scritti nel PWM che pilota i corrispettivi ingressi dei diodi LED RGB