Upload
duongtuyen
View
260
Download
3
Embed Size (px)
Citation preview
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-1-
La piattaforma programmabile
ARDUINO
Dispensa di Sistemi Elettronici del prof.
Aniello Celentano
Anno Scolastico 2018/2019
ITIS Galileo Ferraris di Napoli
Versione 4 Febbraio 2019
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-2-
I N D I C E
Introduzione: La scheda hardware Arduino 3
Il controllore ATMega328 4
La scheda hardware Arduino____________________________________________________________ 5
Il software per programmare Arduino: IDE 6
Il linguaggio di programmazione di Arduino: C++ 7
Struttura logico operativa dello sketch_______________________________________________ 8
Le periferiche collegabili ad Arduino 10
I segnali elettrico di Input/Output di Arduino 10
Il pulsante: una periferica di input__________________________________________________ 10
Il diodo LED: una periferica di segnalazione luminosa d’uscita 12
Il potenziometro: una periferica analogica. 14
La misura del tempo____________________________________________________________________ 16
Monostabile con carico su rete elettrica a 220 Volt AC. 18
Monitoraggio dell’esecuzione di un programma (Serial library) 19
Il display LCD1602 parallelo___________________________________________________________ 22
Il display LCD1602 seriale 23
Sensore di posizione: Misurare le distanze con gli ultrasuoni (HC-SR04) 24
Sensore di posizione: Rilevare la presenza di oggetti con ultrasuoni (FC-51)____________ 25
Modulo seriale Bluetooth 26
La funzione PWM con Arduino 29
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-3-
G l i S k e t c h
01 : Un pulsante controlla l’accensione/spegnimento di un LED 13
02 : La tensione fornita dal cursore di un potenziometro 15
03 : Realizzazione di un circuito monostabile con la scheda Arduino.______________________ 17
04 : Collegamento seriale di due schede Arduino 20
05 : Visualizzare sul display LCD l’orario nel formato mʹsʺ 23
06 : Gestione del display seriale_________________________________________________________ 24
07 : Misurare la distanza di un oggetto 25
08 : Conteggiare gli oggetti che scorrono su nastro trasportatore 26
09 : Acquisizione di comandi tramite modulo Bluetooth_______________________________________ 27
10 : Gestione del modulo Bluetooth con la ridefinizione dei pin Tx e Rx. 28
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-4-
La piattaforma programmabile ARDUINO
Introduzione
La piattaforma programmabile Arduino è una scheda elettronica programmabile attraverso la porta USB di un computer opportunamente attrezzato per tale scopo. La scheda è dotata del microcontrollore (1) ATMega328
prodotto dalla società ATMEL.
Esistono diverse versioni di Arduino, la versione base è Arduino UNO che è la più semplice da gestire e la più
economica. L’immagine che segue raffigura la scheda Arduino.
Le diverse versione di Arduino si differenziano per il numero di linee digitali di Input/Output che può gestire,
per la quantità di memoria RAM flash riservata per la stesura di un programma, alla frequenza di clock.
Il microcontrollore ATmega328
Questo componente elettronico è la parte principale della scheda Arduino. E’ questo componente che permette di eseguire un programma, di analizzare ed eseguire le singole istruzioni di un programma.
Le caratteristiche principali di questo componente sono riassunte di seguito.
- Memoria flash per la stesura dei programmi 32 Kbyte
- Memoria RAM riservata alla definizione delle variabili di programma 2 Kbyte
- Memoria E2PROM per la memorizzazione dei dati tra sessioni successive 1 Kbyte
- Frequenza di Clock con cui vengono eseguite le istruzioni 20 MHz - Capacità di elaborazione istruzioni 20 MIPS, equivalenti a 50 nano-secondi/istruzione
- Range di temperatura di funzionamento tra -40°C e 85°C
- Tensione di alimentazione tra 1.8 V a 5.5 V - Cicli di programmazione 10000 volte, le volte che può essere riprogrammato.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-5-
La scheda hardware Arduino
Sulla scheda Arduino si possono distinguere tre zone elettricamente e concettualmente distinte. La descrizione
che segue analizza la scheda ʺArduino Unoʺ a cui si farà riferimento semplicemente come Arduino.
a) Le linee di Input/Output digitale. Facendo riferimento all’immagine della scheda riportata in alto,
queste linee sono posizionate in alto a destra e contraddistinte dai numeri che vanno da 0 a 13 (14
linee). Queste linee sono preposte per ricevere/fornire segnali digitali compatibili TTL(2). In Output le
linee non possono erogare più di 20/30 mA di corrente. Genericamente si fa riferimento a queste linee con il termine di PIN oppure semplicemente con Linea.
b) In basso a destra sono posizionate sei linee per i segnali analogici. Queste linee sono contraddistinte
con le sigle A0, A1, ... A5. I segnali devono essere limitati al range di valori [0 Volt , +5 Volt], valori di default, diversamente deve essere impostare opportunamente l’ingresso AREF (Analogic
REFerence). La particolarità di queste linee è che possono essere configurate anche come line digitali,
facendovi riferimento con i nome A0,A1,… c) In basso al centro vi sono le linee per l’alimentazione, il così detto BUS di alimentazione. Da questo
bus è possibile prelevare le tensioni +5 Volt, +3.3 Volt, il riferimento di massa GND. La linea indicata
con VIN è riservata per inserire un’alimentazione esterna di +5 Volt, mentre la linea RES permette il
RESET della scheda. Il reset della scheda può essere ottenuto manualmente premendo il pulsante di colore rosa in alto a sinistra visibile nella foto (il colore del pulsante può variare con la versione della
scheda). L’alimentazione alla scheda può essere fatta in tre modi:
1) tramite l’ingresso VIN; 2) tramite la porta USB, nella foto al centro del lato sinistro;
3) tramite un opportuno jack, visibile in basso a sinistra della foto, che permette di alimentare
la scheda con una batteria di 9 Volt.
d) Le linee SCL e SDA sono linee riservate per la comunicazione seriale I2C. Molti dispositivi utilizzano il protocollo di comunicazione denominato I2C per creare una rete di collegamenti in modo che tutti i
dispositivi collegati possano scambiare informazioni.
e) La linea di input AREF è una linea riservata per impostare il livello massimo dei segnali analogici di input da convertire con l’ADC. Il Convertitore Analogico-Digitale (ADC) montato sulla scheda
Arduino è un dispositivo a 10 bit(3) che permette di convertire un segnale elettrico, compreso tra 0 e
+5 Volt, in un equivalente valore numerico tra 0 e 1023 (210-1).
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-6-
Il software per programmare Arduino: l’IDE
La piattaforma Arduino per poter essere programmata deve essere collegata, tramite un opportuno cavetto, alla
porta USB di un PC (Personal Computer). In questo modo con un opportuno programma installato sul PC è
possibile programmare la scheda Arduino tramite la porta USB del computer collegata alla porta USB della scheda Arduino.
Il programma installato sul PC, che permette la programmazione della scheda Arduino, è un IDE:
Integrated Development Environment = Ambiente di sviluppo integrato
In altre parole il programma permette di eseguire una serie di azioni quali:
a) Scrivere il programma che si vuole realizzare nel linguaggio C++ comprensibile al compilatore per Arduino. Il compilatore è un programma che traduce le istruzioni del nostro programma in istruzioni
comprensibili dal microcontrollore ATMega328P montato sulla scheda Arduino.
b) Verificare la correttezza sintattica e strutturale del file dei comandi che intendiamo inviare alla scheda Arduino scritti nel linguaggio C++. Il file dei comandi è indicato con il termine di Sketch.
c) Salvare il programma sul disco di massa del PC e poterlo Stampare. Il file contenete il programma
viene indicato come file sorgente.
d) Modificare il file sorgente in tempi successivi per poter apportare modifiche e correzioni. e) Compilare il file sorgente ed inviarlo alla scheda Arduino (programmazione)
f) Analizzare e risolvere gli errori che possono accadere nel trasferimento dal PC alla scheda Arduino.
g) Monitorare il corretto funzionamento del programma.
La versione aggiornata dell’IDE è scaricabile gratuitamente dal sito ufficiale di Arduino, ossia il sito
www.arduino.cc. Da questo sito è possibile scaricare l’ultima versione dell’IDE e installarla sul proprio
computer. L’icona ufficiale che caratterizza Arduino è la seguente.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-7-
Il linguaggio di programmazione di Arduino: il C++
Il linguaggio di programmazione è il linguaggio orientato ad oggetti indicato come C++. A tal proposito si
rimanda al sito ufficiale www.arduino.cc per un’ampia descrizione dei comandi e della struttura sintattica del
linguaggio C++. Qui ci limitiamo solo a riportare la struttura base dello SKETCH, cioè della struttura del file che permette una corretta programmazione di Arduino.
La realizzazione di un programma per Arduino deve essere strutturato in tre blocchi.
a) Un primo blocco di comandi è riservato alla definizione delle costanti e delle varabili, che hanno una
validità generale, utilizzate da tutte le parti costituenti il programma stesso.
b) Un secondo blocco è costituito da un sottoprogramma con nome SETUP in cui vengono messi tutti i comandi che inizializzano le variabili, le periferiche e configurano tutti i pin digitali che serviranno
per il programma che si vuole realizzare. Il nome è appropriato in quanto vuol dire impostare,
inizializzare. c) Un terzo blocco è costituito da un sottoprogramma che contiene tutti i comandi che verranno eseguiti
all’infinito, in un ciclo continuo dal primo comando all’ultimo, ripetendosi infinite volte. Questo
sottoprogramma ha nome LOOP, giusto per ricordare che i comandi verranno eseguiti in un loop
continuo e infinito.
A questi tre blocchi che costituiscono la struttura minima di un file sketch si devono aggiungere le librerie,
ossia dei file esterni con comandi che permettono la gestione delle periferiche e che ampliano l’insieme dei comandi del linguaggio base. Un ulteriore blocco è riservato ai comandi personalizzati, cioè i comandi che noi
definiamo e creiamo per facilitare la programmazione. Sono sottoprogrammi realizzati specificamente per il
nostro specifico scopo.
La descrizione fatta apparirà più chiara e comprensibile con gli esempi che verranno riportati in seguito.
Il linguaggio di programmazione C++ non verrà analizzato. Lo studio dei costrutti fondamentali di tale
linguaggio è rimandato a testi specializzati in materia, reperibili anche via web.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-8-
Struttura logica operativa dello sketch
Tramite il programma IDE installato sul computer è possibile realizzare uno sketch con il quale programmare
opportunamente la piattaforma Arduino. Lo sketch è un insieme di comandi comprensibili ad Arduino.
I comandi devono essere scritti con una sintassi ben precisa ed inseriti in un file avente una struttura anch’essa ben precisa.
Qualunque sia il problema che vogliamo risolvere, di sicuro avremo bisogno di variabili numeriche e/o logiche
in cui memorizzare i dati. E’ importante sottolineare che la scelta del nome delle variabili da usare deve essere
una scelta importante e ben oculata. Il nome di una variabile deve essere tale da richiamare alla mente del programmatore la natura del dato ch’essa memorizza. Per intenderci, se una variabile deve memorizzare la
temperatura misurata in un dato processo, la variabile non deve essere mai chiamata X oppure Y, che non
richiamerebbero alla mente nessun significato sulla natura del dato memorizzato, ma bensì deve essere chiamata Temperatura, oppure TemperaturaInterna, TemperaturaEsterna ecc. ecc. Questo perché il nome
della variabile stessa suggerisce la natura del dato ch’essa memorizza.
Le variabili non sono tutte uguali, nel senso che non memorizzano tutte lo stesso tipo di dato. Esistono dati
logici, detti anche booleani, dati numerici interi, byte, float ed altri tipi di dati. Ogni variabile deve essere
intesa come una sorta di contenitore appropriato per contenere uno specifico dato.
Un dato booleano può contenere solo le costanti High/Low, oppure True/False oppure anche 0/1. Una variabile di tipo byte, che può contenere tutti i numeri da 0 a 255, è un contenitore piccolo se paragonato ad una variabile
intera (tipo int) che può contenere tutti i numeri da 0 a ±215. Un contenitore ancora più grande è una variabile
foating (tipo float) che può memorizzare i numeri reali.
Ogni variabile deve essere definita all’inizio dello sketch, in modo che sia sempre disponibile in ogni punto
del programma. Il tipo delle variabili deve essere definito sulla base dello specifico problema che si vuole
risolvere. Ad esempio, le istruzioni che seguono definiscono alcune variabili
byte Conteggio ; // Definisce una variabile intera con valori tra 0 e 255
int NumeroAlunni ; // Def. una variabile intera, positiva e negativa
float Temperatura ; // Def. una variabile reale per contenere i valori di temperatura
bool StatoLED ; // Def. una variabile per contenere lo stato Acceso/Spento di un LED
Si osservi l’inserimento dei commenti e degli spazi per allineare le istruzioni. Il nome delle variabili non deve
contenere i caratteri speciali tipo lo spazio o il simbolo di %.
Dopo il blocco di definizione delle variabili e delle costanti di programma, deve seguire il blocco di inizializzazione delle variabili. Tutte le variabili ed i pin digitali di Input/Output devono essere inizializzati.
Ciò deve essere fatto all’interno del blocco di SETUP. L’esempio che segue mostra una tipica inizializzazione.
void setup()
{
NumeroAlunni = 150 ; // Inizializza la variabile NumeroAlunni
Temperatura = 25.0 ; // Inizializza la variabile Temperatura
StatoLED = HIGH ; // Inizializza la variabile StatoLED
pinMode( 5 , OUTPUT ) ; // Configura il pin 5 come porta di uscita (OUTPUT)
digitalWrite( 5,LOW ) ; // Imposta come LOW lo stato del pin 5
}
A questo blocco deve seguire un blocco di istruzioni che vengono eseguite all’infinito, senza fine, con una
sequenzialità ciclica (loop). Ad esempio,
void loop()
{
X = X + 1 ; // Esempio di incrementa di una variabile chiamata X
if( X > 100 ) // Esegue un test sulla variabile X
X = 0 ; // Azzera la variabile X
}
Le istruzioni indicate sono solo indicative per illustrare la struttura della funzione loop().
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-9-
In seguito ai tre blocchi illustrati segue un blocco per la definizione dei comandi personalizzati, cioè dei
comandi che possiamo creare e definire per risolvere in modo più semplice la programmazione che intendiamo realizzare.
Tali comandi personalizzati sono indicati anche come funzioni, sono definite allo stesso modo delle due
funzioni appena illustrate: la setup() e la funzione loop().
Sono definite funzioni perché possono ritornare al programma chiamante (programma main) un tipo di dato.
Se non ritornano nessun valore allora il tipo di dato della funzione è void.
Supponendo di voler scrivere uno sketch per accendere/spegnere un LED. In questo caso converrebbe definire
dei propri comandi che, richiamati, permettono l’accensione o lo spegnimento del LED.
Le definizioni che seguono illustrano questo concetto appena esposto. . . .
. . .
void AccendiLED()
{
// Esegue i comandi che permettono l’accensione del LED
}
void SpegniLED()
{
// Esegue i comandi che permettono lo spegnimento del LED
}
bool StatoLED()
{
// Esegue i comandi per determinare se il LED è acceso oppure spento
}
. . .
. . .
Le tre funzioni o comandi personalizzati permettono di avere un controllo sul funzionamento del LED.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-10-
Le periferiche collegabili ad Arduino
Le periferiche sono dispositivi che possono essere controllate tramite Arduino e che permettono di realizzare
qualche funzione specifica. Possono essere periferiche sia digitali che analogiche.
Ad esempio, un pulsante di tipo N.O. (Normaly Open) è una periferica digitale, può commutare da N.O. allo stato N.C. (Normaly Close) se il pulsante è premuto. E’ collegabile direttamente ad una linea digitale di
Arduino opportunamente configurata come linea di INPUT in modo che Arduino possa acquisire lo stato logico
associato alla commutazione del pulsante. Un sensore di temperatura, come l’integrato LM35, è una periferica analogica che può essere collegata ad uno
degli ingressi analogici di Arduino al fine di acquisire la temperatura rilevata dal sensore.
I segnali elettrici di Input/Output di Arduino
I segnali elettrici digitali che Arduino è in grado di riconoscere sono segnali logici High/Low. Questi segnali spesso sono indicati anche con 1/0 oppure con i termini Alto/Basso. Gli stati logici appena descritti sono
associati a livelli di tensione ben precisi.
Il livello logico Alto/H/1 è associato a +5 Volt, quello Basso/L/0 è associato a 0 Volt. I segnali analogici che Arduino è in grado di analizzare devono essere compresi nel range [0 Volt , +5 Volt].
Per i segnali analogici compresi in un intervallo più piccolo si deve impostare l’ingresso AREF per ottenere
una corretta gestione dei segnali, come si vedrà in seguito.
Il pulsante: una periferica digitale di input
Il pulsante è un dispositivo meccanico che se premuto apre oppure chiude un contatto elettrico. Al primo caso
appartengono i pulsanti N.C., normalmente chiusi, che se premuti commutano in normalmente aperti (N.O.);
al secondo caso appartengono i pulsanti N.O. che se premuti commutano in N.C. Gli schemi elettrici che seguono mostrano come è possibile realizzare una semplice interfaccia(5) per poter
comunicare ad Arduino uno stato logico Low/High (L/H).
Nello schema con il pulsante N.C. (schema a sinistra) il condensatore C risulta cortocircuitato per cui la
resistenza R risulta collegata a massa. L’ingresso di Arduino, il pin colorato nello schema, riceve un segnale elettrico nullo e quindi un segnale logico basso (L).
I valori di R e di C non sono valori critici, per R può essere assunto un valore tra 1 KΩ e i 5 KΩ mentre per il
condensatore C può essere assunto un valore di circa 1 μF. La necessità di mettere il condensatore nasce dal fatto che i contatti elettrici prima di risultare effettivamente
ben saldi generano un serie di impulsi elettrici che possono condizionare le apparecchiature elettroniche. Il
condensatore non si carica istantaneamente per cui nel tempo che impiega a caricarsi i contatti elettrici si stabilizzano superando la fase dei rimbalzi elettrici (4).
Il circuito con il pulsante N.O. (circuito a destra) mostra che il gruppo R-C in parallelo non è connesso
all’alimentazione. Pertanto solo dopo che il pulsante viene premuto e dopo i primi istanti dall’avvenuto
contatto l’ingresso di Arduino riceve un segnale alto (H).
In entrambi gli schemi elettrici, Arduino normalmente riceve un segnale basso e solo dopo che il pulsante è
premuto riceve un segnale alto per tutto il tempo che il pulsante resta premuto.
Nei due schemi il tratteggio in rosso delimita l’interfaccia necessaria per l’utilizzo dei pulsanti. L’alimentazione di +5 Volt è necessaria per la compatibilità TTL dei segnali di Input/Output (I/O) di Arduino.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-11-
La programmazione di Arduino riserva un’istruzione molto semplice per leggere ed ottenere lo stato logico
del pulsante collegato ad un ingresso digitale di Arduino. Supponiamo, per fissare le idee, che il pin 5 di Arduino sia stato configurato come ingresso (INPUT). In questo caso per sapere lo stato logico del pin 5 deve
essere usata la seguente istruzione:
Variabile logica Tasto = digitalRead( 5 )
Dopo l’esecuzione di questa istruzione, la variabile logica (booleana) Tasto conterrà il valore booleano high
(H) o low (L). Pertanto, dal valore booleano assunto dalla variabile Tasto si può dedurre lo stato meccanico/elettrico del pulsante P, se è premuto oppure no. L’istruzione appena descritta richiede che venga
definita una variabile con nome Tasto di tipo booleana. Ciò deve essere fatto nel primo blocco dello sketch,
cioè il blocco delle definizioni delle variabili, con l’istruzione bool Tasto ;
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-12-
Il diodo LED: una periferica di segnalazione luminosa d’uscita
Un diodo LED è un dispositivo capace di emettere luce se polarizzato direttamente. Vediamo come utilizzare
questo dispositivo per segnalare lo stato logico Low/High di una linea di uscita di Arduino.
Il primo schema riportato sopra mostra un diodo LED che tramite la resistenza di polarizzazione R è connesso
ad un pin di uscita di Arduino. Solo quando l’uscita è alta (H) il LED si illumina. Un pin di Arduino configurato come OUTPUT è in grado di erogare una corrente di 20-30 mA ad una tensione di +5 Volt. Calcolando
opportunamente R, il LED risulta acceso solo quando l’uscita è alta poiché il ramo R-LED risulterebbe
alimentato da una tensione di +5 Volt. Viceversa se l’uscita è bassa, il ramo R-LED risulta cortocircuitato a
massa, il LED risulta spento. Il secondo schema riportato sopra mostra il modo di accendere un LED quando l’uscita digitale di Arduino si
porta ad un livello logico basso (L). Un’uscita bassa vuol dire che il pin di uscita si porta ad un potenziale
elettrico nullo, 0 Volt, e ciò è come se il pin di uscita internamente venisse collegato a massa. Pertanto il ramo LED-Resistenza risulta alimentato a +5 Volt ed il LED si illumina. Al contrario, se l’uscita si porta ad un
livello alto, cioè a +5 Volt, il ramo R-LED risulta cortocircuitato al potenziale di +5 Volt e, quindi, non essendo
alimentato il LED risulta spento.
Per entrambi gli schemi elettrici l’interfaccia tra Arduino ed il LED non è altro che una semplice resistenza R di polarizzazione.
La programmazione di Arduino riserva la seguente istruzione per poter impostare/scrivere lo stato logico di un
pin configurato come uscita digitale (OUTPUT). Supponiamo per fissare le idee che il pin 5 sia stato configurato come output digitale ed alimenta il ramo R-LED. L’istruzione da utilizzare è:
digitalWrite( 5 , HIGH ) oppure digitalWrite( 5 , LOW )
La prima istruzione permette di impostare il pin 5 al valore booleano HIGH, ossia elettricamente a +5 Volt.
La seconda espressione permette di impostare l’uscita digitale 5 al valore LOW, a 0 Volt.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-13-
Sketch 1: Un pulsante controlla l’accensione/spegnimento di un LED
Lo sketch si propone di realizzare un programma che ad ogni pressione di un pulsante un LED si accende
oppure si spegne. La realizzazione di questo programma richiede prima lo sviluppo di un flowchart per una
descrizione dettagliata dei passi da eseguire per realizzare il nostro obiettivo e solo successivamente realizzare lo sketch.
Il flowchart è uno strumento grafico per poter
analizzare i passi logici da eseguire per conseguire un
dato obiettivo.
Lo sketch è il file gestito dall’IDE di Arduino in cui ʺtraduciamoʺ il flowchart in istruzioni comprensibili al compilatore C++ per
programmare Arduino.
// Definizione di tutte le variabili e costanti
const byte PinLED = 5 ;
const byte PinPulsante = 6 ;
bool StatoPulsante ;
bool StatoLED ;
void setup()
{
pinMode( PinLED , OUTPUT ) ;
pinMode( PinPulsante , INPUT ) ;
StatoPulsante = LOW ;
SpegniLED() ;
}
void loop()
{
StatoPulsante = digitalRead( PinPulsante ) ;
if( StatoPulsante == HIGH )
{
delay(300) ;
if( StatoLED == LOW )
AccendiLED();
else
SpegniLED() ;
}
}
// Comando personalizzato
void AccendiLED()
{
StatoLED = HIGH ;
digitalWrite( PinLED , HIGH ) ;
}
// Comando personalizzato
void SpegniLED()
{
StatoLED = LOW ;
digitalWrite( PinLED , LOW ) ;
}
Il flowchart si commenta da solo. Un poco più complesso è il commento dello sketch. Si osservi la sintassi con
cui vengono messi dei commenti, fondamentali per la descrizione e per un nostro promemoria sui comandi che
inseriamo. Nello sketch con il colore rosso sono evidenziati i comandi del linguaggio base C++ per la programmazione di Arduino. Per la comprensione della sintassi e dell’uso di tali comandi è necessario
consultare il sito ufficiale www.arduino.cc.
Si osservi l’uso degli spazi per allineare i comandi. L’uso degli spazi non è rilevante ai fine della programmazione, ma è fondamentale per poter leggere e comprendere il programma, mettendo in evidenza
eventuali errori operativi e logici.
Nello sketch con il colore verde sono evidenziati i comandi che possiamo realizzare per facilitare la
programmazione. Sono i così detti comandi personalizzati.
NO
NO
start
Definizione costanti e variabili
Legge lo stato
del pulsante
Pulsante
premuto ?
LED è ON ?
LED in ON
LED in OFF
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-14-
Il potenziometro: una periferica analogica.
Il potenziometro può essere inteso come un sensore di posizione. La tensione ai capi del cursore risulta essere
una porzione della tensione che alimenta il potenziometro stesso e funzione della posizione del cursore.
Tale tensione varia in modo continuo dal valore 0 Volt al valore della tensione che alimenta il potenziometro stesso, diciamo Vo.
Nella figura a lato, un generatore di tensione continua Vo alimenta un
potenziometro. La tensione a cui si porta il cursore per effetto del movimento
del cursore stesso è misurata tramite un voltmetro ed è una tensione che varia con continuità tra il valore 0 Volt, quando il cursore è posizionato in B, ed il
valore Vo corrispondente al cursore posizionato in A.
Vediamo come è possibile acquisire il valore V, misurato dal voltmetro, dalla piattaforma programmabile Arduino.
Per poter acquisire valori analogici, Arduino fa uso di un dispositivo interno chiamato ADC: Analog Digital
Converter, ossia Convertitore Analogico Digitale. Senza scendere nei dettagli operativi del circuito ADC, vediamo brevemente come esso viene utilizzato.
Il circuito ADC deve essere pensato come un blocco funzionale, una black-box, che riceve in ingresso un
segnale analogico e fornisce in uscita un valore numerico intero a 10 bit. Il segnale analogico d’input è un
segnale tra 0 e +5 Volt, mentre il valore numerico in uscita è compreso tra 0 e 1023 = 210-1. Pertanto l’ADC stabilisce una corrispondenza biunivoca tra il livello di tensione in ingresso ed il numero a 10 bit in uscita.
Indicando con Vx il valore analogico in ingresso e con Nx il numero a 10 bit in uscita all’ADC deve sussistere
la seguente relazione (proporzionalità): 𝑉𝑥
5=
𝑁𝑥
210 − 1
Da questa relazione possiamo ricavare il numero Nx che Arduino associa ad un livello di tensione Vx e,
viceversa, dato un numero intero Nx nell’intervallo [0 ; 1023] possiamo ricavare il livello di tensione a cui tale numero corrisponde.
La programmazione di Arduino riserva un’istruzione molto semplice per poter leggere il valore in uscita
all’ADC, ossia Nx. L’istruzione è la seguente:
Nx = analogRead( A0 )
In questa istruzione A0 è il primo ingresso analogico disponibile sulla scheda Arduino UNO. Gli ingressi analogici non devono essere configurati e sono indicati con A0, A1, … A5.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-15-
Sketch 2: La tensione fornita dal cursore di un potenziometro viene monitorata: se inferiore a 2.5 Volt
un LED verde è acceso mentre uno rosso è spento; se supera i 2.5 volt il LED verde è spento e quello
rosso è acceso.
Il circuito elettrico che vogliamo realizzare è il seguente. La tensione che alimenta il potenziometro Vo è di +5 Volt. Per fissare le idee supponiamo che il cursore è collegato all’ingresso analogico A0 e i due LED sono
collegati, con le relative resistenze di polarizzazione, alle due uscite digitale pin 5 e pin 6.
Il circuito risulta semplice da descrivere. La rotazione
del potenziometro determina una tensione sul cursore che entra nell’ingresso analogico A0. In questo modo,
un programma che è eseguito da Arduino, con un
semplice calcolo può determinare se tale tensione è al di sotto o al di sopra della soglia di 2.5 Volt. Se è al di sotto
di tale soglia il LED rosso deve restare spento mentre
quello verde risultare acceso. Viceversa se la tensione del cursore è al di sopra di 2.5 Volt.
// Definizione di tutte le variabili e costanti
const byte PinLEDVerde = 6 ;
const byte PinLEDRosso = 7 ;
int ValoreA0 ;
float Cursore ;
void setup()
{
// Configura i pin che gestiscono i LED
pinMode( PinLEDVerde , OUTPUT ) ;
pinMode( PinLEDRosso , OUTPUT ) ;
// Spegne tutti LED
digitalWrite( PinLEDVerde , LOW ) ;
digitalWrite( PinLEDRosso , LOW ) ;
}
void loop()
{
ValoreA0 = analogRead( A0 ) ;
Cursore = ( (float)ValoreA0/1023.0 )*5.0 ;
if( Cursore < 2.5 )
{ AccendiLEDVerde() ;
SpegniLEDRosso();
}
else
{ AccendiLEDRosso() ;
SpegniLEDVerde();
}
}
// Comandi personalizzati
void AccendiLEDVerde()
{digitalWrite(PinLEDVerde,HIGH) ; }
void AccendiLEDRosso()
{digitalWrite(PinLEDRosso,HIGH) ; }
void SpegniLEDVerde()
{digitalWrite(PinLEDVerde,LOW) ; }
void SpegniLEDRosso()
{digitalWrite(PinLEDRosso,LOW) ; }
Nella formula per il calcolo della tensione del cursore (variabile ‘Cursore’) si osservi la conversione del tipo
di variabile. La variabile ValoreA0 da intera viene convertita in floating. Si osservi anche che le costanti numeriche sono scritte con il punto decimale dato che il calcolo finale è un valore floating.
SI
Start
Definizione costanti e variabili
Legge ingresso A0
Calcola la tensione del cursore Vc
Vc < 2.5
Accende LED verde Spegne LED rosso
Accende LED rosso Spegne LED verde
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-16-
La misura del tempo
Dal portale www.arduino.cc si può constatare che la programmazione di Arduino riserva alcune istruzioni per
controllare e determinare il tempo.
La prima istruzione delay() permette di ritardare l’esecuzione di un programma. Questa istruzione richiede
come parametro di input il numero di millisecondi di pausa nell’esecuzione del programma. Ad esempio,
l’istruzione delay(1500) significa che il programma, eseguendo questa istruzione, resta inattivo per 1,5
secondi. Lo stesso dicasi per l’istruzione delayMicroseconds() il cui parametro di input è il numero di microsecondi di pausa che si richiede.
Un’altra istruzione per la determinazione del tempo è l’istruzione millis(). Questa istruzione è una funzione che quando è richiamata ritorna il numero di millisecondi trascorsi dall’istante dell’accensione della scheda
elettronica Arduino. Ad esempio, dopo aver eseguito l’istruzione x=millis() la variabile x contiene un numero,
ad esempio 315325, che sono i millisecondi conteggiati dal momento che la scheda Arduino è stata alimentata. Nell’esempio riportato ( 315325 / 1000 ) / 60 sono giusto 5.2 minuti. Questa istruzione è importante per poter
determinare il tempo trascorso tra due eventi consecutivi. Ad esempio, se premiamo un pulsante e dopo un
poco lo rilasciamo è possibile determinare per quanto tempo il pulsante è stato premuto. Infatti, indichiamo T1
l’istante in cui viene premuto il pulsante, ossia eseguiamo l’istruzione T1 = millis() quando intercettiamo che il pulsante è stato premuto. Nell’istante successivo, quando il pulsante viene rilasciato, eseguendo l’istruzione
T2=millis() otteniamo l’istante in cui il pulsante viene rilasciato: la differenza T2-T1 è giusto il tempo in
millisecondi che il pulsante è stato tenuto premuto. Un’istruzione analoga, ma con una risoluzione maggiore, è micros() che ritorna il numero di microsecondi
trascorsi dall’istante in cui la scheda Arduino viene alimentata.
Le due istruzioni, millis() e micros(), fanno riferimento a registri interni della CPU a 32 bit che ad intervalli regolari si azzerano. In particolare il registro di conteggio dei millisecondi, ritornato da millis(), si azzera dopo
circa 50 giorni; il registro di conteggio di micros() dopo circa 70 minuti.
Un registro a 32 bit può contenere un numero di conteggi pari a 232. Il periodo di
azzeramento di tale registro, che avviene dopo 232 conteggi, può essere facilmente
determinato. Infatti: 232 μSec = 232 * 10-6 Secondi = 232 * 10-6 / 60 Minuti = 71' 35ʺ
232 mSec = 232 * 10-3 Secondi = 232 * 10-3 / 86400 Giorni = 49g 17h 2' 47ʺ
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-17-
Sketch 03: Realizzazione di un circuito monostabile con la scheda Arduino.
Il circuito monostabile è un circuito che azionato con un pulsante commuta l’uscita per un determinato
intervallo di tempo. Per comprendere meglio la funzione del circuito si può pensare al dispositivo che permette
lo spegnimento delle luci nelle scale condominiali dopo un intervallo di tempo ben preciso. Un possibile schema di principio è quello riportato di seguito.
Il circuito è molto semplice. Il pulsante P quando viene premuto permette al condensatore di caricarsi attraverso la resistenza R1 e di portare il pin di ingresso numero 5 di Arduino ad un livello HIGH: il LED in questo caso
si accende. Dall’istante in cui il LED si accende, il programma memorizzato su Arduino deve conteggiare il
trascorrere dei secondi e dopo 5 minuti spegnere il LED.
// Definizione di tutte le variabili e costanti
const byte PinPulsante = 5 ;
const byte PinLED = 7 ;
int DeltaT = 5 ; // Tempo Reset Minuti
bool StatoPulsante ;
unsigned long T0, T1 ; // Per calcolare tempo
int T ; // Minuti trascorsi
void setup()
{
// Configura i PIN che gestisce il LED
pinMode( PinLED , OUTPUT ) ;
pinMode( PinPulsante , INPUT ) ;
// Spegne il LED
digitalWrite( PinLED , LOW ) ;
}
void loop()
{
StatoPulsante = digitalRead( PinPulsante ) ;
if( StatoPulsante == HIGH )
{
digitalWrite( PinLED , HIGH ) ;
T0 = millis() ; // Istante iniziale
T1 = 0 ;
T = 0 ;
while( T < DeltaT )
{
T1 = millis() ;
T1 = (T1 - T0) ;
T = (int) (T1/1000) ;
}
digitalWrite( PinLED , LOW ) ;
}
}
Lo schema elettrico riportato ad inizio paragrafo è uno schema di principio, ma valido e funzionante. Non è
particolarmente complesso realizzare uno schema elettrico con più pulsanti d’ingresso e un’uscita su carico a
220 Volt AC.
SI
NO
Start
Definizione costanti e variabili
Legge ingresso PIN 5
Pin 5 = HIGH
Accende LED
Memorizza tempo To
T < 5
Calcola i minuti trascorsi T
Spegne il LED
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-18-
Monostabile con carico su rete elettrica a 220 Volt AC.
Descrizione. Il circuito presenta N-Pulsanti con contatto normalmente aperto (N.O.). L’uscita di Arduino pilota
contemporaneamente sia un ramo elettrico con un LED e sia la base del transistor 2N2222 (o uno equivalente). Quando uno dei pulsanti viene premuto, il programma in esecuzione su Arduino intercetta lo stato HIGH
impostato sull’ingresso pin 5 e quindi imposta l’uscita pin 7 nello stato logico HIGH, elettricamente a +5 Volt.
In questo modo il LED si accende e segnalare l’attivazione del monostabile, contemporaneamente la base del transistor viene alimentata. Il transistor in questo caso commuta dallo stato di interdizione (OFF) a quello di
saturazione (ON), permettendo al relè di eccitarsi e commutare i contatti elettrici a 220 Volt. Il risultato è che
il carico, nello schema la lampada LP, viene alimentato a 220 Volt. Dopo un tempo preimpostato l’uscita pin 7 ritorna allo stato logico LOW spegnendo sia il LED che il transistor. In questo modo il relè viene diseccitato
e la sua commutazione toglie la tensione al carico LP.
NOTA. Nello schema potrebbe essere inserito un potenziometro in modo da controllare il tempo di attivazione del monostabile, permettendo di impostare un
tempo da un minimo di 1 minuto ad un massimo di 10 minuti. In altre parole, la
variabile ‘DeltaT’ dello sketch precedente anziché avere un valore preimpostato di 5 minuti si potrebbe fare in modo da controllare questo valore con la rotazione del
cursore di un potenziometro.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-19-
Monitoraggio dell’esecuzione di un programma
Accade spesso che l’esecuzione di un programma non produce i risultati aspettati. In questo caso occorre
monitorare l’esecuzione del programma con una serie di warning, messaggi di attenzione, che vengono
riprodotti sul monitor del computer. La scheda Arduino collegata al computer tramite le porte USB può trasmettere delle warning al computer, che
questo riproduce sul monitor, al fine di monitorare passo-passo l’esecuzione di un programma.
Occorre utilizzare una specifica libreria(6) per poter stabilire il collegamento tra la scheda Arduino e il computer
in modo che quest’ultimo possa ricevere correttamente i messaggi trasmessi dalla scheda Arduino. La libreria da utilizzare per tale scopo è la Serial. Questa libreria permette di gestire il collegamento tra la
scheda Arduino ed un computer tramite la porta USB oppure tra due schede Arduino tramite i pin 0 (Rx) e pin
1 (Tx) riservati per tale scopo. La prima istruzione da inserire nel nostro sketch è l’istruzione Serial.begin(9600).
Questa istruzione stabilisce: a) un collegamento tra il computer ed Arduino; b) la velocità di scambio dei
segnali tra i due dispositivi, necessaria per la corretta comprensione dei segnali tra i due dispositivi. Dopo aver stabilito un collegamento tra i due dispositivi, è possibile usare l’istruzione che permette di inviare
al computer una stringa di caratteri (una frase), le warning.
L’istruzione da usare è: Serial.print( “frase da inviare” ). Con questa istruzione la frase posta tra il carattere
doppio apice di apertura e chiusura (“….”) è inviata al computer che provvede a visualizzarla sul monitor. La visualizzazione è possibile predisponendo l’IDE nella modalità Monitor Seriale, selezionabile sotto la voce
menu Strumenti. In questo modo tutte le warning trasmesse da Arduino sono visualizzate sul monitor del
computer. Con l’utilizzo della libreria Serial oltre a poter monitorare il corretto funzionamento del programma è anche
controllare il contenuto delle variabili per valutare la correttezza dei calcoli effettuati.
Esempio di utilizzo della libreria Serial tra scheda Arduino e PC int ValoreA0 ;
float Tensione ;
void setup()
{
Serial.begin(9600) ; // Stabilisce un collegamento con il PC
while( !Serial ) {;} // Aspetta l’OK per proseguire
Serial.println(ʺCollegamento seriale stabilito.ʺ) ; // Segnala sul Monitor del PC l’OK
}
void loop()
{
ValoreA0 = analogRead( A0 ) ; // Legge un valore dall’ingresso analogico
Tensione = ( (float)ValoreA0/1023.0 )*5.0 ; // Converte il valore letto in tensione
Serial.print( ʺTensione cursore ʺ); // Invia al PC la frase che verrà visualizzata
Serial.print( Tensione ) ; // sul monitor del computer. Ossia:
Serial.println( ʺ Voltʺ ) ; // Tensione cursore 3.5 Volt
}
Dal sito ufficiale www.arduino.cc è possibile ampliare la conoscenza di questa libreria.
Con la libreria Serial è anche possibile il collegamento di due Arduino per un mutuo scambio di informazioni. Il collegamento seriale avviene collegando il pin 0 (Rx) ed il pin 1 (Tx) di un primo Arduino al pin 1 e pin 0
di un secondo Arduino. In questo modo tutti i segnali che escono dal pin Tx (trasmittente) di un Arduino
entrano nel pin Rx (ricevente) dell’altro Arduino.
Il collegamento seriale di due Arduino potrebbe servire in una situazione reale in cui, ad
esempio, bisogna monitorare 10 periferiche analogiche. In questo caso un Arduino
monìtora 6 di queste periferiche e le altre 4 vengono monitorate da un altro Arduino, diciamo Main. Il programma in esecuzione sull’Arduino-Main interroga la scheda
Arduino che monìtora le 6 periferiche richiedendone i dati, mentre i dati delle altre 4
periferiche sarebbero direttamente accessibili dalla scheda Arduino-Main.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-20-
Sketch 04: Collegamento seriale di due schede Arduino
Due schede Arduino sono collegate tramite i pin Rx e Tx con collegamento incrociato, ossia il pin Tx di una
scheda è collegato all’Rx dell’altra scheda. Lo sketch che segue mostra come una scheda Arduino, che chiamiamo Main, riceve i dati rilevati e trasmessi dalla scheda Arduino, modulo secondario, che rileva i primi
tre ingressi analogici. Tramite la funzione Monitor Seriale impostata per la scheda Arduino Main possiamo
visualizzare i dati rilevati dal modulo secondario.
bool IsMain = false ; // Tipo di scheda: Main oppure modulo secondario
unsigned long Tempo = millis() ; // Variabile per conteggiare i secondi
int x, x0, x1, x2 ; // Variabili di appoggio
void setup()
{
Serial.begin( 9600 ) ; // Stabilisce un collegamento con il PC
while( !Serial ) {;} // Aspetta l’OK per proseguire
Serial.println("Comunicazione USB stabilita") ;
if(IsMain)
Serial.println( "Modulo Principale (Main)" );
else
Serial.println( "Modulo Secondario" ) ;
delay(3000) ;
}
void loop()
{
// +-------------------------+
// | |
// | M A I N |
// | |
// +-------------------------+
if( IsMain )
{ if( Serial.available() )
{ while( Serial.available()>0 )
{ x = Serial.read() ;
if( x == 13 ) // Il terminatore di stringa è il New-Line
Serial.println(""); // corrispondente ai codici ASCII 13 e 10.
else
if( x != 10 ) Serial.print( (char) x ) ;
}
}
}
// +-------------------------+
// | |
// | MODULO SECONDARIO |
// | |
// +-------------------------+
if( !IsMain )
{
if( (millis()-Tempo) > 1000 ) // Controlla se è passato 1 secondo
{ //
i0 = analogRead( A0 ) ; // Ad ogni secondo di tempo sono effettuate le
i1 = analogRead( A1 ) ; // letture degli ingressi analogici e trasmessi
i2 = analogRead( A2 ) ; // via seriale.
Serial.print( "Arduino n.0: " ) ;
Serial.print( "[A0]=" ) ; Serial.print( i0 ) ; Serial.print( " ; " ) ;
Serial.print( "[A1]=" ) ; Serial.print( i1 ) ; Serial.print( " ; " ) ;
Serial.print( "[A2]=" ) ; Serial.print( i2 ) ; Serial.print( " ; " ) ;
Serial.println( "" );
Tempo = millis() ;
}
}
}
Il programma deve essere caricato sia sul modulo main, con la variabile booleana IsMain=true, e sia sul
modulo secondario, con l’impostazione IsMain=false. La verifica del programma può essere fatta in modo
semplice variando con un potenziometro il livello elettrico degli ingressi A0, A1 e A2 del modulo secondario.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-21-
Display LCD 16x02 parallelo
Il display LCD1602 è un display a cristalli liquidi (LCD) costituito da 2 righe
ciascuna delle quali di 16 caratteri. Ogni carattere è una matrice di punti
luminosi che si accendono per formare un carattere. L’immagine a lato è reperita dal web. Il display viene gestito attraverso alcune linee di controllo.
Può essere del tipo retro-illuminato, nel qual caso è caratterizzato da 16 linee
di controllo, diversamente possiede 14 linee di controllo. La definizione delle
linee di controllo è riportata nella tabella che segue.
Pin Linea Pin Linea
1 GND 9 D2
2 +5 Volt 10 D3
3 Vo : Contrasto 11 D4
4 RS 12 D5
5 R/W 13 D6
6 E (Enable) 14 D7
7 D0 15 A
8 D1 16 K
La gestione diretta delle linee del display non è una cosa semplice. Per questo motivo deve essere utilizzata
una libreria appropriata, permettendo una semplice gestione e mettendo a disposizione alcuni comandi che
gestiscono il display. La libreria da utilizzare, importata nello sketch che vogliamo realizzare attraverso l’IDE, è la LiquidCrystal.
Attraverso la voce di menu dell’IDE 'Sketch', sottomenu '#include libreria' e quindi 'gestione librerie…' è
possibile importare la libreria LiquidCrystal.
Solo dopo aver importato la libreria è possibile utilizzarla. L’IDE di Arduino in automatico inserisce nel nostro file-sketch il comando #include <LiquidCrystal.h> come prima riga dello sketch.
Il passo successivo è quello di indicare alla libreria quali sono i pin di Arduino che gestiscono le linee del
display. In particolar modo occorre usare l’istruzione:
LiquidCrystal LCD( pin RS, pin Enable, pin D4, pin D5, pin D6, pin D7 )
L’istruzione richiede l’indice dei pin di Arduino a cui sono collegate le linee RS, E, D4, D5, D6 e D7 del display. Solo dopo questa impostazione è possibile utilizzare i seguenti comandi per gestire il display.
comando descrizione
LCD.clear() ; Con questo comando si fa in modo da cancellare tutti i caratteri presenti sul display. Diversamente rimangono caratteri derivanti
da stampe precedenti.
LCD.begin(16, 2) ;
Imposta l’utilizzo della libreria per il display costituito da 2 righe ciascuna con 16 colonne. Questo perché esistono altri
display con più righe.
LCD.setCursor( x-colonna , y-riga ) ;
Con questo comando si imposta la posizione di inizio scrittura
sul display. L’indice x-colonna è un numero tra 0 e 15 (16 colonne); l’indice y-riga è un intero tra 0 e 1 ( 2 righe).
LCD.print( “stringa” ) ;
LCD.print( valore ) ;
Con questa istruzione è possibile inviare al display una tringa di
caratteri o un valore numerico che verrà visualizzato sul display.
Spetta al programmatore controllare che le stringhe siano al massimo di 16 caratteri e su quale riga visualizzare
l’informazione.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-22-
Sketch 05: Visualizzare sul display l’indicazione dell’ora nel formato mʹ sʺ
Lo sketch si propone di illustrare i comandi principali per gestire il display LCD1602. I collegamenti da
effettuare sono i seguenti. Display LCD1602 ARDUINO
Pin Pin
1 GND GND
2 +5 Volt +5 Volt
3 GND o Potenziometro GND
4 RS 8
5 GND GND
6 Enable 9
11,12,13,14 DATA 10,11,12,13
#include <LiquidCrystal.h>
LiquidCrystal LCD(8,9,10,11,12,13) ;
byte Secondi, Minuti ;
unsigned long Tempo ;
unsigned long T ;
void setup()
{
LCD.begin(16, 2) ;
LCD.clear() ;
LCD.setCursor(0,0) ;
LCD.print( "Orologio" ) ;
Secondi=0 ;
Minuti=0 ;
Tempo=millis() ;
}
void loop()
{
T = ((millis()-Tempo)/1000) ;
if( (byte) T > 1 )
{
Tempo=millis() ;
Secondi++ ;
if( Secondi>59 )
{
Secondi=0 ;
Minuti++ ;
if( Minuti>59 ) Minuti=0;
}
LCD.setCursor(0, 1) ;
LCD.print( Minuti ) ;
LCD.print( (char) 39 ) ;
LCD.print( Secondi ) ;
LCD.print( (char) 34 ) ;
LCD.print( " " ) ;
}
}
Imposta la libreria da usare
Imposta nella libreria la corrispondenza tra le
linee del display e i pin di Arduino
Definizione di alcune variabili
Inizializza il display LCD
Cancella i caratteri presenti sull’LCD
Posiziona il cursore nel punto (0,0)
Scrive la frase ‘OROLOGIO’
Azzera le variabili definite
Calcola i secondi trascorsi
Esegue una conversione di tipo
Posiziona il cursore nel punto (0,1)
Forza il tipo (char) del numero indicato
Cancella i caratteri inutili a destra
Effettuati i collegamenti e caricato su una scheda Arduino lo sketch illustrato, sulla prima riga del display
LCD1602 appare la scritta Orologio, mentre sulla seconda riga appare l’indicazione dei minuti e dei secondi che scorrono col passare del tempo, nel formato, ad esempio, 12ʹ38ʺ.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-23-
Display LCD 16x02 Seriale
In commercio è reperibile un tipo di LCD parallelo, gestito da
un’interfaccia seriale montata sul display stesso. In questo caso la
gestione del display è più semplice e richiede meno pin di collegamento. L’immagine a lato mostra il display LCD con
l’interfaccia seriale direttamente montata sul display. Il piccolo
trimmer di colore celeste che si vede nell’immagine permette la
regolazione del contrasto dell’LCD. L’interfaccia seriale ha i seguenti pin:
1) Pin di Alimentazione Vcc da collegare a +5 Volt. 2) Pin di riferimento di massa GND
3) Pin seriale SCL, Serial clock, che deve essere collegato al
SCL di Arduino 4) Pin SDA, Serial Data, che deve essere collegato al pin SDA di Arduino
La gestione del display avviene tramite un’apposita libreria denominata LiquidCrystal_I2C.h, che deve essere
importata nello sketch come prima istruzione con la direttiva #include. I comandi per gestire il display seriale restano gli stessi già descritti per la gestione del display parallelo.
Sketch 06: Gestione del display seriale.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C LCD(0x3F, 16, 2); // Solo 2 indirizzi possibili: 0x27 / 0x3F
void setup()
{
LCD.begin() ; // Una delle due istruzioni funziona
LCD.backlight() ;
}
void loop()
{
LCD.clear() ;
StampaMessaggio( 0 , "Gestione LCD " ) ;
StampaMessaggio( 1 , "Seriale,cod=0x3F" ) ;
delay( 3000 );
StampaMessaggio( 0 , "A. Celentano " ) ;
StampaMessaggio( 1 , "a.s. 2018/2019 " ) ;
delay(3000);
}
void StampaMessaggio( byte PosRiga , char XMessaggio[] )
{
LCD.setCursor( 0 , PosRiga );
LCD.print( XMessaggio ) ;
}
Lo sketch illustra un breve segmento di programmazione per la gestione del display seriale.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-24-
Sensore di posizione: Misurare le distanze con gli ultrasuoni (HC-SR04).
Un’onda sonora si propaga nello spazio e quando colpisce un
ostacolo ne è riflessa proprio come uno specchio riflette un
raggio di luce. L’orecchio umano è in grado di percepire tutti i suoni che hanno una frequenza al di sotto dei 20 KHz. Le onde
sonore con frequenze al di sopra dei 20 KHz (ultrasuoni) non
sono percepiti dall’orecchio umano. Un’onda sonora si propaga
nello spazio ad una velocità di circa Vsuono=340 m/s, valore che può dipendere dalla temperatura e dall’umidità ambientale.
Il dispositivo ad ultrasuoni HC-SR04 è costituito da: a) Un pin di alimentazione Vcc per alimentare il dispositivo a +5 Volt
b) Un sensore-trasduttore Tx (trasmittente) in grado di generare un’onda ad ultrasuoni se abilitato tramite
un segnale elettrico. Il pin di abilitazione è indicato come pin di Trigger. Portando a livello alto (HIGH) tale pin e per tutto il tempo che vi rimane alto il dispositivo genera un’onda ad ultrasuoni.
c) Un sensore-trasduttore Rx (ricevitore) in grado di segnalare elettricamente (+5 Volt) la rilevazione di
onde sonore ad ultrasuoni. Il pin di segnalazione è indicato come pin di Echo. Questo pin normalmente
è tenuto a livello basso (LOW) e solo se rileva gli ultrasuoni è portato a livello alto (HIGH). d) Un pin riservato al potenziale di massa GND.
Logica operativa. La distanza di un oggetto può essere determinata nel seguente modo. Si genera un’onda ad ultrasuoni e si
registra il tempo T1 in cui si interrompe la generazione dell’onda. Si registra il tempo T2 che il dispositivo
segnala l’onda di ritorno riflessa da un oggetto. L’intervallo di tempo T2-T1 è esattamente il tempo impiegato
dall’onda sonora per andare dal dispositivo ad un oggetto e ritornare al dispositivo stesso. Pertanto lo spazio percorso dall’onda è Spazio = Vsuono * (T2-T1). La distanza a cui si trova
l’oggetto è la metà di tale spazio.
L’immagine a lato raffigura un sensore ad ultrasuoni (fonte internet).
Sketch 07: Misurare la distanza di un oggetto
byte TriggerPin = 9 ;
byte EchoPin = 10 ;
long durata = 0 ;
long distanza = 0 ;
void setup()
{ pinMode( TriggerPin, OUTPUT ) ;
pinMode( EchoPin, INPUT ) ;
Serial.begin( 9600 ) ;
while(!Serial){;}
Serial.println( "Sensore Ultrasuoni") ;
delay(100) ;
digitalWrite( TriggerPin , LOW ) ;
delay(100) ;
}
void loop()
{ digitalWrite( TriggerPin, HIGH ) ;
delayMicroseconds( 10 ) ;
digitalWrite( TriggerPin, LOW ) ;
durata = pulseIn( EchoPin, HIGH) ;
if( durata > 38000 )
distanza = 1000 ;
else
distanza = 0.034*durata/2 ;
Serial.println( distanza ) ;
delay(500) ;
}
Pin riservato all’impulso di trigger
Pin riservato per rilevare l'impulso
Variabile di appoggio
Variabile di appoggio
Configura i pin
Stabilisce una comunicazione con il PC
Sospende la generazione di ultrasuoni
Start: Genera un’onda ad ultrasuoni
Stop: Arresta l’emissione di ultrasuoni
Aspetta di rilevare gli ultrasuoni di ritorno
Fuori portata, oltre i 10 metri
Calcola la distanza in cm
Visualizza la distanza
L’istruzione pulseIn() permette di misurare il tempo in cui il pin da monitorare, indicato come input alla
funzione, diventi alto. L’istruzione controlla che il pin EchoPin diventi HIGH (alto), memorizzando nella
variabile durata il numero di milli-secondi impiegati per tale transizione.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-25-
Sensore di posizione: rilevatore di presenza oggetti ad infrarossi FC-51
(IR Infrared Obstacle Detection Sensor Module)
Questo sensore permette di rilevare la presenza di un oggetto posto ad una
distanza inferiore a 30 cm. Segnala solo la presenza dell’oggetto, non misura la distanza dal sensore. L’immagine a lato è da fonte internet e mostra come
si presenta questo dispositivo-sensore.
Il funzionamento del sensore si basa sul principio che qualsiasi oggetto
illuminato riflette la luce in tutte le direzioni, permettendo opportunamente di rilevare sia la presenza.
Il sensore presenta tre pin per la sua gestione:
a) Il pin di alimentazione, indicato con Vcc, deve essere alimentato con una tensione da 3 a 9 volt.
b) Il pin di massa GND (ground).
c) Il pin indicato come OUT. In assenza di oggetti rilevati è a livello alto (H) e solo se rileva la presenza di un oggetto in un range da 2 a 30 cm viene abbasso (L).
Il sensore è provvisto di un diodo emettitore IR (InfraRed) che emette i raggi infrarossi non visibili dall’occhio
umano, ma rilevabili tramite un apposito diodo a IR. Nella foto il diodo trasparente è il fotodiodo trasmettitore IR, il diodo di colore scuro è il diodo IR ricevitore.
Un piccolo trimmer regolabile, nella foto il componente di
colore celeste, permette di controllare la sensibilità del dispositivo regolando la soglia di attivazione per una
distanza inferiore a 30 cm.
Da fonte internet è possibile trovare uno schema elettrico del
dispositivo, come illustrato dallo schema a lato. Il dispositivo è provvisto di due LED per segnalare sia
l’alimentazione del dispositivo che il rilevamento degli
oggetti, come è possibile constatare dall’analisi dello schema elettrico a lato (fonte internet).
Sketch 08: Conteggiare gli oggetti che scorrono su nastro trasportatore
Lo sketch che segue permette di conteggiare il numero di oggetti che passano davanti al sensore. E’ una
situazione reale se si pensa ad un processo produttivo in cui i prodotti realizzati devono essere contati in
automatico.
/*
* Lo sketch registra e visualizza su Monitor
* seriale attivo il numero di oggetti che
* passano davanti al sensore
*/
byte PinInput = 5 ; // Pin di input
int Totale = 0 ; // Totale oggetti
int Tempo = 100 ; // Tempo di transito oggetto
void setup()
{
Serial.begin(9600) ;
pinMode( PinInput , INPUT ) ;
}
void loop()
{
Serial.print("Totale = ");
Serial.println(Totale);
while( digitalRead(PinInput) == HIGH ) {;}
Totale++ ;
delay( Tempo ) ;
}
Definizione delle variabili e dei pin
Configura il pin di input
Visualizza totale oggetti conteggiati
Aspetta che l’input diventi basso
Aspetta che l’oggetto sia passato
davanti al sensore
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-26-
Modulo Bluetooth
I moduli Bluetooth sono piccoli dispositivi che permetto un collegamento a
radiofrequenza tra la scheda Arduino ed un dispositivo mobile tipo cellulare o tablet
su cui è installato il sistema operativo Android. Permettono di scambiare informazioni tra due i dispositivi entro un raggio d’azione di una decina di metri.
L’immagine a lato visualizza il modulo Bluetooth come si presenta ed il logo che
caratterizza questo tipo di protocollo (fonte web).
Il modulo è dotato dei seguenti pin per la gestione Input/Output.
a) Il pin di alimentazione Vcc, collegabile a +5 Volt
b) Il pin di riferimento di massa GND c) Il pin Tx preposto all’invio dei segnali verso dispositivi mobili
d) Il pin Rx preposto alla ricezione dei segnali da dispositivi mobili
Il modulo è collegabile alla scheda Arduino sfruttando l’alimentazione di +5 Volt che Arduino mette a
disposizione e collegando i pin Tx e Rx del Bluetooth ai pin 0 (Rx) e pin 1 (Tx) di Arduino rispettivamente,
ossia collegando l’Rx dell’uno al Tx dell’altro. In questo caso Arduino gestisce il modulo Bluetooth con la
libreria Serial che ha impostato per default.
La gestione del modulo Bluetooth richiede l’installazione su dispositivo mobile di un programma capace di
inviare messaggi alla scheda Arduino tramite il protocollo bluetooth, tali programmi si chiamano App (Application). Un’App molto comoda e semplice da usare è scaricabile dal sito www.keuwl.com denominata
Bluetooth Electronics. L’immagine che segue è l’immagine del main screen da cui si parte per realizzare un
proprio form che permette di dialogare con Arduino.
Dopo aver installato l’app appena descritta, si deve impostare nell’app che tutti i messaggi che vengono inviati
devono terminare con il carattere ; che rappresenta il terminatore delle stringhe e che permette di riconoscere
i comandi inviati dal dispositivo mobile. Questa impostazione è necessaria per poter utilizzare lo sketch che
segue. Lo sketch che segue mostra un esempio di come una scheda Arduino può ricevere ed inviare informazioni (stringhe di caratteri) da/verso un dispositivo mobile. Il programma illustra il modo di gestire i
pin 0 e pin 1 di Arduino con la libreria Serial.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-27-
Sketch 09: Acquisizione di comandi tramite modulo Bluetooth
Lo sketch che segue illustra come ricevere delle stringhe di caratteri da un dispositivo mobile, riconoscerle ed
eseguire un’operazione. Se il comando non viene riconosciuto viene segnalato tramite messaggio sul Monitor
seriale attivo. /*
* Tutti i messaggi ricevuti dalla scheda Bluetooth sono acquisiti da Arduino e
* visualizzati su Monitor seriale dell'IDE.
* Il programma è stato provato con l'App per Android "Bluetooth Electronic",
* scaricabile gratuitamente dal sito www.keuwl.com (ottimo programma!)
*/
#include <string.h>
char Comando[] = " "; // Buffer riservato per i comandi
bool CMD_OK ;
void setup()
{
Serial.begin(9600) ;
while( !Serial ) {;}
Serial.println("OK") ;
}
void loop()
{
if( LeggiComando( Comando ) )
{
CMD_OK = false ;
if( strncmp( Comando , "Start" , 5 ) == 0 ) { Serial.println( "[Start]"); CMD_OK = true ; }
if( strncmp( Comando , "End" , 3 ) == 0 ) { Serial.println( "[End]") ; CMD_OK = true ; }
if( !CMD_OK ) {Serial.print( "Comando non riconosciuto: " ) ; Serial.println( Comando ) ; }
}
}
/*
* La funzione acquisisce un comando che arriva via seriale.
* Il comando deve avere come terminatore il carattere ; .
* La funzione ritorna la lunghezza del comando acquisito, diversamente zero.
*/
byte LeggiComando( char BufferCMD[] )
{
byte Nx = 0 ;
char Dx = 0 ;
char CMDTerminator = ';' ;
if( Serial.available()>0 )
{
while( true )
{
Dx = Serial.read() ;
if( Dx == CMDTerminator ) break ;
if( Dx != (char) -1 )
{
BufferCMD[Nx] = Dx ;
Nx++;
}
}
BufferCMD[Nx]= '\0' ;
}
return Nx ;
}
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-28-
Sketch 10: Gestione del modulo Bluetooth con la ridefinizione dei pin Tx e Rx.
/*
* Il programma stabilisce un collegamento con il "Monitore seriale" per visualizzare
* sul monitor i messaggi di invio e ricezione.
* Allo stesso tempo apre un collegamento con il dispositivo Bluetooth
* per ricevere e inviare messaggi ridefinendo i pin preposti alla ricezione/trasmissione.
* Lo sketch importa la libreria SoftwareSerial che permette la ridefinizione di tali pin
*/
#include <SoftwareSerial.h>
byte PinRx = 8 ; // Definisce il pin preposto alla ricezione Rx
byte PinTx = 9 ; // Definisce il pin preposto alla trasmissione Tx
SoftwareSerial Bluetooth( PinRx , PinTx ) ;
void setup()
{
OpenMonitorSerial() ; // Apertura per scambi messaggi sul monitor
OpenBluetooth() ; // Apertura per scambi messaggi verso il bluetooth
}
void loop()
{
if( Bluetooth.available() )
Serial.write( Bluetooth.read() ) ;
if( Serial.available() )
Bluetooth.write( Serial.read() ) ;
}
void OpenMonitorSerial()
{
Serial.begin(9600);
while (!Serial) {;}
Serial.println("Aperto Monitor Seriale");
}
void OpenBluetooth()
{
Bluetooth.begin(9600);
delay(100);
Bluetooth.println("Aperto Bluetooth Seriale");
}
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-29-
La funzione PWM con Arduino
La tecnica PWM, acrnonimo di Pulse Width Modulation ossia impulsi di ampiezza modulata, consiste nel
generare un segnale digitale ad una data frequenza e variare il Duty-Cycle (D.C.) affinché il valore medio(7)
del segnale generato possa essere controllato da un minimo di 0 ad un valore massimo pari all’ampiezza V0 del segnale digitale. Vediamo come il valor medio del segnale digitale è funzione del duty-cycle che
caratterizza il segnale stesso. Supponendo di dividere il periodo di un segnale periodico digitale in intervalli
Δt, il valore medio del segnale digitale può essere ricavato come segue.
𝑉𝑚𝑒𝑑 = ∑ ( 𝑣(𝑡) ∗ Δt𝑇
0 )
𝑇=
∑ ( 𝑣(𝑡) ∗ Δt𝑇𝑂𝑁0 )
𝑇=
∑ ( 𝑉𝑜 ∗ Δt𝑇𝑂𝑁0 )
𝑇= 𝑉𝑜 ∗
∑ Δt𝑇𝑂𝑁0
𝑇= 𝑉𝑜 ∗ 𝐷. 𝐶.
Pertanto, dall’ultima espressione possiamo dire:
𝑽𝒎𝒆𝒅 = 𝑽𝒐 ∗ 𝑫. 𝑪. Questo risultato esprime la relazione tra il valore medio di un segnale digitale e il Duty-Cycle che caratterizza
i segnali digitali. In altre parole, controllando il D.C. controlliamo la quantità di energia che forniamo
all’utilizzatore del segnale digitale. Ad esempio, si pensi al controllo di velocità di rotazione di una ventola di raffreddamento: controllando il D.C. controlliamo la velocità di rotazione della ventola facendola girare
velocemente se c’è molto da raffreddare e meno velocemente se c’è poco da raffreddare, in questo modo si
razionalizza il bilancio energetico. Con la piattaforma Arduino è possibile realizzare un controllo PWM. Alcuni pin digitali, configurati come
Output, sono preposti per generare un segnale digitale ad una frequenza ben preciso. In particolare:
PIN Digitale Frequenza (Hz)
9,10,11 450
5,6 950
La tabella illustra la corrispondenza tra i pin digitali e la frequenza del segnale che possono generare. Il segnale può essere generato usando l’istruzione analogWrite( Pin , DC ). Questa istruzione richiede come parametro
di input l’indicazione del pin digitale su cui agire (Pin) ed il valore del Duty-Cycle (DC) espresso come indice
numerico intero a 8 bit, ossia un numero tra 0 (DC=0%) e 255 (DC=100%). Dopo l’esecuzione di questa
istruzione, dal pin digitale indicato è possibile prelevare il segnale digitale impostato fino a quando un’ulteriore istruzione analogWrite() non modifica le proprietà del segnale da prelevare.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-30-
Controllo della velocità di una ventola di raffreddamento per computer.
Vediamo come è possibile controllare la velocità di rotazione di una ventola con la
tecnica PWB. Una ventola di raffreddamento per computer in genere è alimentata
con una tensione di 12 Volt ed assorbe non meno di 200-300 mA di corrente ed è costituita da tre poli. L’immagine riportata a lato riporta una tipica ventola di
raffreddamento usata nei computer. Il polo nero è riservato al potenziale di massa;
il polo rosso (sempre centrale nel connettore tripolare) è riservato all’alimentazione
di +12 Volt; il polo giallo è di controllo da cui è possibile rilevare un impulso elettrico digitale dovuto alla rotazione della ventola. I colori descritti possono variare
ad eccezione di quello nero.
La scheda Arduino non può erogare o assorbire più di 20-50 mA di corrente da una qualunque uscita digitale.
Ciò comporta che per controllare la velocità di rotazione di una ventola è necessario l’utilizzo di un’interfaccia
di potenza in grado di controllare la quantità di energia inviata alla ventola. In generale è buona norma usare delle interfacce che permettono di assorbire pochissima corrente dalla scheda
Arduino e che permettono l’erogazione di una corrente ben più alta.
Lo schema che segue permette di realizzare un controllo della rotazione della ventola tramite la tecnica PWB con Arduino. Il
transistor 2N2222 lavora come interruttore elettronico. Il
programma in esecuzione su Arduino controlla l’uscita digitale D9 tramite la tecnica PWM. Il programma legge il livello di tensione
impostato tramite il potenziometro ed imposta il duty-cycle in modo
da controllare la quantità di corrente che entra nella base del
2N2222 e, di conseguenza, controlla la velocità della ventola. Il programma può leggere il segnale che la ventola invia all’ingresso
analogico A0 e determinare se la ventola gira o è ferma. Con un
programma più elaborato è possibile determinare la velocità di rotazione della ventola in giri/minuto.
La piattaforma programmabile Arduino – Appunti del corso di Sistemi a.s. 2018/2019 – Prof. Aniello Celentano
-31-
Riferimenti
(1) La differenza tra un microcontrollore e un microprocessore sta nella potenza delle funzioni che
possono svolgere. Si può pensare molto semplicisticamente allo stesso rapporto che esiste tra un’utilitaria della FIAT, tipo la 500, e una FERRARI: la fiat 500 possiamo dire che è una versione
ridotta (familiare) di una Ferrari. Allo stesso modo il microcontrollore è una versione ridotta del
microprocessore. (2) I segnali elettrici TTL sono segnali digitali di 0 Volt oppure +5 Volt. L’acronimo TTL sta per
Transistor-Transistor-Logic, ossia circuiti con accoppiamento di Transitor in configurazione Logica.
(3) Il dispositivo Analog-Digital-Converter ADC permette di associare ad un livello di tensione tra 0 e +5 Volt un numero tra 0 e 1023. Un opportuno circuito elettronico individua a quale porzione delle 1024
parti di suddivisione dell’intervallo analogico appartiene.
(4) Il prodotto R·C ha le dimensioni di un tempo ed è indicato come costante di tempo. Nel caso specifico
in esame tale prodotto deve essere di circa 1 milli-secondo, tempo necessario affinché due contatti metallici risultino elettricamente ben connessi.
(5) Un’interfaccia è un dispositivo interposto tra due circuiti in grado di adattare le caratteristiche dell’uno
verso l’altro dispositivo. Ad esempio una tastiera è un’interfaccia tra il computer e un operatore. (6) Una libreria software è un programma esterno che permette di ampliare i comandi base per la
programmazione che si sta realizzando. In generale la libreria metta a disposizione del programmatore
dei comandi per realizzare specifiche funzioni. (7) Il valore medio Vmed di un segnale elettrico v(t), variabile nell’intervallo temporale [0,T] con T il
periodo del segnale, si ottiene dividendo T in intervalli Δt e per ogni uno dei quali si determina l’area
del rettangolo con base Δt ed altezza il valore assunto dal segnale v(t). Sommando tutte le aree ottenute
e dividendo per il periodo T si ottiene il valor medio cercato. Al limite per cui Δt tende a zero vale
l’espressione:
𝑉𝑚𝑒𝑑 = 1
𝑇∫ 𝑣(𝑡) 𝑑𝑡
𝑇
0