![14 Numerazione capitolo](14-num-capitolo.png) ## 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](14-ingredienti.png) >**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. ![Processing icon](14-processing.png) > Prima di iniziare il progetto, scarica l'ultima versione di Processing dal sito [processing.org](http://processing.org). Può essere utile guardare i tutorial "Getting Started" e "Overview" al link [processing.org/learning](http://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. ![Processing IDE](14-processingIDE.png) ### COSTRUISCI IL CIRCUITO ![Schema del circuito e montaggio](14-immagine_circuito_processing.png) 1. Collega massa e alimentazione alla breadboard. 2. Collega ogni estremità del potenziometro alla massa e all'alimentazione. Collega il piedino centrale al piedino analogin 0. ![Schema elettrico](14-schema_elettrico.png) ### 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. ```cpp 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. ```cpp 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. ```cpp 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. ```java 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. ```java 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. ```java 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. ```java 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. ```java 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. ```java 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à. ```java myPort = new Serial(this, Serial.list()[0], 9600); } ``` > **L'attributo `this` dice a Processing che stai per usare la connessione seriale in questa stessa applicazione. L'istruzione `Serial.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. ```java 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ì. ```java 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. ![Output console Processing](14-immagine_console_processing.png) 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. ![Forbici e colla](forbici-colla.png) > *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?* ![Lente](lente.png) > *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.* ![Cervello](cervello.png) > *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 ```cpp /* 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); } */ ```