Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
DI PROTOTIPAZIONE
ELETTRONIcA
OPEN
SOURCE
Arduino
La guida ufficiale
Massimo Banzi
ISBN 978-88-481-7424-4
978-88-481-2424-9
Tutti i diritti sono riservati. Nessuna parte del libro può essere riprodotta o diffusa con
un mezzo qualsiasi, fotocopie, microfilm o altro, senza il permesso dell’editore.
All rights reserved. No part of this book shall be reproduced, stored in a retrieval system,
or transmitted, by any means, electronic, mechanical photocopying, recording or
otherwise without written permission from the publisher.
1/Introduzione. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
A chi è rivolto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Cos’è il Physical Computing?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Appendici. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Appendice A/La breadboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Appendice B/Resistenze e condensatori. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Appendice C/Arduino: Guida rapida. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5
Appendice D/Leggere gli schemi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Prefazione v
Questa abitudine di rileggere più volte gli articoli, avvalendomi delle conoscenze
acquisite smontando i circuiti, generò un lento circolo virtuoso.
Feci un grosso passo avanti un Natale, quando mio padre mi regalò un kit pensato
per insegnare l’elettronica agli adolescenti. Ciascun componente era contenuto
in un cubo di plastica che si collegava magneticamente agli altri cubi, creando un
collegamento; sopra appariva il simbolo elettronico. Certo non mi aspettavo che
quel giocattolo era anche una pietra miliare della storia del design tedesco, perché
Dieter Rams lo aveva progettato negli anni 60.
Con questo nuovo strumento, potevo unire rapidamente dei circuiti e provarli per
vedere cosa succedeva. Il ciclo di prototipazione diventava sempre più breve.
Quindi cominciai a costruire radio, amplificatori, circuiti che producevano rumori
orribili o suoni gradevoli, sensori di pioggia e piccoli robot.
Ci impiegai molto a trovare una parola inglese che descrivesse un modo di lavora-
re senza un piano specifico, partendo da un’idea e arrivando a un risultato del tutto
inaspettato. Infine, scoprii la parola “tinkering”. Scoprii che questa parola veniva
usata in molti altri campi per descrivere un modo di agire e di definire le persone
che intraprendevano un percorso sul sentiero dell’esplorazione. Per esempio, la
generazione di registi francesi che diedero vita alla “Nouvelle Vague” venivano
chiamati “tinkerers”. Trovai la definizione migliore di “tinkering” in una mostra
presso l’Exploratorium di San Francisco:
Tinkering è quanto accade quando si cerca di fare qualcosa che non si sa bene
come fare, guidati dal capriccio, dall’immaginazione e dalla curiosità. Quando si
agisce in questo modo, non esistono istruzioni e neanche errori, non esiste un
modo giusto o un modo sbagliato di fare le cose. Si tratta di scoprire come funzio-
nano le cose e di manipolarle.
—www.exploratorium.edu/tinkering
Grazie ai miei primi esperimenti, imparai quanta esperienza è necessaria per riu-
scire a creare un circuito che faccia quello che si vuole a partire dai suoi compo-
nenti fondamentali.
Feci un altro grande passo avanti nell’estate del 1982, quando andai a Londra
con i miei genitori e trascorsi molte ore nel Museo della Scienza. Qui era appena
stata aperta una nuova ala dedicata ai computer e, seguendo una serie di espe-
rimenti guidati, appresi i concetti fondamentali della matematica binaria e della
programmazione.
Quindi scoprii che in molte applicazioni gli ingegneri non costruivano più i circuiti
a partire dai loro componenti fondamentali, ma che invece stavano implementan-
do molta intelligenza nei loro prodotti usando dei microprocessori. Il software sta-
va rimpiazzando molte ore di electronic design e permetteva un ciclo di tinkering
più breve.
Il mio primo e più importante progetto quindi fu usare il mio nuovissimo compu-
ter ZX81 per controllare una saldatrice. So che può sembrare un progetto poco
eccitante, ma ce n’era bisogno e per me era una grossa sfida, perché avevo appe-
na imparato a programmare. A questo punto, divenne chiaro che scrivere linee di
codice avrebbe richiesto meno tempo che modificare circuiti complessi.
Prefazione vii
Innanzitutto voglio ringraziare i miei compagni del Team di Arduino: David Cuartiel-
les, David Mellis, Gianluca Martino e Tom Igoe.
Lavorare con voi è un’esperienza fantastica.
Barbara Ghella non lo sa, ma senza i suoi preziosi consigli Arduino e questo libro
forse non esisterebbero.
Gillian Crampton-Smith per avermi offerto un’opportunità e per tutto ciò che mi
ha insegnato.
Brian Jepson per essere un grande editore e per il suo entusiastico appoggio.
Nancy Kotary, Brian Scott, Terry Bronson e Patti Schiendelman per aver trasformato i
miei scritti in un libro completo.
Vorrei ringraziare molte altre persone, ma Brian dice che non c’è abbastanza spazio,
quindi elencherò solo un numero ridotto di persone che ringrazio per molte ragioni:
Prefazione ix
» Si programma attraverso un cavo USB, non una porta seriale. Questa funziona-
lità è utile, perché molti computer moderni non sono dotati di porte seriali.
Introduzione 1
Questo libro è pensato per aiutare i principianti a capire che vantaggi possono
trarre imparando a usare la piattaforma Arduino e abbracciandone la filosofia.
A chi è rivolto
Questo libro è stato scritto per gli utenti “originali” di Arduino: designer e artisti.
Quindi, cerca di spiegare le cose in un modo che potrebbe innervosire gli inge-
gneri. In realtà, uno di loro ha definito i capitoli introduttivi della mia prima bozza
“banalità”. E questo è proprio quello che volevo. Diciamoci la verità: quasi nessun
ingegnere è capace di spiegare quello che fa a un altro ingegnere, figuriamoci a un
essere umano normale. Quindi ora è il momento di immergerci nella “banalità”.
NOTA: Arduino si basa sulla tesi scritta da Hernando Barragan sulla piattafor-
ma Wiring mentre studiava con Casey Reas e me presso l’IDII di Ivrea.
Arduino nacque per insegnare Interaction Design, una disciplina di design che
mette la prototipazione al centro della sua metodologia. Esistono diverse defini-
zioni di Interaction Design, ma quella che preferisco è:
Nel mondo di oggi, l’Interaction Design ha a che fare con la creazione di espe-
rienze significative tra noi (gli umani) e gli oggetti. È un buon modo di esplorare la
creazione di esperienze meravigliose (e forse anche controverse) tra noi e la tec-
nologia. L’Interaction Design incoraggia il design attraverso un processo iterativo
basato su prototipi sempre più fedeli. Questo approccio (che fa parte anche di
Il progresso che abbiamo fatto con Arduino è stato portare questi strumenti un
passo più vicino ai principianti, permettendo alla gente di cominciare a costruire
qualcosa dopo appena due o tre giorni di corso.
Introduzione 3
I prossimi paragrafi presentano alcune filosofie, eventi e pionieri che hanno ispirato
la forma mentis di Arduino.
La filosofia di Arduino 5
Il nostro eroe è James Dyson, che, prima di sentirsi soddisfatto, ha creato 5127
prototipi del suo aspirapolvere (www.international.dyson.com/jd/1947.asp).
La filosofia di Arduino 7
Ridurre il numero di interruzioni del flusso è molto importante per la creatività: più il
processo è fluido, più “tinkering” si verifica.
Questa tecnica nel mondo del software è stata tradotta da ambienti di “program-
mazione visiva” come Max, Pure Data o VVVV. Questi strumenti possono essere
visualizzati come un insieme di elementi chiusi, detti “box”, ciascuno dei quali offre
una diversa funzionalità, permettendo all’utente di costruire “patch” collegando tra
loro i box. Questi ambienti permettono all’utente di sperimentare con la programma-
zione senza soffrire le costanti interruzioni tipiche del ciclo normale: “digitare il codi-
ce; compilarlo; maledizione, c’è un errore; correggere l’errore; compilare; eseguire”.
Chi ha una mente più visiva farà bene a provarli.
Il circuit bending è una delle forme più interessanti di tinkering. Si tratta di provo-
care cortocircuiti creativi in dispositivi elettronici audio a basso voltaggio, alimen-
tati a batteria, come effetti a pedale per chitarra, giocattoli per bambini e piccoli
sintetizzatori, per creare nuovi strumenti musicali e generatori di suoni. Il fulcro
di questo processo è l’“arte della casualità”. Ebbe inizio nel 1966 quando Reed
Ghazala provocò un cortocircuito nell’amplificatore di un giocattolo mettendolo
casualmente a contatto con un oggetto metallico nel cassetto della sua scrivania,
producendo una serie di suoni inusuali. Quello che mi piace dei circuit bender è la
capacità di creare i dispositivi più originali sperimentando con la tecnologia senza
necessariamente capire cosa stanno facendo dal punto di vista teorico.
La filosofia di Arduino 11
1
Citato in Sara Reese Hedberg, “MIT Media Lab’s quest for perceptive computers”, Intelligent Systems and Their
Applications, IEEE, Lug/Ago 1998.
La filosofia di Arduino 13
La filosofia di Arduino 15
Non molto tempo fa, lavorare con l’hardware significava costruire circuiti da zero,
usando centinaia di componenti diversi con nomi strani come resistenze, conden-
satori, induttori, transistor e così via.
Ogni circuito era “cablato” per eseguire una applicazione specifica e apportare del-
le modifiche significava tagliare cavi, saldare collegamenti e così via.
Con l’avvento delle tecnologie digitali e dei microprocessori, queste funzioni, una
volta implementate con i cavi, sono state sostituite da programmi software.
L’hardware di Arduino
La scheda Arduino è una piccola scheda microcontroller, cioè un piccolo circuito
(la scheda) che contiene un intero computer in un piccolo chip (il microcontroller).
Questo computer è almeno mille volte meno potente del MacBook che sto usan-
La piattaforma Arduino 17
Su questa scheda, noi (il team di Arduino) abbiamo posizionato tutti i componenti
necessari perché questo microcontroller funzioni correttamente e comunichi con
il computer. Della scheda esistono molte versioni; quella che useremo in questo
libro è l’Arduino Duemilanove, la più semplice da usare e la migliore per impara-
re. Queste istruzioni, comunque, valgono anche per le versioni precedenti della
scheda, comprese la più recente Arduino Diecimila e la più vecchia Arduino NG.
La Figura 3-1 mostra l’Arduino Duemilanove; la Figura 3-2 mostra l’Arduino NG.
In queste illustrazioni, vedete la scheda Arduino. Sulle prime, tutti questi connet-
tori possono confondere un po’. Ecco la spiegazione di cosa fa ciascun elemento
della scheda:
La scheda può essere alimentata attraverso la porta USB del computer, la mag-
gior parte dei caricatori USB o un alimentatore esterno (si consiglia un alimentato-
re da 9 volt con spinotto cilindrico da 2,1 mm con positivo centrale). Se nella pre-
sa non è collegato nessun alimentatore, la scheda si alimenta via USB, ma, non
appena si collega un alimentatore di corrente, la scheda lo usa automaticamente.
La piattaforma Arduino 19
Scaricate il file e fatevi doppio clic per decomprimerlo; in questo modo verrà creata
una cartella di nome arduino-[versione], come arduino-0016. Trascinate questa
cartella dove volete che risieda: sulla scrivania, nella vostra cartella /Applicazioni (su
Mac), o nella vostra cartella C:\Programmi (su Windows). Ora, ogni volta che volete
eseguire l’IDE Arduino, dovete aprire la cartella arduino e fare doppio clic sull’icona
di Arduino. Ma non basta fare solo questo: si deve eseguire un altro passaggio.
La piattaforma Arduino 21
Una volta che i driver sono installati, potete lanciare l’IDE Arduino e cominciare a
usare Arduino.
Poi, dovrete scoprire quale porta seriale è stata assegnata alla scheda Arduino,
perché questa informazione servirà in seguito per programmarla. Le istruzioni per
ottenere questa informazione sono fornite nei prossimi paragrafi.
Figura 3-3.
La lista di porte seriali dell’IDE Arduino
La piattaforma Arduino 23
Cercate il dispositivo Arduino nella lista sotto “Porte (COM e LPT)”. Arduino
appare come USB Serial Port e presenta un nome come COM4, come mostra la
Figura 3-4.
Figura 3-4.
Gestione dispositivi di Windows, che mostra tutte le porte seriali disponibili
Una volta scoperta l’assegnazione della porta COM, la potete selezionare nel
menu Tools > Serial Port dell’IDE Arduino.
La piattaforma Arduino 25
Sensazione/Percezione
Sensori
Comportamento
(software)
Attuatori
Azione/reazione
Figura 4-1.
Il dispositivo interattivo
Una volta che i sensori sono stati letti, il dispositivo dispone delle informazioni
necessarie per decidere come reagire. Il processo decisionale è gestito dal micro-
controller e la reazione è eseguita degli attuatori. Nel nostro corpo, per esempio,
i muscoli ricevono segnali elettrici dal cervello e li convertono in movimento. Nel
mondo dell’elettronica, queste funzioni possono essere svolte da una luce o da
un motore elettrico.
void setup()
{
pinMode(LED, OUTPUT); // imposta il pin digitale
// come output
}
void loop()
{
digitalWrite(LED, HIGH); // accende il LED
delay(1000); // aspetta un secondo
digitalWrite(LED, LOW); // spegne il LED
delay(1000); // aspetta un secondo
}
Figura 4-3.
L’IDE Arduino con il primo sketch caricato
Ora che il codice si trova nel vostro IDE, dovete verificare che sia corretto. Fate
clic sul pulsante “Verify” (la Figura 4-3 mostra la sua posizione); se tutto è cor-
retto, in basso nell’IDE Arduino appare il messaggio “Done compiling”. Questo
messaggio significa che l’IDE Arduino ha tradotto lo sketch in un programma ese-
guibile che può essere eseguito sulla scheda, un po’ come un file .exe in Windows
o .app su Mac.
A questo punto, lo si può caricare sulla scheda: fate clic sul pulsante Upload to I/O
Board (Figura 4-3). In questo modo si resetta la scheda, costringendola a interrom-
pere ciò che sta facendo e ad ascoltare le istruzioni che provengono dalla porta
USB. L’IDE Arduino invia lo sketch attuale alla scheda, che lo inserisce nella sua
memoria e poi lo esegue.
Una volta che il codice si trova sulla scheda Arduino, ci rimane finché non vi
caricate un altro sketch. Lo sketch sopravvive anche se la scheda viene riavviata
o spenta, un po’ come i dati sull’hard disk del computer.
Passami il parmigiano
Notate la presenza delle parentesi graffe, che si usano per raggruppare diverse
linee di codice e si rivelano particolarmente utili quando si vuole assegnare un
nome a un gruppo di istruzioni. Se durante una cena chiedete a qualcuno “Mi
passi il parmigiano, per favore?”, con questa domanda generate una serie di azio-
ni che si riassumono nella breve frase che avete appena pronunciato. Dato che
siamo umani, il tutto avviene in modo naturale, mentre nel caso di Arduino, che
Qui potete notare che sono definiti in questo modo due blocchi di codice. Prima
di ciascuno di essi appare uno strano comando:
void setup()
Questa riga assegna un nome al blocco di codice. Se steste scrivendo un elenco
di istruzioni per spiegare ad Arduino come passarvi il parmigiano, dovreste
scrivere void passTheParmesan() all’inizio del blocco e questo blocco divente-
rebbe un’istruzione che si potrebbe chiamare da qualsiasi punto del codice di
Arduino. Questi blocchi si chiamano funzioni. Se poi in un altro punto del codice
scrivete passTheParmesan(), Arduino esegue queste istruzioni e prosegue da
dove era rimasto.
setup() è il posto dove si inserisce tutto il codice che si vuole eseguire una sola
volta all’inizio del programma e loop() contiene il programma vero e proprio, che
viene eseguito ripetutamente. Questo accade perché Arduino non è come un
computer normale: non è in grado di eseguire contemporaneamente diversi pro-
grammi e dai programmi non si può uscire. Quando si accende la scheda, viene
eseguito il codice; quando lo si vuole fermare, basta spegnerla.
void setup()
Questa riga dice a Arduino che il blocco successivo di codice si chiamerà setup().
{
Aprendo questa parentesi graffa, si inizia un blocco di codice.
}
Questa parentesi graffa chiusa indica la fine della funzione setup().
Immaginate che tutti i pin di output siano piccole prese di corrente, come quelle
che avete sui muri di casa vostra. Quelle europee sono a 230 V, quelle americane
a 110 V e Arduino lavora soli 5 V. La magia avviene quando il software diventa
hardware. Quando scrivete digitalWrite(LED, HIGH), mandate al pin di output 5 V
e, se vi collegate un LED, si illumina. Quindi, a questo punto del codice, un’istru-
zione del software fa accadere qualcosa nel mondo fisico, controllando il flusso di
elettricità del pin. Accendere e spegnere il pin ora ci permetterà di tradurre tutto
ciò in qualcosa di più visibile per gli esseri umani; il LED è il nostro attuatore.
}
Questa parentesi graffa chiusa segna la fine della funzione ciclica.
Prima di passare al prossimo paragrafo, voglio che giochiate un po’ con il codi-
ce. Per esempio, potete ridurre il ritardo, usando numeri diversi per gli impulsi
di accensione e spegnimento per vedere pattern di lampeggiamento diversi. In
particolare, dovreste vedere cosa succede quando impostate ritardi molto brevi,
ma usate ritardi diversi per accensione e spegnimento . . . c’è un momento in cui
accade qualcosa di strano; questo “qualcosa” si rivelerà molto utile quando, più
avanti in questo libro, studierete la modulazione di larghezza di impulso.
Cosa costruiremo
Sono sempre stato affascinato dalla luce e dalla possibilità di controllare diverse
sorgenti di luce con la tecnologia. E sono stato così fortunato da lavorare su alcuni
progetti molto interessanti che riguardano proprio il controllo della luce e la pos-
sibilità di farla interagire con la gente. Arduino lo fa davvero bene. In questo libro,
studieremo come progettare “lampade interattive”, usando Arduino come mezzo
per imparare i concetti fondamentali della costruzione dei dispositivi interattivi.
Figura 4-4.
Un ventilatore portatile
In questo semplice sistema idraulico, mostrato nella Figura 4-5, sono importanti
due fattori: la pressione dell’acqua (determinata dalla potenza della pompa) e la
quantità d’acqua che scorrerà nei tubi (che dipende dalla dimensione dei tubi e
dalla resistenza opposta dalla ruota al flusso d’acqua che la investe).
Figura 4-5.
Un sistema idraulico
Presto vi accorgerete che se volete che la ruota giri più in fretta, dovete aumenta-
re la dimensione dei tubi (soluzione efficace solo fino a un certo punto) e aumen-
tare la pressione che la pompa permette di ottenere. Aumentando la dimensione
dei tubi si ottiene un flusso maggiore d’acqua attraverso di essi; rendendoli più
grandi, abbiamo effettivamente ridotto la resistenza dei tubi al flusso d’acqua.
Questo approccio funziona fino a un certo punto, superato il quale la ruota non
girerà più in fretta, perché la pressione dell’acqua non sarà sufficiente. Quando
raggiungiamo questo punto, dobbiamo potenziare la pompa. Questo metodo per
accelerare il movimento della ruota può spingersi fino al punto in cui la ruota si
rompe perché la forza dell’acqua è eccessiva e la distrugge. Un altro aspetto che
noterete è che, mentre la ruota gira, l’asse si scalderà leggermente perché, a
prescindere da quanto bene abbiamo montato la ruota, l’attrito tra l’asse e i buchi
Quali sono, quindi, le parti più importanti del sistema? Una è la pressione prodot-
ta dalla pompa; le altre la resistenza opposta al flusso dell’acqua dai tubi e dalla
ruota e il flusso vero e proprio dell’acqua (diciamo che questo è rappresentato dal
numero di litri d’acqua che fluiscono in un secondo). L’elettricità funziona un po’
come l’acqua. Disponete di una sorta di pompa (una sorgente qualsiasi di elettrici-
tà, come una batteria o una presa della luce) che spinge le cariche elettriche (im-
maginatele come “gocce” di elettricità) nei tubi, che sono rappresentati dai cavi;
alcuni dispositivi sono capaci di usarle per produrre calore (la coperta termica
della nonna), luce (la lampada sul comodino), suoni (il vostro stereo), movimento
(un ventilatore) e molto altro ancora.
Infine, la resistenza che oppone il flusso di corrente nei percorsi che attraversa
viene detta (facile da indovinare) resistenza e si misura in ohm (dal fisico tede-
sco Georg Ohm). Herr Ohm è anche colui che formulò la legge più importante
nell’elettricità e l’unica formula che dovete davvero ricordare. Egli dimostrò che
in un circuito il voltaggio, la corrente e la resistenza sono tutti in relazione e in
particolare che la resistenza di un circuito determina la quantità di corrente che lo
percorrerà, assegnato un determinato voltaggio.
digitalRead() controlla che al pin specificato tra parentesi sia applicato un voltaggio
e restituisce un valore pari a HIGH o LOW, a seconda di quanto rileva. Le altre
istruzioni che abbiamo usato finora non restituivano nessun dato: si limitavano a
eseguire ciò che si chiedeva loro di fare. Ma questo tipo di funzione è un po’ limita-
ta, perché ci costringe ad accontentarci di sequenze di istruzioni molto prevedibili,
senza input da parte del mondo esterno. Grazie a digitalRead(), possiamo “porre
una domanda” ad Arduino e ricevere una risposta che può essere conservata da
qualche parte nella memoria e usata per prendere decisioni, subito o più tardi.
Costruite il circuito mostrato nella Figura 4-6. Per costruirlo, dovete procurarvi alcuni
oggetti (che torneranno utili anche nei prossimi progetti):
» Un kit di cavi di connessione già tagliati, come l’articolo 276-173 di RadioShack o
l’articolo MKKN4 di Maker Shed.
Figura 4-6.
Collegare un pulsante
Diamo un’occhiata al codice che useremo per controllare il LED con il nostro
pulsante:
void setup() {
pinMode(LED, OUTPUT); // segnala ad Arduino che LED è un output
pinMode(BUTTON, INPUT); // e che BUTTON è un input
}
void loop(){
val = digitalRead(BUTTON); // legge il valore dell'input e lo conserva
In Arduino, selezionate File > New (se è aperto un altro sketch, potreste prima vo-
lerlo salvare). Quando Arduino chiede di assegnare un nome alla nuova cartella del-
lo sketch, digitate PushButtonControl. Digitate il codice dell’Esempio 02 in Arduino
(o scaricatelo da www.makezine.com/getstartedarduino e incollatelo nell’IDE
Arduino). Se tutto è corretto, il LED si accende quando premete il pulsante.
Come funziona?
Con questo programma di esempio ho introdotto due nuovi concetti: le funzioni
che restituiscono il risultato del loro lavoro e l’istruzione if.
Tenere il dito sul pulsante per tutto il tempo in cui si vuole la luce accesa non è
molto comodo. Anche se vi renderebbe consapevoli di quanta energia sprecate
quando vi allontanate da una lampada che avete lasciato accesa, dobbiamo trova-
re un modo per cambiare questo comportamento.
Per farlo, useremo quella che si chiama una variabile (ne abbiamo già usata una,
ma non l’ho spiegata). Una variabile è una posizione nella memoria di Arduino
dove si possono conservare dei dati. Immaginatela come una di quelle note
adesive che usate per ricordarvi di qualcosa, come un numero di telefono: ne
prendete una, ci scrivete “Luisa 02 555 1212” e poi lo appiccicate sul monitor del
computer o sul frigo. Nel linguaggio di Arduino, è altrettanto semplice: basta che
decidiate che tipo di dato volete conservare (un numero o del testo, per esem-
pio), gli assegnate un nome e, quando volete, potete salvare o recuperare il dato.
Per esempio:
int val = 0;
int significa che la variabile conterrà un numero intero, val è il nome della variabile
e = 0 vi assegna un valore iniziale pari a zero.
NotA: Avete notato che in Arduino, tutte le istruzioni, con una sola eccezione
(#define), finiscono con il punto e virgola? Sono così perché il compilatore (la
parte di Arduino che converte lo sketch in un programma che il microcontrol-
ler può eseguire) possa riconoscere dove finisce un’istruzione e ne comincia
una nuova. Ricordatevi di usarlo sempre, tranne che nelle righe che comin-
ciano con #define. Le istruzioni #define vengono sostituite dal compilatore
prima che il codice venga tradotto in un eseguibile per Arduino.
Nel programma che segue, usiamo val per conservare il risultato di digitalRead();
qualunque cosa Arduino ricavi dall’input finisce nella variabile e vi resta finché
non viene cambiato da un’altra riga di codice. Notate che le variabili usano un tipo
di memoria chiamata RAM. È abbastanza rapida, ma quando si spegne la scheda
tutti i dati contenuti nella RAM vanno persi (che significa che, quando si riaccen-
de la scheda, tutte le variabili tornano al loro valore iniziale). I vostri programmi
sono invece conservati nella memoria flash (dello stesso tipo usato dal vostro
cellulare per conservare i numeri di telefono), che conserva tutti i suoi contenuti
anche quando la scheda è spenta.
Ora usiamo un’altra variabile per ricordare se il LED deve rimanere acceso o spen-
to dopo che rilasciamo il pulsante. L’Esempio 03A è un primo tentativo:
void setup() {
pinMode(LED, OUTPUT); // indica ad Arduino che LED è un output
pinMode(BUTTON, INPUT); // e che BUTTON è un input
}
void loop() {
val = digitalRead(BUTTON); // legge il valore dell'input e lo conserva
if (state == 1) {
digitalWrite(LED, HIGH); // accende il LED
} else {
digitalWrite(LED, LOW);
}
}
Ora provate questo codice. Noterete che funziona. . . in un certo senso. Scoprire-
te che la luce cambia così rapidamente che non si può impostarla correttamente
premendo il pulsante. Diamo un’occhiata alle parti più interessanti del codice: sta-
te è una variabile che conserva 0 o 1 per ricordare se il LED è acceso o spento.
Dopo che si rilascia il pulsante, la inizializziamo su 0 (LED spento).
Più avanti nel programma, potete vedere che usiamo lo stato per scoprire se il
LED deve essere acceso o spento. Come ho detto, questo produce un risultato
un po’ strano.
Il risultato è discontinuo per via del modo in cui leggiamo il pulsante. Arduino è
molto veloce; esegue le sue istruzioni interne a una velocità pari a 16 milioni di
istruzioni al secondo, cioè potrebbe eseguire tranquillamente alcuni milioni di
righe di codice al secondo. Questo significa che, mentre il nostro dito preme il
pulsante, Arduino probabilmente sta leggendo la posizione del pulsante alcune
centinaia di volte e ne modifica di conseguenza lo stato. Per questo, i risultati
finiscono per essere imprevedibili; il LED potrebbe apparire spento quando lo
vogliamo acceso o viceversa. Dato che perfino un orologio rotto dice la verità due
volte al giorno, il programma qualche volta potrebbe mostrare il comportamento
corretto, ma nella maggior parte dei casi no.
void setup() {
pinMode(LED, OUTPUT); // indica ad Arduino che LED è un output
pinMode(BUTTON, INPUT); // e che BUTTON è un input
}
void loop(){
val = digitalRead(BUTTON); // legge il valore dell'input
// e lo conserva
if (state == 1) {
digitalWrite(LED, HIGH); // accende il LED
} else {
digitalWrite(LED, LOW);
}
}
Avrete notato che questo approccio non è perfetto, per via di un altro problema
degli interruttori meccanici. I pulsanti sono dispositivi molto semplici: due parti di
Quando il pulsante produce questi segnali, Arduino vede una sequenza molto rapi-
da di segnali acceso-spento. Per evitarlo sono state sviluppate molte tecniche, ma
in questo semplice codice ho notato che normalmente basta aggiungere un ritardo
di 10/50 millisecondi quando il codice rileva una transizione.
void setup() {
pinMode(LED, OUTPUT); // indica ad Arduino che LED è un output
pinMode(BUTTON, INPUT); // e che BUTTON è un input
}
void loop(){
val = digitalRead(BUTTON); // legge il valore dell'input
// e lo conserva
if (state == 1) {
digitalWrite(LED, HIGH); // accende il LED
} else {
digitalWrite(LED, LOW);
}
}
Interruttori
Sono come i pulsanti, ma non cambiano automaticamente lo stato quando vengo-
no rilasciati.
Termostati
Interruttori che si aprono quando la temperatura raggiunge un determinato valore.
Figura 5-1.
L’interno di un sensore di inclinazione
Figura 5–2.
Un tipico sensore PIR
Questa tecnica funziona anche con dispositivi diversi dai LED. Per esempio, nello
stesso modo si può cambiare la velocità di un motore.
Facendo esperimenti, vedrete che far lampeggiare il LED inserendo dei ritardi nel
codice è un po’ scomodo, perché appena si vuole leggere un sensore o inviare dei
dati su una porta seriale, il LED tremolerà mentre è in attesa che finiate di leggere
il sensore. Fortunatamente, il processore che usa la scheda Arduino è dotato di
un hardware che può far lampeggiare in modo efficiente tre LED mentre lo sketch
fa qualcos’altro. Questo hardware è implementato nei pin 9, 10 e 11, che possono
essere controllati con l’istruzione analogWrite().
Proviamo. Costruite il circuito che vedete nella Figura 5-4. Notate che i LED sono
polarizzati: il pin lungo (positivo) dovrebbe andare a destra e quello corto (negativo)
a sinistra. Inoltre, la maggior parte dei LED presenta la parte negativa appiattita,
come mostra la figura.
Figura 5-4.
Un LED collegato a un pin PWM
void setup() {
pinMode(LED, OUTPUT); // indica ad Arduino che LED è un output
}
void loop(){
Ora avete replicato una funzionalità dei computer portatili (anche se usare Arduino
per così poco sarebbe un po’ uno spreco). Usiamo questa conoscenza per miglio-
rare la nostra lampada.
Aggiungete il circuito che abbiamo usato per leggere un pulsante (nel Capitolo 4)
a questa breadboard. Provate a farlo senza guardare la prossima pagina, perché
voglio che cominciate a realizzare che ogni circuito elementare che mostro qui è
un “blocco costitutivo” per creare progetti sempre più grandi. Se per procedere
avete bisogno di qualche suggerimento, non importa; la cosa più importante è che
dedichiate un po’ di tempo a pensare come dovrebbe presentarsi.
Se non siete pronti per provarci, non vi preoccupate: limitatevi a collegare entram-
bi i circuiti ad Arduino come mostrano le Figure 4-6 e 5-4. Nel Capitolo 6 vedrete
un esempio dove si usano le piste di terra e di alimentazione della breadboard.
void setup() {
pinMode(LED, OUTPUT); // indica ad Arduino che LED è un output
pinMode(BUTTON, INPUT); // e che BUTTON è un input
}
void loop() {
if (state == 1) {
analogWrite(LED, brightness); // accende il LED
// al livello corrente di luminosità
} else {
analogWrite(LED, 0); // spegne il LED
}
}
Ora provate. Come potete vedere, il nostro modello di interazione sta prenden-
do forma. Se si preme e si rilascia immediatamente il pulsante, si accende o si
spegne la lampada. Se si tiene premuto il pulsante, cambia la luminosità; quando
avete raggiunto la luminosità desiderata, basta rilasciarlo.
Ora nella breadboard, anziché il pulsante, collegate l’LDR. Noterete che, se coprite
l’LDR con le mani, il LED si spegne. Se scoprite l’LDR, la luce si accende. Avete
appena costruito il vostro primo LED gestito da un vero sensore. Questo è impor-
tante perché, per la prima volta in questo libro, stiamo usando un componente che
non è un semplice dispositivo meccanico, ma un sensore vero e proprio.
Nella parte in basso a destra della scheda Arduino, appaiono sei pin contrasse-
gnati “Analog In”; si tratta di pin speciali che possono dirci non solo se su di loro
è applicato un voltaggio, ma, in caso positivo, anche il suo valore. Usando la fun-
zione analogRead(), possiamo leggere il voltaggio applicato a uno dei pin. Questa
funzione restituisce un numero compreso tra 0 e 1023, che rappresenta voltaggi
compresi tra 0 e 5 volt. Per esempio, se sul pin numero 0 è applicato un voltaggio
pari a 2,5 V, analogRead(0) restituisce 512.
Se ora costruite il circuito che vedete nella Figura 5-6, usando una resistenza 10k,
ed eseguite il codice dell’Esempio 06A, vedrete il LED incorporato (ma potete an-
che inserire un vostro LED nei pin 13 e GND come mostrato in “Far lampeggiare
un LED” nel Capitolo 4) lampeggiare a un ritmo condizionato dalla quantità di luce
che colpisce il sensore.
void loop() {
Ora, provate l’Esempio 06B: ma, prima, dovete modificare il vostro circuito. Date
di nuovo un’occhiata alla Figura 5-4 e collegate il LED nel pin 9 come mostrato.
Dato che sulla breadboard ci sono già altre cose, dovete trovare un’area dove il
LED, i cavi e la resistenza non si sovrappongano al circuito dell’LDR.
void setup() {
void loop() {
Se lavorate con un termistore, fate attenzione al fatto che non esiste un collega-
mento diretto tra il valore che si legge e la temperatura vera e propria misurata.
Se vi serve una lettura esatta, dovete leggere i numeri che provengono dal pin
analogico mentre misurate con un termometro vero. Poi potete rappresentare que-
sti numeri in una tabella ed elaborare un criterio per tarare i risultati analogici sulle
temperature del mondo reale.
Finora, come dispositivo di output abbiamo usato solo un LED, ma come facciamo
a vedere i veri valori che Arduino legge dal sensore? Non possiamo fare in modo
che la scheda li comunichi lampeggiando in codice Morse (insomma, potremmo,
ma per gli esseri umani esiste un modo più facile per leggere i valori). Per questo,
dobbiamo fare in modo che Arduino parli con il computer attraverso una porta
seriale, come spiegato nel prossimo paragrafo.
La comunicazione seriale
All’inizio di questo libro avete imparato che Arduino è dotato di un collegamento
USB che viene usato dall’IDE per caricare il codice nel processore. La buona noti-
zia è che questo collegamento può essere usato anche dagli sketch che scriviamo
in Arduino per restituire dei dati al computer o per ricevere dei suoi comandi. A
questo scopo, stiamo per usare un oggetto seriale (un oggetto è una raccolta di
capacità impacchettate insieme per la comodità di chi deve scrivere gli sketch).
Questo oggetto contiene tutto il codice che ci serve per spedire e ricevere dati.
Adesso useremo l’ultimo circuito che abbiamo costruito con la fotoresistenza e in-
vieremo al computer i valori che vi vengono letti. Digitate questo codice in un nuo-
vo sketch (potete anche scaricarlo da www.makezine.com/getstartedarduino):
void setup() {
void loop() {
Dopo aver caricato il codice su Arduino, fate clic sul pulsante “Serial Monitor”
nell’IDE Arduino (il pulsante più a destra della barra strumenti); nella parte in
basso della finestra cominceranno a scorrere dei numeri. Ora, tutti i software
che sono in grado di leggere dati dalla porta seriale possono comunicare con
Arduino. Esistono molti linguaggi di programmazione che permettono di scrive-
re programmi sul computer in grado di dialogare con la porta seriale. Proces-
sing (www.processing.org) è un ottimo complemento per Arduino, perché i
linguaggi e gli IDE sono molto simili.
Nella Figura 5-7, potete vedere come usare un MOSFET come l’IRF520 per
accendere e spegnere un piccolo motore collegato a un ventilatore. Noterete
anche che il motore viene alimentato dal connettore a 9 V sulla scheda Arduino.
Questo è un altro vantaggio offerto dai MOSFET: permettono di gestire dispositivi
la cui alimentazione è diversa da quella usata da Arduino. Dato che il MOSFET è
collegato al pin 9, per controllare la velocità del motore via PWM possiamo anche
usare analogWrite().
Sensori complessi
Definiamo sensori complessi quelli che producono un tipo di dato che richiede
l’uso di qualcosa in più rispetto alle funzioni digitalRead() o analogRead(). Di solito
Figura 5-7.
Il circuito di un motore per Arduino
Output digitale
L’abbiamo usato per controllare un LED ma, con un circuito appropriato, può esse-
re usato per controllare motori, produrre suoni e molto altro ancora.
Output analogico
Ci offre la possibilità di controllare la luminosità del LED, non solo di accenderlo e
spegnerlo. Con questo possiamo addirittura controllare la velocità di un motore.
Input digitale
Questo ci permette di leggere lo stato di sensori semplici, come pulsanti o inter-
ruttori a mercurio.
Input analogico
Possiamo leggere i segnali continui inviati dai sensori che non si limitano a segna-
lare gli stati acceso/spento, come i potenziometri o i sensori di luce.
Comunicazione seriale
Ci permette di comunicare con un computer e scambiare dati o semplicemente
controllare cosa sta succedendo nello sketch che viene eseguito su Arduino.
La lampada, come potete vedere nella Figura 6-1, è una semplice sfera collocata
su una base con un ampio buco che le impedisca di rotolare sul tavolo. Questo
design permette di orientare la lampada in varie direzioni.
Processing
Processing è l’origine di Arduino. Questo linguaggio ci piace moltissimo e
lo usavamo per insegnare la programmazione ai principianti oltre che per
costruire codice bellissimo. Processing e Arduino sono una combinazione
perfetta. Un altro vantaggio è che Processing è open source e gira su tutte le
piattaforme principali (Mac, Linux e Windows). È in grado anche di generare
applicazioni indipendenti per queste stesse piattaforme. Inoltre, la comunità
di Processing è attiva e generosa e permette di trovare molti programmi di
esempio già pronti.
Ecco cosa fa il proxy per noi: scarica il feed RSS da makezine.com ed estrae
tutte le parole dal file XML che ottiene. Quindi, analizzandolo, conta il numero di
volte che nel testo appaiono le parole “peace”, “love” e “Arduino”. Con questi
tre numeri, calcoleremo il valore di un colore e lo invieremo ad Arduino. La sche-
da ci restituirà la quantità di luce misurata dal sensore e la mostrerà sullo scher-
mo del computer.
Dal lato hardware, combineremo l’esempio del pulsante, quello del sensore di
luce, il controllo del LED via PWM (moltiplicato per 3!) e la comunicazione seriale.
Dato che Arduino è un dispositivo semplice, dovremo codificare il colore in un
modo semplice. Useremo il modo standard in cui si rappresentano i colori in
HTML: # seguito da sei cifre esadecimali. I numeri esadecimali sono pratici, per-
ché ciascun numero di 8 bit viene rappresentato esattamente da due caratteri; nel
caso dei numeri decimali, variano da uno a tre caratteri. Prevedibilmente, anche il
codice diventa quindi più semplice: aspettiamo di vedere un #, poi leggiamo i sei
caratteri che seguono in un buffer (una variabile usata come contenitore temporaneo
per questi dati). Infine, convertiamo ciascun gruppo di due caratteri in un byte che
rappresenti la luminosità di uno di tre LED.
import processing.serial.*;
int love = 0;
int peace = 0;
int arduino = 0;
Serial port;
color c;
String cs;
PFont font;
void setup() {
size(640,480);
frameRate(10); // non ci servono aggiornamenti troppo veloci
font = loadFont("HelveticaNeue-Bold-32.vlw");
fill(255);
textFont(font, 32);
// NOTA IMPORTANTE:
// La prima porta seriale ricavata da Serial.list()
// dovrebbe essere quella del vostro Arduino. Se no, togliete
lastTime = 0;
fetchData();
}
void draw() {
background( c );
int n = (interval - ((millis()-lastTime)/1000));
text("love ",10,240);
text(" " + love, 130, 240);
rect(200,212, love, 28);
text("arduino ",10,280);
text(" " + arduino, 130, 280);
rect(200,252, arduino, 28);
if (n <= 0) {
fetchData();
lastTime = millis();
}
// azzeriamo i contatori
love = 0;
peace = 0;
arduino = 0;
try {
URL url = new URL(feed); // un oggetto per rappresentare l'URL
// prepariamo un collegamento
URLConnection conn = url.openConnection();
conn.connect(); // ora ci colleghiamo al sito web
StringTokenizer st =
new StringTokenizer(data,"\"<>,.()[] ");// la suddivide
while (st.hasMoreTokens()) {
// ogni porzione di dati viene scritta tutta in minuscole
chunk= st.nextToken().toLowerCase() ;
Secondo, dovete confermare che lo sketch sta usando la porta seriale corretta per
comunicare con Arduino. E per farlo dovete aspettare di aver assemblato il circuito
di Arduino e caricato lo sketch di Arduino. Nella maggior parte dei sistemi, questo
sketch di Processing non darà problemi. Ma se non vedete succedere niente
su Arduino e sullo schermo non vi appare nessun dato proveniente dal sensore
di luce, cercate il commento dal titolo “NOTA IMPORTANTE” nello sketch di
Processing e seguite le istruzioni che fornisce.
int val = 0; // variabile per conservare il valore che proviene dal sensore
byte r = 0;
byte g = 0;
byte b = 0;
void setup() {
Serial.begin(9600); // apre la porta seriale
pinMode(BUTTON, INPUT);
}
void loop() {
val = analogRead(SENSOR); // legge il valore proveniente dal sensore
Serial.println(val); // stampa il valore sulla
// porta seriale
if (Serial.available() >0) {
}
}
Ricordate che nell’esempio della PWM nel Capitolo 5 abbiamo visto che i LED
sono polarizzati: in questo circuito, il pin lungo (positivo) dovrebbe andare a destra
e quello corto (negativo) a sinistra (la maggior parte dei LED nel lato negativo sono
appiattiti, come si vede nella figura).
Figura 6-2.
Il circuito della “Lampada in rete fatta con Arduino”
Invece di usare tre LED separati, potete usare un unico LED RGB, che presenta
quattro terminali. Dovete collegarlo più o meno allo stesso modo dei LED mostrati
nella Figura 6-2, con una differenza: invece di tre collegamenti separati al pin della
messa a terra di Arduino, avrete un unico terminale (detto “catodo comune”) che
andrà alla terra.
Saldate i cavi più lunghi al LED RGB e incollatelo dove prima c’era la lampadina.
Collegate i cavi che provengono dal LED alla breadboard (dove era collegato prima
della rimozione). Ricordate che se state usando un LED RGB a 4 terminali vi servi-
rà un solo collegamento alla messa a terra.
Come base per la lampada, potete usare un pezzo di legno con un buco o sem-
plicemente ritagliare la parte superiore della scatola di cartone in cui si trovava
la lampada approssimativamente per 5 cm e ritagliarvi un buco con un diametro
adatto ad accogliere la lampada. Rinforzate l’interno della scatola di cartone usan-
do della colla lungo i suoi margini interni, per rendere la base più stabile.
Come esercizio, provate ad aggiungere del codice che faccia accendere la lampa-
da quando la stanza diventa buia. Altri miglioramenti possibili sono:
» Aggiungere dei sensori di inclinazione per fare in modo che la lampada si ac-
cenda o si spenga ruotandola in diverse direzioni.
Dato che tutti i progetti basati su Arduino sono composti sia da hardware che da
software, se qualcosa va storto dovrete cercare in diversi posti. Nel cercare un
bug, dovete seguire tre linee:
Comprensione
Cercate di capire il più possibile come funzionano le parti che state usando e
come dovrebbero contribuire al progetto finale. Questo approccio permetterà di
escogitare un modo per testare separatamente ciascun componente.
Semplificazione e segmentazione
Gli antichi Romani dicevano divide et impera: dividi e comanda. Provate a dividere
(mentalmente) il progetto nei suoi componenti usando quello che avete capito e
scoprite dove comincia e dove finisce la responsabilità di ciascun componente.
Esclusione e certezza
Mentre investigate, testate separatamente ciascun componente in modo da poter
essere assolutamente certi che ciascuno da solo funziona. Gradatamente divente-
rete più sicuri di quali parti del progetto fanno il loro lavoro e quali sono sospette.
Il termine che si usa per descrivere questo processo è debugging, come nel caso
del software. La leggenda dice che lo usò per la prima volta Grace Hopper negli
Molti dei bug di oggi non sono più fisici, ma, almeno in parte, sono virtuali e
invisibili. Quindi richiedono un processo in un certo senso più lungo e noioso per
essere riconosciuti.
Testare la scheda
Cosa si dovrebbe fare se il primo esempio, “Far lampeggiare un LED,” non funzio-
nasse? Non sarebbe un po’ deprimente? Vediamo come intervenire.
» Verificate che il computer sia acceso (sì, può suonare stupido, ma succede).
Se si accende la luce verde con etichetta PWR, significa che il computer sta
alimentando la scheda. Se la luce del LED appare debole, qualcosa non va
nell’alimentazione: provate un altro cavo USB e ispezionate la porta USB del
computer e il connettore USB di Arduino per vedere se c’è qualche guasto.
Se nessuna di queste soluzioni funziona, provate un’altra porta USB sul vostro
computer o un computer completamente diverso.
» Se Arduino è nuovo di zecca, il LED giallo con etichetta L comincerà a lampeg-
giare nervosamente; si tratta del programma di test che è stato caricato dalla
fabbrica per testare la scheda.
NOTA: Quando avete problemi con altri sketch e dovete confermare che
la scheda stia funzionando, aprite il primo esempio, “Far lampeggiare un
LED”, nell’IDE Arduino e caricatelo sulla scheda. Il LED integrato dovrebbe
lampeggiare a ritmo regolare.
Procedere un passo alla volta ed eseguire una sola modifica alla volta è la regola
numero uno per correggere gli errori. Questa regola mi è stata messa in testa dal
mio professore di scuola e primo datore di lavoro Maurizio Pirola. Ogni volta che
sto facendo il debugging di qualcosa e le cose non si mettono bene (e, credetemi,
succede spesso), mi torna in mente la sua faccia mentre dice “una modifica alla
volta . . . una modifica alla volta” e normalmente è in quel momento che riesco
a risolvere tutto. È molto importante, perché così saprete come avete risolto il
problema (perdere le tracce di quale modifica è stata effettivamente risolutiva è fin
troppo facile e per questo è così importante eseguirne una alla volta).
Isolare i problemi
Un’altra regola importante è trovare un modo affidabile di riprodurre un problema.
Se il vostro circuito si comporta in modo strano in momenti disparati, provate a
individuare con precisione il momento esatto in cui si verifica il problema e cosa lo
sta causando. Questo processo vi permetterà di immaginare una causa possibile.
È anche molto utile quando dovete spiegare a qualcuno cosa sta succedendo.
Descrivere il problema nel modo più preciso possibile è un altro buon modo di
trovare una soluzione. Cercate di spiegare il problema a qualcuno: in molti casi,
mentre lo articolate, vi verrà in mente improvvisamente la soluzione. Brian W.
Kernighan e Rob Pike, in The Practice of Programming (Addison-Wesley, 1999),
raccontano di un’università dove “vicino all’help desk tenevano un orsacchiotto di
peluche. Agli studenti che incontravano bug misteriosi veniva chiesto di spiegarli
all’orsetto, prima di rivolgersi a un consulente umano”.
Cercate i dispositivi seriali nell’elenco sotto “Porte (COM e LPT)”. Trovate un dispo-
sitivo seriale che non state usando e che sia numerato COM9 o inferiore. Fatevi clic
Ora fate la stessa cosa con il dispositivo USB Serial Port che rappresenta Arduino,
con una modifica: assegnatevi il numero di porta COM (COM9 o inferiore) che avete
appena liberato.
Per ulteriori indagini, partite dal sito web www.arduino.cc/it e consultate le sue
FAQ (www.arduino.cc/it/Main/FAQ), quindi spostatevi sul playground (www.
arduino.cc/playground), una wiki che gli utenti possono modificare liberamente
per contribuire alla documentazione. Si tratta di una delle parti migliori dell’intera
filosofia dell’open source. La gente fornisce documentazione ed esempi di tutto
ciò che fa con Arduino. Prima di dare inizio a un progetto, cercate nel playground e
troverete una porzione di codice o il diagramma di un circuito da cui cominciare.
Se neanche in questo modo riuscite a trovare una risposta, cercate nel forum
(www.arduino.cc/cgi-bin/yabb2/YaBB.pl). Se non vi trovate niente che vi aiuti,
inviate una domanda. Scegliete l’area corretta in cui rientra il vostro problema:
ne esistono diversi per problemi software o hardware e perfino forum in cinque
lingue diverse. Inviate più dati possibile:
» Scrivere messaggi come “Voglio costruire uno space shuttle usando Arduino:
come faccio?”. Questo significa chiedere agli altri di lavorare al posto vostro e
questo approccio non è divertente per un vero tinkerer. È meglio spiegare cosa
volete costruire e poi formulare domande specifiche su una parte del progetto
e partire da lì.
Dato che i piedini (noti nel gergo tecnico come “pin”) della maggior parte dei com-
ponenti distano tra loro una misura standard, i chip con più piedini vi si adattano
bene. Non tutti i contatti della breadboard nascono uguali: ci sono alcune diffe-
renze. Le righe in alto e in basso (colorate di rosso e blu e contrassegnate con +
e –) sono collegate orizzontalmente e si usano per condurre l’alimentazione nella
scheda in modo che, quando serve l’alimentazione o la terra, la possiate fornire
molto rapidamente con un cavo di connessione (un pezzettino di cavo che collega
due punti di un circuito). L’ultima cosa che dovete sapere delle breadboard è che
nel centro presentano una separazione più larga, di ampiezza pari alla dimensione
di un piccolo chip. Ciascuna linea verticale di buchi è interrotta nel centro, quindi,
quando si inserisce un chip, non si crea un corto circuito tra i pin che si trovano sui
due lati del chip. Astuto, no?
Appendice A 91
Colore Valore
Nero 0
Marrone 1
Rosso 2
Arancione 3
Giallo 4
Verde 5
Blu 6
Viola 7
Grigio 8
Bianco 9
Argento 10%
Oro 5%
Per esempio, una sequenza di strisce marrone, nero, arancione e oro significa
1 0 3 ±5%. Facile, no? Non esattamente, perché c’è una difficoltà: il terzo anello
rappresenta il numero di zeri del valore. Quindi 1 0 3 in realtà significa 1 0 seguito
da 3 zeri e quindi il risultato finale è 10.000 ohm ±5%. I geek dell’elettronica ten-
dono ad abbreviare i valori esprimendoli in kilo ohm (migliaia di ohm) e mega ohm
Appendice B 93
STRUTTURA
Gli sketch di Arduino si dividono in due parti:
void setup()
Qui si inserisce il codice di inizializzazione, le istruzioni che impostano la scheda
prima che cominci il ciclo principale dello sketch.
void loop()
Contiene il codice principale dello sketch. Contiene una serie di istruzioni che si
ripetono continuamente finché la scheda non viene spenta.
SIMBOLI SPECIALI
Arduino comprende diversi simboli che servono a distinguere righe di codice,
commenti e blocchi di codice.
; (punto e virgola)
Ciascuna istruzione (linea di codice) termina con un punto e virgola. Questa
sintassi permette di formattare il codice liberamente. Potete perfino inserire due
istruzioni su una stessa riga, purché le separiate con un punto e virgola (ma questo
renderebbe il codice più difficile da leggere).
Esempio:
delay(100);
{} (parentesi graffe)
Si usano per contrassegnare blocchi di codice. Per esempio, quando scrivete il
codice della funzione loop(), dovete usare le parentesi graffe prima e dopo il codice.
Esempio:
void loop() {
Serial.println("ciao");
}
Appendice C 95
COSTANTI
Arduino comprende una serie di parole chiave predefinite con valori speciali. HIGH
e LOW si usano, per esempio, quando si vuole accendere o spegnere un pin di
Arduino. INPUT e OUTPUT si usano per impostare un determinato pin come
input o output.
true e false indicano esattamente ciò che dicono i loro nomi: il fatto che una con-
dizione o un’espressione sia vera o falsa.
VARIABILI
Le variabili sono aree della memoria di Arduino dotate di nome dove potete
conservare dati da usare e manipolare nel vostro sketch. Come suggerisce il
nome, possono essere cambiate tutte le volte che si vogliono. Dato che Arduino
è un processore molto semplice, quando si dichiara una variabile si deve anche
specificarne il tipo, cioè indicare al processore la dimensione del valore che si
vuole conservare.
boolean
Può avere uno di due valori: true o false.
char
Contiene un solo carattere, come per esempio A. Come tutti i computer, Arduino
lo conserva in forma di numero, anche se quello che vedete è un testo. Quando
queste variabili vengono usate per conservare numeri, possono contenere valori
compresi tra –128 e 127.
byte
Contiene un numero compreso tra 0 e 255. Come nel caso di char, byte usa solo
un byte di memoria.
int
Usa 2 byte di memoria per rappresentare un numero compreso tra –32.768 e
32.767; è il tipo di dato che si usa più spesso in Arduino.
unsigned int
Come int, usa 2 byte ma il prefisso unsigned significa che non può contenere
numeri negativi, quindi il suo intervallo va da 0 a 65.535.
long
La sua dimensione è doppia rispetto a quella di int e contiene numeri compresi tra
–2.147.483.648 e 2.147.483.647.
unsigned long
Versione senza numeri negativi di long; va da 0 a 4.294.967.295.
float
È piuttosto grande e può contenere valori a virgola mobile, un modo originale di
definire i numeri seguiti da valori decimali. Occuperà 4 byte della vostra preziosa
RAM e le funzioni che la possono gestire usano anche loro molta memoria. Quindi
float va usato con parsimonia.
double
Numeri a virgola mobile a doppia precisione, con un valore massimo pari a
1,7976931348623157 x 10 308. Enorme!
string
Una serie di caratteri ASCII che si usano per conservare informazioni testuali
(potete usare una stringa per inviare un messaggio attraverso una porta seriale,
Appendice C 97
array
Un elenco di variabili cui si può accedere attraverso un indice. Si usano per creare
tabelle di valori cui si possa accedere facilmente. Per esempio, se volete conser-
vare diversi livelli di luminosità da usare quando si spegne o accende gradatamen-
te un LED, potete creare sei variabili di nome light01, light02 e così via. Ancora
meglio, potete usare un array semplice come:
int light[6] = {0, 20, 50, 75, 100};
La parola “array” in realtà non si usa esplicitamente nella dichiarazione delle varia-
bili: ci pensano già i simboli [] e {}.
STRUTTURE DI CONTROLLO
Arduino comprende parole chiave che controllano il flusso logico degli sketch.
if . . . else
Questa struttura prende decisioni nel programma. if deve essere seguito da una
domanda specificata in forma di espressione e contenuta tra parentesi. Se l’espres-
sione è vera, viene eseguito ciò che segue. Se è falsa, viene eseguito il blocco di
codice che segue else. È possibile usare solo if senza fornire la clausola else.
Esempio:
if (val == 1) {
digitalWrite(LED,HIGH);
}
for
Permette di ripetere un blocco di codice un numero specifico di volte.
Esempio:
for (int i = 0; i < 10; i++) {
Serial.print("ciao");
}
switch case
L’istruzione if è come un bivio sulla strada del programma. switch case è come
una rotonda, che permette al programma di prendere una varietà di direzioni a se-
while
Simile a if, esegue un blocco di codice mentre è vera una determinata condizione.
Esempio:
// fa lampeggiare il LED finché il sensore è al di sotto di 512
sensorValue = analogRead(1);
while (sensorValue < 512) {
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,HIGH);
delay(100);
sensorValue = analogRead(1);
}
do . . . while
È come while, ma in questo caso il codice viene eseguito subito prima che la con-
dizione venga valutata. Questa struttura si usa quando si vuole che il codice all’in-
terno del blocco venga eseguito almeno una volta prima di verificare la condizione.
Esempio:
do {
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,HIGH);
delay(100);
sensorValue = analogRead(1);
} while (sensorValue < 512);
Appendice C 99
continue
Quando viene usato all’interno di un ciclo, continue permette di saltare il resto del
codice al suo interno e costringe a ricontrollare la condizione.
Esempio:
for (light = 0; light < 255; light++)
{
// salta le intensità comprese tra 140 e 200
if ((x > 140) && (x < 200))
continue;
analogWrite(PWMpin, light);
delay(10);
}
return
Interrompe l’esecuzione di una funzione e ne restituisce il risultato. La si può usare
anche per restituire un valore dall’interno di una funzione. Per esempio, se c’è una
funzione di nome computeTemperature() e volete riportarne il risultato nella parte
di codice che ha invocato la funzione, dovete scrivere qualcosa di simile:
int computeTemperature() {
int temperature = 0;
temperature = (analogRead(0) + 45) / 100;
return temperature;
}
OPERATORI DI CONFRONTO
Quando si specificano le condizioni per le istruzioni if, while e for, si devono usare
questi operatori:
== uguale a
!= diverso da
< minore di
> maggiore di
<= minore di o uguale a
>= maggiore di o uguale a
OPERATORI BOOLEANI
Si usano quando si vogliono combinare diverse condizioni. Per esempio, se volete
controllare se il valore fornito da un sensore è compreso tra 5 e 10, dovete scrivere:
Esistono tre operatori: and, rappresentato da &&; or, rappresentato da ||; e infine
not, rappresentato da !.
OPERATORI Compound
Si tratta di operatori speciali che si usano per rendere più conciso il codice di ope-
razioni molto comuni come incrementare un valore. Per esempio, per incrementa-
re value di 1 potete scrivere:
Appendice C 101
value++;
+= , –=, *= e /=
Permettono di scrivere più brevemente alcune espressioni. Queste due espressio-
ni sono equivalenti:
a = a + 5;
a += 5;
pinMode(pin, mode)
Riconfigura un pin digitale in modo che si comporti come un input o un output.
Esempio:
pinMode(7,INPUT); // converte il pin 7 in un input
digitalWrite(pin, value)
Attiva o disattiva un pin digitale. Perché digitalWrite abbia effetto, i pin devono
essere resi esplicitamente degli output usando pinMode.
Esempio:
digitalWrite(8,HIGH); // attiva il pin digitale 8
int digitalRead(pin)
Legge lo stato di un pin di input, restituisce HIGH se al pin è applicato un voltaggio
o LOW se non ve ne è applicato nessuno.
Esempio:
val = digitalRead(7); // inserisce il valore di pin 7 in val
analogWrite(pin, value)
Cambia la percentuale PWM su uno dei pin contrassegnati PWM. pin può essere
11,10, 9, 6, 5, 3. value può essere un numero compreso tra 0 e 255 che rappresen-
ti la scala tra il voltaggio di output 0 e 5 V.
Esempio:
analogWrite(9,128); // attenua al 50% il LED sul pin 9
FUNZIONI TEMPORALI
Arduino comprende alcune funzioni che servono a misurare il tempo trascorso e
anche per mettere in pausa lo sketch.
Appendice C 103
Esempio:
delay(500); // interrompe il programma per mezzo secondo
delayMicroseconds(us)
Mette in pausa il programma per la quantità specificata di microsecondi.
Esempio:
delayMicroseconds(1000); // aspetta 1 millisecondo
FUNZIONI MATEMATICHE
Arduino comprende molte funzioni matematiche e trigonometriche comuni:
min(x, y)
Restituisce il più piccolo tra x e y.
Esempio:
val = min(10,20); // val ora è 10
max(x, y)
Restituisce il più grande tra x e y.
Esempio:
val = max(10,20); // val ora è 20
abs(x)
Restituisce il valore assoluto di x, che trasforma in positivi i numeri negativi. Se x è
5 restituirà 5, ma se x è –5, restituirà comunque 5.
Esempio:
val = abs(-5); // val ora è 5
constrain(x, a, b)
Restituisce il valore di x, compreso tra a e b. Se x è minore di a, restituirà a e se x
è maggiore di b, restituirà b.
Esempio:
val = constrain(analogRead(0), 0, 255); // rifiuta valori superiori a 255
Esempio:
val = map(analogRead(0),0,1023,100, 200); // mappa il valore di
// analog 0 su un valore
// compreso tra 100 e 200
Esempio:
double x = pow(y, 32); // imposta x al valore y elevato alla 32a potenza
double sqrt(x)
Restituisce la radice quadrata di un numero.
Esempio:
double a = sqrt(1138); // approssimativamente 33,73425674438
double sin(rad)
Restituisce il seno di un angolo specificato in radianti.
Esempio:
double sine = sin(2); // approssimativamente 0,90929737091
double cos(rad)
Restituisce il coseno di un angolo specificato in radianti.
Esempio:
double cosine = cos(2); // approssimativamente -0,41614685058
double tan(rad)
Restituisce la tangente di un angolo specificato in radianti.
Esempio:
double tangent = tan(2); // approssimativamente -2,18503975868
Appendice C 105
randomSeed(seed)
Reimposta il generatore di numeri pseudocasuali di Arduino. Anche se la distribu-
zione dei numeri restituiti da random() è essenzialmente casuale, la sequenza è
prevedibile. Quindi, dovreste reimpostare il generatore su un valore a caso. Se vi
resta un pin analogico scollegato, raccoglierà del disturbo casuale dall’ambiente
circostante (onde radio, raggi cosmici, interferenze elettromagnetiche da telefoni
cellulari e lampade a fluorescenza e così via).
Esempio:
randomSeed(analogRead(5)); // genera un numero a caso usando
// il disturbo che proviene dal pin 5
long random(max)
long random(min, max)
Restituisce un valore intero long pseudocasuale compreso tra min e max – 1.
Se min non viene specificato, il limite minimo è 0.
Esempio:
long randnum = random(0, 100); // un numero compreso tra 0 e 99
long randnum = random(11); // un numero compreso tra 0 e 10
COMUNICAZIONE SERIALE
Come abbiamo visto nel Capitolo 5, possiamo comunicare con dei dispositivi attra-
verso la porta USB usando un protocollo di comunicazione seriale.
Ecco le funzioni seriali.
Serial.begin(speed)
Prepara Arduino a cominciare a spedire e ricevere dati seriali. Generalmente con il
monitor seriale dell’IDE Arduino userete 9600 bit al secondo (bps), ma sono dispo-
nibili anche altre velocità, di solito non superiori a 115.200 bps.
Esempio:
Serial.begin(9600);
Serial.print(data)
Serial.print(data, encoding)
Invia dei dati alla porta seriale. La codifica è facoltativa; se non viene fornita, i dati
vengono trattati come testo semplice.
Serial.println(data)
Serial.println(data, encoding)
Uguale a Serial.print(), ma aggiunge un a capo e un line feed (\r\n) come se si
fossero digitati i dati e poi si fosse premuto Invio.
Esempi:
Serial.println(75); // stampa "75\r\n"
Serial.println(75, DEC); // lo stesso di prima.
Serial.println(75, HEX); // "4B\r\n"
Serial.println(75, OCT); // "113\r\n"
Serial.println(75, BIN); // "1001011\r\n"
Serial.println(75, BYTE); // "K\r\n"
int Serial.available()
Restituisce quanti byte non letti sono disponibili sulla porta seriale da leggere
attraverso la funzione read(). Dopo che si è letto tutto il possibile con read(), Serial.
available() restituisce 0 finché sulla porta seriale non arrivano nuovi dati.
Esempio:
int count = Serial.available();
int Serial.read()
Ricava un byte di dati seriali in arrivo.
Esempio:
int data = Serial.read();
Serial.flush()
Poiché i dati possono arrivare dalla porta seriale più rapidamente di quanto il
programma sia in grado di elaborarli, Arduino conserva in un buffer tutti i dati che
arrivano. Se dovete svuotare il buffer per permettere che venga riempito da dati
nuovi, usate la funzione flush().
Esempio:
Serial.flush();
Appendice C 107
Questioni simili prima o poi emergono in tutte le discipline. Nella musica, dopo che
si è composta una bella canzone, la si deve scrivere usando la notazione musicale.
Gli ingegneri, essendo persone pratiche, hanno sviluppato un modo rapido di cat-
turare l’essenza di un circuito per poterlo documentare e poi ricostruire o passare a
qualcun altro.
In questi simboli si possono incontrare delle variazioni (per esempio, qui sono
mostrate entrambe le varianti del simbolo della resistenza). Per un elenco più va-
sto di simboli elettronici, visitate en.wikipedia.org/wiki/Electronic_symbol. Per
convenzione, gli schemi si disegnano da sinistra a destra. Per esempio, una radio
si disegna partendo con l’antenna a sinistra e poi seguendo il percorso del segnale
radio mentre procede verso l’altoparlante (che si disegna sulla destra).
Questo schema descrive il circuito del pulsante mostrato prima in questo libro:
+5 V
ARDUINO
PIN 7
GND GND
Appendice D 109