14 Numerazione capitolo

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

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

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.

Processing IDE

COSTRUISCI IL CIRCUITO

Schema del circuito e montaggio

  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

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 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.

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.

Output console Processing

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

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

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

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);
  }

*/