1
ARDUINO
Introduzione
Su internet è possibile trovare molti testi, articoli, presentazioni, siti internet e
quant’altro. Lo scopo di questo trattato e dei successivi, è quello di realizzare
una guida introduttiva ad Arduino, spiegando in cosa consiste la board, le
basi e la logica di programmazione.
Questo non vuol essere una sostituzione ai numerosi libri già presenti, bensì
una guida veloce e pratica per i programmatori di domani.
Presentazione
Arduino nasce ad Ivrea, nel 2005, da un'idea di un professore universitario, un Ingegnere
Elettronico, Massimo Banzi, che decise di creare una piattaforma per i propri studenti, per
facilitarli nello studio dell'Interaction Design.
E’ una piattaforma low-cost hardware e software programmabile, con la quale è possibile
creare circuiti per svariate applicazioni, specialmente in ambito di robotica ed
automazione. Il cuore della board è un Microcontrollore della ATMEL: per esempio Arduino
Uno monta un ATMega328.
Dal punto di vista Hardware, la scheda di Arduino ( facciamo l’esempio di Arduino UNO) è
pronta all’uso: nel suo circuito è integrato tutto il necessario per programmare il
microcontrollore collegando la scheda semplicemente alla porta USB del PC.
Può essere alimentato tramite un connettore di alimentazione o una porta usb.
Possiede un integrato che fa da convertitore USB/Seriale, un LED di accensione, un LED di
controllo collegato al PIN 13, due led di segnalazione TX/RX, i connettori femmina per il
collegamento degli ingressi/uscite tramite cavetti per breadboard e, in fine, il controllore
Atmega328 con bootloader Arduino già caricato.
La parte Software invece è rappresentata dal citato bootloader, dalle librerie e dall’IDE,
ovvero l’ambiente di sviluppo, l’interfaccia che permette di programmare la nostra scheda
Arduino.
Il bootloader precaricato sull’Atmega è quello che permette la comunicazione seriale con il
nostro PC. Senza il bootloader, per caricare gli sketch (i nostri “programmi”), avremmo
bisogno di un programmatore esterno più costoso, un po’ più macchinoso da utilizzare e
più lento nel caricare gli sketch. Il bootloader è quindi un “mini” programma(0.5 kB),
residente nella flash memory del microcontrollore, il cui compito è quello di caricare i
nostri sketch compilati, all’interno della memoria flash del microcontrollore tramite
comunicazione seriale/usb, facendo si che tale programmazione non vada a sovrascrivere
la zona di memoria dove è presente il bootloader. Vien da se che, quando facciamo
l’upload di uno sketch, quest’ultimo verrà localizzato in una zona di memoria libera
evitando la sovrascrittura del bootloader.
2
In questo modo aprendo l’IDE e selezionando la porta seriale del PC possiamo caricare i
nostri sketch con un semplice tasto ed in pochi secondi. L’upload avviene tramite la porta
seriale emulata dall’USB, che va a collegarsi ai PIN TX e RX dell’Atmega (piedini
rispettivamente 3 e 2).
Un’altra parte estremamente importante del software sono le librerie. Tali librerie, da
importare secondo necessità, aggiungono svariate funzioni che permettono di semplificare
enormemente il codice che si scriverà, rendendolo molto più fruibile rispetto a quello
standard del microcontrollore.
Il tutto viene gestito tramite l’ambiente di sviluppo (IDE):
- Stesura degli sketch
- Salvataggio (save)
- Compilazione (verify)
- Caricamento (Upload)
Il grande lavoro di semplificazione del progetto Arduino, sia a livello software, sia a
livello hardware, ha reso veramente minimali i requisiti per utilizzare il sistema.
Ovviamente serve un personal computer che sia in grado di far funzionare applicazioni in
Java, con i seguenti sistemi operativi:
Windows Xp, Vista e Seven (Windows 2000 ha dei problemi di driver);
Mac, purché abbiano Mac OS X 10.3.9 o superiore;
Linux con Ubuntu, Debian, Gentoo e molte altre distribuzioni, ricordando che con Linux c'è
da faticare un pochino per predisporre tutti i programmi e le librerie richieste.
Il sito di Arduino dispone di un'area dedicata all'installazione su Linux (arduino.cc/
playground/Learning/Linux) e ti consigliamo di partire da lì se hai intenzione di usare
questo sistema operativo.
Dato che il sistema di sviluppo è scritto in Java. L’IDE di Arduino UNO richiede una
versone di Java correttamente installata e funzionante. A tal proposito, consigliamo di
visionare il sito www.java.com e utilizzare il collegamento "lo ho Java?" per verificare lo
stato del computer. La pagina verifica la situazione del software e fornisce le indicazioni,
che possono essere una richiesta di installazione, l'aggiornamento o un "tutto OK".
Suggeriamo questa soluzione in quanto è molto probabile che si possieda già sul
computer qualche versione dell'ambiente runtime di Java, quindi l’aggiornamento fatto
con le procedure dal sito risultano le più pratiche e veloci.
Scarichiamo e installiamo l'IDE
Nella confezione di Arduino UNO non è presente alcun dischetto o memoria contenente il
software. Bisogna obbligatoriamente andare online su internet e scaricarlo dalla pagina
"arduino.cc/en/Main/Software". Qui si trovano le varie versioni disponibili per le relative
piattaforme supportate.
Una volta terminato il download, basterà estrarre tutto il contenuto dalla cartella
compressa appena scaricata.
L’unico eseguibile nella cartella principale è "arduino.exe" e determina il lancio
dell'ambiente integrato di sviluppo (IDE) scritto in Java.
Colleghiamo l’hardware
Questa fase, con il primo collegamento, richiede un pò di attenzione in quanto in quanto il
computer deve installare il driver da usb a seriale indispensabile per per far pilotare la
scheda dall’IDE.
Se il computer non è stato utilizzato in precedenza con schede Arduino, dispone di
Windows XP e ha avuto una "intensa vita" di collegamenti a periferiche e dispositivi vari,
3
potrebbe avere qualche difficoltà a riconoscere la scheda nel modo corretto. Si tratta di
una possibilità remota, ma con Windows XP e i driver USB, le sorprese sono sempre dietro
l'angolo. Con Vista e Seven, l'installazione non presenta difficoltà specifiche purché si
rispetti la procedura indicata.
Per Prima cosa, bisogna procurarsi il cavetto di collegamento fra scheda Arduino UNO e
personal computer. Si tratta di un cavetto che da una parte ha un maschio USB di Tipo A -
da collegare al computer - e dall'altra un maschio USB Tipo B da collegare alla scheda.
Dato che il connettore Tipo B non è più molto diffuso, potrebbe essere difficile trovare il
cavetto necessario nel negozio d'informatica sotto casa.
Con Seven e Vista l'installazione automatica potrebbe non andare a buon fine e si ottiene
un dispositivo sconosciuto fra quelli elencati fra le risorse. Nessun problema perché da
questo punto è semplice sistemare le cose. Con il tasto destro sul "Dispositivo
sconosciuto” selezionare “Aggiorna Driver” per cercare il driver giusto che si trova nella
cartella Drivers; premere “OK” e lasciare la scheda collegata alla porta USB.
Se durante l’installazione appare qualche finestra relativa alla mancanza della firma del
driver ect, proseguire facendo click su “continua”.
Finita l’installazione , da ora in poi, ogni volta che si collegherà Arduino Uno al PC, questo
lo riconoscerà come una periferica di tipo seriale da COM1 in poi.
Per collaudare l’installazione si terminare la sessione del sistema operativo e riavviare il
PC senza collegare la scheda , quindi collegarla e vedere se viene riconosciuta
correttamente.
La seconda manovra di collaudo consiste nel caricare uno sketch di esempio, compilandolo
e scaricandolo sulla scheda di Arduino UNO.
Per far questo, lanciare l’IDE e dal menù “File” scegliere “Examples> Basic> Blink”; si
aprirà una finestra completa di IDE con il codice dello sketch caricato e pronto all’uso.
Premere il tasto “Verify” e nella barra in basso appare la scritta “Compiling…” e dopo
qualche istante la conferma della creazione del codice oggetto pronto per essere caricato;
premere il pulsante upload e osservare il lampeggio dei led TX ed RX della scheda di
Arduino in varie ondate che conferma l’avvenuto caricamento del programma.
Al termine si avrà come effetto che il LED collegato al pin 13 e contrassegnato dalla scritta
“LED” sulla scheda lampeggerà lentamente con la cadenza di un secondo acceso e un
secondo spento. Adesso prova tu qualche piccola modifica al programma……….(per
esempio accelera la velocità di lampeggio).
4
La soluzione realizzata per programmare la scheda di Arduino UNO nasconde tutta una
serie di passaggi, di configurazione e di programmi che altrimenti avrebbero richiesto
capacità e preparazione per essere messi a punto e utilizzati.
Il grande lavoro svolto dal team di Arduino è stato quindi, in gran parte, creare l’ambiente
di sviluppo (IDE) grazie al quale sembra tutto molto più semplice e lineare, mentre dietro
all’interfaccia scritta in linguaggio Java si trovano migliaia di file che permettono al
computer di trasformare il programma nel modo opportuno e riducendo al minimo
l’insorgere di problemi di compilazione( il processo che trasforma il programma scritto con
il linguaggio ad alto livello in codice macchine adatto al microcontrollore presente sulla
scheda) .
Oltre a creare il codice e a scaricarlo sul microcontrollore della scheda (upload), l’IDE
permette anche di raccogliere informazioni di ritorno dalla scheda stessa.
Con la sua schiera di porte e di pin di ingresso e di uscita, Arduino è in grado di acquisire
informazioni da una miriade di sensori e dispositivi elettronici, potendo allo stesso tempo
accendere luci, pilotare motori, emettere suoni , attivare dispositivi.
Una volta ultimato il processo creativo e di programmazione, Arduino UNO potrà anche
operare senza PC,autonomamente, eseguendo le istruzioni inserite al suo interno.
I programmi di Arduino(il linguaggio usato è una versione semplificata del C/C++,
arricchito da una serie di funzioni specifiche della scheda) si chiamano sketch cioè
bozzetti.
Arduino resta un mucchietto di elettronica se non si aggiungono idee e creatività.
Quest’ultima, insieme alle capacità personali di ideare progetti per Arduino UNO, vanno
quindi stimolate sperimentando un po’ in tutti i vari campi applicativi.
Ma come strutturare le idee affinché possano diventare un programma?
Basta trasformarle in piccoli passi logici che descrivono funzionalmente quello che deve
succedere. Il primo passo è la creazione di un diagramma di flusso(flow chart); i
diagrammi di flusso sono di per sé una forma di programmazione e sono ad un livello tale
di astrazione da essere da un lato comprensibili a tutti e dall’altro sufficienti a descrivere
un programma nella sua totalità. Con un programma di flusso ben fatto, un
“programmatore” è in grado di scrivere il codice, mentre l’autore è in grado di dettagliare
Arduino Uno Rev3 è una scheda elettronica con le seguenti caratteristiche:
 Microcontrollore: ATmega328
 Tensione di funzionamento: 5 V
 Tensione di alimentazione (raccomandata): da 7 a 12 V
 Tensione di alimentazione (limiti): 6-20V
 Ingressi/uscite Digitali: 14 (di cui 6 possono essere utilizzate come uscite PWM)
 Ingressi analogici: 6
 Corrente Dc per pin I/O: 40 mA
 Corrente DC per pin 3,3 V: 50 mA
 Memoria Flash: 32 kB (di cui 0,5 kB utilizzati dal bootloader)
 SRAM: 2 kB
 EEPROM: 1 kB
 Velocità di Clock : 16 MHz
5
ciascuna funzione senza conoscere le caratteristiche specifiche del linguaggio di
programmazione che verrà utilizzato.
Per fare qualche esempio, un diagramma di flusso può
essere visto come una serie di frasi che descrivono passo
a passo quello che succede, utilizzando delle strutture
grafiche predefinite per evidenziare gli elementi tipici
della programmazione quali i salti condizionali, i loop (la
ripetizione di una serie di istruzioni), l'ingresso e l'uscita
di informazioni.
Un flusso può quindi essere basato su una "storia" come
quella di una luce temporizzata sulle scale(vedi flow
chart):
1. Predisposizione lampadina
2. Lettura stato del tasto:
chiuso (premuto)
aperto (rilasciato)
3. Se è chiuso si passa alla fase successiva, altrimenti
aspetto.
4. Se l'interruttore è chiuso allora, cambia lo stato della
lampadina aspettando un minuto
5. Quindi torno a controllare se l'interruttore è premuto
ricominciando da capo.
Guardando questo schema, si capisce sia cosa si deve fare per realizzare il programma,
sia cosa il programma stesso faccia nel suo complesso.
Due risultati molto importanti che dimostrano quanto l'ideazione del programma non sia
nella scrittura del codice, ma nella creazione di un diagramma di flusso dettagliato e
logicamente completo.
Non possiamo dire "funzionante" per un diagramma di flusso, ma è chiaro che la
completezza dal punto di vista logico presuppone che chi lo ha ideato si sia posto una
serie di domande alle quali ha dato una risposta esaustiva.
6
Spiegazione dell'Atmega328
Atmega328 è la sigla di questo microcontrollore. All'interno di questo componente viene
salvato il programma scritto dall'utente e tutta la configurazione di base che permette ad
Arduino un funzionamento corretto. Quando acquisterete Arduino Uno riceverete uno di
questi microcontrollori con solamente il Bootloader all'interno dell'ATMega328. Questo
"file" è una configurazione di base che permette l'utilizzo del software dedicato.
Questo setting puo' essere modificato per utilizzare un software differente e per modificare
la posizione e configurazione dei PIN.
Piedinatura del Microcontrollore ATMega328
7
8
Le OUTPUT PWM
La modulazione di larghezza di impulso,
dall’inglese pulse-width modulation o
PWM, è un tipo di modulazione digitale
che permette di ottenere una tensione
media variabile dipendente dal rapporto
fra durata dell’impulso positivo e di quello
negativo. Allo stesso modo è utilizzato
per protocolli di comunicazione in cui
l’informazione è codificata sotto forma di
durata nel tempo di ciascun impulso.
Grazie ai moderni microcontrollori è
possibile attivare o disattivare un
interruttore ad alta frequenza e, allo
stesso modo, rilevare lo stato e il periodo
di un impulso.
9
Descrizione
La durata di ciascun impulso può essere espressa in rapporto al periodo tra due impulsi
successivi, implicando il concetto di duty cycle. Un duty cycle pari a 0% indica un impulso
di durata nulla, in pratica assenza di segnale, mentre un valore del 100% indica che
l’impulso termina nel momento in cui inizia il successivo.
Applicazione
Una modulazione a larghezza di impulso è largamente utilizzata anche per regolare la
potenza elettrica inviata ad un carico, per esempio negli inverter, per regolare la velocità
dei motori a corrente continua e per variare la luminosità delle lampadine.
Come si può intuire, con un duty cycle pari a zero, la potenza trasferita è nulla, mentre al
100% la potenza corrisponde al valore al valore massimo trasferito nel caso non sia
presente il circuito di modulazione. Ogni valore intermedio determina una corrispondente
fornitura di potenza.
Il vantaggio di questa tecnica è ridurre drasticamente la potenza dissipata del circuito
limitatore rispetto all’impiego di transistor controllati analogicamente. In un
semiconduttore, la potenza dissipata è determinata dalla corrente che lo attraversa per la
differenza di potenziale presente ai suoi capi. In un circuito PWM, il transistor in un istante
conduce completamente, riducendo al minimo la caduta ai suoi capi, oppure non conduce
annullando la corrente
In entrambi i casi, la potenza dissipata è minima.
INPUT Analogici
Arduino dispone di alcuni pin analogici e di un relativo convertitore analogico/digitale
(ADC).
Un ADC converte dei valori di tensioni in bit, quindi la tensione diventa digitale per
essere gestita dal microcontrollore, come l’Atmel.
La precisione della conversione viene definita in bit di risoluzione. Maggiori sono i bit,
maggiore è la risoluzione.
Questi sono una sequenza in uscita digitale di 0 e 1 la cui combinazione è la tensione letta
in ingresso.
Gli ADC hanno una tensione di riferimento che termina il range in cui operano la lettura.
Per calcolare quanti possibili combinazioni possono esserci si usa la seguente formula
Per determinare a che tensione corrisponde un valore digitale con 8 bit di risoluzione (256
combinazioni) e una tensione di riferimento di 12V (o-12V):
12V/256 = 0.047V = 47mV per ogni valore
10
Il rapporto segnale/rumore un fattore importante soprattutto con tensioni basse e/o con
l’aumentare del bit di risoluzione.
Infatti, maggiore è la precisione in bit e minore è la variazione di tensione tra un valore e
l’altro di lettura.
Con il termine Sampling rate si definisce la frequenza di campionamento del ADC.
Infatti ADC non fa una lettura immediata, ma campiona in un strettissimo tempo una serie
di valori analogici in modo da avere una certa stabilità e poi converte la media. In questo
modo si migliora la precisione. Viene espressa in kSPS.
Gli ADC possono essere integrati nei microcontrollori, come nel caso di Arduino, oppure in
un chip specifico che poi viene collegato al microcontrollore tramite un bus, linee di
comunicazione di periferiche.
ADC integrato in Arduino dispone di una risoluzione di 10bit.
Se servisse maggior precisione, in casi estremi, possiamo collegare un ADC esterno ad
Arduino.
10bit sono sufficienti nella maggior parte dei casi.
Applicazioni
Gli ingressi analogici sono usati nei casi in cui si deve leggere una tensione analogica e
gestirla digitale,( per esempio una tensione di alimentazione, di un partitore di tensione,
sensori che forniscono in uscita tensione analogica come nel caso di alcuni sensori di
temperatura.)
La tensione di riferimento del ADC di default è quella di alimentazione, ma possiamo
definire un altro valore anche esterno.
Il pin indicato come AREF (Reference voltage for the analog inputs) definisce un
riferimento esterno per ADC e può avere un valore da 0 a 5V.
Questa tensione diventa il valore di riferimento della ADC con un range che va da 0 a
AREF, quindi con un valore 0 punti in digitale abbiamo una tensione di 0V e con 1023
punti abbiamo AREF.
La tensione può anche essere definita a livello software senza usare AREF.
Per usare tale riferimento oltre alla parte hardware con una tensione fissa sul pin AREF,
nel caso di un riferimento esterno, si deve indicare a livello di codice l’utilizzo di un
riferimento specifico.
Si definisce usando l’istruzione analgoReference(type)
Type può essere:
DEFAULT= analog reference di default pari a 5V o 3.3V (sulla scheda Arduino).
INTERNAL= built-in reference, uguale a 1.1V per ATmega168 o ATmega328 e 2.56V per
ATmega8 (non disponibile per Arduino Mega)
INTERNAL1V1= built-in 1.1V reference (solo per Arduino Mega)
INTERNAL2V56= built-in 2.56V reference (solo per Arduino Mega)
EXTERNAL= la tensione applicata l pin AREF (da 0 a 5V) è usata come reference.
11
12
La board Arduino UNO ha subito una revisione del hardware risepetto alle precednti (rev 1
e rev 2) con introduzione del PINOUT 1.0 e altre piccole modifiche, mantenendo la
compatibilità hardware e software con le precedenti.
13
Sono state introdotte:
1.Sono stati aggiunti nuovi due pin, SDA e SCL, dedicati al bus I2C.
Sono posti vicino al pin AREF e questi non sono altro che delle duplicazioni del pin
A4(SDA) e A5(SCL) usati per il bus I2C. Questo lo potete vedere anche sullo schema.
2.Vicino al pin di RESET è stato introdotto il pin IOREF, che serve come riferimento delle
tensioni di uscita del I/O per le varie schede opzionali (shields) in modo che si adeguino
alla tensione corretta. Nella board che usano AVR come la UNO e Mega 2560, queste
sono a 5V, mentre nella Arduino DUE è a 3,3V. E’ stato introdotto un ulteriore pin per
usi futuri.
3.Il convertitore USB passa dal ATMEGA8u2 (8K flash) al ATMEGA16u2 (16K flash).
Questa modifica per il momento non comporta variazioni importanti, ma visto una
maggiore memoria della flash, in futuro potrà essere usata per gestire periferiche come
tastiere e mouse USB, per esempio.
4.Migliorato il circuito di RESET. E’ stato spostato il pulsante vicino il connettore USB.
5.La parte posteriore della board ora è contradistinta dal colore bianco che dà un bel
effetto al design della board.
6.Le modifiche introdotte riguardano anche le board come Arduino MEGA2560.
Istruzioni standard di Arduino
Qui di seguito sono riportate le istruzioni standard supportate dal linguaggio di
programmazione di Arduino (derivato dal C e C++).
STRUTTURA
Il codice di qualsiasi programma per Arduino è composto essenzialmente da due parti:
void setup() - Questo è il posto dove mettiamo il codice di inizializzazione.
Inizializza tutte le impostazioni e le istruzioni della scheda (gli INPUT e OUTPUT) prima
che il ciclo principale del programma si avvii.
void loop() - E' il contenitore del codice principale del programma.
Contiene una serie di istruzioni che possono essere ripetute una dopo l'altra fino a quando
non spegniamo la scheda Arduino.
Precisiamo che prima di void setup(), esiste una teza parte:
bisogna dichiarare le variabili utilizzate e le costanti.
14
Dichiarare vuol dire assegnare ad ogni variabile e costante che si utilizzerà nel void
loop() un valore o un tipo in base all’utilizzo che ne faremo.
Per esempio:
Val int =0; // Definiamo la variabile Val come variabile int( integer) e assegnamo ad essa
il valore 0
COSTANTI
Nella scheda Arduino è inserita una serie predefinita di parole chiave con valori speciali.
HIGH e LOW sono usati per esempio quando si vuole accendere o spegnere un Pin di
Arduino. INPUT e OUTPUT sono usate per definire se uno specifico Pin deve essere un
dato di entrata o un dato di uscita. TRUE e FALSE indicano il rispettivo significato italiano:
se abbiamo un'istruzione, la condizione può essere vera o falsa.
VARIABILI
Sono aree della memoria di Arduino dove si possono registrare dati e intervenire all’interno
del programma. Come dice il nome stesso, le variabili possono essere cambiate tutte le
volte che vogliamo. Quando si dichiara una variabile bisogna dichiararne anche il tipo.
Questo significa dire al processore le dimensioni del valore che si vuole memorizzare. Ne
esistono di diversi tipi:
boolean - Può assumere solamente due valori: vero o falso.
char - Contiene un singolo carattere.
L'Arduino lo registra come un numero (ma noi vediamo il testo). Quando i caratteri sono
usati per registrare un numero, possono contenere un valore compreso tra -128 e 127.
byte - Può contenere un numero tra 0 e 255.
Come un carattere usa solamente un byte di memoria.
int - Contiene un numero compreso tra -32'768 e 32'767.
E' il tipo di variabile più usata e usa 2 byte di memoria.
unsigned int - Ha la stessa funzione di int, solo che non può contenere numeri negativi,
ma numeri tra 0 e 65.535.
long - E' il doppio delle dimensioni di un int e contiene i numeri da -2'147'483'648 a
2'147'483'647.
unsigned long - Versione senza segno di long va da 0 a 4'294'967''295.
15
float - Può memorizzare numeri con la virgola. Occupa 4 bytes della RAM.
double - A doppia precisione in virgola mobile con valore massimo di
1'7976931348623157x10^308.
string - Un set di caratteri ASCII utilizzati per memorizzare informazioni di testo.
Per la memoria, usa un byte per ogni carattere della stringa, più un carattere NULL che
indica ad Arduino la fine della stringa. Esempio:
char string1[] = "Hello"; // 5 caratteri+carattere NULL
char string2[6]="Hello" // La stessa cosa di sopra
array - un elenco di variabili accessibili tramite un indice. Vengono utilizzate per creare
tabelle di valori facilmente accessibili. Come esempio se si vuole memorizzare diversi livelli
di luminosità di un LED possiamo creare 4 variabili, una per ogni livello di luminosità.
Si può utilizzare una semplice array come:
int Luce[5]={0,25,50,100};
Nel tipo della variabile la parola "array" non si dichiara, ma si usano i simboli [] e {}.
ISTRUZIONI
Istruzioni sono tutti quei comandi all’interno del programma che comandano delle variabili
Un esempio di Blocco di Istruzioni per ARDUINO:
{
digitalWrite (pin, HIGH); // il 'pin' è su
delay (1000); // un secondo di pausa
digitalWrite (pin, LOW); // il 'pin' è giù
delay (1000); // un secondo di pausa
}
N.B. ogni istruzione deve sempre terminare con ";".
ogni istruzione deve essere racchiuso tra parentesi graffe.
Le istruzioni del Preprocessore NON vanno racchiuse col “;”.
"//" è usato per inserire commenti che non saranno eseguiti dal
programma.
16
FUNZIONI
Una funzione è un blocco di codice che ha un nome ben definito, quindi è un blocco di
istruzioni che vengono eseguiti quando la funzione viene chiamata.
Le funzioni sono utilizzate per eseguire operazioni ripetitive in modo da ridurre il codice
programma ed evitare quindi confusione nel programma stesso.
Le funzioni sono dichiarate all’inizio del programma e specificate dal tipo di funzione.
Una funzione è come una scatola chiusa (blackbox) alla quale vengono passati dei valori
(parametri) e dalla quale si ricevonoo un risultato che dipende dai valori in ingresso.
Chiaramente quando si costruisce una funzione si deve assegnare un nome che ne renda
immediatamente evidente lo scopo.
La struttura della funzione è la seguente:
<Tipo del valore restituito> <nome funzione> ( <elenco dei parametri> )
Dopo il tipo, occorre dichiarare il nome dato alla funzione e tra parentesi i parametri che
vengono passati alla funzione.
Un esempio di dichiarazione di Funzione per ARDUINO:
int delayVal() // funzione senza parametri
{
int v; // dichiaro la variabile
v = analogRead(pot); // funzione arduino
v = v / 4; // espressione aritmetica
return v; // valore di ritorno della funzione
}
STRUTTURE DI CONTROLLO
Il linguaggio di Arduino include parole chiave per controllare il progetto logico del nostro
codice.
If - L’istruzione if verifica se una certa condizione.Se l’espressione è vera lo sketch esegue
le istruzioni che seguono.Se falsa il programma ignora la dichiarazione. Esempio:
if (variabile == valore)
{
// esegue blocco di istruzioni
}
If…else - Permette di prendere delle decisioni all’interno del programma, ma deve essere
seguito da una domanda sotto forma di espressione tra parentesi. Se la domanda è vera
tutto ciò che segue verrà eseguito. Se falso verrà eseguito tutto il codice che segue else.
If è possibile usarlo senza usare necessariamente else. Esempio:
17
if (val=1)
{digitalWrite(LED, HIGH);} // (val=1) è la domanda se è vera esegue ciò che è fra
parentesi
For - Ripete il codice per un numero predefinito di volte.
for(int i=0;i<10;i++)
{Serial.print(“Ciao”);} //stampa 10 volte “Ciao”
Switch - E’ come un interruttore nel corso del programma. Fa prendere al programma
diverse direzioni in base al valore della variabile (il suo nome deve essere messo
tra parentesi dopo switch). E’ utile perché può sostituire lunghe serie di if.
switch(valore sensore)
{case 38: digitalwrite(12, High);
break;
case 55: digitalwrite(3, High);
break;
default: // si usa per indicare tutti i casi in cui non è ne 38 ne 55
digitalwrite(12, Low);
digitalwrite(13, Low);}
While - Esegue un blocco di codice fino a quando una certa condizione posta tra le
parentesi è vera.
while(valore sensore<500)
{digitalWrite(13, HIGH);
delay(100);
digitalWrite (13, HIGH);
delay(100);
Valoresensore=analogRead(1); }
Do…While - E’ uguale a while solo che il codice è avviato prima che la condizione sia
verificata. Si usa quando si vuole eseguire il codice almeno una volta prima che la
condizione sia valutata. Esempio:
do {digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,HIGH);
delay (100);
valore sensore=analogread(1); }
Break - Questo termine consente di bloccare il ciclo e continuare ad eseguire il codice
fuori dal ciclo. Viene utilizzato anche per separare le varie condizioni nella funzione Switch.
18
Continue - Questo comando fa saltare il resto del codice all’interno del ciclo, e riavvia il
ciclo. Esempio:
for(luminosità=0; luminosità<200; luminosità++)
f((x>120) && (x<180)) continue;
analogWrite(PWMPin, luminosità);
delay(20);}
Return - Ferma una funzione che si sta eseguendo e restituisce un risultato. E’ possibile
infatti usarlo per restituire un valore da una funzione. Esempio chiama una funzione
“calcolaumidità” e ritorna il valore dell’umidità.
Int calcolaumidità()
{Int umidità=0;
umidità0(analogread(0)+45/100)/100;
return umidità;}
OPERAZIONI ARITMETICHE
Si può usare Arduino per compiere operazioni matematiche complesse con una semplice
sintassi: + e – indicano addizione e sottrazione, * indica la moltiplicazione, e / la divisione.
C’è un operatore in più in questo linguaggio chiamato “Modulo” che è un comando che
restituisce il resto di una divisione. Esempio:
a=3+3; luminosità=((12*valore sensore)/4);
OPERATORI DI COMPARAZIONE
Quando si specificano delle condizioni ci sono vari operatori che tu puoi usare:
== Uguale a
> maggiore di
< minore di
!= diverso da
<= minore o uguale
>= maggiore o uguale
19
OPERATORI BOOLEANI
Sono usati quando si vogliono combinare più condizioni, ad esempio se vogliamo verificare
se il valore di un sensore è tra 1 e 5
basta scrivere:
if(sensore=>1) && (sensore=<=5);
Esistono tre tipi di operazioni booleane: &&(And), ||(Or), !(Not).
OPERATORI COMPUTAZIONALI
Servono a ridurre la mole di un codice e a renderlo più semplice e chiaro per operazioni
semplici come incrementare o decrementare una variabile.
Esempio: val=val+1; è come dire val++
incremento (++) e decremento (--)
++ e -- incrementano/decrementano una variabile di 1; lo stesso è applicabile a +=, -=,
*=, /= .
Esempio: le seguenti espressioni sono equivalenti:
val=val+5;
Val+=5;
FUNZIONI INPUT E OUTPUT
Arduino include funzioni per la gestione degli Input e degli Output.
pinMode(pin,mode) - Riconfigura un pin digitale a comportarsi come uscita o come
entrata.
pinMode(13,INPUT) - imposta il pin 13 come Input.
digitalWrite(pin,value) - imposta un pin digitale ad ON o a OFF.
digitalWrite(7,HIGH) - imposta come digitale il pin 7.
int digitalRead(pin) - Legge lo stato di un input Pin, ritorna HIGH se il Pin riceve
della tensione oppure LOW se non c’è tensione applicata.
20
Val=digitalRead(7); // legge il pin 7 dentro a val
Int analogRead(pin) - Legge la tensione applicata a un ingresso analogico e ritorna un
numero tra 0 e 1023 che rappresenta le tensioni tra 0 e 5 V.
Val=AnalogRead(0); // legge l’ingresso analogico 0 dentro a val
analogWrite(pin,value) - Cambia la frequenza PWM su uno dei pin segnati PWM, nella
voce pin si può mettere 11 10 9 6 5 3,
value invece può essere un valore da 0 a 255 che rappresenta la scala da 0 a 5 V.
analogWrite(9,128);
shiftOut(dataPin, clock, Pin, bit, Order, value) - Invia i dati ad un registro. Questo
protocollo usa un pin per i dati e uno per il clock. bitOrder indica l'ordine dei bytes (least
significant byte=LSB, most significant byte=LMB) e value è il byte da inviare. Esempio:
shiftOut(dataPin, Clock Pin, LSBFIRST, 255);
insigned long pulseIn(pin, value) - misura la durata degli impulsi in arrivo su uno
degli ingressi digitali. E’ utile ad esempio per leggere alcuni sensori a infrarossi o
alcuni accelerometri che emettono impulsi di diversa durata.
Tempo=pulsin(8,HIGH);
FUNZIONI DI TEMPO
Arduino include alcune funzioni per misurare il tempo trascorso e anche per mettere in
pausa il nostro programma.
Insigned long millis() - Ritorna il numero in millisecondi trascorsi dall’inizio del
programma, esempio:
durata=millis()-tempo // calcola il tempo trascorso prima di “tempo”
delay(ms) - Mette in pausa il programma per un numero di millisecondi specificato.
delay(1000); //stoppa il programma per 1 secondo
delayMicroseconds(us) - Come delay mette in pausa il programma ma l’unità di misura
è molto più piccola, parliamo di microsecondi.
delayMicroseconds(2000); // aspetta per 2 millisecondi (1000us=1ms)
21
FUNZIONI MATEMATICHE
Arduino include molte funzioni matematiche comuni. Servono, per esempio, per trovare il
numero max o il numero min.
min (x,y) - Ritorna il più piccolo fra x e y. Esempio:
Val= min(5,20); // val adesso è 5
max(x,y) - Ritorna il più grande fra x e y.
abs(x) - Ritorna il valore assoluto di x, ossia trasforma i numeri negativi in numeri
positivi. Se x fosse 5 ritorna 5, ma anche se x fosse -5 ritorna sempre 5. Esempio:
Val= abs(-5); // val vale 5
constrain(x,a,b) - Ritorna il valore "x" costretta tra "a" e "b". Ciò vuol dire che se "x"
è minore di "a" ritornerà semplicemente "a" e se x è maggiore di "b" restituirà
semplicemente il valore di "b".
map(value, fromLow, fromHigh, toHigh) - Associa un valore che sta nel range
fromLow e maxlow in un nuovo range che va
da toLow a toHigh. E’ molto utile per processare valori provenienti da sensori analogici.
Esempio:
Val=map(analogRead(0),0,1023,100,200); // associa il valore analogico 0 ad un valore
tra 100 e 200
double pow(base,exponent) - Restituisce come risultato la potenza di un numero. Si
deve indicare la base e l’esponente.
Double sqrt(x) - Restituisce la radice quadrata di un numero x.
Double sin(rad) - Restituisce il seno dell’angolo specificato in radianti. Esempio:
Double sine= sine(2); // circa 0.909297370
Double cos(rad) - Restituisce il coseno dell’ angolo specificato in radianti.
Double tan(rad) - Restituisce il valore della tangente di un angolo specificato in radianti.
22
FUNZIONI NUMERI RANDOM
Se si ha bisogno di generare numeri random (a caso), Arduino ci viene incontro con alcuni
comandi standard per generarli.
randomSeed(seed) - Anche se la distribuzione di numeri restituita dal comando
random() è essenzialmente casuale, la sequenza è prevedibile. randomSeed(seed)
inizializza il generatore di numeri pseudo-casuali, facendola partire da un punto arbitrario
nella sua sequenza casuale.
Long random(min,max) - Restituisce un valore long intero di valore compreso fra min e
max -1. Se min non è specificato il suo
valore minimo è 0. Esempio:
long random= random(13); // numero compreso fra 0 e 12
COMUNICAZIONE SERIALE
Queste sono le funzione seriali cioè quelle funzioni che Arduino usa per comunicare
tramite la porta Usb del nostro Pc.
Serial.begin(speed) - Prepara Arduino a mandare e a ricevere dati tramite porta seriale.
Possiamo usare generalmente 9600 bits per secondo con la porta seriale dell’Arduino, ma
sono disponibili anche altre velocità, di solito non si supera i 115.200 bps.
Serial.print(data)Serial.begin(9600);
Serial.print(data,codifica) - Invia alcuni dati alla porta seriale. La codifica è opzionale.
Serial.print(32); // stampa 32
Serial.Print(32, DEC); // stampa 32 come sopra
Serial.Print(32, OCT); // 40 (stampa10 in ottale)
Serial.Print(32 , BIN); // 100000 (stampa 10 in binario)
Serial.Print(32 , BYTE); // “Space” valore associato nella tabella ASCII
Int Serial.available() - Ritorna quanti bytes non ancora letti sono disponibili sulla porta
Serial per leggerli tramite la funzione read(). Dopo aver read() tutti i bytes disponibili
Serial.Available restituisce 0 fino a quando nuovi dati non giungono sulla Porta.
23
Int.Serial.read() - Recupera un byte di dati in entrata sulla porta Seriale.
int data= Serial.read();
Poichè i dati possono giungere nella porta seriale prima che il programma li possa
leggere(per la velocità), Arduino salva tutti i dati in un buffer. Se è necessario ripulire il
buffer e aggiornarlo con i dati aggiornati, usiamo la funzione flush().
Serial.flush();
Conclusioni
Con questa prima guida, si è cercato di spiegare in cosa consiste Arduino:
la storia della board, la parte hardware e la parte software.
Sono stati trattati e illustrati i processi di cablaggio e le principali istruzioni per la stesura
degli sketch.
Crediamo che come introduzione al fantastico Mondo dei maker (coloro che ideano,
progettano e realizzano) le informazioni ricevute siano sufficienti per iniziare a prendere
confidenza con la board e il programma di editazione.
Flaviano Fior

Arduino prima spiegazione

  • 1.
    1 ARDUINO Introduzione Su internet èpossibile trovare molti testi, articoli, presentazioni, siti internet e quant’altro. Lo scopo di questo trattato e dei successivi, è quello di realizzare una guida introduttiva ad Arduino, spiegando in cosa consiste la board, le basi e la logica di programmazione. Questo non vuol essere una sostituzione ai numerosi libri già presenti, bensì una guida veloce e pratica per i programmatori di domani. Presentazione Arduino nasce ad Ivrea, nel 2005, da un'idea di un professore universitario, un Ingegnere Elettronico, Massimo Banzi, che decise di creare una piattaforma per i propri studenti, per facilitarli nello studio dell'Interaction Design. E’ una piattaforma low-cost hardware e software programmabile, con la quale è possibile creare circuiti per svariate applicazioni, specialmente in ambito di robotica ed automazione. Il cuore della board è un Microcontrollore della ATMEL: per esempio Arduino Uno monta un ATMega328. Dal punto di vista Hardware, la scheda di Arduino ( facciamo l’esempio di Arduino UNO) è pronta all’uso: nel suo circuito è integrato tutto il necessario per programmare il microcontrollore collegando la scheda semplicemente alla porta USB del PC. Può essere alimentato tramite un connettore di alimentazione o una porta usb. Possiede un integrato che fa da convertitore USB/Seriale, un LED di accensione, un LED di controllo collegato al PIN 13, due led di segnalazione TX/RX, i connettori femmina per il collegamento degli ingressi/uscite tramite cavetti per breadboard e, in fine, il controllore Atmega328 con bootloader Arduino già caricato. La parte Software invece è rappresentata dal citato bootloader, dalle librerie e dall’IDE, ovvero l’ambiente di sviluppo, l’interfaccia che permette di programmare la nostra scheda Arduino. Il bootloader precaricato sull’Atmega è quello che permette la comunicazione seriale con il nostro PC. Senza il bootloader, per caricare gli sketch (i nostri “programmi”), avremmo bisogno di un programmatore esterno più costoso, un po’ più macchinoso da utilizzare e più lento nel caricare gli sketch. Il bootloader è quindi un “mini” programma(0.5 kB), residente nella flash memory del microcontrollore, il cui compito è quello di caricare i nostri sketch compilati, all’interno della memoria flash del microcontrollore tramite comunicazione seriale/usb, facendo si che tale programmazione non vada a sovrascrivere la zona di memoria dove è presente il bootloader. Vien da se che, quando facciamo l’upload di uno sketch, quest’ultimo verrà localizzato in una zona di memoria libera evitando la sovrascrittura del bootloader.
  • 2.
    2 In questo modoaprendo l’IDE e selezionando la porta seriale del PC possiamo caricare i nostri sketch con un semplice tasto ed in pochi secondi. L’upload avviene tramite la porta seriale emulata dall’USB, che va a collegarsi ai PIN TX e RX dell’Atmega (piedini rispettivamente 3 e 2). Un’altra parte estremamente importante del software sono le librerie. Tali librerie, da importare secondo necessità, aggiungono svariate funzioni che permettono di semplificare enormemente il codice che si scriverà, rendendolo molto più fruibile rispetto a quello standard del microcontrollore. Il tutto viene gestito tramite l’ambiente di sviluppo (IDE): - Stesura degli sketch - Salvataggio (save) - Compilazione (verify) - Caricamento (Upload) Il grande lavoro di semplificazione del progetto Arduino, sia a livello software, sia a livello hardware, ha reso veramente minimali i requisiti per utilizzare il sistema. Ovviamente serve un personal computer che sia in grado di far funzionare applicazioni in Java, con i seguenti sistemi operativi: Windows Xp, Vista e Seven (Windows 2000 ha dei problemi di driver); Mac, purché abbiano Mac OS X 10.3.9 o superiore; Linux con Ubuntu, Debian, Gentoo e molte altre distribuzioni, ricordando che con Linux c'è da faticare un pochino per predisporre tutti i programmi e le librerie richieste. Il sito di Arduino dispone di un'area dedicata all'installazione su Linux (arduino.cc/ playground/Learning/Linux) e ti consigliamo di partire da lì se hai intenzione di usare questo sistema operativo. Dato che il sistema di sviluppo è scritto in Java. L’IDE di Arduino UNO richiede una versone di Java correttamente installata e funzionante. A tal proposito, consigliamo di visionare il sito www.java.com e utilizzare il collegamento "lo ho Java?" per verificare lo stato del computer. La pagina verifica la situazione del software e fornisce le indicazioni, che possono essere una richiesta di installazione, l'aggiornamento o un "tutto OK". Suggeriamo questa soluzione in quanto è molto probabile che si possieda già sul computer qualche versione dell'ambiente runtime di Java, quindi l’aggiornamento fatto con le procedure dal sito risultano le più pratiche e veloci. Scarichiamo e installiamo l'IDE Nella confezione di Arduino UNO non è presente alcun dischetto o memoria contenente il software. Bisogna obbligatoriamente andare online su internet e scaricarlo dalla pagina "arduino.cc/en/Main/Software". Qui si trovano le varie versioni disponibili per le relative piattaforme supportate. Una volta terminato il download, basterà estrarre tutto il contenuto dalla cartella compressa appena scaricata. L’unico eseguibile nella cartella principale è "arduino.exe" e determina il lancio dell'ambiente integrato di sviluppo (IDE) scritto in Java. Colleghiamo l’hardware Questa fase, con il primo collegamento, richiede un pò di attenzione in quanto in quanto il computer deve installare il driver da usb a seriale indispensabile per per far pilotare la scheda dall’IDE. Se il computer non è stato utilizzato in precedenza con schede Arduino, dispone di Windows XP e ha avuto una "intensa vita" di collegamenti a periferiche e dispositivi vari,
  • 3.
    3 potrebbe avere qualchedifficoltà a riconoscere la scheda nel modo corretto. Si tratta di una possibilità remota, ma con Windows XP e i driver USB, le sorprese sono sempre dietro l'angolo. Con Vista e Seven, l'installazione non presenta difficoltà specifiche purché si rispetti la procedura indicata. Per Prima cosa, bisogna procurarsi il cavetto di collegamento fra scheda Arduino UNO e personal computer. Si tratta di un cavetto che da una parte ha un maschio USB di Tipo A - da collegare al computer - e dall'altra un maschio USB Tipo B da collegare alla scheda. Dato che il connettore Tipo B non è più molto diffuso, potrebbe essere difficile trovare il cavetto necessario nel negozio d'informatica sotto casa. Con Seven e Vista l'installazione automatica potrebbe non andare a buon fine e si ottiene un dispositivo sconosciuto fra quelli elencati fra le risorse. Nessun problema perché da questo punto è semplice sistemare le cose. Con il tasto destro sul "Dispositivo sconosciuto” selezionare “Aggiorna Driver” per cercare il driver giusto che si trova nella cartella Drivers; premere “OK” e lasciare la scheda collegata alla porta USB. Se durante l’installazione appare qualche finestra relativa alla mancanza della firma del driver ect, proseguire facendo click su “continua”. Finita l’installazione , da ora in poi, ogni volta che si collegherà Arduino Uno al PC, questo lo riconoscerà come una periferica di tipo seriale da COM1 in poi. Per collaudare l’installazione si terminare la sessione del sistema operativo e riavviare il PC senza collegare la scheda , quindi collegarla e vedere se viene riconosciuta correttamente. La seconda manovra di collaudo consiste nel caricare uno sketch di esempio, compilandolo e scaricandolo sulla scheda di Arduino UNO. Per far questo, lanciare l’IDE e dal menù “File” scegliere “Examples> Basic> Blink”; si aprirà una finestra completa di IDE con il codice dello sketch caricato e pronto all’uso. Premere il tasto “Verify” e nella barra in basso appare la scritta “Compiling…” e dopo qualche istante la conferma della creazione del codice oggetto pronto per essere caricato; premere il pulsante upload e osservare il lampeggio dei led TX ed RX della scheda di Arduino in varie ondate che conferma l’avvenuto caricamento del programma. Al termine si avrà come effetto che il LED collegato al pin 13 e contrassegnato dalla scritta “LED” sulla scheda lampeggerà lentamente con la cadenza di un secondo acceso e un secondo spento. Adesso prova tu qualche piccola modifica al programma……….(per esempio accelera la velocità di lampeggio).
  • 4.
    4 La soluzione realizzataper programmare la scheda di Arduino UNO nasconde tutta una serie di passaggi, di configurazione e di programmi che altrimenti avrebbero richiesto capacità e preparazione per essere messi a punto e utilizzati. Il grande lavoro svolto dal team di Arduino è stato quindi, in gran parte, creare l’ambiente di sviluppo (IDE) grazie al quale sembra tutto molto più semplice e lineare, mentre dietro all’interfaccia scritta in linguaggio Java si trovano migliaia di file che permettono al computer di trasformare il programma nel modo opportuno e riducendo al minimo l’insorgere di problemi di compilazione( il processo che trasforma il programma scritto con il linguaggio ad alto livello in codice macchine adatto al microcontrollore presente sulla scheda) . Oltre a creare il codice e a scaricarlo sul microcontrollore della scheda (upload), l’IDE permette anche di raccogliere informazioni di ritorno dalla scheda stessa. Con la sua schiera di porte e di pin di ingresso e di uscita, Arduino è in grado di acquisire informazioni da una miriade di sensori e dispositivi elettronici, potendo allo stesso tempo accendere luci, pilotare motori, emettere suoni , attivare dispositivi. Una volta ultimato il processo creativo e di programmazione, Arduino UNO potrà anche operare senza PC,autonomamente, eseguendo le istruzioni inserite al suo interno. I programmi di Arduino(il linguaggio usato è una versione semplificata del C/C++, arricchito da una serie di funzioni specifiche della scheda) si chiamano sketch cioè bozzetti. Arduino resta un mucchietto di elettronica se non si aggiungono idee e creatività. Quest’ultima, insieme alle capacità personali di ideare progetti per Arduino UNO, vanno quindi stimolate sperimentando un po’ in tutti i vari campi applicativi. Ma come strutturare le idee affinché possano diventare un programma? Basta trasformarle in piccoli passi logici che descrivono funzionalmente quello che deve succedere. Il primo passo è la creazione di un diagramma di flusso(flow chart); i diagrammi di flusso sono di per sé una forma di programmazione e sono ad un livello tale di astrazione da essere da un lato comprensibili a tutti e dall’altro sufficienti a descrivere un programma nella sua totalità. Con un programma di flusso ben fatto, un “programmatore” è in grado di scrivere il codice, mentre l’autore è in grado di dettagliare Arduino Uno Rev3 è una scheda elettronica con le seguenti caratteristiche:  Microcontrollore: ATmega328  Tensione di funzionamento: 5 V  Tensione di alimentazione (raccomandata): da 7 a 12 V  Tensione di alimentazione (limiti): 6-20V  Ingressi/uscite Digitali: 14 (di cui 6 possono essere utilizzate come uscite PWM)  Ingressi analogici: 6  Corrente Dc per pin I/O: 40 mA  Corrente DC per pin 3,3 V: 50 mA  Memoria Flash: 32 kB (di cui 0,5 kB utilizzati dal bootloader)  SRAM: 2 kB  EEPROM: 1 kB  Velocità di Clock : 16 MHz
  • 5.
    5 ciascuna funzione senzaconoscere le caratteristiche specifiche del linguaggio di programmazione che verrà utilizzato. Per fare qualche esempio, un diagramma di flusso può essere visto come una serie di frasi che descrivono passo a passo quello che succede, utilizzando delle strutture grafiche predefinite per evidenziare gli elementi tipici della programmazione quali i salti condizionali, i loop (la ripetizione di una serie di istruzioni), l'ingresso e l'uscita di informazioni. Un flusso può quindi essere basato su una "storia" come quella di una luce temporizzata sulle scale(vedi flow chart): 1. Predisposizione lampadina 2. Lettura stato del tasto: chiuso (premuto) aperto (rilasciato) 3. Se è chiuso si passa alla fase successiva, altrimenti aspetto. 4. Se l'interruttore è chiuso allora, cambia lo stato della lampadina aspettando un minuto 5. Quindi torno a controllare se l'interruttore è premuto ricominciando da capo. Guardando questo schema, si capisce sia cosa si deve fare per realizzare il programma, sia cosa il programma stesso faccia nel suo complesso. Due risultati molto importanti che dimostrano quanto l'ideazione del programma non sia nella scrittura del codice, ma nella creazione di un diagramma di flusso dettagliato e logicamente completo. Non possiamo dire "funzionante" per un diagramma di flusso, ma è chiaro che la completezza dal punto di vista logico presuppone che chi lo ha ideato si sia posto una serie di domande alle quali ha dato una risposta esaustiva.
  • 6.
    6 Spiegazione dell'Atmega328 Atmega328 èla sigla di questo microcontrollore. All'interno di questo componente viene salvato il programma scritto dall'utente e tutta la configurazione di base che permette ad Arduino un funzionamento corretto. Quando acquisterete Arduino Uno riceverete uno di questi microcontrollori con solamente il Bootloader all'interno dell'ATMega328. Questo "file" è una configurazione di base che permette l'utilizzo del software dedicato. Questo setting puo' essere modificato per utilizzare un software differente e per modificare la posizione e configurazione dei PIN. Piedinatura del Microcontrollore ATMega328
  • 7.
  • 8.
    8 Le OUTPUT PWM Lamodulazione di larghezza di impulso, dall’inglese pulse-width modulation o PWM, è un tipo di modulazione digitale che permette di ottenere una tensione media variabile dipendente dal rapporto fra durata dell’impulso positivo e di quello negativo. Allo stesso modo è utilizzato per protocolli di comunicazione in cui l’informazione è codificata sotto forma di durata nel tempo di ciascun impulso. Grazie ai moderni microcontrollori è possibile attivare o disattivare un interruttore ad alta frequenza e, allo stesso modo, rilevare lo stato e il periodo di un impulso.
  • 9.
    9 Descrizione La durata diciascun impulso può essere espressa in rapporto al periodo tra due impulsi successivi, implicando il concetto di duty cycle. Un duty cycle pari a 0% indica un impulso di durata nulla, in pratica assenza di segnale, mentre un valore del 100% indica che l’impulso termina nel momento in cui inizia il successivo. Applicazione Una modulazione a larghezza di impulso è largamente utilizzata anche per regolare la potenza elettrica inviata ad un carico, per esempio negli inverter, per regolare la velocità dei motori a corrente continua e per variare la luminosità delle lampadine. Come si può intuire, con un duty cycle pari a zero, la potenza trasferita è nulla, mentre al 100% la potenza corrisponde al valore al valore massimo trasferito nel caso non sia presente il circuito di modulazione. Ogni valore intermedio determina una corrispondente fornitura di potenza. Il vantaggio di questa tecnica è ridurre drasticamente la potenza dissipata del circuito limitatore rispetto all’impiego di transistor controllati analogicamente. In un semiconduttore, la potenza dissipata è determinata dalla corrente che lo attraversa per la differenza di potenziale presente ai suoi capi. In un circuito PWM, il transistor in un istante conduce completamente, riducendo al minimo la caduta ai suoi capi, oppure non conduce annullando la corrente In entrambi i casi, la potenza dissipata è minima. INPUT Analogici Arduino dispone di alcuni pin analogici e di un relativo convertitore analogico/digitale (ADC). Un ADC converte dei valori di tensioni in bit, quindi la tensione diventa digitale per essere gestita dal microcontrollore, come l’Atmel. La precisione della conversione viene definita in bit di risoluzione. Maggiori sono i bit, maggiore è la risoluzione. Questi sono una sequenza in uscita digitale di 0 e 1 la cui combinazione è la tensione letta in ingresso. Gli ADC hanno una tensione di riferimento che termina il range in cui operano la lettura. Per calcolare quanti possibili combinazioni possono esserci si usa la seguente formula Per determinare a che tensione corrisponde un valore digitale con 8 bit di risoluzione (256 combinazioni) e una tensione di riferimento di 12V (o-12V): 12V/256 = 0.047V = 47mV per ogni valore
  • 10.
    10 Il rapporto segnale/rumoreun fattore importante soprattutto con tensioni basse e/o con l’aumentare del bit di risoluzione. Infatti, maggiore è la precisione in bit e minore è la variazione di tensione tra un valore e l’altro di lettura. Con il termine Sampling rate si definisce la frequenza di campionamento del ADC. Infatti ADC non fa una lettura immediata, ma campiona in un strettissimo tempo una serie di valori analogici in modo da avere una certa stabilità e poi converte la media. In questo modo si migliora la precisione. Viene espressa in kSPS. Gli ADC possono essere integrati nei microcontrollori, come nel caso di Arduino, oppure in un chip specifico che poi viene collegato al microcontrollore tramite un bus, linee di comunicazione di periferiche. ADC integrato in Arduino dispone di una risoluzione di 10bit. Se servisse maggior precisione, in casi estremi, possiamo collegare un ADC esterno ad Arduino. 10bit sono sufficienti nella maggior parte dei casi. Applicazioni Gli ingressi analogici sono usati nei casi in cui si deve leggere una tensione analogica e gestirla digitale,( per esempio una tensione di alimentazione, di un partitore di tensione, sensori che forniscono in uscita tensione analogica come nel caso di alcuni sensori di temperatura.) La tensione di riferimento del ADC di default è quella di alimentazione, ma possiamo definire un altro valore anche esterno. Il pin indicato come AREF (Reference voltage for the analog inputs) definisce un riferimento esterno per ADC e può avere un valore da 0 a 5V. Questa tensione diventa il valore di riferimento della ADC con un range che va da 0 a AREF, quindi con un valore 0 punti in digitale abbiamo una tensione di 0V e con 1023 punti abbiamo AREF. La tensione può anche essere definita a livello software senza usare AREF. Per usare tale riferimento oltre alla parte hardware con una tensione fissa sul pin AREF, nel caso di un riferimento esterno, si deve indicare a livello di codice l’utilizzo di un riferimento specifico. Si definisce usando l’istruzione analgoReference(type) Type può essere: DEFAULT= analog reference di default pari a 5V o 3.3V (sulla scheda Arduino). INTERNAL= built-in reference, uguale a 1.1V per ATmega168 o ATmega328 e 2.56V per ATmega8 (non disponibile per Arduino Mega) INTERNAL1V1= built-in 1.1V reference (solo per Arduino Mega) INTERNAL2V56= built-in 2.56V reference (solo per Arduino Mega) EXTERNAL= la tensione applicata l pin AREF (da 0 a 5V) è usata come reference.
  • 11.
  • 12.
    12 La board ArduinoUNO ha subito una revisione del hardware risepetto alle precednti (rev 1 e rev 2) con introduzione del PINOUT 1.0 e altre piccole modifiche, mantenendo la compatibilità hardware e software con le precedenti.
  • 13.
    13 Sono state introdotte: 1.Sonostati aggiunti nuovi due pin, SDA e SCL, dedicati al bus I2C. Sono posti vicino al pin AREF e questi non sono altro che delle duplicazioni del pin A4(SDA) e A5(SCL) usati per il bus I2C. Questo lo potete vedere anche sullo schema. 2.Vicino al pin di RESET è stato introdotto il pin IOREF, che serve come riferimento delle tensioni di uscita del I/O per le varie schede opzionali (shields) in modo che si adeguino alla tensione corretta. Nella board che usano AVR come la UNO e Mega 2560, queste sono a 5V, mentre nella Arduino DUE è a 3,3V. E’ stato introdotto un ulteriore pin per usi futuri. 3.Il convertitore USB passa dal ATMEGA8u2 (8K flash) al ATMEGA16u2 (16K flash). Questa modifica per il momento non comporta variazioni importanti, ma visto una maggiore memoria della flash, in futuro potrà essere usata per gestire periferiche come tastiere e mouse USB, per esempio. 4.Migliorato il circuito di RESET. E’ stato spostato il pulsante vicino il connettore USB. 5.La parte posteriore della board ora è contradistinta dal colore bianco che dà un bel effetto al design della board. 6.Le modifiche introdotte riguardano anche le board come Arduino MEGA2560. Istruzioni standard di Arduino Qui di seguito sono riportate le istruzioni standard supportate dal linguaggio di programmazione di Arduino (derivato dal C e C++). STRUTTURA Il codice di qualsiasi programma per Arduino è composto essenzialmente da due parti: void setup() - Questo è il posto dove mettiamo il codice di inizializzazione. Inizializza tutte le impostazioni e le istruzioni della scheda (gli INPUT e OUTPUT) prima che il ciclo principale del programma si avvii. void loop() - E' il contenitore del codice principale del programma. Contiene una serie di istruzioni che possono essere ripetute una dopo l'altra fino a quando non spegniamo la scheda Arduino. Precisiamo che prima di void setup(), esiste una teza parte: bisogna dichiarare le variabili utilizzate e le costanti.
  • 14.
    14 Dichiarare vuol direassegnare ad ogni variabile e costante che si utilizzerà nel void loop() un valore o un tipo in base all’utilizzo che ne faremo. Per esempio: Val int =0; // Definiamo la variabile Val come variabile int( integer) e assegnamo ad essa il valore 0 COSTANTI Nella scheda Arduino è inserita una serie predefinita di parole chiave con valori speciali. HIGH e LOW sono usati per esempio quando si vuole accendere o spegnere un Pin di Arduino. INPUT e OUTPUT sono usate per definire se uno specifico Pin deve essere un dato di entrata o un dato di uscita. TRUE e FALSE indicano il rispettivo significato italiano: se abbiamo un'istruzione, la condizione può essere vera o falsa. VARIABILI Sono aree della memoria di Arduino dove si possono registrare dati e intervenire all’interno del programma. Come dice il nome stesso, le variabili possono essere cambiate tutte le volte che vogliamo. Quando si dichiara una variabile bisogna dichiararne anche il tipo. Questo significa dire al processore le dimensioni del valore che si vuole memorizzare. Ne esistono di diversi tipi: boolean - Può assumere solamente due valori: vero o falso. char - Contiene un singolo carattere. L'Arduino lo registra come un numero (ma noi vediamo il testo). Quando i caratteri sono usati per registrare un numero, possono contenere un valore compreso tra -128 e 127. byte - Può contenere un numero tra 0 e 255. Come un carattere usa solamente un byte di memoria. int - Contiene un numero compreso tra -32'768 e 32'767. E' il tipo di variabile più usata e usa 2 byte di memoria. unsigned int - Ha la stessa funzione di int, solo che non può contenere numeri negativi, ma numeri tra 0 e 65.535. long - E' il doppio delle dimensioni di un int e contiene i numeri da -2'147'483'648 a 2'147'483'647. unsigned long - Versione senza segno di long va da 0 a 4'294'967''295.
  • 15.
    15 float - Puòmemorizzare numeri con la virgola. Occupa 4 bytes della RAM. double - A doppia precisione in virgola mobile con valore massimo di 1'7976931348623157x10^308. string - Un set di caratteri ASCII utilizzati per memorizzare informazioni di testo. Per la memoria, usa un byte per ogni carattere della stringa, più un carattere NULL che indica ad Arduino la fine della stringa. Esempio: char string1[] = "Hello"; // 5 caratteri+carattere NULL char string2[6]="Hello" // La stessa cosa di sopra array - un elenco di variabili accessibili tramite un indice. Vengono utilizzate per creare tabelle di valori facilmente accessibili. Come esempio se si vuole memorizzare diversi livelli di luminosità di un LED possiamo creare 4 variabili, una per ogni livello di luminosità. Si può utilizzare una semplice array come: int Luce[5]={0,25,50,100}; Nel tipo della variabile la parola "array" non si dichiara, ma si usano i simboli [] e {}. ISTRUZIONI Istruzioni sono tutti quei comandi all’interno del programma che comandano delle variabili Un esempio di Blocco di Istruzioni per ARDUINO: { digitalWrite (pin, HIGH); // il 'pin' è su delay (1000); // un secondo di pausa digitalWrite (pin, LOW); // il 'pin' è giù delay (1000); // un secondo di pausa } N.B. ogni istruzione deve sempre terminare con ";". ogni istruzione deve essere racchiuso tra parentesi graffe. Le istruzioni del Preprocessore NON vanno racchiuse col “;”. "//" è usato per inserire commenti che non saranno eseguiti dal programma.
  • 16.
    16 FUNZIONI Una funzione èun blocco di codice che ha un nome ben definito, quindi è un blocco di istruzioni che vengono eseguiti quando la funzione viene chiamata. Le funzioni sono utilizzate per eseguire operazioni ripetitive in modo da ridurre il codice programma ed evitare quindi confusione nel programma stesso. Le funzioni sono dichiarate all’inizio del programma e specificate dal tipo di funzione. Una funzione è come una scatola chiusa (blackbox) alla quale vengono passati dei valori (parametri) e dalla quale si ricevonoo un risultato che dipende dai valori in ingresso. Chiaramente quando si costruisce una funzione si deve assegnare un nome che ne renda immediatamente evidente lo scopo. La struttura della funzione è la seguente: <Tipo del valore restituito> <nome funzione> ( <elenco dei parametri> ) Dopo il tipo, occorre dichiarare il nome dato alla funzione e tra parentesi i parametri che vengono passati alla funzione. Un esempio di dichiarazione di Funzione per ARDUINO: int delayVal() // funzione senza parametri { int v; // dichiaro la variabile v = analogRead(pot); // funzione arduino v = v / 4; // espressione aritmetica return v; // valore di ritorno della funzione } STRUTTURE DI CONTROLLO Il linguaggio di Arduino include parole chiave per controllare il progetto logico del nostro codice. If - L’istruzione if verifica se una certa condizione.Se l’espressione è vera lo sketch esegue le istruzioni che seguono.Se falsa il programma ignora la dichiarazione. Esempio: if (variabile == valore) { // esegue blocco di istruzioni } If…else - Permette di prendere delle decisioni all’interno del programma, ma deve essere seguito da una domanda sotto forma di espressione tra parentesi. Se la domanda è vera tutto ciò che segue verrà eseguito. Se falso verrà eseguito tutto il codice che segue else. If è possibile usarlo senza usare necessariamente else. Esempio:
  • 17.
    17 if (val=1) {digitalWrite(LED, HIGH);}// (val=1) è la domanda se è vera esegue ciò che è fra parentesi For - Ripete il codice per un numero predefinito di volte. for(int i=0;i<10;i++) {Serial.print(“Ciao”);} //stampa 10 volte “Ciao” Switch - E’ come un interruttore nel corso del programma. Fa prendere al programma diverse direzioni in base al valore della variabile (il suo nome deve essere messo tra parentesi dopo switch). E’ utile perché può sostituire lunghe serie di if. switch(valore sensore) {case 38: digitalwrite(12, High); break; case 55: digitalwrite(3, High); break; default: // si usa per indicare tutti i casi in cui non è ne 38 ne 55 digitalwrite(12, Low); digitalwrite(13, Low);} While - Esegue un blocco di codice fino a quando una certa condizione posta tra le parentesi è vera. while(valore sensore<500) {digitalWrite(13, HIGH); delay(100); digitalWrite (13, HIGH); delay(100); Valoresensore=analogRead(1); } Do…While - E’ uguale a while solo che il codice è avviato prima che la condizione sia verificata. Si usa quando si vuole eseguire il codice almeno una volta prima che la condizione sia valutata. Esempio: do {digitalWrite(13,HIGH); delay(100); digitalWrite(13,HIGH); delay (100); valore sensore=analogread(1); } Break - Questo termine consente di bloccare il ciclo e continuare ad eseguire il codice fuori dal ciclo. Viene utilizzato anche per separare le varie condizioni nella funzione Switch.
  • 18.
    18 Continue - Questocomando fa saltare il resto del codice all’interno del ciclo, e riavvia il ciclo. Esempio: for(luminosità=0; luminosità<200; luminosità++) f((x>120) && (x<180)) continue; analogWrite(PWMPin, luminosità); delay(20);} Return - Ferma una funzione che si sta eseguendo e restituisce un risultato. E’ possibile infatti usarlo per restituire un valore da una funzione. Esempio chiama una funzione “calcolaumidità” e ritorna il valore dell’umidità. Int calcolaumidità() {Int umidità=0; umidità0(analogread(0)+45/100)/100; return umidità;} OPERAZIONI ARITMETICHE Si può usare Arduino per compiere operazioni matematiche complesse con una semplice sintassi: + e – indicano addizione e sottrazione, * indica la moltiplicazione, e / la divisione. C’è un operatore in più in questo linguaggio chiamato “Modulo” che è un comando che restituisce il resto di una divisione. Esempio: a=3+3; luminosità=((12*valore sensore)/4); OPERATORI DI COMPARAZIONE Quando si specificano delle condizioni ci sono vari operatori che tu puoi usare: == Uguale a > maggiore di < minore di != diverso da <= minore o uguale >= maggiore o uguale
  • 19.
    19 OPERATORI BOOLEANI Sono usatiquando si vogliono combinare più condizioni, ad esempio se vogliamo verificare se il valore di un sensore è tra 1 e 5 basta scrivere: if(sensore=>1) && (sensore=<=5); Esistono tre tipi di operazioni booleane: &&(And), ||(Or), !(Not). OPERATORI COMPUTAZIONALI Servono a ridurre la mole di un codice e a renderlo più semplice e chiaro per operazioni semplici come incrementare o decrementare una variabile. Esempio: val=val+1; è come dire val++ incremento (++) e decremento (--) ++ e -- incrementano/decrementano una variabile di 1; lo stesso è applicabile a +=, -=, *=, /= . Esempio: le seguenti espressioni sono equivalenti: val=val+5; Val+=5; FUNZIONI INPUT E OUTPUT Arduino include funzioni per la gestione degli Input e degli Output. pinMode(pin,mode) - Riconfigura un pin digitale a comportarsi come uscita o come entrata. pinMode(13,INPUT) - imposta il pin 13 come Input. digitalWrite(pin,value) - imposta un pin digitale ad ON o a OFF. digitalWrite(7,HIGH) - imposta come digitale il pin 7. int digitalRead(pin) - Legge lo stato di un input Pin, ritorna HIGH se il Pin riceve della tensione oppure LOW se non c’è tensione applicata.
  • 20.
    20 Val=digitalRead(7); // leggeil pin 7 dentro a val Int analogRead(pin) - Legge la tensione applicata a un ingresso analogico e ritorna un numero tra 0 e 1023 che rappresenta le tensioni tra 0 e 5 V. Val=AnalogRead(0); // legge l’ingresso analogico 0 dentro a val analogWrite(pin,value) - Cambia la frequenza PWM su uno dei pin segnati PWM, nella voce pin si può mettere 11 10 9 6 5 3, value invece può essere un valore da 0 a 255 che rappresenta la scala da 0 a 5 V. analogWrite(9,128); shiftOut(dataPin, clock, Pin, bit, Order, value) - Invia i dati ad un registro. Questo protocollo usa un pin per i dati e uno per il clock. bitOrder indica l'ordine dei bytes (least significant byte=LSB, most significant byte=LMB) e value è il byte da inviare. Esempio: shiftOut(dataPin, Clock Pin, LSBFIRST, 255); insigned long pulseIn(pin, value) - misura la durata degli impulsi in arrivo su uno degli ingressi digitali. E’ utile ad esempio per leggere alcuni sensori a infrarossi o alcuni accelerometri che emettono impulsi di diversa durata. Tempo=pulsin(8,HIGH); FUNZIONI DI TEMPO Arduino include alcune funzioni per misurare il tempo trascorso e anche per mettere in pausa il nostro programma. Insigned long millis() - Ritorna il numero in millisecondi trascorsi dall’inizio del programma, esempio: durata=millis()-tempo // calcola il tempo trascorso prima di “tempo” delay(ms) - Mette in pausa il programma per un numero di millisecondi specificato. delay(1000); //stoppa il programma per 1 secondo delayMicroseconds(us) - Come delay mette in pausa il programma ma l’unità di misura è molto più piccola, parliamo di microsecondi. delayMicroseconds(2000); // aspetta per 2 millisecondi (1000us=1ms)
  • 21.
    21 FUNZIONI MATEMATICHE Arduino includemolte funzioni matematiche comuni. Servono, per esempio, per trovare il numero max o il numero min. min (x,y) - Ritorna il più piccolo fra x e y. Esempio: Val= min(5,20); // val adesso è 5 max(x,y) - Ritorna il più grande fra x e y. abs(x) - Ritorna il valore assoluto di x, ossia trasforma i numeri negativi in numeri positivi. Se x fosse 5 ritorna 5, ma anche se x fosse -5 ritorna sempre 5. Esempio: Val= abs(-5); // val vale 5 constrain(x,a,b) - Ritorna il valore "x" costretta tra "a" e "b". Ciò vuol dire che se "x" è minore di "a" ritornerà semplicemente "a" e se x è maggiore di "b" restituirà semplicemente il valore di "b". map(value, fromLow, fromHigh, toHigh) - Associa un valore che sta nel range fromLow e maxlow in un nuovo range che va da toLow a toHigh. E’ molto utile per processare valori provenienti da sensori analogici. Esempio: Val=map(analogRead(0),0,1023,100,200); // associa il valore analogico 0 ad un valore tra 100 e 200 double pow(base,exponent) - Restituisce come risultato la potenza di un numero. Si deve indicare la base e l’esponente. Double sqrt(x) - Restituisce la radice quadrata di un numero x. Double sin(rad) - Restituisce il seno dell’angolo specificato in radianti. Esempio: Double sine= sine(2); // circa 0.909297370 Double cos(rad) - Restituisce il coseno dell’ angolo specificato in radianti. Double tan(rad) - Restituisce il valore della tangente di un angolo specificato in radianti.
  • 22.
    22 FUNZIONI NUMERI RANDOM Sesi ha bisogno di generare numeri random (a caso), Arduino ci viene incontro con alcuni comandi standard per generarli. randomSeed(seed) - Anche se la distribuzione di numeri restituita dal comando random() è essenzialmente casuale, la sequenza è prevedibile. randomSeed(seed) inizializza il generatore di numeri pseudo-casuali, facendola partire da un punto arbitrario nella sua sequenza casuale. Long random(min,max) - Restituisce un valore long intero di valore compreso fra min e max -1. Se min non è specificato il suo valore minimo è 0. Esempio: long random= random(13); // numero compreso fra 0 e 12 COMUNICAZIONE SERIALE Queste sono le funzione seriali cioè quelle funzioni che Arduino usa per comunicare tramite la porta Usb del nostro Pc. Serial.begin(speed) - Prepara Arduino a mandare e a ricevere dati tramite porta seriale. Possiamo usare generalmente 9600 bits per secondo con la porta seriale dell’Arduino, ma sono disponibili anche altre velocità, di solito non si supera i 115.200 bps. Serial.print(data)Serial.begin(9600); Serial.print(data,codifica) - Invia alcuni dati alla porta seriale. La codifica è opzionale. Serial.print(32); // stampa 32 Serial.Print(32, DEC); // stampa 32 come sopra Serial.Print(32, OCT); // 40 (stampa10 in ottale) Serial.Print(32 , BIN); // 100000 (stampa 10 in binario) Serial.Print(32 , BYTE); // “Space” valore associato nella tabella ASCII Int Serial.available() - Ritorna quanti bytes non ancora letti sono disponibili sulla porta Serial per leggerli tramite la funzione read(). Dopo aver read() tutti i bytes disponibili Serial.Available restituisce 0 fino a quando nuovi dati non giungono sulla Porta.
  • 23.
    23 Int.Serial.read() - Recuperaun byte di dati in entrata sulla porta Seriale. int data= Serial.read(); Poichè i dati possono giungere nella porta seriale prima che il programma li possa leggere(per la velocità), Arduino salva tutti i dati in un buffer. Se è necessario ripulire il buffer e aggiornarlo con i dati aggiornati, usiamo la funzione flush(). Serial.flush(); Conclusioni Con questa prima guida, si è cercato di spiegare in cosa consiste Arduino: la storia della board, la parte hardware e la parte software. Sono stati trattati e illustrati i processi di cablaggio e le principali istruzioni per la stesura degli sketch. Crediamo che come introduzione al fantastico Mondo dei maker (coloro che ideano, progettano e realizzano) le informazioni ricevute siano sufficienti per iniziare a prendere confidenza con la board e il programma di editazione. Flaviano Fior