ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento –...

49
ARDUINO La Guida Essenziale Leonardo Miliani

Transcript of ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento –...

Page 1: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

ARDUINOLa Guida Essenziale

Leonardo Miliani

Page 2: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Leonardo Miliani, Arduino – La Guida Essenziale 2016 Edizioni del FaroGruppo Editoriale Tangram SrlVia Verdi, 9/A – 38122 Trentowww.edizionidelfaro.it – [email protected]

Prima edizione: aprile 2016 – Printed in EU

ISBN 978-88-6537-483-2

Nonostante la cura posta nel realizzare quest’opera, non è garantito che essa sia priva di errori. L’autore e l’editore declinano, quindi, qualunque responsabilità derivante dall’uso del materiale in essa contenuto.

Le foto delle schede Arduino dei capitoli 1 e 2 appartengono a Arduino S.A. (www.arduinoc.cc) e sono distribuite sotto licenza Creative Commons Attribution ShareAlike 3.0.

Gli schemi di montaggio sono stati realizzati con il software Frizting (fritzing.org).

Page 3: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Questo libro è dedicato alle persone che hanno creato Arduino: grazie alla loro scheda di

prototipazione, come tante altre persone mi sono potuto avvicinare all’elettronica ed alla programmazione dei microcontrollori.

Ringrazio anche tutti coloro che hanno creduto nell’open source mettendo il loro lavoro

a disposizione completa degli altri: questo è il modo migliore

per trasmettere la conoscenza.

!3

Page 4: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Indice

Introduzione 15 1.1 Un po’ di storia 15

1.2 Le vecchie schede 17

1.3 La filosofia “o n” 21

1.4 Arduino o Genuino? 21

L’hardware 22 2.1 La scheda Arduino UNO 22

2.1.1 Avvertenze sull’uso della scheda 25

2.2 Il microcontrollore ATmega328P 26

2.3 Le schede Arduino MEGA2560, 101, DUE, Yún 29

2.4 Gli shield ufficial 33

2.5 Altre schede Arduino 35

Il software 38 3.1 Installazione dell’IDE e dei driver 38

3.1.1 Piattaforma Windows 39

3.1.2 Piattaforma OS X 43

3.1.3 Piattaforma Linux 44

3.2 Primi approcci con l’IDE 46

3.3 Programmiamo l’Arduino 49

Introduzione al linguaggio di Arduino 54 4.1 Che cos’è un linguaggio di programmazione 54

4.2 Il linguaggio C 56

4.3 Il linguaggio di Arduino 57

Basi del linguaggio di Arduino 59 5.1 Struttura di un programma in Arduino 59

5.2 Basi del linguaggio 61

5.3 Variabili 63

5.3.1 Visibilità: variabili locali e globali 65

5.3.2 Variabili di tipo static e auto 67

5.3.3 Variabili di tipo register e volatile 68

5.4 I tipi di dato 69

5.4.1 Costanti e letterali 72

5.4.2 I numeri binari 74 !5

Page 5: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

5.4.3 I numeri ottali e esadecimali 76

5.5 Gli operatori 77

5.5.1 Operatori aritmetici 77

5.5.2 Operatori relazionali 78

5.5.3 Operatori logici e algebra di Boole 79

5.5.4 Operatori di incremento e decremento 82

5.5.5 Operatori per la manipolazione dei bit 84

5.5.6 Operatori di assegnamento 89

5.5.7 Operatori vari 90

5.5.8 Precedenza degli operatori 91

Il controllo del flusso di un programma 93 6.1 I blocchi di codice 93

6.2 Il costrutto if..else 94

6.3 Il costrutto switch..case 96

6.4 I cicli iterativi 97

6.4.1 Il ciclo for 97

6.4.2 Il ciclo while 99

6.4.3 Il ciclo do..while 99

6.4.4 Break e continue 100

6.4.5 I salt i: goto ed etichette 101

Funzioni e vettori 103 7.1 - Definizion di funzione 103

7.1.1 Prototipi di funzione 103

7.1.2 Argomenti in ingresso e dati in uscita 104

7.1.2 Argomenti per valore e per riferimento 106

7.1.4 Argomenti predefini i 107

7.1.5 Funzioni ricor sive 107

7.2 Vettori 108

7.2.1 Vettori multidimensionali 111

I puntatori 113 8.1 I puntatori 113

8.2 Puntatori e vettori 115

8.3 Aritmetica dei puntatori 116

8.4 Puntatori e costanti 118

8.5 Puntatori a funzioni 119

8.6 Puntatori a puntatori e vettori di puntatori 120

!6

Page 6: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Stringhe, strutture di dati e tipi personalizzati 122 9.1 Le stringhe 122

9.2 Le stringhe in stile C 122

9.2.1 Vettori di stringhe 126

9.2.2 Funzioni principali 126

9.3 Le Stringhe in Arduino: la classe String 127

9.3.1 I metodi della classe String 128

9.3.2 Operatori per le stringhe 134

9.4 Strutture di dati 135

9.5 Tipi personalizzati 137

9.6 Enumerazioni 138

9.7 Unioni 139

9.8 Campi di bit 140

Le funzioni di I/O di Arduino 142 10.1 - Input/Out put digitale 142

10.1.1 Avvertenze sull’uso dei pin 146

10.2 Input analogico 146

10.3 I segnali PWM (simulare l’output analogico) 149

10.4 Funzioni t emporali 152

Numeri casuali, bit e byte e funzioni matematiche 157 11.1 - Numeri casuali 157

11.2 Bit e byte 160

11.3 Funzioni ma tematiche 161

La comunicazione seriale 163 12.1 La classe Serial 163

12.1.1 Il metodo write() 166

12.1.2 I metodi print() e println() 166

12.2 Lettura di dati dalla seriale 168

12.3 Convertire i dati letti sulla seriale 169

12.4 Gestione del buffer seriale 170

Le librerie 173 13.1 - Usare una libreria di Arduino 173

13.2 Installazione di una libreria da un archivio 175

13.3 Installazione tramite gestore delle librerie 178

13.4 Le librerie standard 179

Principi di Elettronica, componenti elettronici di base 182 !7

Page 7: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

14.1 Che cos’è l’elettricità 182

14.2 Corrente continua e corrente alternata 183

14.3 La legge di Ohm 185

14.4 Il resistore 187

14.5 Il condensatore 189

14.6 Il diodo 191

14.7 I LED 194

14.8 Il transistor BJT 197

14.9 Il pulsante 202

14.10 La basetta di prototipazione 204

I primi progetti 206 15.1 Progetto 1: Accensione di un LED mediante un pulsante 206

15.2 Progetto 2: Accensione temporizzata di un LED 209

15.3 Progetto 3: Esecuzione di 2 compiti temporizzati 210

15.4 Progetto 4: Scambio di dati sulla seriale 212

Interazione con l’utente 218 16.1 Schermi a cristalli liquidi (LCD) 218

16.2 La libreria LiquidCrystal 221

16.2.1 Gestione dello schermo 221

16.3 Progetto 5: Uso di LiquidCrystal 226

16.4 Tastiere alfanumeriche 229

16.4.1 P rogetto 6: Lettura di una tastiera 230

16.5 Progetto 7: Scrittura e lettura 234

Le porte logiche 239 17.1 Le porte logiche del microcontrollore 239

17.2 Gestione digitale delle porte 239

17.3 Le porte analogiche 242

17.3.1 Il registro ADMUX 244

17.3.2 Il registro ADCSRA 246

17.3.3 I registri ADCSRB e DIDR0 247

17.3.4 I registri ADCL/H 248

17.3.5 Esempi di utilizzo 249

I timer/counter 251 18.1 I t imer/count er 251

18.2 Registri dei timer/count er 253

18.3 Modalit à dei timer/count er 256

!8

Page 8: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

18.3.1 Modalit à Normal 258

18.3.2 Modalit à CTC 258

18.3.3 Modalit à Fast PWM 261

18.3.4 Modalit à Phase Correct PWM 262

18.3.5 Fast PWM con massimo variabile 263

18.3.6 Phase Correct PWM con massimo variabile 264

18.4 Ot tenere una certa frequenza 265

Gli interrupt 269 19.1 Gestione degli interrupt 269

19.2 Int errupt esterni 273

19.2.1 Gestione degli interrupt INT 275

19.2.2 Gli int errupt INT tramite registri 276

19.2.3 Gli int errupt PCINT 278

19.2.4 P rogetto 8: Gestione di più interrupt PCINT 280

Il Watchdog 283 20.1 Il Cane da Guardia 283

20.2 Cara tteristiche del watchdog 283

20.3 Uso del watchdog mediante la libreria “wdt.h” 284

20.4 Uso del watchdog mediante i registri 287

Progetti stand-alone 291 21.1 Arduino stand-alone 291

21.2 Diverse impostazioni per l’ATmega328P 296

Risparmio energetico 299 22.1 Consumi e Risparmio energetico 299

22.2 Il “sonno” dei microcontrollori 300

22.2.1 Le modalità di sleep 302

22.2.2 Il registro SMCR 303

22.2.3 La libreria “sleep.h” 303

22.3 Riduzione del consumo energetico 305

22.3.1 Il registro PRR 305

22.3.2 La libreria “power.h” 306

22.3.3 Come ridurre i consumi 307

22.5 Esempio pratico 309

Il preprocessore 312 23.1 Direttive per il preprocessore 312

23.2 Definizioni macro 312 !9

Page 9: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

23.3 Inclusioni condizionali 315

23.4 Gestione degli errori 318

23.5 Inclusione di fil 318

23.6 Macro predefini e 319

!10

Page 10: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Prefazione

Questa guida nasce come uno strumento utile a tutti coloro che si avvicinano per la prima volta al mondo della prototipazione elettronica. Anni fa, leggendo una rivista vidi un articolo che trattata di Arduino e della sua facilità di programmazione. Da programmatore fui tentato molto da quell’articolo, ed alla fine cedetti ed acquistai la mia prima scheda. Venivo da oltre 20 anni in cui mi ero dilettato, per passione e non per lavoro, con la programmazione spaziando tra un’infinità di linguaggi: dal BASIC dei computer Commodore all’assembly 65xx, dal GW-BASIC dell’era MS-DOS all’assembly x86, dal Turbo Pascal al COBOL, dal Visual Basic di Windows alla sua controparte linuxiana Gambas per finire al linguaggio multipiattaforma LiveCode ma mai avevo avuto a che fare col C, reputandolo un linguaggio “particolare”: all’epoca in cui avevo mosso i miei passi informatici era considerato un linguaggio per “scrivere sistemi operativi”, più che altro. Eppure la sua semplicità ha fatto la sua fortuna dato che nell’era dei sistemi embedded ha conosciuto una seconda giovinezza: per le sue doti di velocità e compattezza il C è la scelta migliore sui piccoli microcontrollori. Forte, quindi, della mia esperienza di programmazione, non ebbi grossi problemi ad apprendere l’ennesimo linguaggio. Ciò di cui ero digiuno era la parte elettronica: in ambito embedded devi conoscere entrambe, la programmazione e l’elettronica, perché una è la mente e l’altra è il braccio. Senza la prima la seconda “non si muove”, ma senza la seconda la prima “parla al vento”. Dovetti quindi procurarmi qualche manuale di elettronica e cominciare a studiarmi almeno le basi di questa materia. Col tempo la conoscenza ma, soprattutto, un po’ di esperienza, mi hanno aiutato a barcamenarmi per realizzare i miei progetti: certo, da autodidatta non si possono raggiungere i livelli di un ingegnere elettronico ma un display LCD con un port expander I2C riesco a collegarlo anch’io alla mia scheda Arduino. E questo è già un bel passo in avanti per me e per il mio ego!

Perché questa guida, quindi? Questa guida l’ho scritta proprio con in mente quelle persone che mancano di una se non di entrambe le cose, le nozioni di informatica e quelle di elettronica. La guida è dedicata ai principianti, a chi “vorrebbe fare” ma non ha abbastanza conoscenze. Non è un manuale che insegna la programmazione a 360° ma si focalizza sul C/C++ in generale e sul linguaggio di Arduino nello specifico. Se cercate di portare le vostre conoscenze informatiche apprese con questo manuale su un computer vi accorgerete che non tutte le cose corrispondono fra il linguaggio che avete studiato qui e quello usato sui computer, nonostante la base sia comune. Inoltre in questa guida ho saltato alcuni concetti del C/C++ che ho ritenuto inutile approfondire: se volete studiare i linguaggi C/C++ in modo completo rivolgetevi ad uno specifico testo. Similmente, questa guida vuole anche fornire quel minimo di conoscenze di elettronica a chi non sa la differenza fra tensione e corrente oppure che non sa l’utilizzo

!1111

Page 11: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

di un condensatore, senza dover andare nello specifico addentrandosi in argomenti che potrebbero risultare complessi da affrontare e trattare senza adeguati studi di base. Un unico libro, quindi, in cui trovare un po’ di tutto ma, soprattutto, trovare cose mirate a ciò che si ha di fronte, la scheda Arduino. Anche chi ha già una conoscenza degli argomenti trattati potrà trarre beneficio dalla lettura di questo manuale, ripassando i concetti del linguaggio e dell’elettronica e di come essi vengano adattati alle schede tipo l’Arduino. Il libro è stato diviso per argomenti. Iniziamo con una parte di storia, che ci aiuta a comprendere cos’è l’Arduino e da dove viene, per poi affrontare anche la conoscenza delle altre schede meno note della grande famiglia Arduino e degli shield, il nome con cui sono indicate le schede accessorie che ne espandono le capacità. Passiamo poi ad affrontare l’ostico tema della programmazione, con gli argomenti che vengono aggiunti uno alla volta, come gli ingredienti in una ricetta. Il passo successivo è fatto tuffandoci più in profondità, per studiare cosa offre l’Arduino per sfruttare la scheda: le librerie di sistema sono molto ricche e permettono di utilizzare quasi a pieno la scheda. Viene poi la volta dell’elettronica, anch’essa affrontata a piccoli passi, partendo dalle nozioni di base come la notissima legge di Ohm, per poi arrivare ad una vista generica sui componenti base dell’elettronica quali resistore, condensatore, diodo e transistor. Infine ci addentriamo un po’ più nello specifico, realizzando alcuni piccoli progetti che ci permettono di sperimentare e di applicare le nozioni apprese in modo più approfondito perché, secondo il mio modesto parere, non c’è modo migliore per imparare qualcosa che facendoci pratica. Si possono leggere tutti i manuali del mondo ma senza la pratica non si impara nulla di concreto. Anche il C è, sotto questo punto di vista, un ottimo linguaggio: poche parole chiave, dal significato chiaro, che però permettono di fare grandi cose se messe insieme nel modo giusto. Alla fine della guida una piccola parte è dedicata ad alcune nozioni avanzate, cose poco usate, argomenti un po' ostici, relegati in un “angolo della soffitta” perché non usate tutti i giorni.

Bene, dopo tutto questo…. tocca a voi! Armatevi quindi di pazienza ed iniziate la lettura, addentrandovi nell’affascinante mondo della prototipazione per realizzare in autonomia piccoli progetti di elettronica da installare in casa ed esibire agli amici curiosi quando ricevete delle visite ;-)

Buona lettura.

Leonardo Miliani

!1212

Page 12: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Convenzioni adottate

In questa guida abbiamo utilizzato alcune convenzioni per la scrittura del testo.

Le parole in lingua straniera o di una certa rilevanza ed i nomi di variabili li abbiamo scritti in corsivo.

Le parole importanti le abbiamo evidenziate in grassetto la prima volta che le abbiamo incontrate.

Le parole chiave del linguaggio le abbiamo scritte utilizzando un carattere a larghezza fissa.

Nel caso di un blocco di codice, lo abbiamo evidenziato utilizzando un carattere diverso ed uno sfondo colorato

Informazioni aggiuntive sono evidenziate con un apposito riquadro a lato di un’icona riportante la lettera “i”:

Prova di box informativo

Avvisi di una certa rilevanza sono invece evidenziati da uno sfondo di un colore più marcato e dal segnale di attenzione:

Attenzione Questo è un messaggio importante

!1313

Page 13: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Sezione 1

Arduino: La Storia,

L’Hardware

!14

Page 14: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 1

Introduzione

1.1 Un po’ di storia

Arduino nasce come un sistema per facilitare lo sviluppo di prototipi di circuiti elettronici. È stato sviluppato inizialmente da Massimo Banzi, David Cuar tiel les , Nicholas Zambetti e David Mellis. I primi esemplari furono realizzati nel 2005 resso l’Interaction Design Institute Ivrea (IDII), un istituto post- laurea aperto da Olivetti e Telecom Italia nella città di Ivrea dove veniva insegnato interaction design, una disciplina che studia l’interazione fra l’essere umano ed i dispositivi meccanici ed informatici (l’istituto è rimasto aperto poco più di 2 anni).

Tra i docenti che tenevano lezione presso l’istituto vi era Massimo Banzi, che insegnava physical computing: per facilitare gli studenti nella realizzazione dei loro progetti venivano usate schede di prototipazione normalmente reperibili in commercio quali la BasiX BX24 e le Basic Stamp di Parallax. Ma Massimo Banzi non era soddisfatto di questi prodotti, sia per la scarsa interattività degli stessi sia perché l’ambiente di sviluppo era disponibile solo per il sistema operativo Windows mentre all’istituto utilizzavano prevalentemente sistemi Mac. Egli iniziò quindi a studiare i PICmicro, programmabili con il BASIC, ed a fare esperimenti con JAL, un linguaggio simile al Pascal. Alla fin decise di progettare una propria piattaforma di prototipazione, e fu così che realizzò nel 2003 la Programma 2003 (il nome riprende la prima calcolatrice programmabile di Olivetti, la Programma 101, realizzata a metà anni Sessanta), la prima scheda realizzata presso l’IDII, pensata per essere economica, facile da usare e completamente open source.1 Come base per l’editor di codice fu scelto il JEdit , che era basato sul Java ed era quindi multi-piattaforma: da esso Massimo Banzi sviluppò l’editor per la Programma 2003, che fu poi integrato in

!15

Figura 1: uno dei primi esemplari di Arduino USB, la Extreme: in alto a sinistra sono indicati i nomi dei membri di allora del gruppo di sviluppo.

15

Page 15: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

un sistema di compilazione dei programmi e programmazione della scheda realizzato da Nicholas Zambetti e David Mellis, all’epoca studenti dell’istituto,2

derivandolo da Processing, un linguaggio ed un ambiente di sviluppo progettato nel 2001 da Casey Reas e Benjamin Fry, due studenti del MIT Media Lab (un laboratorio della scuola di architettura e progettazione del Massachusetts Institute of Technology) che in quel periodo frequentavano i corsi dell’istituto.

Osservando i progetti che gli studenti avevano realizzato con la sua scheda, Massimo Banzi stabilì i punti da rivedere per migliorare il progetto della Programma 2003. Massimo Banzi e Casey Reas lanciarono quindi un progetto di tesi per la nuova piattaforma, progetto raccolto da Hernando Barragán, il quale iniziò lo sviluppo del prototipo della nuova scheda. Fu deciso di abbandonare i PICmicro in favore dei microcontrollori Atmel, scelti su consiglio di uno dei professori di Massimo Banzi che ne faceva già uso presso l’università di Stanford dove insegnava. L’ambiente di sviluppo ed il linguaggio di programmazione furono derivati da Processing, in modo da avere una piattaforma di sviluppo compatibile con più sistemi operativi. La revisione del progetto portò alla Programma 2005, una scheda però ancora rudimentale. Mentre Barragán continuava lo sviluppo in proprio della sua scheda che aveva denominato Wiring e che era basata su un ATmega1280, Massimo Banzi procedeva parallelamente con la realizzazione di un progetto derivato, basato su un ATmega8. Inizialmente denominato Wiring Lite, ben presto divenne Arduino.

Arduino fu realizzato in qualche centinaio di esemplari ed utilizzato dagli studenti per numerosi progetti. Verso la fin dello sviluppo del progetto arrivò presso l’istituto il dottor David Cuartielles, un ingegnere dell’università svedese di Malmo, per studiare la scheda Wiring. Con Cuart ielles, Massimo Banzi sviluppò gli shield, ossia schede accessorie da applicare sulla scheda principale per espanderne le funzionalit à, che furono poi portati anche sull’Arduino. Fu poi scelta la forma e la struttura della scheda, che conserva tuttora, ed il colore blu del circuito stampato, per contraddistinguere Arduino dalle altre schede in commercio. L’ambiente di sviluppo fu poi reimplementato per renderlo completamente open source, sviluppando gli strumenti e mantenendo solo le API originali per compatibilità con i progetti già realizzati. Al gruppo di sviluppo si unirono anche Tom Igoe, che, grazie alle sue esperienze nell’insegnamento della programmazione, realizzò guide ed esempi facilmente comprensibili, e Gianluca Martino, che ottimizzò gli schemi elettrici dell’Arduino seguendone anche la fase realizzativa. Nicholas Zambetti lasciò successivamente il gruppo di sviluppo.

!1616

Page 16: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 2

L’hardware

2.1 La scheda Arduino UNO

La scheda Arduino entry-level, dedicata cioè a chi si avvicina per la prima volta al mondo della prototipazione elettronica mediante microcontrollori, è la UNO. Essa sarà la scheda di riferimento in questa guida: le informazioni date varranno per questo modello, adattamenti ad altre schede potrebbero non essere sempre possibili.

La UNO è stata introdotta nel 2010 come evoluzione della precedente Duemilanove. Rispetto a quest’ultima si differenzia principalmente per l’utilizzo di un differente chip per la comunicazione con il computer a cui viene connessa la scheda: al posto del convertitore USB/se rial FT232RL di FTDI viene ora utilizzato un chip Atmel Atmega16U2 (a seconda della versione della scheda) appositamente programmato. Di questa scheda ne sono stati prodotti, al momento della stesura di questa guida, 3 versioni:

• la prima, indicata semplicemente con UNO, è il modello originale;• la seconda, indicata come UNO R2, è un’evoluzione che si differenzia

dalla precedente principalmente per l’adozione del chip ATmega16U2 alposto dell’ATmega8U2 (collocato anche in posizione ruotata di 45°);

• l’ultima è indicata come UNO R3, e mostra il riposizionamento delconvertitore nella dislocazione originale nonché l’adozione di alcuni pinaddizionali e l’uso di un diverso circuito di reset.

I componenti principali dell’Arduino UNO sono indicati in figura 5. Analizziamo in dettaglio la scheda ed i suoi componenti principali:

Porta USBLa porta USB serve a collegare la scheda ad un computer. Questa porta è utilizzata sia per la trasmissione dei dati da e verso la scheda sia per alimentare la scheda: è possibile infatti utilizzare un alimentatore a 5 V con uscita USB per fornire la necessaria corrente alla UNO.

!2222

Page 17: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Jack alimentazione esternaMediante questo jack (di tipo Japan con positivo centrale e diametro 2,5/5,5 mm rispettivamente per il polo centrale ed il diametro esterno) è possibile fornire l’alimentazione alla scheda. Per evitare problemi di stabilità e surriscaldamento è consigliabile utilizzare una tensione compresa fra 7 e 12 Volt.

Circuito regolatore di tensioneLa scheda integra un circuito di regolazione della corrente e di selezione della fonte di alimentazione nel caso siano presenti contemporaneamente tensioni su entrambi i connettori USB e jack: in questo caso il circuito seleziona come fonte primaria la tensione proveniente dal jack esterno. La tensione che va fornita al jack dovrebbe essere compresa fra 7 e 12. Questi valori sono quelli consigliati affin hé il regolatore integrato possa funzionare correttamente ed in sicurezza: valori inferiori a 7 V non garant iscono in uscita la tensione operativa di 5 V per cui è stata progettata la scheda mentre valori superiori a 12 V possono portare al surriscaldamento dello stesso regolatore.

!23

Figura 5: i componenti principali dell’Arduino UNO

23

Page 18: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Convertitore USB/serialeIl convertitore USB/se riale è un piccolo microcontrollore Atmel che permette la comunicazione fra il computer a cui è connessa la scheda Arduino ed il microcontrollore Atmega328P. Il convertitore cambia a seconda della versione della scheda UNO ut ilizzata: sulla UNO R1 e in parte della seconda versione, la UNO R2, è stato utilizzato un Atmega8U2, mentre sulle UNO R2 più recenti e sulle UNO R3 è stato montato un Atmega16U2. Questo chip si occupa non solo di trasmettere i dati di transito dal canale USB (lato computer) al canale seriale (lato Atmega328P ) e viceversa ma anche di permettere l’invio di un nuovo sketch (così si chiama il programma dell’utente) dal computer al cuore della scheda (vedi sotto).

Microcontrollore Atmega328PIl microcontrollore Atmega328P è il vero cuore della scheda. Un microcontrollore è in parole povere un computer in miniatura: esso infatti integra la memoria su cui è salvato il programma, l’unità di esecuzione capace di eseguirlo (detta CPU) e tutte le periferiche con le quali esso può comunicare con il mondo esterno (vedi il cap. 2.1.1). Nonostante il chip possa funzionare con clock fino a 20 MHz, esso è impostato per motivi storici per lavorare a 16 MHz: questo è infatti il valore della frequenza massima supportata dai microcontrollori Atmel realizzati a quel tempo ed utilizzati sulle prime schede Arduino. Solo in tempi più recenti Atmel ha aggiornato i suoi processori elevando il clock massimo da 16 a 20 MHz ma, per compatibilità con il software già scritto, si è scelto di mantenere la frequenza operativa dei vecchi chip.

Pin digitaliL’Arduino UNO dispone di 14 pin di input/out put (I/O) di tipo digitale: ciò vuol dire che a questi pin possono essere collegati in ingresso dei sensori oppure in uscita dei dispositivi che funzionano con la logica digitale. La logica digitale con valori TTL considera come valore “0” uno stato elettrico pari (o prossimo) a 0 V e come valore “1” uno stato elettrico pari (o prossimo) a 5 V. Valori di tensione intermedi non dovrebbero essere utilizzati con questi pin perché potrebbero essere interpretati in maniera casuale (1 oppure 0). Da notare la differente spaziatura fra i connettori della parte superiore e quelli della parte inferiore: essa è nata come un errore di progettazione che poi è stato lasciato perché impedisce agli utenti inesperti di montare sulla scheda gli shield invertendone il verso.

Pin analogiciL’Arduino UNO dispone di 6 linee di input analogico: ciò significa che a questi pin possono essere collegati dei segnali elettrici di tipo analogico, con tensione

!2424

Page 19: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Sezione 2

Arduino: Il Software

!37

Page 20: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 3

Il software

3.1 Installazione dell’IDE e dei driver

L’IDE (Integrated Development Environment, o Ambiente di Sviluppo Integrato) fornito, liberamente scaricabile dal sito di Arduino (www.arduino.cc) è derivato da quello di Processing, di cui riprende l’impostazione base. Essendo basato su Java, è un ambiente che può girare su più sistemi differenti: è infatti offerto già compilato per Microsoft Windows, Apple Mac OS X e Linux. Sono disponibili anche i sorgenti, per chi vuole compilarselo in proprio o per chi vuole espanderlo aggiungendo nuove funzionalit à. Al momento in cui scriviamo (gennaio 2016) l’IDE è disponibile in due versioni: la 1.0.6 e la 1.6.7. La prima è la versione sviluppata fino al 2015, che non supporta alcune delle schede più recenti mentre la seconda supporta tutti i modelli Arduino. A causa del fatto che il ramo 1.0 dell’IDE è in circolazione da più tempo, è la versione per la quale sono state scritte la maggior parte delle librerie di terzi. È la versione che è preferibile utilizzare, essendo quella più collaudata. Il ramo 1.6 è stato inizialmente rilasciato per supportare specific tamente la scheda Arduino DUE, dato che il suo microcontrollore è un chip con un core ARM per cui necessita di un compilatore differente rispetto a quello utilizzato per compilare il codice scritto per i chip Atmega utilizzati sulle altre schede. In seguito è stato aggiunto il supporto alla Yún, alla Zero ed alla 101. È da poco uscita dalla beta e, rispetto al ramo 1.0, sono stati pesantemente cambiati il formato delle librerie e la versione degli strumenti di compilazione: questo significa che software scritto per l’IDE 1.0 non è detto che funzioni anche con l’IDE 1.6. La scelta dell’IDE è personale: per i nostri scopi abbiamo deciso di adottare la 1.6.7 ma quanto detto dovrebbe valere senza signific tive modifi he nel processo di installazione, scrittura dei programmi e caricamento sulle schede anche per la versione 1.0.6. Scelta la versione, per prima cosa procuriamoci l’IDE per il nostro sistema operativo. Colleghiamoci al sito www.arduino.cc e, dal menu a barra, selezioniamo la pagina “Download”. Qui, scorrendo, arriviamo ai link. Preleviamo la versione che fa al caso nostro:

•Piattaforma Windows:•con installer automatico oppure come singolo ZIP;

!3838

Page 21: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

•Piattaforma OS X: •app compressa

•Piattaforma Linux: •binari per sistemi a 32 o 64 bit

3.1.1 Piattaforma Windows

Il software è fornito sia con un installer che provvede in automatico a copiare tutti i fil dell’ambiente di sviluppo ed a creare i collegamenti necessari affin hé l’utente trovi l’IDE nel menu dei programmi sia tramite un archivio da decomprimere. Il sistema dell’installer è più semplice ma l’archivio compresso è da preferire se non si vogliono lasciare fil di configurazion nel sistema: per rimuovere o aggiornare l’IDE basta eliminare la cartella dove risiede, cancellando tutto con una semplice operazione. L’archivio ZIP è anche l’unica strada se non si hanno i permessi di amministratore necessari per poter installare software sulla propria postazione lavorativa. Se si opta per l’installer, dopo il download fate un doppio click sull’icona per avviare il software di installazione. Sarà richiesto se vogliamo autorizzare il programma ad apportare modifi he al sistema: diamo conferma.

L’IDE è distribuita con licenza GNU LGPL (Lesser General Public License), per utilizzar lo dobbiamo accettarla.

!3939

Page 22: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 4

Introduzione al linguaggio di Arduino

4.1 Che cos’è un linguaggio di programmazione

Tutti i giorni abbiamo a che fare con il concetto di linguaggio: quando esprimiamo un concetto, quando parliamo con gli altri, quando scriviamo, quando leggiamo, quando pensiamo. Il linguaggio è quindi la capacità che abbiamo di comunicare per mezzo di una lingua: utilizziamo un lessico, ossia un insieme di parole, con una sintassi, ossia delle regole per mettere insieme queste parole, e una semantica, ossia attribuiamo un signific to a queste parole. Grazie a ciò possiamo comporre delle frasi per chiedere a qualcuno che ore sono e capire la risposta che ci viene fornita, possiamo ordinare di fare un’azione e vedere che il nostro interlocutore ha capito cosa gli stiamo chiedendo dal fatto che stia o meno compiendo ciò che gli è stato detto. Per noi il linguaggio è una cosa semplice: parliamo con la bocca ed ascoltiamo con le orecchie, esprimiamo la nostra volontà e ascoltiamo le idee degli altri.

Ma con un computer o, nel nostro caso, con un microcontrollore, come possiamo interagire? Dobbiamo utilizzare un mezzo di comunicazione capibile da entrambi: dobbiamo usare un linguaggio di programmazione. Un linguaggio di programmazione è un linguaggio destinato a permetterci di interagire con un dispositivo informatico: come un linguaggio umano, un linguaggio di programmazione è composto da un lessico, ossia di un insieme di istruzioni, usa una sintassi, ossia delle regole per usare queste istruzioni, ed è basato su di una semantica, ossia assegna un preciso signific to d ogni istruzione. Ciò che si occupa dell’interpretazione e dell’esecuzione di queste istruzioni è la CPU, acronimo inglese che sta per Central Processing Unit, detta in italiano anche Unità di Elaborazione Centrale. La CPU è un circuito integrato composto da diversi moduli: • fetch: è il modulo che si occupa di recuperare l’istruzione dalla memoria (ed

eventualmente i dati che servono ad eseguirla);• decode: questo modulo si occupa di decodifica e l’istruzione stessa, usando il

“vocabolario”, il lessico di comandi che essa è in grado di capire, che è

!5454

Page 23: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

memorizza to sotto forma di numeri detti codici macchina o opcode (da “operation code”, “codice operativo”); ogni opcode rappresenta un’azione che la CPU può compiere: ad esempio, un “salto” del programma, il caricamento di un determinato valore in un registro, un’addizione, una sottrazione, un confronto fra due valori ecc…

• execute: questo è il modulo che si occupa materialmente di eseguire l’istruzione.

Scrivere un programma, ossia un insieme di istruzioni per far eseguire alla CPU un determinato compito, utilizzando gli opcode è un lavoro estenuante e incline agli errori: considerate però che agli inizi dell’era informatica i computer venivano programmati proprio scrivendo programmi in codice macchina, detto anche “linguaggio macchina” anche se in realtà non si tratta di un “linguaggio” nel vero senso del termine dato che non abbiamo un insieme di parole (lessico) ma una serie di codici numeri. Il programmatore, colui che scrive un programma informatico, era perciò costretto a scrivere pagine di numeri per creare il programma che voleva realizzare. Per facilitare il compito fu creato l’assembly: l’assembly era una rappresentazione del codice macchina fatta con codici testuali facilmente memorizzabili (detti “mnemonici”): l’opcode per il salto diveniva quindi “JMP” (da “jump”, che in inglese vuol dire appunto salto), l’opcode dell’addizione veniva sostituito da “ADD”, per quello della sottrazione si usava “SUB” e così via. La programmazione divenne sì più semplice ma il programmatore era comunque sempre legato al fatto che l’unica istruzione condizionale era il salto: questo rendeva difficil seguire la logica del programma per via del fatto che l’esecuzione passava da un punto all’altro del codice.

Questo modo di scrivere i programmi è detto “spaghetti code”, perché il flusso di istruzioni si intreccia, come gli spaghetti in un piatto di pasta.

Per risolvere il problema del rendere il codice facile da scrivere e da leggere, furono introdotti i linguaggi di programmazione ad alto livello, che si differenziavano da quelli a basso livello come l’assembly e quelli a bassissimo livello come il codice macchina per il fatto che erano più vicini, più “simili”, al linguaggio umano. Uno dei primi linguaggi di programmazione ad alto livello sviluppati fu il FORTRAN, nato alla fin degli anni Cinquanta del ventesimo secolo, e seguito da altri “pezzi storici” contemporanei quali l’ALGOL, il LISP ed il COBOL. A metà degli anni Sessanta nacque un linguaggio che, nel giro di poco tempo, si affermò come il più diffuso linguaggio di programmazione, restando in auge per diverse decadi, il BASIC. Istruzioni come “PRINT”, per

!5555

Page 24: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

visualizzare sullo schermo un risultato o un messaggio all’utente, “INPUT”, per leggere ciò che l’utente digitava sulla tastiera, “FOR..NEXT” per eseguire cicli, “GOTO” per eseguire dei salti, “DIM” per dichiarare una variabile divennero termini noti a tutti: i computer ad 8 bit degli anni Ottanta, come il Commodore 64, lo ZX Spectrum, i computer MSX ed altri ancora contribuirono all’affermazione di questo linguaggio dato che esso era preinstallato nelle memorie di quasi ogni macchina venduta a quel tempo.

4.2 Il linguaggio C

Ma è un altro il linguaggio quello che ci interessa: il C. Nato per opera di Dennis Ritchie e Ken Thompson alla fin degli anni Sessanta come linguaggio di programmazione per il da poco creato sistema operativo UNIX, si impose in breve tempo per la sua semplicità e per la compattezza, l’effici nza e la velocità del codice compilato. Grazie a questi fattori fu deciso di riscrivere il kernel di UNIX in C: rispetto alla precedente versione in assembly, il C permetteva di avere un unico sorgente indipendente dall’hardware sottostante, facilitando la distribuzione del software: prima ogni macchina basata su UNIX doveva avere la propria versione del kernel perché l’assembly è intimamente legato ad una particolare CPU ed il codice scritto per un tipo di processore non gira su un altro modello perché gli opcode sono differenti. In poco tempo il C rafforzò la sua fama di linguaggio di rilievo per la scrittura dei sistemi operativi. Il C univa i vantaggi di un linguaggio a basso livello a quelli di un linguaggio ad alto livello: come un linguaggio ad alto livello, permetteva di scrivere codice usando un linguaggio facile da ricordare, semplice, con poche istruzioni native ma che permetteva all’utente di crearsi istruzioni personalizzate anche complesse; come un linguaggio a basso livello permetteva di dialogare facilmente con l’hardware di una macchina, ed il suo compilatore generava un eseguibile molto compatto e dotato di una elevata velocità di esecuzione, quasi pari a quelli di un programma scrit to direttamente in codice macchina.

Agli inizi degli anni Ottanta nacque il successore del C, il C++, ad opera di Bjarne Stroustrup. Nato come “C con le Classi” e poi ridenominato C+ + , per richiamare l’operatore di incremento “+ + ” del linguaggio C, esso introduceva il supporto alla programmazione orientata agli oggetti, un nuovo modo di programmare basato sul fatto di utilizzare “oggetti” software, ossia porzioni delimitate del codice chiamate classi che racchiudono sia le dichiarazioni dei dati usati sia i metodi, ossia le funzioni che la classe stessa è in grado svolgere. L’ereditarietà permette, una volta creata una classe principale, di creare delle classi fi lie di quella classe genitore, da cui ereditano i tipi di dati ed i metodi su

!5656

Page 25: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 11

Numeri casuali, bit e byte e funzioni matematiche

11.1 - Numeri casuali

L’Arduino può generare dei numeri pseudo-casuali. Sono detti “pseudo-causali” perché non provengono da un vero generatore casuale ma sono creati da un algoritmo matematico e non hanno quindi una vera casualità. Per ottenere un numero casuale si usa la funzione random(). La sintassi è la seguente: long numero = random([min, ] [ max]);

La funzione restituisce un numero intero di tipo long (quindi con segno). min e max sono opzionali, possono essere passati entrambi oppure solo il secondo: • random()

restituisce un numero intero casuale compreso fra 0 e 231- 1 (2.147.483.647); • random(max)

restituisce un numero intero casuale compreso fra 0 e max-1; • random(min, max)

restituisce un numero intero casuale compreso fra min e max-1.

Vediamo alcuni esempi: random(); //forma base random(100); //numeri compresi fra 0 e 99 (100-1) random(-1000, 1000); //numeri compresi fra -1000 e 999 (1000-1)

Se volessimo “tirare” un dado dovremmo scrivere: byte dado = random(1, 7);

Abbiamo scelto una variabile di tipo byte per contenere il numero casuale perché un dado può dare solo valori compresi fra 1 e 6: il compilatore esegue qui l’autocasting convertendo il tipo del risultato da long a byte. La funzione random viene chiamata passando come argomenti i numeri 1 e 7 che rappresentano gli estremi min e max.

!157157

Page 26: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Il numero restituito cade nell’intervallo compreso fra il valore minimo passato per min, che è compreso fra i numeri che vengono generati, ed il valore fornito per max, che non è invece compreso perché il numero più grande estraibile è sempre inferiore di 1 unità rispetto al valore massimo passato.

Stampiamo sul monitor seriale i valori di 10 “lanci” di un ipotetico dado usando questo sketch: void setup() { Serial.begin(19200); delay(1000); for (byte i = 0; i < 10; i++) { Serial.println(random(1, 7)); }

}

void loop() { }

L’output che otteniamo è il seguente: 2 2 6 3 5 3 1 3 6 2

Adesso premiamo il pulsante di reset sulla scheda e guardiamo la nuova sequenza di “lanci”: 2 2 6 3 5 3 1 3 6 2

Essa è perfettamente identica alla precedente perché il generato di numeri casuali è in realtà un generatore di numeri pseudo-casuali! Essendo forniti da un algoritmo, ogni volta che avviamo la scheda l’algoritmo genere i medesimi valori. Esiste un modo per rendere più casuale la sequenza: fornendo un seme. Viene chiamato seme il valore che viene utilizzato per inizializzar e un algoritmo crittografico. La funzione per inizializzar e l’algoritmo di numeri pseudo-casuali dell’Arduino è randomSeed():randomSeed(seme);

!158158

Page 27: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

seme è un numero intero di tipo unsigned int. Attenzione: se utilizzate un seme costante, la sequenza rimarrà anche in questo caso sempre uguale ad ogni riavvio della scheda. Ad esempio, se riprendiamo l’esempio precedente e lo modifi hiamo così: void setup() { Serial.begin(19200); delay(1000); randomSeed(999); for (byte i = 0; i < 10; i++) { Serial.println(random(1, 7)); } }

void loop() { }

Ogni volta che avvieremo la scheda otterremo sempre questi numeri: 4 5 6 5 3 5 3 1 4 1

I numeri cambiano rispetto al precedente esempio in cui generavamo numeri casuali senza l’uso di un seme ma si ripetono comunque. Come fare quindi per ottenere un seme variabile e poter avere delle sequenze sempre diverse ad ogni avvio della scheda? Possiamo utilizzare come sorgente un pin analogico non connesso a niente. Abbiamo visto in precedenza che un pin non connesso porta ad una lettura fluttuante. Se in un pin digitale la cosa si limita a due valori, un pin analogico flo tante può dare invece molti più valori. Sfruttando questa caratteristica, possiamo utilizzare la lettura di un pin analogico lasciato libero come seme per l’algoritmo pseudo-causale dell’Arduino. Se proviamo il seguente codice possiamo vedere come ad ogni sequenza di “lanci” i valori siano sempre diversi: void setup() { Serial.begin(19200);   delay(1000);   randomSeed(analogRead(A0));    for (byte i = 0; i < 10; i++) {      Serial.println(random(1, 7));    } }

void loop() { }

!159159

Page 28: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Sezione 3

L’elettronica E La Sperimentazione

!181

Page 29: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 14

Principi di Elettronica, componenti elettronici di

base

14.1 Che cos’è l’elettricità

L’Arduino non è solo programmazione. Essendo una scheda di prototipazione elettronica, essa può interagire con dispositivi elettrici ed elettronici. Conoscere le basi dell’elettronica è fondamentale per poter sfruttare al massimo le capacità offerte ed interagire con il mondo esterno. Gli appunti che leggerete qui non vogliono in alcun modo sostituirsi ai testi specifici sull’argomento né pretendere di poter offrire le nozioni che si possono apprendere nei corsi di studi appositi ma rappresentare solo un’infarina tura sui concetti base e sui componenti passivi elementari che andremo ad utilizzare nei capitoli successivi per eseguire alcuni esercizi pratici.

Il termine elettricità indica tutti quei fenomeni fisici che si manifestano grazie alla forza elettromagnetica. Un fulmine è l’esempio più evidente di una manifestazione dell’elettricità: una scarica elettrica che percorre il cielo dalle nuvole di un temporale a terra. La scarica visibile ad occhio nudo è solo il fenomeno macroscopico: a livello microscopico la scarica è data dall’interazione di alcune particelle cariche elettricamente che compongono gli atomi della materia, gli elettroni. Gli elettroni orbitano intorno al nucleo di un atomo e sono in numero pari a quello dei protoni contenuti nel nucleo stesso: i protoni sono particelle elettriche dotate di una carica arbitrariamente detta positiva. Gli elettroni sono di carica opposta, arbitrariamente detta carica negativa. La somma delle cariche positive e negative in un atomo è pari a zero: difatti un atomo è elettricamente neutro. Gli elettroni ruotano disponendosi su più livelli detti orbitali. Gli elettroni sull’orbitale più esterno possono essere influ nzati da forze esterne e spostarsi da quegli orbitali, come ad esempio per la vicinanza di un altro atomo: è il caso delle molecole, in cui due o più atomi si legano elettricamente insieme condividendo gli elettroni degli orbitali esterni. Un orbitale può contenere un certo numero di elettroni: il primo orbitale ne può

!182182

Page 30: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

contenere 2, il secondo 8 e così via. Gli atomi sono classific ti secondo il numero di elettroni sull’orbitale più esterno, secondo la nota tavola periodica degli elementi sviluppata da Mendeleev nell’800. In tale tavola gli elementi sono disposti in 8 classi, ognuna indicante il numero di elettroni dell’ultimo orbitale: 1, 2, 3, ecc.. Un atomo tende a perdere o guadagnare elettroni per avere l’orbitale più esterno sempre completo, con 8 elettroni. Se l’atomo ha meno di 4 elettroni sull’orbitale esterno esso tenderà a perdere facilmente quegli elettroni per mostrare l’orbitale inferiore, che è completo. Se invece ha più di 4 elettroni, esso tenderà ad acquistarli per completare l’orbitale. Questa capacità di cedere o acquistare elettroni è detta elettronegatività ed è indicata da un numero:più il numero è prossimo allo zero e più l’atomo tende a perdere elettroni, più ilnumero è grande e più l’atomo tende ad acquistare elettroni. Lo spostamento dielettroni crea degli atomi con una carica elettrica, detti ioni: se l’atomo haperso degli elettroni, esso acquisterà una carica positiva perché i protoni delnucleo saranno in numero maggiore rispetto agli elettroni con carica negativarimasti, mentre se l’atomo ha acquistato degli elettroni mostrerà una caricanegativa perché gli elettroni saranno in numero maggiore rispetto ai protoni delnucleo. Il movimento degli elettroni crea un flusso di cariche elettriche, ed èquesto flusso il esponsabile dei fenomeni elettrici.

14.2 Corrente continua e corrente alternata

Finora abbiamo parlato di corrente in senso generico. Esistono però due tipi di corrente dalle caratteristiche differenti: la corrente continua e la corrente alternata.

La corrente continua è una corrente che manifesta un flusso di intensità e direzione costanti nel tempo. La corrente continua è quella erogata da una normale batteria alcalina, ad esempio le batterie stilo da 1,5 V. Se colleghiamo ai poli di una di queste batterie una lampadina ad incandescenza di pari tensione di lavoro, vedremo che essa si accende. La lampadina emetterà una luce costante perché l’intensità della corrente continua resta costante, così come la direzione in cui scorre la corrente: la corrente continua scorre sempre dal polo positivo al polo negativo. La corrente continua è abbreviata in CC, da “Corrente Continua”, oppure DC, dall’inglese “Direct Current”.

Ben diversa è la corrente alternata. La corrente alternata è quella che abbiamo disponibile dalle prese elettriche di casa, che è detta tensione di rete e che ci viene fornita dal nostro gestore elettrico. Essa è caratterizza ta da un flussoche cambia periodicamente di direzione o, per meglio dire, cambia di polarità:

!183183

Page 31: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

possiamo infatti immaginare che la corrente scorra dal primo polo al secondo per un breve lasso di tempo, poi inverta polarità e scorra dal secondo verso il primo, poi nuovamente dal primo al secondo e così via infini amente. Nel caso della tensione di rete disponibile in Italia essa cambia polarità 50 volte al secondo, vale a dire che ogni 1/50 di secondo essa scorre prima in un verso (per metà del tempo, ossia 1/100 s) e poi nel verso opposto (per l’altra metà, ossia ancora 1/100 s). La tensione di rete è infatti a 50 hertz, e l’hertz (simbolo Hz) è l’unità di misura della frequenza: prende il nome dal fisico tedesco Heinrich Hertz. La corrente alternata non cambia solo di polarità ma anche di intensità: essa scorre con un valore di intensità inizialmente pari a zero per poi aumentare fino al valore massimo e diminuire nuovamente a zero, e così via. Per facilitarci la comprensione di come varia la corrente alternata nel tempo possiamo aiutarci con un grafico:

L’onda sinusoidale rossa rappresenta la corrente alternata. È detto periodo il tempo che essa impiega a compiere due oscillazioni complete; è detta tensione di picco la tensione misurata al picco massimo (positivo o negativo),;è detta tensione picco picco la tensione misurata fra il picco massimo positivo ed il picco massimo negativo; è detto valore efficace, indicato anche come RMS (da Root Mean Square), il valore che avrebbe un segnale costante di pari potenza. Nel caso della tensione di rete italiana la tensione di picco è pari a ca. 325 V, la tensione picco picco è pari a 325 + 325 = 650 V, ed il valore efficac è pari a 230 V. Nei regimi di corrente alternata quest’ultimo valore si ottiene dividendo la tensione di picco per la radice quadrata di 2: RMS = Vmax / √2

Spiegare come si arriva a questo valore esula dagli scopi di questa guida, per approfondire l’argomento è consigliata la consultazione di un testo di elettrotecnica. Il valore efficac serve principalmente per semplifica e i calcoli

!184184

Page 32: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 15

I primi progetti

15.1 Progetto 1: Accensione di un LED mediante un pulsante Il percorso che ci ha portato sin qui è stato molto lungo: abbiamo fatto una panoramica sull’hardware, abbiamo studiato il linguaggio di programmazione ed abbiamo terminato con lo studio delle basi di elettronica e dei più semplici componenti elettronici. Adesso è tempo di mettere in pratica tutto quello che abbiamo studiato realizzando i nostri primi progetti. Questo capitolo mostrerà alcuni semplici esercizi pratici che potremo realizzare con componenti comunemente reperibili in un qualunque negozio di materiale elettronico oppure presso un fornito shop virtuale. Gli esercizi verranno corredati dell’elenco dei componenti impiegati, di uno schema di montaggio realizzato con il programma libero Fritzing (www.fritzing.org), dello schema elettrico realizzato con il CAD elettronico Eagle (nella versione freeware) e dello sketch da caricare sulla scheda Arduino UNO direttamente dall’IDE ufficial .

Il primo progetto che andremo a realizzare è il classico circuito in cui l’utente può accendere/spe gnere un LED mediante la pressione di un pulsante.

Materiale occorrente Per questo progetto avremo bisogno dei seguenti componenti: •1 scheda Arduino UNO•1 pulsante a montaggio superficial•1 LED di colore rosso, verde o giallo•1 resistore da 10 KOhm (marrone/ne ro/arancione )•1 resistore da 220 Ohm (rosso/r osso/mar rone)•cavetti per i collegamenti

Ut ilizziamo per il LED un resistore di limitazione di corrente di 220 ohm perché questo valore va bene per l’uso con uno qualunque dei 3 LED indicati (rosso, verde e giallo), senza dover calcolare il valore specifico per il colore che intendiamo utilizzare.

!206206

Page 33: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Collegamenti Effettuiamo i seguenti collegamenti (vedi figura “ rogetto 1”):

• collegare il pin 5V dell’Arduino con le linee positive della basetta;

• c o l l e g a r e u n o d e i p i n G N D dell’Arduino con le linee di massa della basetta;

•piazzare il pulsante a cavallo del solco centrale della basetta;

• collegare il piedino in alto a sinistra del pulsante del lato opposto a quello del l ’Arduino a l la l inea posi t iva dell’alimentazione mediante il resistore da 10K;

•collegare il piedino in basso a sinistra del pulsante con il pin 9 dell’Arduino;

• collegare il piedino in basso a destra del pulsante con la linea di massa;

•p i a z za r e i l LED su l l a ba se t t a mantenendo i suoi terminali su una delle colonne principali ma prestando attenzione a infila li in due fil diverse;

• collegare l’anodo del LED (il terminale più lungo) al pin 3 dell’Arduino;

• collegare il catodo del LED alla linea di massa mediante il resistore da 220 Ohm.

Sketch Adesso dobbiamo caricare il programma sulla scheda. Apriamo l’IDE e carichiamo il seguente sketch: //Progetto 1 - Azionamento di un LED mediante un pulsante //costanti const byte LED_OUT = 3; //pin di uscita (LED) const byte SWITCH_IN = 9; //pin di ingresso (pulsante)

//variabili globali byte statoLed = 0; //stato iniziale del LED: spento

//configurazione dei pin void setup() { pinMode(LED_OUT, OUTPUT); //pin del LED come output pinMode(SWITCH_IN, INPUT); //pin del pulsante come input }

!207

Progetto 1 - Collegamenti

!

207

Page 34: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

//ciclo principale void loop() { //controllo se il pulsante è stato premuto if (digitalRead(SWITCH_IN) == LOW) { //LED spento o acceso? if (statoLed == 0) { //spento: lo accendo statoLed = 1; } else { //acceso: lo spengo statoLed = 0; } //imposto il nuovo stato digitalWrite(LED_OUT, statoLed); delay(250); //piccola pausa “anti-rimbalzo" } }

Funzionamento Definiamo inizialmente alcune costanti che utilizzeremo per l’indicazione dei pin: questo ci sarà utile se in un secondo momento vorremo cambiare i pin a cui abbiamo collegato il LED ed il pulsante perché basterà modifica e il numero del pin nell’assegnazione della relativa costante che andremo a cambiare questo valore in qualunque parte dello sketch in cui abbiamo utilizzato il nome della variabile al posto del numero esplicito. Segue la dichiarazione di una variabile globale relativa allo stato del LED. La variabile globale ha, oltre al fatto di essere visibile in qualunque funzione dello sketch, la particolarità di conservare il suo valore alla fin del loop(), potendo così mantenere lo stato del LED attraverso le varie ripetizioni della funzione principale del programma.

Nella funzione setup() abbiamo inserito la dichiarazione relativa alla modalità di funzionamento dei pin utilizzati dallo sketch: abbiamo dichiarato il pin a cui è collegato il LED come output, mentre abbiamo dichiarato come input quello a cui è connesso il pulsante. Nella funzione loop() c’è il codice principale del programma: leggiamo continuamente lo stato del pulsante e, nel caso esso venga premuto, di cambiare lo stato del LED. Il controllo sulla lettura viene effettuato con la funzione digitalRead() a cui passiamo come parametro il numero del pin: questo valore è contenuto nella costante SWITCH_IN. La funzione digitalRead() restituisce LOW se viene letto un valore di tensione prossimo a 0 V e HIGH se la tensione è prossima a 5 V. Nell’esempio abbiamo utilizzato il valore restituito in maniera diretta, semplicemente inserendo la funzione come membro sinistro dell’operatore di uguaglianza. Il confronto lo facciamo con lo stato LOW. Nel caso il pulsante venga premuto, cambiamo lo stato del LED, accendendolo o spegnendolo, mediante l’uso della variabile globale statoLed. La piccola pausa alla fin del blocco di codice dell’if serve ad

!208208

Page 35: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

evitare che, alla pressione del pulsante, il codice accenda/spe nga il LED ripetutamente nel caso si faccia una pressione un po’ più lunga del necessario.

15.2 Progetto 2: Accensione temporizzata di un LED Questo progetto è simile al precedente: differisce per il fatto che il pulsante serve solo ad accendere il LED. Questo si spegne in automatico dopo un certo periodo di tempo. Ogni pressione del pulsante fa ripart ire il conteggio del tempo di timeout.

Materiale occorrente Il materiale occorrente è identico a quello del progetto 1.

Collegamenti I collegamenti sono identici a quelli del progetto 1.

Sketch // Progetto 2 - Accensione temporizzata di un LED //costanti const byte LED_OUT = 3; //pin di uscita (LED) const byte SWITCH_IN = 9; //pin di ingresso (pulsante) const int TIMEOUT = 5000; //timeout - 5 secondi

//variabili globali byte statoLed = 0; //stato iniziale del LED: spento unsigned long attivazione; //memorizza l'istante di accensione //configurazione dei pin void setup() { pinMode(LED_OUT, OUTPUT); //pin del LED come output pinMode(SWITCH_IN, INPUT); //pin del pulsante come input }

//ciclo principale void loop() { //controllo se il pulsante è stato premuto if (digitalRead(SWITCH_IN) == LOW) { //accendo il LED statoLed = 1; digitalWrite(LED_OUT, HIGH); attivazione = millis(); //salvo l'istante } if (statoLed) { //il LED è acceso? //controllo se è trascorso il tempo di timeout if (millis() - attivazione > TIMEOUT) { //sì, devo spegnere il LED digitalWrite(LED_OUT, LOW); statoLed = 0; } } }

!209209

Page 36: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 16

Interazione con l’utente

16.1 Schermi a cristalli liquidi (LCD)

Finora abbiamo visto esaminato le funzionalit à base dell’Arduino: abbiamo preso dimestichezza con la lettura di un ingresso analogico, abbiamo imparato come impostare i pin in input ed in output, abbiamo provato la lettura e la scrittura di dati sulla linea seriale. In questo capitolo inizieremo a sperimentare con funzionalit à per l’interazione con l’utente: Arduino è un microcomputer e come tale può gestire forme di input/out put con un utente, in modo del tutto autonomo. Con l’uso di dispositivi semplici quali i display LCD o le tastiere in stile telefonico possiamo fornire dei dati ed ottenere informazioni dal nostro progetto basato su Arduino.

Gli schermi a cristalli liquidi, detti anche display LCD, da Liquid Crystal Display, sono comunemente utilizzati come dispositivi di output per la loro semplicità d’uso e per il loro moderato consumo energetico. Sono in genere identific ti dal numero di colonne e righe che li compongono: ad esempio, un display 16x2 è un display composto da una matrice di 16 colonne per 2 righe di celle, ogni cella è composta da una matrice di pixel, generalmente 5x8 pixel.

Sono per la maggior parte basati sul controller Hitachi HD44780: grazie alla sua diffusione, questo controller ha creato uno standard de-facto nell’industria. Questi schermi comunicano con una linea parallela a 4 oppure 8 bit, e permettono di regolare il contrasto da un pin mediante il collegamento di un

!218218

Page 37: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

potenziometro. Alcuni display sono forniti anche di retroilluminazione, pilotabile tramite un transistor, ad esempio.

Grazie all’uso di controller compatibili fra loro è stato possibile realizzare una libreria in grado di gestire la stragrande maggioranza degli schermi in circolazione: la libreria si chiama LiquidCrystal ed è inclusa in quelle disponibili con l’IDE di Arduino.

Prima di pensare alla parte software, dobbiamo pensare a collegare lo schermo alla nostra scheda Arduino. Per fare ciò abbiamo bisogno dei seguenti componenti:

• scheda Arduino UNO •schermo a cristalli liquidi compatibile HD44780 di una qualunque misura

supportata dalla libreria (es.: 16x2, o 16x4); •potenziometro da 10 KOhm; • striscia di pin; • cavetti per i collegamenti.

I display sono generalmente distribuiti già montati su una scheda, con il controller saldato sulla parte posteriore ed una fila di 16 fori per i collegamenti (standard HD44780). Consiglio di saldare una fila di pin per facilitare i collegamenti ed evitare falsi contatti: saldate i pin montando la parte più lunga sul retro della scheda, in modo da facilitare l’inserimento su una basetta di prototipazione o il montaggio su un circuito realizzato da voi (vedi figura 8).

I pin sono numerati dall’1 al 16 per facilitarne l’identificazion , vedi tabella 8. La tensione dell’alimentazione è generalmente a 5 V, per poter lavorare con le logiche TLL. L’alimentazione fornita tramite i pin VDD/ VSS serve l’elettronica di controllo: la retroilluminazione, se presente, è servita dai pin A/K: controllare sulla scheda tecnica fornita dal costruttore se anche su questi pin

!219

Figura 8: i pin di collegamento saldati sulla scheda di un display LCD 16x2

219

Page 38: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

dobbiamo dare 5 V oppure una tensione differente e se dobbiamo utilizzare un resistore per limitare la corrente, dato che questa linea alimenta dei LED, o se il resistore è già integrato sulla scheda elettronica. Come detto, il bus dati può funzionare sia a 4 che ad 8 pin: si collegano perciò solo i pin utilizzati. Sarà cura dell’utente in fase di inizializzazione della libreria indicare la dimensione del bus stesso. Di solito si utilizzano solo 4 linee di dati per risparmiare sui collegamenti e impiegare meno pin dell’Arduino: usando 8 linee, comunque, l’invio dei dati avviene in maniera più veloce. Il pin VLC va collegato ad un potenziometro per la regolazione del contrasto. Il pin RS è pilotato dalla libreria e serve ad indicare al controller se stiamo inviando un comando o dei dati. Il pin R/W può essere collegato direttamente a massa perché in genere il display è utilizzato per visualizzare dei dati per cui necessitiamo della possibilità di scrivere sulla memoria RAM del buffer video del controller integrato.

!220

Pin Nome Note

1 VSS Massa dell’alimentazione

2 VDD Positivo dell’alimentazione

3 VLC Contrasto dell’immagine

4 RS 0 per l’invio di comandi, 1 per l’invio di dati

5 R/W 0 per lettura/scrit tura, 1 per sola lettura

6 E Pin di “Enable” per le operazioni di R/S o R/W

7 D0 Bus dati

8 D1 Bus dati

9 D2 Bus dati

10 D3 Bus dati

11 D4 Bus dati

12 D5 Bus dati

13 D6 Bus dati

14 D7 Bus dati

15 A Positivo per retroilluminazione

16 K Massa per retroilluminazione

Tabella 8: corrispondenza fra pin e linee dei display con controller HD44780

220

Page 39: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Sezione 4

Tecniche Avanzate

!238

Page 40: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 17

Le porte logiche

17.1 Le porte logiche del microcontrollore

Abbiamo visto nel capitolo 10 che Arduino ci mette a disposizione delle comode funzioni per poter operare con le linee di I/O digitale della scheda: con pinMode() possiamo dire al microcontrollore se un dato pin lo vogliamo usare come ingresso (INPUT) o come uscita (OUTPUT), con digitalWrite() possiamo impostare lo stato di un pin e con digitalRead() lo possiamo leggere. Sembra semplice. Ma se andiamo ad analizzar e il codice delle librerie base di Arduino ci accorgiamo che non lo è. È vero che la semplicità dell’IDE di Arduino permette di fare queste operazioni usando poche istruzioni ma nel “retrobottega” le operazioni che vengono eseguite sono diverse, perché Arduino deve effettuare una serie di calcoli per trasformare il numero di pin nel corrispondente piedino fisico e poi ancora controllare se quel pin è collegato ad un timer, e nel caso disattivare l’eventuale segnale PWM che ci può essere collegato. Solo allora il pin viene impostato come si vuole. Se non si ricerca una grande velocità tutti questi passaggi, che vengono eseguiti tutte le volte che invochiamo tali istruzioni, possono anche non creare problemi ma se vogliamo fare le cose in modo più rapido e diretto la soluzione è solo una: operare a livello di porte logiche del microcontrollore.

17.2 Gestione digitale delle porte Come abbiamo visto in precedenza, microcontrollore è un dispositivo elettronico complesso composto da diverse periferiche: tutto, però, è fatto a livello digitale. Non esiste un meccanismo meccanico da azionare, un interruttore che viene premuto quando vogliamo cambiare lo stato di un pin: esistono dei particolari registri mappati in memoria che contengono lo stato di ogni singola linea di input/out put (I/O) del microcontrollore. Ogni registro rappresenta lo stato di una porta logica quindi una porta logica è l’insieme dei bit collegati ad un gruppo di piedini fisici del microcontrollore. Leggendo o scrivendo in questi registri si può operare in maniera diretta sui pin.

!239239

Page 41: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Le porte logiche degli Atmel della serie AVR ATtiny e ATmega sono registri ad 8 bit, per cui ogni porta logica può contenere al massimo lo stato di 8 linee di I/O, ossia di 8 pin del microcontrollore. Ogni pin è identific to da una sigla, come PD0, PC1 o PB2. Ad esempio, PB0 identifica il pin 0 della porta logica “B”. L’ATmega328P ha 23 linee di I/O raggruppate in 3 porte logiche da 8 bit l’una denominate B, C e D. Ogni porta è gestita da 3 registri, denominati DDRx, PORTx e PINx dove la “x” rappresenta la lettera identific tiva della porta. Per ogni porta possiamo agire sulla corrispondente linea di I/O mediante i bit del registro collegato. Negli schemi seguenti, la lettera “y” indica la porta (B, C, o D) e “x” il bit (può assumere un valore compreso fra 0 e 7), es.: DDRB2:

• DDRx: questo registro è di lettura/scrit tura e contiene la direzione dei pin adesso collegati. I bit sono denominati DDyx. Un bit a 0 rappresenta un pinimpostato come INPUT; un bit ad 1 rappresenta un pin impostato comeOUTP UT.

• PORTB: questo registro è di lettura/scrit tura e contiene lo stato dei pin. I bitsono denominati PORTyx. Questo stato cambia a seconda della direzione delpin:

• se il pin è impostato come INPUT, un bit ad 1 attiva il resistore interno dipull-up, mentre un bit a 0 la disattiva;

• se il pin è impostato come OUTP UT, un bit ad 1 indica un segnale alto(HIGH) sul relativo pin, mentre un bit a 0 indica la presenza di un segnalebasso (LOW).

• PINB: questo registro è di sola lettura e contiene, nel caso di un pin impostatocome INPUT, la lettura del segnale collegato al pin. I bit sono denominatiPINyx. I bit valgono 1 per un segnale alto (HIGH) e 0 per un segnale basso(LOW).

Da ciò si capisce subito come per impostare un pin come OUTP UT con un livello HIGH non dobbiamo far altro che impostare prima la direzione dello stesso mediante il registro DDRx e poi cambiare il livello del segnale con il registro PORTx. Tutto questo lo possiamo effettuare ricorrendo all’uso degli operatori per la manipolazione dei bit visti nel capitolo 5.5.5.

Facciamo un esempio pratico. Vogliamo impostare il pin PB2 come OUTP UT con livello in uscita HIGH. Dobbiamo operare sul 3° bit (ricordatevi che il

DDy7 DDy6 DDy5 DDy4 DDy3 DDy2 DDy1 DDy0

PORTy7 PORTy6 PORTy5 PORTy4 PORTy3 PORTy2 PORTy1 PORTy0

PINy7 PINy6 PINy5 PINy4 PINy3 PINy2 PINy1 PINy0

!240240

Page 42: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

conteggio delle posizioni parte da 0, per cui il bit n° 2 è il 3° bit) dei registri DDRB e PORTB, usando il primo per impostare la direzione del pin ed il secondo il segnale che vogliamo: DDRB |= (1<<DDB2); //imposta il pin PB2 come OUTPUT PORTB |= (1<<PORTB2); //mette il pin PB2 sullo stato ALTO

Aiutandoci con la figura 7 del capitolo 10.1 dov’è riportata la corrispondenza fra pin dell’Arduino e piedini del microcontrollore possiamo trovare che il pin PB2 corrisponde al pin digitale 10, per cui le istruzioni viste qui sopra corrispondono alle seguenti funzioni di Arduino: pinMode(10, OUTPUT); digitalWrite(10, HIGH);

Come detto, la differenza fra i due insiemi risiede nella velocità: il primo viene sempre eseguito con una velocità maggiore. E c’è anche il vantaggio della compattezza del codice. La differenza è ancora più notevole nel caso si debba cambiare lo stato a diverse porte: manipolando direttamente le porte logiche possiamo cambiare la direzione e lo stato di più pin in un unico passaggio. Ad esempio, se volessimo impostare i pin dal PB0 e PB1, i pin digitali da 8 e 9, come output con segnale alto non dovremmo far altro che scrivere questo codice: DDRB |= ((1<<DDB0) | (1<<DDB1)); PORTB |= ((1<<PORTB0) | (1<<PORTB1));

Oppure, se non ci interessa cambiare anche gli altri pin, usare istruzioni di assegnazione dirette, ancora più veloci: DDRB = 0b00000011; PORTB = 0b00000011;

Usando il linguaggio di Arduino saremmo stati costretti a scrivere qualcosa di simile: pinMode(8, OUTPUT); pinMode(9, OUTPUT); digitalWrite(8, HIGH); digitalWrite(9, HIGH);

E avremmo dovuto anche considerare il tempo occorso ad eseguire ogni singola chiamata a pinMode() ed a digitalWrite(), ricordandoci quanto detto in precedenza circa le operazioni ed i controlli che l’Arduino esegue sui pin.

Eseguiamo adesso la lettura digitale di un pin e troviamo l’equivalente delle seguenti istruzioni: pinMode(10, INPUT); byte a = digitalRead(10);

Dobbiamo impostare prima la direzione del pin PB2 (corrispondente al pin digitale 10) scrivendo 0 sul bit DDRB2 per attivare il pin come ingresso e poi

!241241

Page 43: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 19

Gli interrupt

19.1 Gestione degli interrupt

Il signific to del nome spiega già il loro compito: gli interrupt sono dei particolari segnali che vengono utilizzati per interrompere le normali funzioni della CPU del microcontrollore ed obbligarla ad eseguire una porzione speciale di codice detta Interrupt Service Routine (ISR), ossia una funzione di servizio di un interrupt. A cosa servono gli interrupt? Principalmente a svolgere un compito che ha una priorità maggiore di quella del codice dello sketch e che deve essere eseguito nel momento stesso in cui arriva l’ordine di farlo, ordine dato da un particolare evento che può accadere sia all’interno che all’esterno del microcontrollore. Gli interrupt esterni sono interrupt generati da segnali elettrici letti sui piedini del microcontrollore mentre gli interrupt interni sono segnali inviati dalle periferiche integrate. Abbiamo studiato in precedenza i timer: anche i timer possono essere programmati per sollevare un interrupt, ad esempio quando il registro contatore va in overfl w oppure quando il valore che contiene è identico al valore di un registro di comparazione.

Il verbo usato per indicare l’arrivo di un segnale di interruzione è sollevare, che deriva dall’inglese to raise.

La gestione degli interrupt avviene tramite appositi registri i cui bit vengono costantemente monitorati dalla CPU per controllare se un interrupt è stato sollevato. Il microcontrollore può essere programmato per ignorare tutti gli interrupt oppure per ignorarne solo alcuni: nel primo caso esiste un bit nel registro di stato del microcontrollore che attiva o disattiva gli interrupt a livello globale. Se questo bit è “acceso” (se cioè il bit corrispondente vale 1) il microcontrollore gestisce tutti gli interrupt in arrivo, se invece è “spento” (se il bit vale 0) allora il microcontrollore ignora tutti i segnali. Il registro in questione si chiama SREG ed il bit in questione, l’ottavo di quel registro, si chiama “I”. Possiamo modifica e quel bit in maniera diretta usando alcune istruzioni particolari oppure mediante la manipolazione dei bit. Nel primo caso il compilatore offre due istruzioni: sei() (da “set interrupts”), che attiva gli interrupt globali, impostando il bit ad 1; cli() (da “clear interrupts”), che li

!269269

Page 44: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

disattiva ponendolo a 0. Il linguaggio di Arduino ci mette a disposizione due alias (alternative) dei suddetti comandi: interrupts() e noInterrupts(), con le stesse identiche funzioni. Se invece vogliamo manipolare direttamente quel bit possiamo utilizzare la costante predefini a SREG_I che il compilatore ci mette a disposizione per indicare in maniera implicita la posizione del relativo bit. Per “accendere” il bit il codice sarà il seguente: SREG |= (1<<SREG_I);

mentre per “spegnerlo” scriveremo questo: SREG &= ~(1<<SREG_I);

Prestate attenzione al fatto che, se disattivate gli interrupt globali, tutte le funzioni temporali di Arduino cessano di funzionare perché sono tutte gestite da una funzione di servizio di un interrupt agganciata al timer 0.

Se gli interrupt sono disattivati a livello globale qualsiasi segnale di interrupt verrà ignorato dal microcontrollore. Se invece sono attivi, il microcontrollore gestirà tutti i segnali in arrivo secondo le impostazioni delle periferiche a cui è arrivato il segnale. Ad esempio, un interrupt in arrivo su un piedino del microcontrollore sarà sollevato solo se è stato acceso il relativo bit di abilitazione, altrimenti verrà ignorato. Quando l’interrupt è gestito, il microcontrollore imposta ad 1 il bit relativo: questo provoca da parte della CPU l’interruzione dell’esecuzione del codice dello sketch ed il passaggio ad un blocco di codice specifico che, come abbiamo visto, si chiama Interrupt Service Routine (ISR). La chiamata alla funzione avviene mediante una “jump table”, ossia una “tavola dei salti”: in una zona di memoria posta normalmente nella prima parte della memoria Flash viene scritto un elenco di indirizzi, chiamati anche vettori di salto, che sono gli indirizzi di memoria dove la CPU può trovare ed eseguire le funzioni per gestire i singoli interrupt.

In tabella 24 è possibile vedere le prime posizioni della tavola dei salti dell’ATmega328P (l’elenco completo è contenuto nella scheda tecnica del microcontrollore fornita dal produttore). Questo elenco è ordinato per priorità: un interrupt con numero di posizione x nella tavola avrà una priorità maggiore rispetto ad un interrupt il cui vettore di salto è posto in posizione x+1 e priorità inferiore rispetto ad un altro con un vettore in posizione x-1. Ad esempio, l’interrupt INT1 avrà priorità maggiore rispetto a PCINT0 ma priorità inferiore rispetto a INT0. La priorità è importante per capire l’ordine con cui vengono esegui t i g l i in t er rupt . Nel caso in cui vengano sollevati contemporaneamente 2 interrupt, la CPU eseguirà per primo quello

!270270

Page 45: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

con priorità maggiore. Ogni interrupt resta registrato fino a che non viene eseguita la corrispondente ISR. All’uscita della ISR il relativo bit viene resettato (posto a 0). È anche possibile resettarlo manualmente scrivendo il valore 0 nel relativo bit: in questo caso viene cancellata la richiesta di esecuzione della ISR. E se arriva un segnale di interrupt mentre la CPU sta già eseguendo una ISR? Per impostazione predefini a le ISR sono atomiche, ossia il relativo blocco di codice non è interrompibile da altri interrupt: il compilatore inserisce automaticamente l’istruzione cli() subito all’inizio del blocco di codice e poi l’istruzione sei() subito in fondo. Questo comporta anche che le operazioni basate sugli interrupt cessano di funzionare all’interno di una ISR. Quando arriva un interrupt la CPU ferma l’esecuzione del codice principale, salva nello stack il punto del programma a cui era, arrivata rappresentato dal valore del registro Program Counter (PR) che contiene il valore della cella da cui prelevare la prossima istruzione da eseguire, salva tutti i suoi registri interni in modo da poter recuperare l’esatta situazione del lavoro interrotto quando uscirà dalla ISR e poi salta ad eseguire la funzione di gestione dell’interrupt sollevato. Al termine della ISR, la CPU recupera il valore dei registri interni ed infin quello del registro PR in modo che la successiva operazione che andrà ad eseguire sarà quella del programma principale che era stato messo in sospeso. In figura 10 possiamo vedere graficam nte qual è il flusso del programma eseguito dalla CPU prima e dopo l’arrivo del segnale di interrupt.

Analizziamo ora come si scrive una ISR. L’esempio qui sotto dichiara la funzione ISR per gestire l’interrupt sollevato dall’overflow del timer 2: ISR(TIMER2_OVF_vect) { …..codice…. }

!271

VETTORE INDIRIZZO SORGENTE INTERRUPT

1 0x000 RESET Pin esterno, reset di avvio, reset di Brown-out, reset del watchdog

2 0x001 INT0 Segnale dall’interrupt INT0

3 0x002 INT1 Segnale dall’interrupt INT1

4 0x003 PCINT0 Segnale dall'interrupt PCINT0

5 0x004 PCINT1 Segnale dall'interrupt PCINT1

6 0x005 PCINT2 Segnale dall'interrupt PCINT2

7 0x006 WDT Segnale dal Watchdog

8 0x007 TIMER2 COMPA Segnale dal Timer/Count er 2 Compare Match A

Tabella 24: estratto della tavola dei salti (“jump table”) delle ISR dell’ATmega328P

271

Page 46: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

La funzione si dichiara usando la speciale parola chiave ISR facendo seguire fraparentesi il vettore dell’interrupt. Come si vede dall’esempio, il vettore dell’interrupt è il nome dell’interrupt seguito dal suffisso vect: al posto degli spazi fra le parole viene usato il carattere di sottolineatura (underscore) come separatore.

Il blocco di codice della ISR segue le stesse regole di visibilità del linguaggio per cui per utilizzare una variabile esterna essa deve essere di tipo globale. Questo da solo però non basta: serve in più l’accortezza di anteporre alla dichiarazione la parola chiave volatile per evitare che il compilatore ne ottimizzi l’usodurante la compilazione, cosa che potrebbe portare a comportamenti del programma inattesi (vedi capitolo 5.3.3): volatile int contatore = 0; ….. ISR(TIMER2_OVF_vect) { contatore++; }

Che succede nel caso in cui si attivi un interrupt ma non si sia scritta la relativa ISR? In questo caso il comportamento predefini o è quello di resettare il microcontrollore perché il compilatore interpreta la condizione di chiamata ad una

!272

Figura 10: gestione di una ISR da parte della CPU

!

272

Page 47: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Capitolo 21

Progetti stand-alone

21.1 Arduino stand-alone

Finora abbiamo sempre parlato di scheda Arduino nella sua interezza. Per ogni progetto abbiamo previsto l’utilizzo di una UNO. Un po' dispendioso, economicamente parlando, vero? Non possiamo ogni volta includere nel progetto una scheda e acquistarla ex-novo. Dobbiamo trovare un sistema per poter risparmiare soldi e componenti. La UNO è una scheda di prototipazione per principiant i e come tale è stata studiata per permettere ai principiant i di fare ciò che gli riesce meglio: i danni! Prima o poi chiunque commette un errore e magari collega un LED ad un pin senza usare il necessario resistore oppure mette a corto con massa un pin impostato in uscita con un segnale di livello alto sul pin stesso. Il risultato è disastroso: il microcontrollore cessa di funzionare, e se ne richiede la sostituzione. I progettisti di Arduino hanno pensato anche a questo scenario, quando hanno sviluppato la scheda, ed hanno scelto un microcontrollore in formato DIP, sigla che sta per Dual In-line Package, ossia un chip i cui piedini sono disposti su due fil ordinate ai lati del contenitore. Se abbiamo bruciato il chip e ci rivolgiamo al nostro amico smanettone oppure al nostro rivenditore, ci verrà risposto che “il chip è facilmente estraibile dal suo zoccolo per poter essere sostituito con un altro identico, basta che abbia il bootloader precaricato”. Acquistiamo il chip, estraiamo quello danneggiato, montiamo quello nuovo… et voilà, la scheda è tornata funzionante!

!291

Figura 12: una scheda Arduino UNO con il microcontrollore ATmega328P estratto dallo zoccolo

!

291

Page 48: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

Che succederebbe, però, se noi estraessimo non un chip danneggiato ma un chip perfettamente funzionant e? Potrebbe tornare a funzionare anche montato al di fuori della scheda Arduino? La risposta è sì! Potrebbe funzionare a patto di corredarlo dei componenti minimi necessari a ricreare una scheda Arduino. Quindi avremmo trovato un modo per risparmiare una scheda, usando il solo microcontrollore. Non resterebbe altro da fare, ora, che capire quali sono i componenti minimi necessari affin hé il chip possa funzionare anche non montato sulla scheda. Studiando la scheda tecnica del microcontrollore ed i fil di progetto della scheda Arduino UNO (grazie al fatto che l’Arduino è open-source, chiunque ha accesso ai fil di progetto) possiamo vedere come l’ATmega328P sia abbastanza indipendente. Tralasciando i collegamenti tra i pin D0 e D1 con il chip convertitore USB/S eriale ATmega16U2, che servono per il dialogo con il computer, ciò di cui ha realmente bisogno per funzionare è essenzialmente un segnale di clock esterno. Sull’Arduino UNO c’è un risonatore ceramico con i relativi condensatori sulle linee del segnale ma noi possiamo sostituire quel risonatore con un più comune e altrettanto facilmente maneggiabile quarzo esterno, sostituendo i condensatori a montaggio superficial del primo con dei più normali condensatori ceramici. Infin , ci serve un semplice resistore da 10 KOhm come pull-up sul pin di reset per evitare reset indesiderati del microcontrollore stesso. Tutto qui? Sì, tutto qui! I componenti per un Arduino autonomo, o stand-alone come viene detto in inglese, sono solo questi: •microcontrollore ATmega328P •quarzo a 16 MHz (la stessa frequenza dell’Arduino UNO) •2 condensatori ceramici da 18 pF (pico Farad) per il quarzo •1 resistore da 10 Kohm

Il microcontrollore è quello della scheda UNO: assicuratevi, al momento dell’acquisto, che la sua sigla contenga la lettera “P” final . Come detto nel capitolo 2.2, ATmega328 e ATmega328P sono due chip differenti. A noi serve il modello “con P”, che ha un core differente. Il quarzo da 16 MHz è necessario affin hé la velocità del nostro Arduino autonomo sia identica a quella della scheda UNO. In alternativa potete anche utilizzare un risonatore ceramico di pari valore ma attenzione al fatto che un risonatore ha una minor precisione per cui se usate delle funzioni basate sullo scorrere del tempo il risonatore darà intervalli meno regolari e precisi. I condensatori ceramici servono per evitare auto-oscillazioni del quarzo stesso. Atmel nella scheda tecnica dell’ATmega328P fornisce un intervallo di valori utilizzabili compreso fra 12 e 22 pF: 18 pF è un valore abbastanza comune e medio rispetto a quelli suggeriti. Il resistore da 10 KOhm serve come pull-up sul piedino di reset del microcontrollore: senza di esso, flu tuazioni elettrostatiche intorno al chip potrebbero portare a reset

!292292

Page 49: ARDUINO - edizionidelfaro.it · Gruppo Editoriale Tangram Srl Via Verdi, 9/A – 38122 Trento – info@edizionidelfaro.it Prima edizione: aprile 2016 – Printed in EU ISBN 978-88-6537-483-2

imprevisti, quindi mettetelo sempre. Tutti i componenti sono normalmente reperibili presso un negozio ben fornito di materiale elettronico: se invece acquistate in rete non avrete che l’imbarazzo della scelta dato il numero considerevole di rivenditori presenti. Ovviamente ci serve un Arduino UNO completo e funzionante, che utilizzeremo per la programmazione del microcontrollore montato in solitario.

Reperito tutto il materiale, provvediamo all’assemblaggio del nostro Arduino autonomo, seguendo il seguente schema e rifacendoci alla figura 13:

•prendiamo una basetta di p r o t o t i p a z i o n e e colleghiamo insieme le due linee dell’alimentaz ione super iore ed infer iore rispettando le polarità;

•montiamo l’ATmega328P al centro della basetta in modo che ogni f la di piedini sia incastrata in una metà della basetta;

• colleghiamo il piedino n° 1 del chip alla linea di alimentazione rossa della basetta mediante il resistore da 10 KOhm;

•montiamo il quarzo da 16 MHz in una zona libera alla destra del chip;

• colleghiamo i due piedini del quarzo rispettivamente ai piedini 9 e 10 del microcontrollore;

•montiamo i 2 condensatori da 18 pF affin hé ognuno di essi abbia un piedino montato sulla linea in comune con uno dei piedini del quarzo e l’altro sia libero al suo esterno; non essendo polarizza ti, possono essere montati come capita;

• colleghiamo i piedini liberi dei condensatori alle linee di massa della basetta; • colleghiamo i piedini 7 e 20 del microcontrollore alle linee di alimentazione

rosse della basetta;

!293

Figura 13: realizziamo un Arduino stand-alone

!

293