
14 - MODIFICA IL LOGO DI ARDUINO
USANDO LA COMUNICAZIONE SERIALE, UTILIZZERAI ARDUINO PER CONTROLLARE UN PROGRAMMA SUL TUO COMPUTER
Scopri: la comunicazione seriale con il computer, Processing
Tempo: 45 MINUTI Livello: ■ ■ ■ ■ ■ Basato sui progetti: 1, 2, 3
Hai fatto cose molto interessanti con il mondo fisico, ora è il momento di controllare il computer con Arduino. Quando programmi Arduino, stai aprendo una connessione tra il computer e il microcontrollore. Puoi utilizzare questa connessione per inviare i dati avanti e indietro ad altre applicazioni.

INGREDIENTI
Potenziometro
Arduino ha un chip che converte la comunicazione USB del computer alla comunicazione seriale che utilizza Arduino. La comunicazione seriale significa che i due computer, l’Arduino e il PC, si scambiano bit di informazioni serialmente o uno dopo l’altro nel tempo. Per la comunicazione seriale, i computer devono mettersi d’accordo sulla velocità con cui parlano l’un l’altro. Probabilmente hai notato che quando utilizzi il monitor seriale c’è un numero nell’angolo in basso a destra della finestra. Quel numero, 9600 bit al secondo, o baud, è lo stesso del valore che hai dichiarato con Serial.begin(). Questa è la velocità alla quale Arduino e il computer si scambiano i dati. Un bit è la più piccola quantità di informazioni che un computer è in grado di capire. Hai usato il monitor seriale per guardare i valori degli ingressi analogici; userai un metodo simile per trasferire i valori in un programma che stai per scrivere in un ambiente di programmazione chiamato Processing. Processing è basato su Java e l’ambiente di programmazione Arduino è basato su quello di Processing. Sembrano molto simili, così dovresti sentirti come a casa.

Prima di iniziare il progetto, scarica l’ultima versione di Processing dal sito processing.org. Può essere utile guardare i tutorial «Getting Started» e «Overview» al link processing.org/learning. Questo ti aiuterà a familiarizzare con Processing prima di iniziare a scrivere il software per comunicare con Arduino.
Il modo più efficiente di inviare dati tra Arduino e Processing è usare la funzione Serial.write() in Arduino. Questa funzione è simile alla Serial.print() che hai già utilizzato in quanto invia le informazioni a un computer collegato, ma, invece di inviare le informazioni leggibili dall’uomo come numeri e lettere, invia i valori compresi tra 0 e 255 sotto forma di byte non elaborati. Questo limita i valori che Arduino può inviare, ma consente uno scambio rapido di informazioni.
Sia sul computer che su Arduino, c’è una cosa chiamata buffer seriale che parcheggia le informazioni fino a quando non vengono lette da un programma. Invierai byte dal buffer seriale di Arduino a quello di Processing. Processing quindi leggerà i byte dal buffer. Mano a mano che il programma legge le informazioni dal buffer seriale, libera lo spazio per ulteriori informazioni.
Quando si utilizza la comunicazione seriale tra dispositivi e programmi, è importante che entrambe le parti non solo sappiano quanto velocemente comunicheranno, ma anche quello che si aspettano. Quando incontri qualcuno, probabilmente ti aspetti un «Ciao!». Se invece ti dicono qualcosa come «Il gatto è peloso», è probabile che sarai preso in contropiede. Con il software, è necessario ottenere un accordo da entrambe le parti su ciò che viene inviato e ricevuto.

COSTRUISCI IL CIRCUITO

Collega massa e alimentazione alla breadboard.
Collega ogni estremità del potenziometro alla massa e all’alimentazione. Collega il piedino centrale al piedino analogin 0.

IL CODICE DI ARDUINO
Apri una connessione seriale
In primo luogo, programma Arduino. Nel setup(), inizia la comunicazione seriale, così come hai fatto in precedenza per mostrare i valori di un sensore collegato. Il programma Processing che scrivi ha la stessa velocità di comunicazione seriale di Arduino.
void setup() {
Serial.begin(9600);
}
Invia il valore del sensore
Nel loop(), stai per usare il comando Serial.write() per inviare informazioni tramite la connessione seriale.
Serial.write() può inviare solo valori tra 0 e 255. Per assicurarti che stai mandando solo valori compresi in questo intervallo, dividi la lettura analogica per 4.
void loop() {
Serial.write(analogRead(A0)/4);
Stabilizza l’ADC
Dopo l’invio del byte, attendi un millesimo di secondo per consentire all’ADC di stabilizzarsi. Carica il programma in Arduino, poi mettilo da parte mentre scrivi il tuo sketch di Processing.
delay(1);
}
ORA SALVA E CHIUDI L’IDE DI ARDUINO E APRI PROCESSING.
IL CODICE DI PROCESSING
Importa la libreria seriale e crea l’oggetto
Il linguaggio di Processing è simile a quello di Arduino, ma ci sono abbastanza differenze per cui varrebbe la pena guardare i tutorial e la guida «Getting Started» citata prima per familiarizzare con questo linguaggio. Apri un nuovo sketch di Processing. Processing, al contrario di Arduino, non conosce le porte seriali a meno che non venga inclusa una libreria esterna. Importa quindi la libreria seriale. Devi creare un’istanza dell’oggetto seriale, come hai fatto in Arduino con la libreria Servo. Usa questo oggetto dal nome univoco ogni volta che desideri utilizzare la connessione seriale.
import processing.serial.*;
Serial myPort;
Crea un oggetto per l’immagine
Per usare immagini in Processing, devi creare un oggetto che contiene l’immagine e dargli un nome.
PImage logo;
Variabile per immagazzinare il colore di sfondo
Crea una variabile che contiene il colore di sfondo del logo di Arduino. Il logo è un file png e ha la trasparenza, in modo che sia possibile vedere il cambiamento di colore dello sfondo.
int bgcolor = 0;
Imposta la modalità colore
Processing ha una funzione setup(), proprio come Arduino. Apri la connessione seriale e dai al programma un paio di parametri che verranno utilizzati durante l’esecuzione.
Puoi modificare il modo in cui Processing lavora con le informazioni sul colore. In genere, funziona con colori in modalità RGB (rosso, verde, blu). Questo è simile al colore che hai miscelato nel progetto 04, quando hai usato valori compresi tra 0 e 255 per modificare il colore di un LED RGB. In questo programma, utilizza invece una modalità di colore chiamata HSB, acronimo di Hue, Saturation e Brightness (tonalità, saturazione e luminosità). Potrai modificare la tonalità quando giri il potenziometro.
colorMode() richiede due parametri: il tipo di modalità e il valore massimo che può aspettarsi.
void setup() {
colorMode(HSB, 255);
Carica l’immagine
Per caricare l’immagine di Arduino nello sketch, leggila nell’oggetto logo che hai creato in precedenza. Quando fornisci l’URL di un’immagine, Processing la scarica quando esegui il programma. Con la funzione size(), dici a Processing quanto grande deve essere la finestra sullo schermo. Se usi logo.width e logo.height come istruzioni, lo sketch si ridimensiona automaticamente alle dimensioni dell’immagine.
logo = loadImage("http://arduino.cc/logo.png");
size(logo.width, logo.height);
Stampa le porte seriali disponibili
Processing ha la capacità di stampare i messaggi di stato usando il comando println(). Usandolo con la funzione Serial.list(), ottieni un elenco di tutte le porte seriali del computer quando il programma viene avviato. Lo userai quando hai finito di programmare per vedere su quale porta è collegata Arduino.
println("Available serial ports:");
println(Serial.list());
Crea l’oggetto porta seriale
Devi fornire a Processing le informazioni sulla connessione seriale. Per dare all’oggetto seriale myPort le informazioni necessarie, il programma ha bisogno di una istanza dell’oggetto seriale. I parametri che si aspetta sono: con quale applicazione parla, con quale porta seriale comunica e a quale velocità.
myPort =
new Serial(this, Serial.list()[0], 9600);
}
L’attributo
thisdice a Processing che stai per usare la connessione seriale in questa stessa applicazione. L’istruzioneSerial.list()[0]specifica quale porta seriale stai usando.Serial.list()contiene un array di tutti i dispositivi seriali collegati. Il parametro 9600 dovrebbe esserti familiare: definisce la velocità alla quale comunica il programma.
Leggi i dati di Arduino dalla porta seriale
La funzione draw() è analoga al loop() di Arduino in quanto si ripete continuamente. Qui è dove si disegna sulla finestra del programma.
Controlla se ci sono informazioni da Arduino. Il comando myPort.available() indica se c’è qualcosa nel buffer seriale. Se ci sono byte, leggi il valore nella variabile bgcolor e stampalo nella finestra di debug.
void draw() {
if (myPort.available() > 0) {
bgcolor = myPort.read();
println(bgcolor);
}
Imposta lo sfondo dell’immagine e visualizza l’immagine
La funzione background() imposta il colore della finestra. Ha tre parametri. Il primo è la tonalità, il secondo la luminosità e l’ultimo la saturazione. Usa la variabile bgcolor come valore della tonalità e imposta la luminosità e la saturazione al valore massimo, 255.
Disegna il logo con il comando image(). Devi dire a image() cosa disegnare e le coordinate dove iniziare a disegnare nella finestra. 0,0 è in alto a sinistra: incomincia da lì.
background(bgcolor, 255, 255);
image(logo, 0, 0);
}
USALO
Collega Arduino e apri il monitor seriale. Ruota la manopola del potenziometro. Dovresti vedere dei caratteri quando la giri. Il monitor seriale si aspetta caratteri ASCII, non byte grezzi. ASCII è l’informazione codificata per rappresentare il testo nel computer. Quello che vedi nella finestra è il monitor seriale che cerca di interpretare i byte come ASCII.
Quando usi Serial.println(), mandi informazioni formattate per il monitor seriale.
Quando usi Serial.write(), come nell’applicazione che stai eseguendo ora, stai inviando informazioni grezze. Programmi come Processing possono capire questi byte grezzi.
Chiudi il monitor seriale. Esegui lo sketch di Processing premendo il tasto freccia nell’IDE di Processing. Guarda la finestra di output di Processing. Si dovrebbe vedere un elenco simile alla figura sottostante.

Questa è una lista di tutte le porte seriali del tuo computer.
Se usi Mac OS X, cerca una stringa che dica qualcosa del tipo «/dev/tty.usbmodem411», sarà probabilmente il primo elemento nella lista. Su Linux, appare come «/dev/ttyUSB0», o qualcosa di simile. Per Windows, appare come una porta COM, la stessa che usi quando programmi la scheda. Il numero di fronte è l’indice dell’array Serial.list()[]. Cambia il numero nel tuo sketch di Processing in modo che corrisponda alla porta corretta sul computer.
Riavvia lo sketch di Processing. Quando il programma inizia a girare, ruota il potenziometro collegato ad Arduino. Dovresti vedere cambiare il colore dietro il logo di Arduino. Dovresti anche vedere i valori nella finestra di Processing. Quei numeri corrispondono ai byte grezzi che hai inviato da Arduino.

Una volta che hai smanettato a più non posso, prova a sostituire il potenziometro con un sensore analogico. Trova qualcosa di interessante per controllare il colore. Che sensazione ti dà l’interazione? Probabilmente è diversa rispetto a usare un mouse o la tastiera; ti sembra naturale?

Quando utilizzi la comunicazione seriale, solo un’applicazione alla volta può parlare con Arduino. Quindi, se stai eseguendo uno sketch di Processing che è collegato ad Arduino, non sarai in grado di caricare un nuovo sketch di Arduino né di utilizzare il monitor seriale fino a quando non avrai chiuso l’applicazione attiva.

Con Processing e gli altri ambienti di programmazione, puoi controllare suoni, immagini e video sul computer, in modo interessante e innovativo. Se ti interessa la possibilità di controllare i contenuti sul computer, prenditi del tempo per sperimentare con Processing. Ci sono diversi esempi di comunicazione seriale sia in Processing sia nell’IDE di Arduino che ti aiuteranno a sperimentare ancora.
La comunicazione seriale permette ad Arduino di comunicare con programmi sul computer. Processing è un ambiente di programmazione open source sul quale è basato l’IDE di Arduino. È possibile controllare uno sketch di Processing con Arduino tramite la comunicazione seriale.
CODICE COMPLETO
/*
Arduino Starter Kit example
Project 14 - Tweak the Arduino Logo
This sketch is written to accompany Project 14 in the Arduino Starter Kit
Parts required:
- 10 kilohm potentiometer
Software required:
- Processing (3.0 or newer) https://processing.org/
- Active Internet connection
created 18 Sep 2012
by Scott Fitzgerald
https://store.arduino.cc/genuino-starter-kit
This example code is part of the public domain.
*/
void setup() {
// initialize serial communication
Serial.begin(9600);
}
void loop() {
// read the value of A0, divide by 4 and send it as a byte over the
// serial connection
Serial.write(analogRead(A0) / 4);
delay(1);
}
/* Processing code for this example
// Tweak the Arduino Logo
// by Scott Fitzgerald
// This example code is in the public domain.
// import the serial library
import processing.serial.*;
// create an instance of the serial library
Serial myPort;
// create an instance of PImage
PImage logo;
// a variable to hold the background color
int bgcolor = 0;
void setup() {
size(1, 1);
surface.setResizable(true);
// set the color mode to Hue/Saturation/Brightness
colorMode(HSB, 255);
// load the Arduino logo into the PImage instance
logo = loadImage("http://www.arduino.cc/arduino_logo.png");
// make the window the same size as the image
surface.setSize(logo.width, logo.height);
// print a list of available serial ports to the Processing status window
println("Available serial ports:");
println(Serial.list());
// Tell the serial object the information it needs to communicate with the
// Arduino. Change Serial.list()[0] to the correct port corresponding to
// your Arduino board. The last parameter (e.g. 9600) is the speed of the
// communication. It has to correspond to the value passed to
// Serial.begin() in your Arduino sketch.
myPort = new Serial(this, Serial.list()[0], 9600);
// If you know the name of the port used by the Arduino board, you can
// specify it directly like this.
// port = new Serial(this, "COM1", 9600);
}
void draw() {
// if there is information in the serial port
if ( myPort.available() > 0) {
// read the value and store it in a variable
bgcolor = myPort.read();
// print the value to the status window
println(bgcolor);
}
// Draw the background. the variable bgcolor contains the Hue, determined by
// the value from the serial port
background(bgcolor, 255, 255);
// draw the Arduino logo
image(logo, 0, 0);
}
*/