Sei sulla pagina 1di 87

E

corso F L O
WCOD

Flowcode permette
di apprendere in
maniera molto
intuitiva lo sviluppo
di software per
applicazioni
embedded, in
quanto il codice
viene scritto facendo
uso di oggetti
grafici, in luogo dei
classici linguaggi
di programmazione
come il C e
lAssembler.
Prima puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

al giorno dellinvenzione del primo


transistor, avvenuta ormai nel
1947, lelettronica diventata parte
integrante della nostra vita, e sarebbe
impensabile ormai, credere di poter fare
a meno di questo tassello fondamentale
della storia dellevoluzione umana. Una
delle derivazioni pi comuni di questa
disciplina sicuramente rappresentata dal
mondo dei dispositivi embedded. Quando
facciamo una telefonata, o navighiamo
su internet usando il nostro smartphone,
quando guidiamo la nostra auto, quando
facciamo la spesa pagando con la nostra carta di credito, in ognuna di queste
circostanze, diversi dispositivi elettronici

dotati di intelligenza elaborano milioni di


informazioni al secondo, semplificandoci
la vita. Dietro tali dispositivi, veri e propri
instancabili ed invisibili servitori dei nostri
giorni, si cela comunque la mano delluomo: qualcuno ne ha ideato le funzionalit,
li ha progettati elettronicamente e ne ha
sviluppato la logica. Anche lo sviluppo dei
sistemi embedded ha subito una sua evoluzione nel corso degli anni, e si passati dai
dispositivi totalmente analogici ai sistemi a
microcontrollore che, per svolgere il compito specifico, devono essere opportunamente programmati, usando appositi linguaggi
di programmazione. La programmazione,
vero e proprio cuore dello sviluppo, stata

Elettronica In ~ Giugno 2013

127

Fig. 1
Logo della Matrix
Multimedia.

per anni appannaggio di poche aziende


nel mondo, essendo di fatto inaccessibile
alle aziende non specializzate ed ai privati, per via degli altissimi costi dei sistemi
di sviluppo. Negli ultimi ventanni, con
lavvento dei primi controllori basati su
memorie FLASH (riprogrammabili elettricamente), il costo dei sistemi di sviluppo
calato vertiginosamente, rendendo questo
tipo di tecnologie accessibili anche agli
sviluppatori privati ed al mondo hobbistico. Sono cos comparsi i primi ambienti
di sviluppo software e compilatori (generalmente basati su linguaggi come il C e
lassembler) a basso costo. Tali ambienti
hanno, comunque, continuato a mantenere
caratteristiche di complessit duso ed i
linguaggi utilizzati richiedono, per essere impiegati efficacemente, delle basi di
programmazione non indifferenti. Cos lo
sviluppo su sistemi embedded diventato
pi accessibile dal punto di vista economico, ma le difficolt tecniche nelluso dei
tools sono rimaste comunque uno scoglio
notevole da superare per i neofiti della
programmazione software. Per ovviare a
problematiche di questo tipo sta nascendo,
in questi anni, una nuova generazione di
ambienti di sviluppo, che ha lo scopo di
astrarre le difficolt intrinseche di un linguaggio di programmazione text-based, facendo uso di formalismi pi comuni. Uno
degli esponenti di spicco di questa nuova
generazione di ambienti di sviluppo
Flowcode, prodotto da Matrix Multimedia,
azienda leader nel settore della produzione
di sistemi di sviluppo hardware/software
per microcontrollori.

Il concetto su cui si basa Flowcode luso


di una rappresentazione grafica basata su
diagrammi di flusso (o flowchart, da cui
il nome Flowcode) per lo sviluppo di un
programma per target embedded. Questo
approccio permette di rimpiazzare limplementazione basata sulle keywords, tipica dei
linguaggi di programmazione tradizionali.
Un esempio di frammento di codice grafico
scritto in Flowcode riportato in Fig. 2.
Lambiente di sviluppo, oltre a generare
leseguibile per la programmazione del
chip (ed eventualmente anche la traduzione in codice sorgente C), integra un
simulatore ed un ICD (in-circuit debugger)
per eseguire il debugging del codice direttamente sul target. Una delle caratteristiche
pi interessanti di Flowcode , come vedremo in dettaglio nelle prossime puntate, la
disponibilit di una ricca libreria di componenti per lutilizzo delle periferiche normalmente integrate nei microcontrollori.
Luso dei componenti semplifica notevolmente laccesso alle periferiche, anche nel
caso delle periferiche pi complesse, come

Fig. 2
Esempio
di codice
Flowcode.

cors
o
F
L
O
W
CO

Programmazione grafica con Flowcode


Lambiente di sviluppo Flowcode, giunto
ormai alla versione 5, nasce per ovviare al
problema della complessit degli ambienti
di sviluppo tradizionali e per consentire
lo sviluppo di applicazioni embedded
complesse anche a chi ha una minima
(se non nulla) conoscenza di linguaggi di
programmazione. Flowcode un completo
IDE (Integrated Development Enviroment)
per microcontrollori ad 8, 16 e 32-bit. Gli
attuali target supportati sono:
Microchip PICmicro della serie 10, 12, 16

e 18 (8-bit),
Microchip dsPIC30F, dsPIC33F, dsPIC33E e PIC24 (E, H ed F),
Atmel AVR e piattaforma Arduino,
Atmel ARM.

DE

128

Giugno 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 3
Sito Matrix
multimedia
per download
di FlowCode.

ad esempio la porta USB, la porta Ethernet o altri sistemi di comunicazione e/o


controllo. Una descrizione pi dettagliata
dei componenti sar fatta in seguito, ma
importante sottolineare che la disponibilit
di queste librerie consente di sviluppare
applicazioni anche molto complesse con
linterconnessione di pochi semplici blocchi
funzionali.
Installazione e configurazione
di Flowcode V5
Come primo argomento del corso illustriamo come installare e configurare lIDE. Il
pacchetto di installazione di Flowcode
scaricabile dal sito web della Matrix (www.
matrixmultimedia.com) e, come gi detto precedentemente, attualmente sono supportati
diversi target, a cui corrispondono diverse versioni del software. Come versione
base del corso stata scelta la versione
per i microcontrollori PIC della Microchip
Technology. Dopo esserci collegati al sito
web della Matrix, accediamo alla sezione
download e scarichiamo la versione per
PICmicro.
Al termine del download eseguiamo il file
FlowcodeV5 - PICMicro.exe e avviamo
linstallazione del programma. Comparir il wizard di installazione, la cui prima
schermata riportata in Fig. 4. Premiamo il
pulsante Next per accedere alla schermata
successiva, confermiamo di accettare la
licenza duso e proseguiamo.

Fig. 4 - Finestra iniziale di installazione di FlowCode.

Fig. 5 - Accettazione della licenza duso.

Elettronica In ~ Giugno 2013

129

Fig. 6 - Inserimento dati di installazione.

Fig. 7 - Selezione codice attivazione prodotto.

Installazione scheda di sviluppo EB006


A questo punto il nostro ambiente di

Fig. 8
Schermata
iniziale
installazione
driver per
E-block
EB006.

cors
o
F
L
O
W
CO

Inseriamo ora il nostro nome ed il nome


nellorganizzazione (che in questo caso
abbiamo indicato come ElettronicaIn),
come illustrato in Fig. 6, e premiamo ancora una volta il pulsante Next. Selezioniamo
la cartella di destinazione e procediamo
alla schermata successiva.
A questo punto il wizard ci chiede conferma
di proseguire con linstallazione e dopo
averla ricevuta inizier il processo di copia
dei file su disco. Al termine delloperazione viene richiesto di attivare il prodotto
mediante una chiave di attivazione, o di
attivare una licenza free, come possiamo
vedere in Fig. 7. La licenza free non ha
limitazioni in termini di tempo, ma attivato un set ridotto di componenti allinterno dellambiente.

sviluppo correttamente installato e


possiamo procedere alla realizzazione
delle nostre applicazioni. Come supporto hardware al corso verr utilizzato un
sistema modulare di schede di sviluppo,
prodotte sempre dalla Matrix, che prende
il nome di E-block. Il sistema costituito
da una scheda madre alla quale possono
essere connessi diversi blocchi per espanderne le funzionalit. Ogni blocco offre
le risorse hardware necessarie per implementare una specifica interfaccia, come,
ad esempio, porte USB o Ethernet, display
grafici, interfacce CAN, driver per
motori passo-passo, etc. La scheda scelta
come scheda madre per lo sviluppo
delle applicazioni che saranno presentate lungo la durata del corso la EB006.
La scheda EB006 corredata di un CD di
installazione che serve per installare tutti i
driver necessari per poter utilizzare correttamente il sistema di sviluppo. Inseriamolo
allinterno del nostro lettore CD e posizioniamoci allinterno della cartella drivers\
EB-006. In base allarchitettura del nostro
PC scegliamo dpinst_amd64 (64 bit AMD
o Intel), dpins_ia64 (64 bit itanium) oppure
dpins_x86 (32bit) ed avviamo leseguibile.
Comparir la schermata di Fig. 8, che ci informa che premendo sul pulsante Avanti verr avviata la procedura di installazione dei driver. Proseguiamo e, nel caso
ci venga notificato da Windows che non
possibile verificare lautenticit dei driver,
scegliamo di proseguire con linstallazione. Al termine delloperazione apparir la

DE

130

Giugno 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 9
Interfaccia
FlowCode.

schermata che ci indica che linstallazione


stata eseguita correttamente. Per concludere linstallazione premiamo il pulsante
Fine.
Colleghiamo ora la scheda di sviluppo
EB006 mediante il cavo USB (fornito in
dotazione) al computer. Il sistema operativo installer i driver aggiuntivi ed uno dei
due led sulla scheda si accender, segnalandoci che il debugger attivo.
Interfaccia di Flowcode
A questo punto anche il nostro hardware
di sviluppo configurato e pronto per
essere utilizzato, passiamo quindi alla
descrizione dellinterfaccia di programmazione dellIDE. Come gi detto nella parte
introduttiva di questa puntata, Flowcode
un ambiente di sviluppo grafico: questo
vuol dire che il programma non viene
rappresentato, come avviene invece con i
linguaggi di programmazione tradizionale,
da un codice testuale, ma verr composto
facendo uso solo di oggetti grafici. Nel
caso di Flowcode la rappresentazione
scelta quella dei diagrammi di flusso (o
flowchart). Gli elementi base del diagramma di flusso implementano le strutture di
controllo fondamentali del programma,
come i blocchi decisionali, i cicli, i ritardi, le
selezioni multiple, le operazioni logiche e
matematiche e altro ancora. Per la gestione
delle periferiche pi complesse sono invece
forniti una serie di componenti che non
sono altro che dei contenitori che offrono
delle funzioni predefinite, per semplificare

la gestione della periferica. Infine, tramite


un opportuno wizard di configurazione,
possibile impostare la configurazione base
del microcontrollore, come la frequenza
del clock interno, eventuali protezioni, le
impostazioni sulla memoria, etc.
Linterfaccia di FlowCode suddivisa
principalmente in barre e pannelli, ognuno dei quali ha uno specifico compito che
ora andremo ad analizzare. Qualora non
tutte le barre siano visualizzate, possibile
aggiungerle dal menu visualizza semplicemente aggiungendo una spunta vicino al
nome che le identifica.
In Fig. 9 rappresentata la schermata principale di Flowcode. Al centro dello schermo presente un tab (che nel nostro caso
si chiama Main), che chiameremo area
di progetto nel quale verr implementato
il diagramma di flusso. Nella parte sinistra
dello schermo invece presente la barra
delle icone, dalla quale possibile scegliere quale blocco inserire allinterno del
programma.

Elettronica In ~ Giugno 2013

131

Fig. 10
Barre degli
strumenti.

Fig. 11
Barre
delle
icone.

Fig. 12
Opzioni di progetto.

132

Giugno 2013 ~ Elettronica In

Fig. 13
Inserimento
descrizione
progetto.

DE

Creare un progetto
Per creare un progetto apriamo Flowcode
e premiamo sul pulsante Nuovo progetto
nella barra degli strumenti. Configureremo
questo progetto in modo da poterlo utilizzare negli esempi che vedremo in seguito.
Selezioniamo il microcontrollore scegliendo la famiglia 18 e successivamente

18F4550, come indicato in Fig. 12. Ora


passiamo al tab Descrizione progetto e
inseriamo una descrizione significativa.
Dal punto di vista della funzionalit del
programma non cambia nulla se lasciamo
vuoti questi campi ma, per poter capire
meglio che cosa realizza il nostro progetto,
sarebbe buona norma inserirne almeno
una breve descrizione. Nel nostro caso
abbiamo inserito il titolo e la descrizione
del progetto che realizzeremo al termine di
questa puntata: un semplice programma
che fa lampeggiare un LED.
Allinterno del tab Operazioni Generali,
visibile in Fig. 14, configuriamo il progetto
in modo che rispecchi limplementazione
hardware del sistema. La casella Velocit
di clock del PIC deve essere impostata a
48MHz e la casella Configura componente deve essere selezionata. Passiamo
ora a configurare i settaggi specifici del
microcontrollore cliccando sul pulsante

cors
o
F
L
O
W
CO

In alto, sopra larea di progetto troviamo la


barra degli strumenti (illustrata in Fig. 10),
che ci fornisce i comandi base per gestire
il progetto, generare codice, debuggare,
compilare e simulare il nostro progetto.
Tra la barra degli strumenti e larea di
progetto troviamo invece la barra dei
componenti che ci consente di utilizzare,
allinterno dei nostri progetti, componenti
complessi quali USB, Ethernet, controllo
di motori brushless, e molto altro ancora,
semplicemente inserendoli allinterno del
pannello che visibile in basso al centro
della schermata del programma.
La barra delle icone, rappresentata in Fig.
11, contiene tutti i possibili blocchi che
possono essere aggiunti allinterno del
diagramma di flusso. Per inserire un blocco sufficiente trascinarlo allinterno del
diagramma: una freccia gialla ci indicher
il punto esatto in cui lo stiamo inserendo e
licona del mouse viene modificata prendendo la forma delloggetto che vogliamo
inserire allinterno del nostro diagramma
di flusso.
Descriveremo nelle prossime puntate le
altre barre e pannelli che non abbiamo
approfondito in questa sezione.

corso F L O
WCOD

Fig. 14
Impostazioni generali
nuovo progetto.

Configura componente, che ci far accedere a una schermata di configurazione come


quella rappresentata in Fig. 15. Per motivi
di tempo ci limiteremo a settare ogni campo come indicato in figura, senza soffermarci sul perch di ogni scelta, che potr
comunque essere approfondita leggendo
il datasheet specifico del microcontrollore
utilizzato. Dopo aver correttamente compilato ogni campo premiamo il pulsante OK,
per tornare alla schermata di configurazione di progetto e nuovamente premiamo
OK per iniziare a realizzare il diagramma
di flusso.
Per poter utilizzare questa configurazione
negli esempi successivi salviamo il progetto, premendo sul pulsante Salva progetto
nella barra degli strumenti, con il nome
ConfigurazioneBase.fcf.
Aggiunta di blocchi
nel diagramma di flusso
Una volta completata la configurazione
dellhardware, torniamo nellarea progetto per inserire blocchi del diagramma di
flusso. Per inserire un blocco basta trascinarlo dalla barra delle icone allinterno
dellarea di progetto. Una freccia gialla ci
indicher il punto esatto in cui lo stiamo
inserendo. Per rimuovere un blocco basta
selezionarlo e premere il tasto Canc.
Cliccando sul blocco con il tasto destro
possibile eseguire altre operazioni quali
tagliarlo, copiarlo, esaminarne le propriet
e altro ancora che vedremo nelle puntate
successive.
Proviamo ora a esaminare le propriet di

un blocco. Come prima operazione inseriamo il blocco di gestione delle uscite del
microcontrollore, trascinando allinterno
dellarea di progetto licona uscita, (presente nella barra delle icone) tra i blocchi
di INIZIO e FINE, gi presenti di default
allinterno del diagramma. Cliccando
con il tasto destro sul blocco che abbiamo
inserito appare la finestra a scomparsa di
Windows. Scegliamo lopzione Propriet
ed esaminiamo la finestra che si aperta,
riportata per comodit nella Fig. 16.
Possiamo ora impostare tutte le propriet disponibili per il blocco che abbiamo
selezionato. Il blocco utilizzato per
controllare lo stato delle uscite del nostro
microcontrollore. Nella lista a scorrimento Port possiamo selezionare la porta
della quale vogliamo modificare il valore

Elettronica In ~ Giugno 2013

133

Fig. 15
Configurazione
specifica del
microcontrollore.

Fig. 16
Propriet
blocco uscita.

Fig. 17
Propriet
blocco
ritardo.

di uscita, mentre nella casella Variabile


o Valore indichiamo il valore alla quale
vogliamo impostare la porta selezionata.
Solitamente non vogliamo impostare il
valore dellintera porta di uscita, ma solo
di uno o alcuni bit. Per far ci ci viene in
aiuto il pannello Uscita a. Se selezioniamo Singolo bit possiamo scegliere quale
bit impostare lasciando invariato il valore
degli altri pin della porta. Selezionando
Intero Port e selezionando la casella Usa
Maschera possibile selezionare quali bit
devono essere impostati. In questo modo
possibile lasciare invariati i valori dei pin
della porta il cui bit non contrassegnato
nella maschera. La casella di testo Etichetta permette di modificare il testo che
verr indicato sopra il blocco allinterno
del diagramma. molto importante indicare
per ogni blocco unetichetta significativa perch, anche se per progetti molto semplici pu
sembrarci inutile, qualora volessimo realizzare diagrammi complessi, potrebbe esserci
molto di aiuto avere a disposizione etichette
che, con poche parole, ci indichino che cosa
implementa quel particolare blocco. Sono
in pratica lequivalente dei commenti scritti

Le strutture di controllo flusso


Passiamo ora ad analizzare alcune delle

cors
o
F
L
O
W
CO

Fig. 18
Struttura
decisionale
binaria e
panello di
configurazione
del confronto.

durante la stesura di un codice realizzato in


un qualsiasi linguaggio di programmazione.
Inseriamo adesso un ritardo software
allinterno del nostro schema a blocchi. Per
eseguire questa operazione selezioniamo
licona del blocco di ritardo, presente sempre nella barra delle icone, e trasciniamola
allinterno del diagramma, posizionandola
proprio sotto il blocco precedentemente
inserito. A questo punto accediamo alle
propriet del blocco, cliccando con il tasto
destro del mouse, come abbiamo fatto
precedentemente. Come possibile vedere
in Fig. 17, il blocco permette di inserire
un ritardo nellesecuzione del flusso del
programma. Possiamo scegliere lentit del
ritardo da inserire indicandone il valore e
lunit di misura. Il valore che possiamo
inserire deve essere di tipo intero, cio
senza virgola, ma possiamo comunque
inserire ritardi minori del secondo passando allunit di misura con risoluzione
maggiore. Ad esempio per aggiungere
un ritardo del valore di 0.5s baster che
inseriamo allinterno della casella valore
ritardo, il numero 500, mentre come unit
indichiamo millisecondi. Ricordiamoci
che 1 millisecondo equivale a 1000 microsecondi e che 1 secondo equivale a 1000
millisecondi.

DE

134

Giugno 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 19
Struttura
di selezione
multipla.

altre icone presenti nella barra delle icone.


In Flowcode possono essere utilizzate tutte
le normali strutture di controllo presenti
normalmente nei linguaggi di programmazione come, a titolo di esempio, il C.
Decisione binaria
Mediante licona decisione possibile
implementare la funzionalit di decisione binaria. Il blocco fa s che il flusso di
programma passi per il primo o il secondo ramo, in base al valore del confronto
effettuato allinterno del blocco. In pratica,
se la condizione verificata, il programma
continuer lesecuzione dei blocchi presenti nel ramo identificato dalletichetta si,
altrimenti eseguir laltro ramo. Per coloro
che conoscono il linguaggio C il blocco
lequivalente dellistruzione if.
Selezione multipla
Utilizzando licona selezione possibile
implementare la funzionalit di selezione
multipla. Il flusso di programma deviato
attraverso il ramo per il quale lequazione
di confronto soddisfa il valore indicato
allinterno del caso specifico. Qualora
nessuno dei casi indicati soddisfi lequazione di selezione, il programma eseguir
le istruzioni presenti nel ramo di default.
Possono essere realizzate selezioni con
massimo 10 differenti casi, ma questo
numero pi che sufficiente per realizzare
la maggior parte dei possibili programmi.
In pratica se uno dei rami indicati ha come
etichetta il valore che soddisfa lequazione
viene eseguito, altrimenti viene scartato.
Solo uno dei rami pu essere eseguito ed
ognuno deve avere un valore di selezione
differente dallaltro.
lequivalente del costrutto switch
case di un programma implementato in
linguaggio C. Un esempio duso della
struttura di selezione multipla riportato
in Fig. 19.
Icona ciclo
Licona Ciclo permette di realizzare tre differenti controlli di flusso:
- Finch
- Esegui...finch
- Ripeti

Il blocco implementa di default la struttura


Finch, ma per realizzare gli altri due
costrutti basta modificarne le propriet
come visto per gli altri blocchi nelle sezioni
precedenti. Analizziamo le tre opzioni
offerte:
Ciclo Finch
Fintanto che lequazione di confronto
risulta vera vengono eseguite le istruzioni
allinterno del ciclo. Il confronto effettuato al primo ingresso nel blocco di ciclo ed
ogni volta che vengono terminate tutte le
istruzioni interne al ciclo. Quando il confronto risulta falso le istruzioni interne non
sono pi eseguite e il programma continua
attuando le istruzioni successive al ciclo.
Nel caso in cui lequazione di confronto
risulti falsa al primo controllo, il codice
interno al ciclo non viene eseguito neppure
una volta e il programma continua la sua
esecuzione ignorando le istruzioni contenute allinterno dei due blocchi di ciclo. Un
esempio di ciclo di questo tipo riportato
in Fig. 20.
Ciclo EseguiFinch
Impostando la propriet del blocco Testa il ciclo a: al valore Termine, come in

Elettronica In ~ Giugno 2013

135

Fig. 20
Ciclo
while
(Finch
vero).

Fig. 21 - Ciclo Esegui ...Finch. Il confronto effettuato al termine del blocco.

Fig. 21, lo rendiamo equivalente al blocco


realizzato in C con le istruzioni Do While.
In questo caso listruzione di confronto
eseguita al termine di ogni attuazione delle
istruzioni contenute allinterno del ciclo.
Il codice interno quindi eseguito almeno
una volta.
Ciclo Ripeti
Selezionando la propriet del blocco a
Numero cicli:, come stato fatto in Fig.
22, il ciclo viene impostato per funzionare
come un for. Configurato in questo modo
le istruzioni interne vengono eseguite un
numero di volte pari al numero indicato

nella cella a fianco dellimpostazione Numero cicli:. Il blocco fondamentale quando abbiamo bisogno che una porzione del
nostro diagramma di flusso venga eseguita
per un numero predefinito di volte.
Esempio pratico:
facciamo lampeggiare un LED
Ora che conosciamo i blocchi principali e le
possibili variazioni per il controllo di flusso, possiamo implementare un semplice
diagramma per far lampeggiare un LED.
Per realizzare questo esempio abbiamo
bisogno dei seguenti componenti:
- EB006 USB PICmicro multiprogram-

cors
o
F
L
O
W
CO

Fig. 23
Scheda EB006
a sinistra e
scheda
E-Blocks
EB004 a
destra.

Fig. 22 - Ciclo Ripeti.

DE

136

Giugno 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 24
Metodo per la rimozione del
microcontrollore PIC.

con uno a 12MHz e spostiamo il jumper di


selezione della sorgente di clock su OSC
e linterruttore di selezione oscillazione su
XTAL. Un riassunto grafico dellimpostazione dei vari jumper riportato in Fig. 25.
Colleghiamo ora la scheda EB006 con la EBlocks EB004 utilizzando la PORT A, come
illustrato in Fig. 26.

mer board
- EB004 LED Board
- PIC18F4550
- Quarzo 12MHz
La scheda EB006 contiene il
microcontrollore e lhardware necessari
per interfacciarsi con le altre schede EBlocks e il PC dal quale lo programmiamo;
deve essere configurata per poter essere
utilizzata nel nostro esempio. I jumper di
selezione dellalimentazione devono essere
posizionati sul lato di sinistra, in modo
da far s che lalimentazione provenga
dallUSB. Il jumper di programmazione
deve anchesso essere settato su USB, in
modo da poterlo programmare direttamente da PC, senza lausilio del programmatore ICSP della Microchip. Sostituiamo
ora il microcontrollore che attualmente
montato sulla scheda con il PIC18F4550.
Questa operazione molto delicata, quindi dobbiamo prestare molta attenzione nel
rimuovere il microcontrollore senza danneggiare la scheda di sviluppo. Per evitare
danni aiutiamoci con il tappo di una biro
ed eseguiamo loperazione come indicato
nella sequenza di Fig. 24.
Facendo attenzione alla direzione dellalloggiamento a 40 pin, inseriamo il PIC18F4550, assicurandoci che tutti i piedini
entrino senza piegarsi, allinterno dello
zoccolo. Per piegare correttamente i piedini del PDIP40, possiamo aiutarci con il
piano della nostra scrivania, appoggiando
il PDIP di traverso e facendo leva sul case,
finch i piedini risultano paralleli al bordo.
A questo punto sostituiamo il quarzo

Lhardware ora pronto e possiamo dedicarci allimplementazione del programma.


Apriamo Flowcode e carichiamo la configurazione di base che avevamo salvato
durante la configurazione del nostro primo
progetto. Premiamo sul pulsante Apri
progetto nella barra degli strumenti e
selezioniamo il file ConfigurazioneBase.fcf.
Per evitare di sporcare il file, dato che
Flowcode durante alcune operazioni salva
automaticamente il progetto, salviamo
immediatamente il progetto con un nuovo
nome. Dal menu scegliamo File/Salva con
nome... e indichiamo come nuovo nome
LampeggioLed.fcf. Proviamo ora a pensare

Fig. 25
Configurazione
selettori e jumper
scheda EB006.

Jumper selezione
alimentazione
Jumper selezione
Programmatore

Jumper selezione
funzione pin oscillatore
Selettore
oscillatore

Elettronica In ~ Giugno 2013

137

Fig. 26
Configurazione
completa per la
realizzazione
dellesempio.

138

Giugno 2013 ~ Elettronica In

DE

Fig. 27
Diagramma di flusso per il
lampeggio del led collegato
alla porta A pin 0.

cors
o
F
L
O
W
CO

alle operazioni che devono


essere eseguite per fare in
modo che si veda lampeggiare un LED sulla scheda.
Innanzitutto dobbiamo
realizzare un ciclo infinito
che il programma dovr
eseguire per tutto il tempo di attivit e per questo
scegliamo il blocco Finch.
Impostiamo in modo che il
ciclo venga sempre eseguito
come descritto nella sezione precedente. Abbiamo
poi bisogno di qualcosa
che ci permetta di modificare il valore di un pin
del microcontrollore ed il
blocco che fa al caso nostro
licona uscita. Inseriamo
due blocchi allinterno del
ciclo e impostiamoli in
modo che il primo setti il bit
0 al valore 1 e il secondo il
bit 0 al valore 0. Se eseguissimo il flusso cos com
attualmente implementato,

vedremmo a causa dei fenomeni fisici interni al nostro occhio il LED sempre
acceso, ma con unintensit
minore rispetto a quella massima. Per evitare
questo problema inseriamo
un blocco di ritardo dopo
il set a uno della porta e
un altro identico - dopo
il blocco di set a zero della
porta. Impostiamo il valore
del ritardo a 1 secondo per
entrambi i blocchi inseriti.
Se avete eseguito tutto
correttamente dovreste
ottenere un diagramma
di flusso simile a quello
riportato in Fig. 27.
Il nostro flusso ora pronto per essere caricato sulla
scheda. Salviamo il progetto premendo il pulsante
salva progetto nella barra
degli strumenti perch lo
riutilizzeremo in seguito
come base di partenza
per altri esempi. Premiamo il pulsante compila e
trasferisci per caricare il
programma allinterno del
microcontrollore presente sulla nostra scheda di
sviluppo. Attendiamo che
il programma esegua le
operazioni e al termine
del caricamento potremo
notare che il nostro primo
programma viene eseguito
sulla scheda con il LED che
si accende e si spegne ogni
g
secondo.

corso F L O
WCOD

Continuiamo il
nostro viaggio alla
scoperta di Flowcode,
linnovativo sistema
di sviluppo grafico
per microcontrollori
proposto da Matrix
Multimedia. Flowcode
permette di sviluppare
con facilit il software
per applicazioni
embedded in quanto
il codice viene scritto
facendo uso di oggetti
grafici, in luogo dei
classici linguaggi di
programmazione come
il C e lAssembler.
Seconda puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

ella scorsa puntata del corso abbiamo iniziato a prendere confidenza


con lambiente di sviluppo grafico
FlowCode, sviluppato da Matrix Multimedia. stato presentato lambiente grafico,
descritta dettagliatamente linterfaccia,
presentate le strutture di controllo ed
stato illustrato un primo esempio di programmazione. In questa puntata spiegheremo luso delle variabili, delle costanti e
descriveremo i blocchi ingresso e calcolo.
Successivamente verranno descritte due
funzionalit molto potenti di flowcode: le
macro e i componenti. Con le conoscenze
acquisite realizzeremo il secondo progetto
pratico: la gestione del modulo E-block

LED tramite il modulo KeyPad, usandone i


rispettivi componenti software.
Le variabili in Flowcode
Nella puntata precedente abbiamo utilizzato unicamente periferiche di uscita e non
abbiamo mai fatto uso di variabili, che sono
invece una parte molto importante della
programmazione in quanto ci permettono
di memorizzare dati ed effettuare calcoli.
Attraverso il menu principale di Flowcode
Visualizza->Esplora progetto, apriamo il
pannello aggiuntivo nel quale possiamo
esaminare tutte le costanti e le variabili
globali disponibili allinterno del nostro
progetto, come illustrato in Fig. 1.

Elettronica In ~ Luglio / Agosto 2013

113

Fig. 1
Progetto
Flowcode
con pannello
esplora
progetto
visibile sulla
destra della
schermata.

114

Fig. 3 - Finestra di creazione/


configurazione variabile.

Fig. 4 - Finestra di creazione/


configurazione costante.

Luglio / Agosto 2013 ~ Elettronica In

Rimozione di
variabili/costanti
Qualora volessimo cancellare
una variabile o una costante
sufficiente selezionare con il
mouse lelemento desiderato
dal pannello esplora progetto,
allinterno della sezione Globali, e premere il pulsante
Canc. Al termine del progetto potrebbe risultare molto
utile rimuovere tutte quelle
variabili/costanti che risultano incluse nella lista, ma
non sono utilizzate allinterno
del nostro progetto. Per far
ci basta cliccare con il tasto
destro su Variabili o Costanti allinterno del pannello
Esplora progetto e scegliere

DE

Aggiungere costanti
Alla creazione di un nuovo
progetto sono gi presenti
due costanti pre-configurate:
false e true, rispettivamente ai valori 0 e 1. Per ag-

Fig. 2 - Aggiunta variabile.

giungere una nuova costante


posizioniamo il mouse
sulletichetta costanti,
clicchiamo con il tasto destro
e scegliamo dal menu a tendina Aggiungi nuovo. Nella
finestra di configurazione,
mostrata in Fig. 4, inseriamo
il nome della costante, il suo
valore e una breve descrizione. Le costanti non necessitano dellindicazione di
tipo perch vengono trattate
come delle #define.

cors
o
F
L
O
W
CO

Aggiungere variabili
Per aggiungere una nuova
variabile dobbiamo posizionare il mouse sulletichetta
variabili e cliccare con
il tasto destro in modo da
poter scegliere dal menu a
tendina la casella aggiungi
nuovo, come mostrato in
Fig. 2.
Premendo sul pulsante Aggiungi nuovo viene aperta
la finestra di creazione di
una nuova variabile, come
evidenziato in Fig. 3.
I tipi di dati finora supportati spaziano da logici a
numerici, con o senza segno,
numeri a virgola mobile e
stringhe. Per configurare la
variabile dobbiamo inserire
il nome, il valore iniziale,
una breve descrizione e il
tipo. Premendo il pulsante
OK la variabile viene creata e aggiunta alla lista nella
finestra di esplorazione del
progetto.

corso F L O
WCOD

Fig. 5
Blocco di
ingresso e
finestra di
configurazione

dal menu a tendina lopzione


Cancella inutilizzati.

selezione che pu aiutarci


a scegliere quale variabile
utilizzare, come mostrato in
Blocco ingresso e calcolo
Fig. 6. Possiamo scegliere tra
La scorsa puntata avevamo
le variabili locali o tra quelle
esaminato il blocco di output
globali e, qualora non fossero
e quello di ritardo. Siamo
ancora state create, possiamo
quindi capaci di imporre
crearle direttamente dalla
il valore di una porta/pin
finestra come abbiamo fatto
di uscita e di attendere un
in precedenza dal pannello
tempo prefissato tra due
esplora progetto. Facendo
Fig. 6 - Finestra di selezione
operazioni. Impariamo ora a
doppio clic su una variabile
variabile.
utilizzare il blocco di ingresso
presente nella lista, possiamo
e di calcolo.
inserirla direttamente nella
casella di testo di configuraBlocco ingresso
zione del pannello.
Il blocco ingresso il blocco
Esattamente come per il
duale del blocco uscita che
pannello di configurazione
abbiamo utilizzato nella
delle uscite, sono disponibili
puntata precedente per
le opzioni Singolo Bit e la
controllare i pin di uscita del
mascheratura. Nellesempio
Fig. 7 - Esempio di
microcontrollore. Per inserire
in Fig. 7 la variabile assumemascheratura porta di ingresso.
il blocco, trasciniamo dalla
r il valore di PORTA, ma
Barra delle icone licona corriunicamente per il 2 e 4 bit
spondente nel diagramma di flusso. Come
perch solo il pin 1 e 3 hanno la spunta.
per gli altri blocchi, eseguendo un doppio
Facciamo un esempio. Supponiamo che
clic sullicona, possibile aprire la finestra
PORTA abbia un valore pari a 9, che in
di configurazione, mostrata in Fig. 5.
binario equivale a 0b00001001. Nella vaSelezionando dalla lista a scorrimento
riabile VariabileIngresso avremo il valore
Port:, impostiamo la porta dalla quale vo- 8 mascherato con 0b00001010 che ha come
gliamo effettuare la lettura e, nella casella
risultato 0b00001001 AND 0b00001010 =
di testo Variabile:, inseriamo il nome della 0b00001000, cio 8.
variabile nella quale vogliamo caricare il
valore letto. Premendo sulla freccia a destra Blocco calcolo
della casella di testo apriamo la finestra di
Altro blocco di fondamentale importanza

Elettronica In ~ Luglio / Agosto 2013

115

Fig. 8
Finestra
propriet del
blocco calcolo.

quello che ci permette di svolgere i calcoli


allinterno del nostro diagramma di flusso.
Per inserirlo basta scegliere licona calcolo
dalla Barra delle icone e trascinarlo allinterno dellarea di progetto. Facendo doppio
clic sul blocco entriamo nella finestra di
configurazione, come mostrato in Fig. 8.
Tabella 1 - Operatori logico/matematici.
(,)

Parentesi

= , <>

Uguale a, diverso da

+ , - , * , / , MOD

Addizione, sottrazione, moltiplicazione, divisione e


modulo

<, <= , > , >=

Minore di, minore o uguale a, maggiore di, maggiore o


uguale a

>>, <<

Spostamento a destra, spostamento a sinistra.

~,&,|,^

NOT, AND, OR, OR Esclusivo, bit per bit

NOT, AND , OR , XOR

NOT, AND, OR, OR Esclusivo ,bit per bit

&& , || , !

AND, OR, NOT, logici

Tabella 2 - Funzioni utilizzabili in Flowcode.


Somma due numeri in notazione
a virgola mobile

float = fsub(float, float)

Differenza tra due numeri in notazione


a virgola mobile

float = fmul(float, float)

Moltiplica due numeri in notazione


a virgola mobile

float = fdiv(float, float)

Divide due numeri in notazione a virgola mobile

float = fmod(float, float)

Esegue il MODULO di due numeri


in notazione a virgola mobile

byte = isinf(float)

Verifica se il numero in virgola mobile infinito

byte = isnan(float)

Verifica se il numero in virgola mobile


un numero

byte = float_eq(float, float)

Verifica luguaglianza di due numeri


in virgola mobile

byte = float_ge(float, float)

Controlla se un numero in virgola mobile


maggiore o uguale allaltro

byte = float_gt(float, float)

Controlla se un numero in virgola mobile


maggiore dellaltro

byte = float_le(float, float)

Controlla se un numero in virgola mobile


minore o uguale allaltro

byte = float_lt(float, float)

Controlla se un numero in virgola mobile


minore dellaltro

int = random()

Genera un numero casuale tra


-32768 e 32767

Fig. 9
Esempio di
calcolo per
conversione di
unit di misura
da pollici in
centimetri.

convertire in centimetri allinterno della


variabile LunghezzaCm. Il frammento di
codice necessario per svolgere questa semplice operazione indicato in Fig. 9.
Le macro e i componenti software
Gli esempi che abbiamo visto fino ad ora
utilizzavano un numero limitato di blocchi per implementare la funzionalit, ma
normalmente non possibile implementare
un intero flusso su un unico diagramma.
Il blocco macro ci di ausilio in questo
compito. In pratica ci permette di creare
delle sottoparti di diagramma su aree di
lavoro differenti e di poterle richiamare
agevolmente.
Creare una macro
Per creare una macro entriamo nel menu
Macro e premiamo su Nuova... La finestra di configurazione ci permette di gestire
e configurare tutte le caratteristiche salienti
della macro. Allinterno della casella Nome
della nuova macro inseriamo il nome con
il quale richiameremo la macro allinterno

cors
o
F
L
O
W
CO

float = fadd(float, float)

Nella casella di testo Calcoli possono


essere inserite le righe nelle quali specifichiamo i calcoli da effettuare, mentre nella
parte di destra presente un pannello di
selezione dal quale possiamo attingere i
valori delle variabili, delle costanti e delle
funzioni che Flowcode ci mette a disposizione. Gli operatori logico/matematici che
possiamo utilizzare sono rappresentati in
Tabella 1.
Le funzioni valide sono invece riportate in
Tabella 2.
Per capirne meglio il funzionamento facciamo un semplice esempio. Supponiamo di avere la variabile LunghezzaInch
che contiene il valore di una lunghezza
rappresentato in pollici e di volerla

DE

116

Luglio / Agosto 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 10
Barra dei componenti.

del nostro diagramma di flusso e, anche se


non obbligatorio, vivamente consigliato
inserire dei commenti allinterno della casella descrizione nuova macro per facilitare
in futuro la comprensione della funzionalit che svilupperemo allinterno.
Una macro pu comunicare con il diagramma che la istanzia facendo uso di
parametri, di valori di ritorno e di variabili
globali, esattamente come avviene per
una classica funzione in linguaggio C. I
parametri sono utilizzati quando necessario passare dei valori dal diagramma
chiamante alla macro. Il valore di ritorno
utilizzato quando si vuole restituire al
diagramma chiamante un valore mentre le
variabili globali possono essere utilizzate
in tutti gli altri casi. Quando una macro
utilizza delle variabili globali sarebbe buona norma indicare, nella descrizione della
macro, tipo e nome delle variabili globali
in modo che, qualora si dovesse riutilizzare la macro in altri diagrammi, si possano
ricreare tutte le variabili in modo corretto. Una volta creata, la macro pu essere
istanziata nel diagramma di flusso usando
licona macro e valorizzando opportunamente gli eventuali parametri. Durante
la spiegazione del progetto pratico di
questa puntata, vedremo un esempio che
ci aiuter a comprendere come configurare
e utilizzare una macro allinterno di un
progetto Flowcode.

componenti sono stati realizzati da Matrix


Multimedia per esserci di aiuto nello sviluppo di progetti complessi. La libreria dei
componenti suddivisa in base alla tipologia. Possiamo trovare i seguenti principali
raggruppamenti: Comuni, Ingressi, Uscite,
Trasmissioni Dati, Wireless, Periferiche,
Elettromeccanici, Moduli Miac e Varie.
Per il momento i gruppi e i componenti
disponibili sono quelli che vi mostreremo
durante il corso, ma nelle versioni successive questa libreria sar sicuramente pi
ampia e ricca di nuove funzionalit.
La barra dei componenti
La libreria dei componenti di Flowcode
accessibile mediante la barra dei componenti mostrata in Fig. 10. I blocchi disponibili
sono organizzati per area tematica in modo
da facilitarci nella ricerca. I componenti
possono essere utilizzati per aiutarci nella
realizzazione di sistemi, anche molto complessi, permettendoci di trascurare limplementazione effettiva del driver del componente, lasciandoci cos concentrare sulla

Esportare e importare una macro


Mediante il menu macro nella barra principale di Flowcode possibile esportare
una macro in modo da renderla disponibile per altri progetti. La macro scelta verr
quindi salvata in formato *.fcm e potr
essere importata utilizzando lo stesso
menu. Questa potenzialit di Flowcode ci
permette in pratica di creare una libreria
di macro che possiamo incrementare ogni
qualvolta creiamo una funzione che pensiamo possa essere utile e riutilizzabile in
altri progetti.
I componenti
La possibilit di creare delle macro molto
importante, mentre fondamentale la
possibilit di utilizzare i componenti. I

Fig. 11
Principali
componenti
disponibili in
Flowcode.

Elettronica In ~ Luglio / Agosto 2013

117

Fig. 12
Inserire il
componente
LED
utilizzando
la Barra dei
componenti.

funzionalit che vogliamo implementare.


Per essere correttamente utilizzato, un
componente - dopo essere stato inserito
- deve essere configurato utilizzando la
propria interfaccia specifica. Nelle sezioni
successive ne vedremo alcuni esempi.
Aggiungere un componente software
Per aggiungere un componente software
basta cliccare sulla barra di libreria (nel
nostro caso inseriamo un LED, come rappresentato in Fig. 13) e vedremo apparire

nel pannello, in basso, il componente che


abbiamo scelto.
Ora il componente attivo allinterno
del nostro progetto ma, per funzionare
correttamente, deve avere le connessioni
configurate opportunamente. Clicchiamo
sul componente con il tasto destro del
mouse, come in Fig. 13. A questo punto
si apre un menu a tendina: premiamo su
Connessioni in modo che si apra la finestra di settaggio come mostrato in Fig. 14.
Configuriamo le connessioni per collegare

Fig. 13
Menu
connessioni
relativo al
componente.

cors
o
F
L
O
W
CO
DE

118

Luglio / Agosto 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 15
Macro
disponibili
per il
componente
LED.

Fig. 14
Esempio
di connessione per il
componente
LED.

il componente LED al pin 0 di PORTA.


Ora il componente software configurato
ed possibile inserirlo, dove necessario,
allinterno del nostro flusso di programma.
Per far ci basta inserire licona macro componente, selezionandola dalla Barra delle
icone e trascinarla in posizione corretta
allinterno del nostro diagramma. Pi blocchi possono utilizzare lo stesso componente in modo da svolgere una o pi attivit
allinterno del diagramma di flusso.
Per poter funzionare correttamente, il blocco deve essere configurato. Per far ci basta
che con doppio clic entriamo nella finestra
Propriet: Componente macro e selezioniamo nella parte di sinistra il componente
al quale deve far riferimento il blocco, nel
nostro caso LED(0). Vedremo cos apparire
nella parte di destra le macro che possono
essere chiamate, come mostrato in Fig.
15. In questo caso, avendo scelto il LED,
abbiamo a disposizione due macro: quella per accendere il led LEDOn e quella
per spegnerlo LEDOff. Selezioniamo la
funzionalit voluta e premiamo il pulsante
OK per terminare la configurazione.
Tutti i componenti hanno inoltre delle
propriet extra, accessibili mediante tasto
destro sul componente, selezionando la
voce Propriet extra. Per ogni componente verr aperta una finestra specifica con
differenti caratteristiche configurabili. Nel
pannello relativo al componente LED
possibile impostarne la forma, il colore e la
polarit, come mostrato in Fig. 17.
Progetto Pratico:
gestione di 3 LED tramite Keypad
Passiamo adesso alla realizzazione di un
progetto che ci consenta di mettere in
pratica alcuni dei concetti esposti in questa
puntata e che ci aiuti a prendere maggior

confidenza con i primi componenti di


Flowcode. Quello che ci proponiamo di
realizzare un sistema di controllo che
gestisca i dati in ingresso da un KeyPad a
12 tasti (il classico KeyPad telefonico) e che
utilizzi le informazioni lette per gestire un
gruppo di tre LED. Le specifiche del nostro
sistema sono le seguenti:
alla pressione del tasto 1 del KeyPad accendere il LED1 e spegnere gli altri LED;
alla pressione del tasto 2 del KeyPad accendere il LED2 e spegnere gli altri LED;
alla pressione del tasto 3 del KeyPad accendere il LED3 e spegnere gli altri LED;
alla pressione del tasto cancelletto del
Keypad spegnere tutti i LED.
Abbiamo utilizzato i LED per semplicit didattica ma avremmo potuto, con
lo stesso sistema, pilotare dei rel, delle
elettrovalvole o altri carichi esterni.

Fig. 16 - Propriet extra relative


al componente LED.

Elettronica In ~ Luglio / Agosto 2013

119

Fig. 17 - Collegamento E-Blocks


per la realizzazione del progetto pratico.

Per realizzare questo progetto abbiamo


bisogno dei seguenti componenti:
- EB006 USB PICmicromultiprogrammerboard (PIC18F4550 e Quarzo 12MHz)
- EB004 LED Board
- EB014 Keypadboard
Colleghiamo ora le schede in modo da
avere i LED su PORTA ed il tastierino sulla
PORTB, come mostrato in Fig. 17.
Apriamo ora il progetto vuoto che avevamo creato con il nome ConfigurazioneBase.
fcf e salviamolo con il nome
SwitchLed.fcf. In questo modo il
microcontrollore risulta gi configurato
per funzionare con lhardware a nostra
disposizione: possiamo cos dedicarci alla
realizzazione del diagramma di controllo
del sistema.

Fig. 19
Finestra
connessioni
del componente
LED.

cors
o
F
L
O
W
CO

Fig. 18
Finestra
connessioni del
componente
keypad.

In questo nuovo progetto faremo uso dei


primi componenti, quindi, dalla barra dei
componenti inseriamo nel nostro progetto
un componente Keypad e tre componenti
LED, che sono le periferiche che dovremo gestire. Come spiegato in precedenza,
per inserire un componente bisogna selezionarlo dalla barra dei componenti. Dopo
averlo selezionato, il componente comparir nel pannello sotto larea di progetto. A
questo punto configuriamo le connessioni
dei componenti, cominciando dal KeyPad.
Eseguiamo un clic con il tasto destro sul
componente keypad comparso sul pannello e selezioniamo lopzione connessioni.
Comparir la schermata di Fig. 18.
Come evidenziato in figura, colleghiamo
le tre colonne e le quattro righe alla porta
B (le tre colonne ai pin 0, 1 e 2 e le quattro

DE

120

Luglio / Agosto 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 20
Finestra di propriet
del componente.
Fig. 21
Creazione della
variabile di
LetturaKeypad.

righe ai pin 4, 5, 6 e 7). Una volta eseguite


le connessioni confermiamo premendo su
Fatto. Allo stesso modo configuriamo
i tre LED, collegandoli rispettivamente ai
pin 0, 1 e 2 della porta A.
In Fig. 19 possibile vedere la configurazione del primo LED. A questo punto
possiamo iniziare la stesura del blockdiagram, inserendo il classico ciclo principale, allinterno del quale creeremo la
nostra applicazione. Una volta realizzato
il ciclo, inseriamo anche un blocco Macro
Componente ed una struttura Selezione,

dotandola di quattro casi. A questo punto


eseguiamo un doppio clic sul blocco Macro
Componente, ed esaminiamo la finestra che
si apre, riportata per comodit in Fig. 21.
Selezioniamo il componente Keypad e la
macro GetKeypadNumber che ci consentir
di rilevare il tasto premuto. A questo punto
ci serve una variabile per immagazzinare il
valore, che poi utilizzeremo nella successiva
struttura di selezione.
Creiamo una variabile sfruttando il pulsante con il simbolo della freccia in basso
presente sulla finestra attiva, e chiamiamola
LetturaKeypad (come tipo scegliamo un
unsigned byte). Se avete eseguito tutto correttamente dovreste avere un risultato simile a

Fig. 22
Schema a blocchi parziale
del progetto.

Elettronica In ~ Luglio / Agosto 2013

121

Fig. 23
Macro LED0.

quello riportato in Fig. 21.


la descrizione, come riportato
Passiamo ora alla gestione della
in Fig. 23.
struttura di selezione. AssociaNella macro inseriamo tre
mo alla selezione la variabile
blocchi Macro componente con
precedentemente creata e valoi quali gestiremo i componenti
rizziamo i primi tre casi con i vaLED precedentemente creati.
lori numerici 1, 2 e 3 ed il quarto
Chiamiamo la funzione LEDOn
con il valore 11 (cancelletto). A
per il LED0 e la funzione LEquesto punto il diagramma di
DOff per i LED 1 e 2. Se abbiaflusso dovrebbe apparire come
mo eseguito tutto correttamente
quello riportato in Fig. 22.
otterremo uno schema come
Abbiamo quasi finito: non ci
quello riportato in Fig. 25.
Fig. 25
resta che gestire correttamente
Creiamo altre due macro analoSchema a blocchi della
il pilotaggio delle uscite nei vari
ghe per laccensione dei LED 1
macro LED0.
casi. Per evitare di rendere il
e 2 ed una macro di spegnimenblockdiagram troppo complesto che chiameremo LEDOff.
so, utilizziamo delle macro specifiche per
Ora posizioniamo quattro blocchi Chiamata
il pilotaggio delle uscite. Cominciamo dal
Macro nei quattro rami della struttura di
caso corrispondente al tasto 1 che, secondo
selezione e chiamiamo opportunamente
le nostre specifiche, dovrebbe accendere il
le macro appena create. Il nostro progetto
LED0 e spegnere gli altri. Creiamo una nuo concluso; il blockdiagram complessivo
va macro, che chiameremo appunto LED0,
riportato in Fig. 26, a questo punto non ci
come abbiamo visto in precedenza nel
resta che collegare opportunamente gli
g
paragrafo dedicato alle macro ed inseriamo
E-block e testare quanto realizzato.

cors
o
F
L
O
W
CO

Fig. 26
Schema a blocchi
complessivo.

Fig. 24
Propriet
del
componente
LED.

DE

122

Luglio / Agosto 2013 ~ Elettronica In

corso F L O
WCOD

Continuiamo il
nostro viaggio alla
scoperta di Flowcode,
linnovativo sistema
di sviluppo grafico
per microcontrollori
proposto da Matrix
Multimedia. In questa
puntata ci occupiamo
dellimplementazione
degli interrupt in
Flowcode e iniziamo ad
analizzare i componenti.
Terza puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

elle precedenti puntate abbiamo


analizzato in dettaglio lambiente di
sviluppo, descrivendone la struttura
ed analizzando gli elementi di base come
le strutture di controllo e le strutture dati.
In questa puntata completeremo lanalisi
delle strutture di controllo, descrivendo la
gestione degli interrupt, e continueremo
lanalisi dei componenti (che sono uno dei
principali valori aggiunti di Flowcode)
descrivendo il componente ADC ed il componente LCD. Successivamente passeremo
alla descrizione della gestione delle memorie non volatili, analizzando il componente
EEPROM. Sfruttando le nuove conoscenze
acquisite realizzeremo un progetto prati-

co pi evoluto rispetto ai precedenti: un


termometro con display LCD.
Per i progetti di questa puntata cambieremo
microcontrollore, passando dal PIC18F4550
al PIC18F4580. Vedremo cos quanto sia
semplice, gestendo i progetti con Flowcode,
cambiare target senza risentire di problematiche di configurazione e faremo qualche
esperimento con un PIC diverso.
Per agevolare i lettori nella sperimentazione abbiamo generato un file di configurazione base anche per il PIC18F4580, cos
come avevamo fatto in precedenza.
Gli interrupt
Come tutti gli ambienti di sviluppo per

Elettronica In ~ Settembre 2013

129

Fig. 1
Propriet
del blocco
interrupt.

Settembre 2013 ~ Elettronica In

DE

130

cors
o
F
L
O
W
CO

microcontrollori, anche Flowcode prevede


la gestione degli interrupt. In un sistema
embedded un interrupt (o interruzione)
un segnale asincrono rispetto allesecuzione del programma principale, proveniente
da una specifica periferica, che segnala
una situazione particolare che richiede
una gestione differente rispetto al resto
del programma. Un interrupt pu provenire da una porta di comunicazione, da
una risorsa interna, da un timer, eccetera.
Normalmente, quando viene generato
un interrupt, la gestione del programma
si arresta, la posizione corrente del program counter ed il contesto di esecuzione
vengono salvati nello stack e il programma salta a una locazione specifica, che
funzione dellinterrupt stesso e dellarchitettura specifica del microcontrollore.
A questo punto, a seconda dei casi, viene
eseguita una funzione speciale (in genere denominata ISR, Interrupt Service
Routine) che serve linterrupt e che,
una volta terminata, ritorna il controllo al
programma principale, che ricomincia dal
punto in cui era stato interrotto (recuperando tutte le informazioni necessarie
dallo stack, allinterno del quale era stata
salvata la posizione corrente ed il contesto).
In Flowcode esiste un blocco speciale,
presente allinterno della barra delle icone
e denominato appunto blocco interrupt,
che serve ad implementare la gestione
degli interrupt allinterno di un programma Flowcode. Se inseriamo questo blocco
allinterno di uno schema Flowcode e
clicchiamo due volte con il tasto sinistro,
potremo accedere alla finestra propriet
del blocco, come riportato in Fig. 1.
Da questa finestra possibile selezionare
la sorgente dellinterrupt che ci interessa,
accedendo al menu a tendina Interrupt
Attivi. Analizzando questo menu, vedremo che per il PIC18F4580, sono disponibili

diversi interrupt sui timer, sugli ingressi


della porta B, sulla ricezione della porta
UART e altro ancora. Una volta selezionata
la sorgente dellinterrupt, bisogner indicare anche la relativa ISR. Flowcode gestisce questo aspetto, fornendo la possibilit
di chiamare unopportuna macro creata in
precedenza. Tutto ci non molto diverso
da quello che accade con altri sistemi di
sviluppo, basati su linguaggi classici come,
ad esempio, il C: in quel caso la ISR generalmente una comune funzione scritta in
linguaggio C, che ha per la particolarit
di essere chiamata quando viene generato
il relativo interrupt.
Il concetto di interrupt abbastanza
delicato in ambito di sviluppo embedded,
in quanto gli interrupt sono largamente
utilizzati nella gestione dellhardware e
sono di fondamentale importanza man
mano che i sistemi sviluppati si fanno pi
complessi. Cerchiamo di fissare questo
concetto con un esempio, riproponendo il
progetto pratico visto nella prima puntata
con una gestione ad interrupt.
Nella prima puntata avevamo fatto lampeggiare un LED alla frequenza di 1 Hz,
sfruttando i ritardi software. Proviamo
adesso a fare la stessa cosa, ma anzich
generare il ritardo con dei cicli software
vuoti, proviamo a generare la temporizzazione con una risorsa hardware interna
al microcontrollore. Per farlo ci serviamo
del Timer 2, che pu generare un interrupt quando il suo valore corrisponde a
quello di un registro di confronto. Procediamo quindi creando un nuovo progetto
Flowcode, partendo dal template ConfigurazioneBase2, fornito insieme al materiale
relativo a questa puntata, e cambiamo il
nome del progetto in Interrupt.fcf. Per
prima cosa creiamo la macro che useremo
come ISR, nominandola LED. Eseguiamo
i passi necessari come abbiamo visto nella
puntata precedente e generiamo anche una
variabile che chiameremo LedStatus (booleana, valore iniziale false) ed unaltra che
chiameremo Counter (byte, valore iniziale
0). A questo punto passiamo sullo schema
a blocchi principale, inseriamo un blocco
interrupt, e a seguire un blocco ciclo. Il
ciclo ci serve solo per evitare che il pro-

corso F L O
WCOD

Fig. 2
Propriet
interrupt
timer 2.

gramma termini e riparta dal principio,


lo possiamo quindi considerare come la
nostra applicazione principale, anche se
non fa nulla. A questo punto configuriamo il blocco interrupt. Nel menu a tendina,
alla voce interrupt attivi selezioniamo
TMR2 e clicchiamo su propriet. Otterremo la finestra di Fig. 2, che ci permette di
configurare linterrupt sul Timer 2.
Funzionando a 12 MHz, anche intervenendo sui vari pre e post-scaler non c modo
di generare un interrupt a 1Hz. Configuriamo quindi linterrupt con i valori riportati
in figura, per ottenere un interrupt a circa
50 Hz. Partendo da questa base tempi ci
baster semplicemente utilizzare un contatore di servizio per generare la frequenza
di 1Hz che ci serve per pilotare opportunamente il nostro LED. Completiamo
la configurazione tornando sulla finestra
precedente e selezionando la macro LED
alla voce verr chiamata la macro. Questo fa s che ad ogni interruzione generata
dal timer 2 venga chiamata la nostra macro.
A questo punto non ci rimane altro da fare
che completare la macro precedentemente
creata. Per vedere come abbiamo fatto ci
serviamo della Fig. 3. Come si pu vedere
dallo schema a blocchi, ad ogni chiamata
della macro viene incrementato il contatore
Counter. Se il valore inferiore al valore
della costante timeout (che abbiamo impostato pari a 50) non succede nulla, altrimenti si passa alla gestione effettiva del LED.
In questo ramo del flowchart si controlla il
valore della variabile LedStatus, invertendolo, di volta in volta, rispetto al suo stato
attuale e pilotando di conseguenza il LED.
A questo punto provate a flashare il
microcontrollore con il flowchart fornito come esempio (notate che il micro

Fig. 3
Flowchart della macro LED.

cambiato e che ora il pin controllato D0)


e vedrete lo stesso effetto ottenuto nel
caso delloscillazione generata con i ritardi
software. Notate che questo esempio non
puramente didattico. Infatti, se volessimo aggiungere funzionalit a questo
programma, ci basterebbe inserire i relativi
blocchi sul ciclo principale che attualmente
vuoto, dimenticandoci della gestione
ad interrupt, che non viene disturbata dallesecuzione del main (in quanto
asincrona rispetto a questultimo), mentre
la stessa cosa non si potrebbe dire per la
versione fatta con i ritardi software.
Il componente ADC
Passiamo ora allanalisi di uno dei componenti che utilizzeremo nel prossimo
progetto pratico: il componente ADC. Questo componente permette di configurare
e gestire in maniera semplice un canale
analogico di ingresso, sfruttando il convertitore integrato nel microcontrollore.
Il componente ADC pu essere inserito
selezionandolo dalla barra dei componenti,
sotto la voce ingressi. Una volta inserito, nel pannello comparir una manopola
del tutto simile a quella che si trova nei
pannelli frontali della strumentazione da
laboratorio. Come abbiamo gi visto nella

Elettronica In ~ Settembre 2013

131

Fig. 4
Finestra
connessioni del
componente
ADC.

ne impostazioni base del componente,


come la tensione di riferimento (Vref) , la
velocit di conversione e altro ancora. Per
quanto riguarda invece le macro che il
componete ADC pu sfruttare, in Tabella
1 sono elencate le principali macro disponibili. Il componente dispone anche di
macro pi specifiche, ma al momento non
le prenderemo in considerazione in quanto
non strettamente necessarie.

Fig. 5
Propriet
extra del
componente
ADC.

Tabella 1 - Principali macro disponibili per il componente ADC.


Nome Macro

Descrizione

LeggiComeByte

Il valore del canale selezionato acquisito e il risultato fornito con formato numerico e 8-bit di risoluzione.

LeggiComeIntero

Il valore del canale selezionato acquisito e il risultato fornito con formato numerico e 10-bit o 12-bit di
risoluzione (a seconda del convertitore).

LeggiComeTensione

Il valore del canale selezionato acquisito e il risultato fornito con formato in tensione (il valore deve
essere immagazzinato in una variabile di tipo float).

LeggiComeStringa

il valore del canale selezionato acquisito e il risultato fornito come stringa di caratteri (il valore deve
essere immagazzinato in un array di caratteri).

cors
o
F
L
O
W
CO

puntata precedente per il componente


LED, anche il componente ADC dotato di
connessioni e di propriet extra. possibile accedere a questi due menu cliccando
con il tasto destro sullicona del componente presente sul pannello. Cliccando sulla
voce connessioni comparir la finestra
di Fig. 4, che permette di impostare il pin
del micrcocontrollore da utilizzare come
ingresso analogico (nellesempio An0).
Per accedere alle propriet extra, basta
selezionare la relativa voce nel menu che
compare sempre cliccando con il tasto
destro sullicona del pannello. La finestra
propriet extra del componente ADC
riportata in Fig. 5.
Com possibile vedere - impostazioni
dellicona a parte - sono disponibili alcu-

Il componente LCD
Passiamo ora allanalisi del componente
LCD, che ci permetter di aggiungere
un output visuale ai nostri progetti. Il
componente LCD permette di gestire un
display a cristalli liquidi con controller
Hitachi HD44780 (noto anche come Hitachi compatibile); questa interfaccia costituisce lo standard de facto per gli LCD alfanumerici monocromatici con interfaccia
parallela. In particolare, il componente
sfrutta la configurazione parallela a 4-bit,
in modo da poter impiegare una singola
porta per il controllo del dispositivo (oltre
ai 4 bit di dato vengono infatti utilizzati 2
segnali di controllo).
Il componente LCD pu essere inserito
dalla barra dei componenti, selezionando, sotto la voce uscite, il componente
LCD. Una volta eseguita questa operazione, allinterno del pannello verr
posizionata limmagine di un display
alfanumerico 16x2. Come per gli altri
componenti visti in precedenza, anche
per il componente LCD sono disponibili
le solite propriet connessioni e propriet extra. Se clicchiamo sulla voce
connessioni, comparir la finestra di Fig.
6, che ci permette di configurare le connessioni del display. Da questa finestra

DE

132

Settembre 2013 ~ Elettronica In

corso F L O
WCOD

possibile impostare le 6 linee necessarie


allinterfacciamento del componente con il
microcontrollore.
Se apriamo invece la finestra propriet
extra, rappresentata in Fig. 7, sar possibile configurare la dimensione del display
(16x1, 16x2, 16x4, 20x4), pi altre caratteristiche che comunque sono utili pi ai fini
della simulazione che altro.
Diamo ora uno sguardo alle macro disponibili per questo componente, per capire
come poterlo gestire efficacemente nei no-

Fig. 6
Connessioni del
componente
LCD.

stri progetti. In Tabella 2 sono indicate le


macro disponibili per il componente LCD
corredate della relativa descrizione.
Le memorie non volatili
Come sappiamo, diversi PIC dispongono
al loro interno di un certo quantitativo di
memoria non volatile di tipo EEPROM
(Electrical Erasable and Programmable
Read Only Memory); questa pu essere
utilizzata per limmagazzinamento di dati
che non devono essere persi dopo uno
spegnimento del sistema. Una on-board
EEPROM pu essere un grande vantaggio nel caso in cui si debba sviluppare
un sistema embedded che ha esigenze di
memorizzazione permanente di alcuni
dati, perch in questo caso non necessario ricorrere alluso di una memoria
esterna I2C o SPI. Il PIC18F4580 dispone di
256 byte di on-board EEPROM, garantiti
per circa un milione di cicli di scrittura e
con una ritenzione di pi di 40 anni.
Il componente EEPROM
Flowcode dispone di un componente
apposito per la gestione della EEPROM interna. Tale componente pu essere inserito
dalla barra dei componenti, selezionando
sotto la voce varie il componente EEPROM. Una volta inserito il componente
vedrete comparire nel pannello un array
bidimensionale che mostra la locazione di
memoria e il suo contenuto. Per il componente EEPROM non sono presenti le
connessioni, in quanto questo componente
non collegato esternamente in quanto il
bus per la gestione della memoria interno
al chip. disponibile invece lopzione

Fig. 7
Propriet
extra del
componente
LCD.

Tabella 2 - Principali macro disponibili per il componente LCD.


Nome Macro

Descrizione

Inizio

Inizializza il display.

Trasparente

Cancella tutte le righe del display.

VisualizzaASCII

Visualizza il carattere ASCII corrispondente al byte passato come argomento.

Comando

Invia il comando passato come argomento.

Cursore

Posiziona il cursore alla posizione indicata dai due argomenti x e y (coordinate del cursore).

VisualizzaNumero

Visualizza il numero passato come argomento gi convertito in ASCII.

VisualizzaStringa

Visualizza la stringa passata come argomento

CancellaLinea

Cancella la linea passata come argomento.

Scrivi_RAM

Scrive nella RAM del controller i dati passati come argomento.

Elettronica In ~ Settembre 2013

133

Fig. 8
Propriet
extra del
componente
EEPROM.

Tabella 3
Nome Macro

Descrizione

Read

Legge la locazione di memoria specificata con il parametro address e ritorna il valore letto nella variabile
di ritorno.

Write

Scrive la variabile specificata con il parametro data


allinterno della locazione specificata con il parametro
address.

propriet extra, che pu essere selezionata sempre premendo il tasto destro


sullicona del componente presente sul
pannello. La finestra delle propriet
visibile in Fig. 8.
Sono disponibili pi che altro propriet
relative alla simulazione ed possibile settare a mano la dimensione della EEPROM,
altrimenti lambiente imposta quella massima relativa al chip utilizzato.
In Tabella 3 sono riportate le macro disponibili per il componente che sono tutte
molto semplici.
Lunica accortezza da utilizzare quella
di lasciare un intervallo di almeno 200
microsecondi tra una scrittura e la successiva, per garantire il tempo necessario al
completamento delloperazione.
Per testare la EEPROM stato realizzato
un flowchart di prova che scrive in tutte
le 256 locazioni di memoria un numero
crescente da 0 a 256. Il sorgente Flowcode
EepromTest.fcf reperibile allinterno del
materiale di supporto.
Progetto Pratico: Termometro LCD
Passiamo ora alla descrizione del progetto pratico relativo a questa puntata,
nello sviluppo del quale metteremo in
pratica le nuove conoscenze acquisite.
Ci che ci proponiamo di realizzare
un termometro digitale che impiega
un LM335 ed un display LCD Hitachi
compatibile. Le specifiche del nostro
progetto sono:
Lettura del termometro digitale sul
canale analogico AN0,

cors
o
F
L
O
W
CO

Fig. 9
Collegamento E-Blocks
per la realizzazione del
progetto pratico.

DE

134

Settembre 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 11
Connessioni
del
componente
ADC.

Fig. 10
Collegamento
LM335.

Conversione del dato di temperatura in


gradi Celsius,
Visualizzazione continua della temperatura sul display.
Per la realizzazione del progetto utilizzeremo i seguenti componenti:
- EB006 USB PICmicro multiprogrammer board (PIC18F4580 e Quarzo
12MHz),
- EB005 LCD board,
- EB016 Prototype board.
Useremo la EB016 per la realizzazione del
circuito di acquisizione della temperatura
tramite lLM335. Naturalmente Matrix
dispone di alcune schede con sensori di
temperatura, pi o meno evolute, ma volevamo mostrare ai lettori come sia possibile interfacciare qualsiasi tipo di sensore
usando la scheda di prototipazione.
Colleghiamo le schede come segue:
EB016 collegata alla porta A ed alla porta B della EB006,
EB005 collegata alla porta C della EB006.
I collegamenti sono illustrati in Fig. 9.
Prima di andare avanti, bisogna realizzare
il circuito di acquisizione della temperatura sulla scheda di prototipazione. Per
farlo abbiamo fatto riferimento al datasheet dellLM335, che riporta alcuni esempi
di circuiti. La nostra scelta caduta sul
sensore con circuito di calibrazione, il cui
schema riportato in Fig. 10.
Questo circuito ci consente di avere una
misura pi precisa della temperatura, in
quanto si utilizza un potenziometro per
calibrare il sensore. Una volta completato il
progetto, potremo eseguire la calibrazione
semplicemente agendo sul potenziometro
ed utilizzando un termometro calibrato per

ottenere la temperatura di riferimento. A


questo punto procediamo alla realizzazione del circuito sulla breadboard e colleghiamo luscita del sensore allingresso
analogico AN0 del microcontrollore, che
troviamo disponibile sulla strip montata
a ridosso del connettore J1 sulla EB016.
Ora che i collegamenti di segnale sono
ultimati, non ci resta che distribuire anche
le alimentazioni ai vari E-Block. Per farlo
preleviamo riferimento e tensione di alimentazione dalla scheda madre (presenti
sulla morsettiera J10) e li portiamo alle
morsettiere a vite J1 della EB005 e J3 della
EB016.
Ora che lhardware pronto, possiamo
procedere allo sviluppo delle componenti
software. Per prima cosa preoccupiamoci
di inserire e collegare opportunamente
tutti i componenti che utilizzeremo nel
progetto. Viste le specifiche, ci occorre
sicuramente un componente ADC ed un
componete LCD. Non abbiamo da memorizzare informazioni permanenti, quindi
in questo progetto non avremo bisogno
del componente EEPROM. Procediamo
trascinando i componenti sul pannello. A
questo punto effettuiamo le connessioni. Il
componente ADC dovr leggere il canale
analogico 0 (AN0), quindi effettuiamo la
connessione con quel canale, come illustrato in Fig. 11.
Completate le connessioni, occupiamoci delle propriet extra del convertitore
analogico-digitale. Per questo progetto
impostiamo:
- Tempo di conversione: 50 cicli
- Velocit di conversione: Fosc/16
- Opzioni Vref: Vdd
Per quanto riguarda la voce Tensione

Elettronica In ~ Settembre 2013

135

Fig. 12
Connessioni
display LCD.

componente ADC di Flowcode ci offre la


possibilit di acquisire la lettura del canale
analogico considerato direttamente in
tensione, ritornando un float. Questa caratteristica risulta molto comoda perch
cos sar pi facile effettuare la conversione in temperatura. In virt di queste
considerazioni creiamo una variabile
di tipo virgola mobile e chiamiamola
Tensione (come illustrato in Fig. 13)
con la quale immagazzineremo il valore
di tensione letto sul canale AN0. Creiamo anche una ulteriore variabile, chiamandola Temperatura, sempre di tipo
virgola mobile, allinterno della quale
immagazzineremo il corrispondente
valore di temperatura.

Fig. 13
Creazione
della
variabile
Tensione.

Passiamo ora alla realizzazione dello


schema a blocchi che sar composto da un
flowchart principale e da tre macro:
- Inizializzazione del sistema,
- Lettura del sensore di temperatura,
- Visualizzazione della lettura.

Fig. 14
Macro
Inizializzazione.

cors
o
F
L
O
W
CO

Vref possiamo impostare 4,5V se alimentiamo il sistema tramite la porta USB (


la tensione tipica) o 5V se alimentiamo
dallesterno con un regolatore stabilizzato.
In ogni caso potremo aggiustare in seguito
la misura, usando il circuito di calibrazione
che ci siamo preparati in precedenza.
A questo punto passiamo alle connessioni
del display LCD, collegato sulla porta C,
come illustrato in Fig. 12. Ricordiamo che
linterfaccia del display parallela a 4-bit e
utilizza due ulteriori segnali: RS ed Enable.
Assicuriamoci di avere la finestra delle
connessioni del display configurata come
quella in Fig. 12 e di avere il jumper della
EB005 posizionato su default.
Non ci sono propriet extra rilevanti per
il display, quindi per quanto riguarda la
configurazione dei componenti e delle
connessioni abbiamo concluso.
Prima di passare allanalisi del flowcart ci
serve ancora la definizione della struttura dati sulla quale andremo a lavorare. Il

DE

136

Settembre 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 15
Flowchart della macro
Acquisisci LM335.

Partiamo dalla macro di inizializzazione,


che ha lo scopo di inizializzare il display e
le variabili e di scrivere una prima riga di
testo per informare lutente. Il flowchart
della macro di inizializzazione riportato
in Fig. 14.
Come si vede, si utilizzando tre blocchi
Chiamata Macro Componente, un blocco
Calcolo e un blocco Ritardo.
In sequenza le operazione eseguite sono le
seguenti: si inizializza il display, lo si pulisce, si visualizza la stringa Init System,
si inizializzano le variabili e si genera un

Fig. 16
Finestra
propriet
del blocco
Chiamata
Macro
Componente.

ritardo di 1 secondo. Molto semplice.


A questo punto passiamo alla macro di
lettura del sensore di temperatura, che
abbiamo chiamato AcquisisciLM335, il
cui flowchart riportato in Fig. 15.
Questa macro il cuore del programma,
eppure la potenza di Flowcode ci permette
di ridurla a due soli blocchi. Il compito
da eseguire quello di acquisire il dato in
tensione ed effettuare la conversione in
temperatura, in modo che possa poi essere
facilmente visualizzata dal display. Per
prima cosa si sfrutta la macro LeggiCo-

meTensione del componente ADC, che


permette di acquisire un canale analogico
riportando direttamente il dato in tensione
(in Volt), associabile ad una variabile di
tipo float (virgola mobile).
Noi associamo il valore di ritorno alla variabile Tensione, che avevamo creato in
precedenza. In Fig. 16 riportata la finestra
di propriet del blocco Chiamata Macro
Componente che realizza loperazione.
A questo punto bisogna convertire il dato
letto in un dato di temperatura. LLM335
ha un segnale in uscita proporzionale alla
temperatura con fattore di proporzionalit
di 10mV/Kelvin. Invertiamo la formula,
scaliamo il valore di tensione da V a mV e
sottraiamo 273 per ottenere la temperatura
in gradi Celsius. Per introdurre questa formula nel codice usiamo un blocco calcolo,
come riportato in Fig. 17.
Il dato immagazzinato allinterno della
variabile Temperatura gi correttamente convertito in gradi Celsius, quindi
baster convertirlo in codifica ASCII per
ottenere la visualizzazione corretta. Ora
anche la seconda macro completata.
Passiamo allultima macro da realizzare, la
macro di visualizzazione, che chiameremo
VisualizzaTemperatura, il cui flowchart
riportato in Fig. 18.
In questo flowchart usiamo solo chiamate
a macro di componeti, in quanto il dato
gi pronto e lunica cosa che dobbiamo
fare scriverlo correttamente sul display,
sfruttando le funzioni a corredo del componente LCD nonch le stringhe di contorno. Per prima cosa si pulisce il display,
in modo che non rimangano porzioni di
stringe scritte in precedenza. Fatto questo
si visualizza la stringa Temperatura:,
come stringa di intestazione. A questo
punto si usa la funzione Cursore per
muoversi sulla seconda riga, che verr usa-

Elettronica In ~ Settembre 2013

137

Fig. 17
Conversione
del dato in
tensione nel
corrispondete
valore di
temperatura.

Fig. 18
Flowchart della macro
VisualizzaTemperatura.

stato inserito un ritardo software di un


secondo.
Possiamo ora procedere con la compilazione e lesecuzione del programma. Una
volta programmato il micro, se abbiamo
eseguito tutto correttamente, vedremo
comparire il valore della temperatura letta
dal sensore sul display. Se la lettura non
fosse corretta, possiamo agire sul potenziometro del circuito di calibrazione per
regolarla.
In questa puntata abbiamo iniziato a
prendere confidenza con i componenti di
Flowcode, realizzando un primo programma di un certo peso (un dispositivo che
ha una reale funzione), e abbiamo cominciato a renderci conto di come, inserendo
i componenti appositi e collegando pochi
blocchi, sia possibile implementare in
breve tempo anche funzioni di una certa
complessit. Nella prossima puntata continueremo questo percorso, esaminando
in dettaglio le interfacce di comunicazione
che ci permettono di realizzare sistemi pi
complessi, interfacciati a periferiche esterg
ne pi intelligenti.

cors
o
F
L
O
W
CO

ta per visualizzare il dato. Qui possiamo


usare la macro VisualizzaNumero per
visualizzare su display il valore immagazzinato nella variabile Temperatura
che, come abbiamo visto prima, contiene
il valore della temperatura in gradi Celsius. Ora non ci rimane altro da fare che
visualizzare il carattere C per indicare
che la temperatura in gradi Celsius e riportare il cursore alla posizione di partenza: la nostra terza macro cos pronta.
Ora abbiamo le tre macro pronte alluso,
lultima operazione da fare metterle
insieme sul flowchart principale e lanciare
la compilazione. Il flowchart principale
riportato in Fig. 19.
Come potete vedere stata chiamata prima
di tutto la macro Inizializzazione. Poi,
allinterno di un ciclo while infinito, sono
state inserite le due chiamate alle macro
AcquisisciLM335 e VisualizzaTemperatura. La prima macro acquisisce il valore
di tensione proveniente dal sensore di
temperatura e passa i dati alla seconda, che
li visualizza sul display LCD. Per evitare
un eccessivo effetto Refresh sul display

Fig. 19
Flowchart principale
dellesempio pratico
Termometro LCD.

DE

138

Settembre 2013 ~ Elettronica In

corso F L O
WCOD

Continuiamo il nostro
viaggio alla scoperta
di Flowcode, il sistema
di sviluppo grafico
per microcontrollori
proposto da Matrix
Multimedia, in cui il
codice viene scritto
facendo uso di oggetti
grafici.
Quarta puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

elle scorse puntate abbiamo spiegato la gestione degli interrupt in


Flowcode e insegnato a utilizzare i
componenti ADC, LCD e la memoria EEPROM interna. In questa puntata parleremo
delle principali interfacce di comunicazione
seriali a disposizione dei microcontrollori di
bassa gamma: lUART (o RS232), lIC, SPI
e lOneWire. Termineremo con un progetto
pratico nel quale svilupperemo un controllo
di una batteria di rel comandata tramite
porta seriale.
Le periferiche di comunicazione di base
I sistemi che abbiamo trattato finora erano
in grado di gestire solo sistemi chiusi, cio

non potevano interfacciarsi con piattaforme


esterne. Parleremo ora di altri componenti
fondamentali di un microcontrollore, che
sono le interfacce di comunicazione. I bus di
comunicazione sono in continua evoluzione ed oggigiorno ve ne sono di moltissime
tipologie. Facciamo un piccolo passo indietro ed analizziamo brevemente le interfacce
di comunicazione che sono state utilizzate
in questi ultimi decenni. Con lavvento
dellera digitale, il sistema di comunicazione maggiormente utilizzato stato quello
parallelo, dove i dati sono scambiati a
pacchetti, solitamente di 8 bit, ed uno o
pi segnali trasportano linformazione del
clock. Il trasporto dei dati in parallelo non

Elettronica In ~ Ottobre 2013

113

Fig. 1
Pannello
SPI.

SCK/SCLK (Serial Data Clock) su cui


viene trasmesso il segnale di clock.

consigliabile sulle grandi distanze, in quanto richiederebbe molti fili e -per contrastare
il degrado del segnale- lamplificazione
per ciascuno di essi; per questa ragione
che sono state inventate le comunicazioni seriali, nelle quali il valore digitale da
trasmettere suddiviso in singoli bit, che
sono trasmessi in ordine sequenziale sullo
stesso canale di trasmissione, impiegando
quindi due soli fili. Possiamo suddividere
i sistemi di comunicazione in due grandi
famiglie, in base alla distanza che riescono
a coprire: quelli interni permettono la comunicazione tra sistemi vicini o comunque
appartenenti allo stesso sistema, mentre
quelli tra sistemi collegano apparati con
compiti solitamente differenti su distanze
anche molto ampie. Inizieremo parlando di
quelli interni ed in particolare di SPI, IC e
OneWire. Successivamente passeremo alla
descrizione della RS232, interfaccia con la
quale realizzeremo un progetto pratico.

Fig. 2
Pannello di
configurazione del
bus SPI.

cors
o
F
L
O
W
CO

Serial peripheral interface (SPI)


Linterfaccia SPI (acronimo di Serial Peripheral Interface) semplice da utilizzare ed
affidabile e, per queste ragioni, divenuta
il sistema di comunicazione comunemente
utilizzato da memorie, ADC e DAC esterni
al microcontrollore.
La comunicazione mediante porta SPI necessita di tre collegamenti:
SDO/MOSI (Serial Data Output) dal
quale i dati vengono inviati;
SDI/MISO (Serial Data Input) dal quale i
dati vengono ricevuti;

I dati trasmessi e ricevuti passano su due


connessioni differenti e, per questa ragione,
la comunicazione detta di tipo full-duplex.
Pi periferiche possono essere collegate allo
stesso bus di comunicazione, ma, in questo
caso, solo una di esse di tipo master,
mentre tutte le altre sono di tipo slave.
Per poter utilizzare questo sistema di comunicazione non comunque necessaria una
conoscenza approfondita del livello fisico
e di protocollo, perch Flowcode mette a
disposizione una potentissima libreria di
componenti che ci permette di utilizzarla e
gestirla in modo ancora pi semplice.
Allinterno della barra dei componenti nel
menu Trasmissione dati troviamo il componente SPI; se lo inseriamo nel nostro progetto mediante un clic sulla relativa icona,
notiamo che appare, nel pannello, come
una finestra suddivisa in tre parti. Partendo dallalto verso il basso possiamo cos
esaminare i caratteri inviati, quelli ricevuti
e in basso i caratteri in coda, come mostrato
in Fig. 1.
Ora che il componente stato inserito nel
progetto, necessario configurarlo in modo
che possa comunicare correttamente con
le periferiche. I campi della finestra delle
propriet, mostrata in Fig. 2, devono essere
valorizzati esaminando il data-sheet del
componente che vogliamo collegare esternamente, in modo che tutto possa funzionare correttamente.
Il box in cui si pu indicare se trasmettere
byte o caratteri non influenza la modalit

DE

114

Ottobre 2013 ~ Elettronica In

corso F L O
WCOD

Tabella 1 - Parametri di configurazione del bus SPI.


Parametro

Descrizione
Rappresenta la velocit di trasmissione dei dati. Deve obbligatoriamente essere minore di quella supportata
dal componente pi lento collegato al bus di comunicazione. Facciamo un semplice esempio supponendo
che il componente slave supporti una velocit massima di comunicazione di 300 kHz ed il microcontrollore
abbia una frequenza di oscillazione pari a 4 MHz.

SPI Clock
Dividendo la frequenza massima della comunicazione per la frequenza di oscillazione del microcontrollore,
otteniamo il rapporto massimo che vi pu essere tra le due grandezze e scegliamo il valore pi grande, tra
quelli disponibili nel menu a tendina, che risulta minore del risultato della frazione.
SPI Clock polarity

utilizzato per definire lo stato di inattivit (idle) del segnale di clock.

SPI Clock Edge

Serve per scegliere se il dato scritto durante il fronte di salita o discesa del segnale di clock.

SPI Sample bit

Indica quando il dato deve essere campionato per poter effettuare una corretta trasmissione/ricezione del
dato da tutti i dispositivi collegati. In pratica, modifica il punto di campionamento del dato.

di trasmissione/ricezione dei dati sul bus


di comunicazione, ma unicamente la loro
visualizzazione sul componente nel pannello di Flowcode.
Al termine della configurazione possiamo
inserire le macro gestite del componente dal
menu delle icone, come fatto per il componente KeyPad e per lADC esaminati nelle
puntate precedenti. In questo caso le principali macro a nostra disposizione sono quelle
elencate nella Tabella 2.
Vi sono altre macro specifiche, mostrate in
Tabella 3, che ci possono essere di aiuto nel

caso volessimo utilizzare la scheda EB013,


che contiene al suo interno una memoria
FRAM (rimpiazzabile con una memoria
EEPROM) ed un convertitore digitale/analogico, entrambi su bus SPI.
Per poter utilizzare questi componenti
inoltre necessario configurare le connessioni
esterne dei piedini di abilitazione. Utilizzando queste semplici macro quindi possibile utilizzare una memoria EEPROM/
FRAM od un DAC in modo davvero semplice ed intuitivo. Qualora il componente
scelto non appartenesse a questa lista o non

Tabella 2 - Macro disponibili per il controllo del bus SPI.


Nome Macro
SPI_Init

Descrizione
utilizzata per inizializzare le periferica di comunicazione SPI. Solitamente posta
ad inizio programma e viene chiamata una volta sola.

SPI_Send_Char

utilizzata per inviare un carattere.

SPI_Get_String

utilizzata per ricevere una stringa di caratteri.

SPI_Send_String

utilizzata per inviare una stringa di caratteri.

SPI_Get_Char
SPI_Unint

utilizzata per ricevere un carattere.


utilizzata per rimuovere le inizializzazioni della connessione SPI e poter quindi utilizzare i pin del
microcontrollore come normali bit della porta di I/O.

Tabella 3 - Macro supplementari per componenti specifici su bus SPI.


Nome Macro

Descrizione

DAC_Send_Char

Invia un carattere/byte al convertitore digitale/analogico che lo trasformer direttamente


in un valore analogico visibile sui morsetti esterni.

NVM_Send_Char

Invia un dato alla memoria EEPROM che verr caricato allinterno della cella selezionata.

NVM_Get_Char

Legge il valore memorizzato allinterno della cella di memoria indicata.

FramOutput

Invia un valore alla memoria FRAM.

EnableFRAM

Abilita la memoria FRAM/EEPROM. Prima di ogni comando verso la memoria, necessario


abilitarla altrimenti tutti i comandi verrebbero ignorati.

DisableFRAM

Disabilita la memoria FRAM/EEPROM in modo da poter comunicare con altri dispositivi


collegati sullo stesso bus SPI.

Elettronica In ~ Ottobre 2013

115

Fig. 3
Pannello del
componente
I2C Master.

fosse compatibile, baster semplicemente


utilizzare le macro generiche in modo da
realizzare il protocollo corretto.
La porta IC
Passiamo ora a descrivere il bus di comunicazione IC, il cui protocollo richiede unicamente due linee di comunicazione:
SDA (Serial Data Line) per la trasmissione/ricezione dei dati ;
SCL (Serial Clock Line) per la trasmissione del clock di sincronizzazione.

Tabella 4 - Parametri di configurazione componente I2C.


Parametro

Descrizione

Enableslew rate control

Attiva il controllo sullo slew-rate (velocit dei fronti) del segnale trasmesso sul bus.
Abilita lutilizzo del SMBus sulla connessione IC (modalit di compatibilit).

Enable SMBus Inputs

Baud rate

Imposta la frequenza con la quale vengono trasmessi i dati sul bus di comunicazione. Deve obbligatoriamente, come visto per il bus SPI, essere minore della velocit massima supportata dal componente pi
lento collegato al bus. Possono essere utilizzati i valori pre-configurati (preset), oppure dei valori custom
scelti utilizzando la barra a scorrimento.

IC2 hardware

Seleziona quale periferica, messa a disposizione dal microcontrollore, coinvolta nella trasmissione dei
dati. Qualora ve ne fossero pi di una disponibili, come mostrato in Fig. 4, possono essere inseriti due
componenti IC, ciascuno su un differente canale in modo da avere due bus distinti di comunicazione.

Fig. 4
Propriet del
componente
I2C master.

cors
o
F
L
O
W
CO

Sullo stesso bus possono essere collegati


fino a 112 dispositivi differenti. A differenza
dellSPI, sia i dati in trasmissione che quelli
in ricezione viaggiano sulla stessa connessione fisica. Il bus SPI di tipo half-duplex
perch solo un componente alla volta pu
trasmettere i dati; inoltre, la comunicazione
pu essere iniziata solo dal master, mediante una stringa che contiene un bit di start,
lindirizzo dello slave con il quale vuole
comunicare e un bit che indica se richiesta

una risposta. Successivamente vengono


inviati, in sequenza, i dati veri e propri,
iniziando sempre dal bit pi significativo.
Allinterno della barra dei componenti
possiamo selezionare il controller per il bus
IC ed inserirlo allinterno del pannello di
Flowcode. Il pannello appare come in Fig. 3
e ci permette di visualizzare le comunicazioni presenti sul bus e poter interagire aggiungendo byte nella comunicazione in modo da
rendere la simulazione interattiva.
Per utilizzare il componente necessario
configurarlo come abbiamo fatto precedentemente con il bus SPI, ma i parametri da
settare sono differenti; nel caso del bus IC,
essi sono quelli elencati nella Tabella 4.
Invece le macro a disposizione sono riassunte in Tabella 5.
Continuando nel nostro percorso di descrizione di bus di comunicazione, passiamo
al bus con il minor numero di connessioni
possibili: una connessione unica per la
trasmissione/ricezione di dati e segnale di
sincronizzazione: il bus OneWire.

DE

116

Ottobre 2013 ~ Elettronica In

corso F L O
WCOD

Tabella 5 - Macro disponibili per la gestione della connessione I2C master.


Nome Macro
MI2C_Init
MI2C_Start
MI2C_Restart
MI2C_Stop

Descrizione
Inizializza la periferica interna di comunicazione IC. Deve essere chiamata uno volta prima di
eseguire le altre macro altrimenti non verrebbe trasmesso/ricevuto alcun byte.
Invia il segnale di start della comunicazione sul bus IC.
Invia il segnale di riavvio della comunicazione sul bus IC.
Invia il segnale di stop della comunicazione sul bus IC.

MI2C_Transmit_Byte

Trasmette un byte sul bus di comunicazione. Restituisce zero se rileva la ricezione di una
conferma di ricezione acknowledge.

MI2C_Receive_Byte

Riceve un byte dal bus di comunicazione. Necessita della valorizzazione del parametro che, se
posto a uno, indica che il byte da ricevere lultimo.

MI2C_Send_Byte_Transaction
MI2C_Receive_Byte_Transaction

Invia ad uno specifico dispositivo il valore che deve essere posto allindirizzo indicato.
Riceve da uno specifico dispositivo il valore caricato allindirizzo di memoria scelto.

La porta OneWire
Il bus OneWire stato realizzato da Dallas
Semiconductor per consentire comunicazioni tra due o pi dispositivi attraverso
un unico filo di interconnessione. Non
essendoci un filo dedicato per la trasmissione del segnale di sincronizzazione,
questultimo deve essere trasmesso assieme ai dati.
Per evitare problemi di cortocircuiti sulla
linea presente un pull-up, cio una
resistenza collegata tra la linea e lalimentazione, e tutti i dispositivi possono
imporre uno zero sulla linea attivando il
transistor/MOSFET di pilotaggio della
porta connessa. La velocit di comunicazione non elevatissima ( prefissata a 16
kbps), tuttavia permette comunicazioni tra
dispositivi in modo davvero semplice.
Si tratta di un bus di tipo Master/Slave,
dove ogni dispositivo ha un indirizzo
univoco e questo deve essere utilizzato dal
master per iniziare la comunicazione con
lo slave.
La codifica dei simboli differisce notevolmente dai casi esaminati in precedenza,
perch sono codificati in base alla lunghezza dellimpulso, come indicato in
Tabella 6.
Nel caso di ricezione, cio durante la
comunicazione di dati dallo slave verso il
master, lo slave mantiene la linea al valore
0 per 60 s qualora voglia inviare un valore logico zero mentre non fa nulla se intende inviare il valore logico uno a seguito di
ogni impulso generato dal master.

Tabella 6 - Tempi di impulso per la


trasmissione dei dati su bus OneWire.
Linea a 0 per almeno 480 s

Reset
Valore logico uno

115 s linea a 0

Valore logico zero

60 s linea a 0

Per accertarsi che il pacchetto di dati sia


stato correttamente ricevuto/inviato,
presente il controllo mediante CRC a 8 bit
che trasmesso come primo byte. Nella
finestra di configurazione del componente,
mostrata in Fig. 5, possiamo unicamente
scegliere se utilizzare o no il controllo
CRC.
Le macro disponibili in Flowcode per
gestire questa porta sono riassunte nella
Tabella 7.
In Tabella 8 sono riportate altre macro che
potrebbero risultare utili qualora si volesse utilizzare il dispositivo DS1820.
Prima di poter utilizzare il componente

Fig. 5
Propriet del
componente
OneWire.

Elettronica In ~ Ottobre 2013

117

Tabella 7 - Macro disponibili per la gestione del bus OneWire.


Nome Macro

Descrizione
Invia un comando di reset e restituisce uno se nessun dispositivo risulta resettato oppure non vi sono
dispositivi collegati al bus.

oo_BusReset

oo_GetPadByte

Restituisce il dato letto dal dispositivo identificato dal parametro passato alla macro;
I dispositivi letti sono al massimo 9 ed il parametro pu variare da 0 a 8 se un dispositivo risulta resettato
oppure non vi sono dispositivi collegati al bus.

oo_Tx_Byte

Trasmette un byte sul bus.

oo_Rx_Byte

Riceve un byte dal bus.

oo_ScanBus

Esegue una scansione del bus per lidentificazione del numero di dispositivi. Restituisce 1 se vi sono stati
dei problemi durante la scansione.

oo_Get_DeviceCount

Restituisce il numero di dispositivi rilevati sul bus dopo un comando di scansione del bus.
Legge il dispositivo identificato dal numero in ordine di scansione.

oo_ReadDevice

Tabella 8 - Macro per la gestione del componente DS1820 su bus OneWire.


Nome Macro

Descrizione

DS1820_Start_Conversion

Avvia la conversione del dato del dispositivo DS1820. Restituisce uno se il dispositivo entrato in
time-out senza terminare la conversione.

DS1820_Read_Scratchpad

Legge i valori dal dispositivo DS1820. Pu essere utilizzata unicamente qualora vi sia un unico
dispositivo collegato al bus altrimenti necessario utilizzare la macro oo_ReadDevice.

DS1820_Get_Temp

Legge la temperatura del dispositivo DS1820.


Il valore letto rappresentato su un intero con risoluzione di 0,0625C.

necessario configurare il piedino che sar


utilizzato per trasmettere/ricevere i dati,
come indicato in Fig. 6.
Un semplice esempio di diagramma di
flusso per il controllo del bus OneWire per
la gestione del componente DS1820 raffigurato in Fig. 7: con lutilizzo di soli quattro
blocchi possiamo comunicare con il componente dimenticandoci completamente tutte
le problematiche inerenti al livello fisico e
del protocollo di comunicazione.
Ora che abbiamo esaminato tre esempi di

bus di comunicazione interni, passiamo a


descrivere la porta RS232, che una tra le
pi usate e semplici interfacce seriali.
La Porta RS232
La RS232 una linea di comunicazione
asincrona, in quanto il segnale di temporizzazione non viene trasmesso, ma generato in modo autonomo da entrambe le
periferiche collegate. La connessione di
tipo punto-punto, quindi permette di far
comunicare tra loro solo due dispositivi.

Fig. 6 - Configurazione connessioni bus OneWire.

cors
o
F
L
O
W
CO

Fig. 7 - Esempio di flusso


di controllo per il
componente DS1820.

DE

118

Ottobre 2013 ~ Elettronica In

corso F L O
WCOD

Tabella 9 - Macro disponibili per la gestione della connessione RS232.


Nome Macro

Descrizione

SendRS232Char

Invia un dato a 8-bit sulla seriale.

SendRS232String

Invia una stringa di caratteri sulla seriale.

ReceiveRS232Char

Riceve un carattere sulla seriale. La macro accetta come parametro il valore del tempo massimo di attesa del
dato e qualora non venga ricevuto entro il tempo massimo indicato restituisce il valore INVALID_RETURN (255).

ReceiveRS232String

simile alla ReceiveRS232Char ma legge una stringa di caratteri la cui lunghezza


indicata dal parametro Length.

ChangeHWBaud

Modifica la velocit di trasmissione dei dati.


Accetta un valore numerico intero compreso tra 0 e 7 codificato come nella Tabella 10.

I dati vengono trasmessi in modo seriale,


in pacchetti da 8-9 bit racchiusi tra un bit
di start ed uno di stop. La durata di ogni
bit dipende dalla velocit di comunicazione; affinch tutto funzioni correttamente,
questultima deve essere uguale per entrambi i dispositivi.
Flowcode dispone di un componente
specifico per la gestione della RS2332, le
cui macro sono riassunte in Tabella 9. Per
poter utilizzare il componente dobbiamo
configurarlo (come fatto per gli altri visti in
precedenza) attraverso la finestra di configurazione, accessibile dal menu a tendina
del componente nel pannello; qui abbiamo
a disposizione i controlli per impostare la
velocit di comunicazione (baud-rate), il
numero di bit del frame, nonch la possibilit di utilizzare le connessioni per il
controllo di flusso.
Non ci soffermeremo sui dettagli di ogni
singola configurazione, perch il nostro
obiettivo dare a tutti le nozioni base per
utilizzare i componenti trattati in modo
rapido e efficace; qualora si volessero approfondire alcune caratteristiche e funzionalit, sempre possibile utilizzare lhelp
di Flowcode, che consigliamo di tenere
sempre sottomano, perch potrebbe, soprattutto allinizio, permettervi di imparare
molto.
Questo tipo di connessione molto
semplice da utilizzare e permette comunicazioni con dispositivi anche molto
complessi come ricevitori GPS o display
grafici. Per comprenderne meglio le
potenzialit, passiamo ora alla realizzazione di un semplice progetto pratico, che
ci permetter di gestire una batteria di
rel tramite linterfaccia seriale del PC.

Tabella 10 - Valori disponibili per la modifica


al volo della velocit di connessione.
Parametro

Velocit

1200 bps

2400 bps

4800 bps

9600 bps

19200 bps

38400 bps

57600 bps

115200 bps

Gestione di una scheda a rel


tramite interfaccia RS-232
Nella realizzazione di questo semplice
progetto tralasceremo i passaggi base che
abbiamo gi spiegato nelle puntate precedenti e ci soffermeremo maggiormente sui
nuovi concetti.
Il nostro sistema presenta le caratteristiche
seguenti.
Comunica via RS232 bidirezionale tra PC
e scheda di controllo a rel.
Deve supportare i seguenti comandi:
- A: Attiva rel;
- D: Disattiva rel;
- R: Leggi stato rel.
La sintassi dei comandi <xp>, dove x
identifica il codice del comando (che pu
essere uno dei tre comandi visti al punto
precedente), mentre p identifica il rel
controllato, ed rappresentato da un
numero con codifica ASCII. Quindi, ad
esempio, per attivare il rel 3 inviamo il
comando <A3>, per spegnere il rel
2 inviamo <D2> mentre per leggere
lo stato del rel 1 inviamo il comando
<R1>.
La sintassi delle risposte ai comandi la

Elettronica In ~ Ottobre 2013

119

seguente: <xp-v>. In essa, x e p hanno


lo stesso significato assunto al punto
precedente, mentre v il valore o lesito
del comando. Qualora il comando non
richieda un valore di ritorno e sia stato
eseguito correttamente, v avr valore
K mentre nel caso vi siano errori avr
valore N. Ad esempio, come risposta
al comando di attivazione del rel 1 con
esito positivo, si avr <A1-K>, mentre
se lesito fosse stato negativo la risposta
sar <A1-N>. Nella risposta al comando
di lettura, v vale 1 o 0 in base al valore
letto. Ad esempio, nel caso che il rel 2
sia attivo e ne venga chiesta la lettura, la
risposta sar <R2-1>.

Fig. 8
Assemblaggio dei
moduli necessari
a pilotare una
batteria di rel
attraverso la
connessione
RS232.

Ora che abbiamo steso le direttive principali per realizzare il nostro progetto, passiamo allidentificazione dei componenti
necessari per la realizzazione, che sono:
Fig. 10 - Configurazione del componente LED array.

Ottobre 2013 ~ Elettronica In

DE

120

cors
o
F
L
O
W
CO

Fig. 9 - Configurazione del componente RS232.

corso F L O
WCOD

EB006 sono quelle gi utilizzate nella scorsa


puntata.
Flowcode non dispone di un componente
Rel Array, ma il funzionamento di un
rel, dal punto di vista del comando, del
tutto simile a quello di un LED, quindi
utilizzeremo il componente LED array
per controllare la nostra batteria di rel.
Apriamo il progetto ConfigurazioneBase2.
fcf ed inseriamo, prendendoli dalla barra
dei componenti, il componente RS232 ed il
LED array. Impostiamo la RS232 mediante
il menu a scomparsa Propriet extra in
modo da avere una velocit di comunicazione pari a 9.600 bps, il timeout indicato
in millisecondi e scegliamo la porta UART1
come indicato in Fig. 9.
Configuriamo anche il componente LED

Fig. 11 - Main
del programma
di controllo.

-
EB006 USB PICmicromult
iprogrammerboard(PIC18F4580 e
quarzo 12 MHz);
-
EB038 Relay Board;
-
EB015 RS232 Board.
Colleghiamoli in modo da avere la scheda
EB038 sulla porta A e la EB015 sulla porta
C, come mostrato in Fig. 8.
Le schede devono essere alimentate per
poter funzionare correttamente, perch
attraverso il connettore DB9 passano solo le
connessioni dati ed il riferimento di massa
perci, utilizzando dei fili da prototipazione, colleghiamo tutti i morsetti con indicato
+V al corrispondente morsetto della scheda EB006. Posizioniamo, inoltre, i connettori di patch in posizione C e 2 per la scheda
EB038, e in posizione LOW per la scheda
EB015. Le altre configurazioni della scheda

array seguendo la stessa procedura come


indicato in Fig. 10.
Quindi scegliamo i pin al quale sono collegati mediante il menu a scomparsa Connessioni ed assegniamoli alla porta A dal
pin 0 al pin 4.
Ora che tutto pronto, possiamo dedicarci
alla stesura del diagramma di flusso. Per ottimizzare luso di Flowcode possiamo pensare di suddividere, utilizzando le macro,
lintero programma in tre parti principali:
Inizializzazione = inizializza tutto ci
che deve essere preimpostato prima che
il ciclo principale inizi;
Main = chiama linizializzazione del sistema, legge i caratteri ricevuti da seriale
e li aggrega in ununica stringa in modo
da esaminarla mediante un semplice
controllo di correttezza;
ControllaComando = esegue il controllo

Elettronica In ~ Ottobre 2013

121

del controllo, il comando viene resettato


in modo da abilitare la ricezione di nuovi
comandi;
in tutti gli altri casi, il carattere viene
aggiunto alla stringa di comando.
Lintero flusso in Flowcode rappresentato
nella Fig. 11.

Fig. 12
Macro
Controlla Comando.

Fig. 13
Macro
di Inizializzazione.

sulla correttezza del comando ricevuto,


esegue il comando ed invia la risposta.

Tabella 11 - Formato del file .cvs.

122

Stato Rel 1

Ottobre 2013 ~ Elettronica In

Stato Rel 2

Stato Rel 3

Stato Rel 4

DE

Tempo di esecuzione [ms]

cors
o
F
L
O
W
CO

Main
Il main contiene la chiamata alla macro di
inizializzazione, oltre ad un ciclo infinito
nel quale viene richiesta una lettura da
seriale ed analizzato il carattere ricevuto:
quindi, ogni volta che viene ricevuto un
carattere da seriale, esso viene analizzato.
Dopo la ricezione e lanalisi ci sono tre
possibilit:
il carattere <, allora viene azzerata la
stringa che contiene il carattere ricevuto;
il carattere >, allora la stringa di
comando stata ricevuta completamente
e quindi viene controllato il comando
attraverso la specifica macro; al termine

corso F L O
WCOD

Fig. 14 - Sezione Manual Control dellinterfaccia sw.

Macro ControllaComando
Realizza il controllo del comando ricevuto
come parametro, lo esegue nel caso sia stato ricevuto correttamente e, in ogni caso,
invia una risposta sulla linea seriale. Nella
prima parte della macro vengono estrapolati dalla stringa il carattere di comando
ed il parametro associato. Viene fatto un
controllo sul valore del parametro (che nel
nostro caso deve essere compreso tra 1 e
4) e successivamente, in base al carattere
del comando, viene eseguita loperazione
di accensione, spegnimento o lettura del
rel. Gli stati del rel sono memorizzati in
un vettore globale di appoggio chiamato
StatoRele. Al termine dellesecuzione,
prima di ritornare il controllo alla funzione
chiamante, la macro invia la risposta utilizzando la macro SendRs232String.
Lintero diagramma visibile in Fig. 12.
Macro Inizializza
utilizzata per inizializzare lo stato dei
rel e le variabili di appoggio del programma. In questo caso lunica variabile
che deve essere azzerata il vettore con lo
stato dei rel StatoRele che, per essere concorde allo stato fisico, deve essere
impostato a zero. Il diagramma Flowcode
rappresentato nella Fig. 13.
Interfaccia Software
Per lutilizzo della scheda rel appena
realizzata stata sviluppata unapposita
interfaccia software, scritta in Labview
2010. Linterfaccia permette sia il controllo
manuale dei 4 rel, sia lesecuzione di sequenze automatizzate. Subito dopo lavvio
dellinterfaccia possiamo scegliere tra le due
modalit, mediante un radio button posto
in basso, sulla destra del pannello. Uno scre-

Fig. 15 - Sezione Automatic Control dellinterfaccia sw.

Fig. 16
Esempio di file
.cvs.

enshoot dellinterfaccia software visibile in


Fig. 14. Come si pu notare, possibile selezionare la porta RS-232 (COM1 o COM2),
selezionare il baud-rate (limpostazione
predefinita 9600) mentre sono presenti
due tab, Manual Control e Automatic
Control, contenenti i comandi specifici per
le due modalit. Per la modalit di controllo manuale sono presenti 4 pulsanti, con i
quali possibile controllare lo stato dei rel.
Due parole in pi merita la sezione automatica, della quale in Fig. 15 riportiamo uno
screenshoot. Tale sezione permette di automatizzare il controllo della scheda da PC,
impostando sequenze di controllo temporizzate. Per impostare le sequenze automatizzate sufficiente generare un file .cvs con
la formattazione indicata nella Tabella 11.
Come si pu vedere, il primo campo indica
il tempo (in ms) al quale verranno inviate
le istruzioni presenti nei 4 campi successivi,
che rappresentano lo stato dei 4 rel (0 o 1).
Un esempio di file .cvs riportato in Fig. 16.
Tramite questa modalit, possibile impostare sequenze di controllo che possono essere impiegate per le pi svariate necessit,
dallautomazione alla domotica, al controllo
g
di macchinari.

Elettronica In ~ Ottobre 2013

123

corso F L O
WCOD

Continuiamo il
nostro viaggio alla
scoperta del sistema
di sviluppo grafico
per microcontrollori
proposto da Matrix
Multimedia. In
questa puntata
iniziamo a lavorare
con le periferiche
di comunicazione
avanzate, partendo da
quella che ha riscosso
un notevole e crescente
successo negli ultimi
15 anni: il CAN-Bus.
Quinta puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

l mese scorso abbiamo illustrato


luso delle periferiche di comunicazione di base, imparando ad utilizzare le porte di comunicazione UART, IC,
SPI e OneWire. In questa puntata introduciamo una periferica di comunicazione
decisamente pi avanzata, che permette di
creare reti anche piuttosto complesse e largamente utilizzata ai giorni nostri, specialmente nel settore automotive: stiamo parlando della porta CAN (Controller Area
Network), che oggi costituisce lo standard
de facto per le reti di comunicazione delle
automobili e si sta espandendo anche ad
applicazioni industriali e custom, grazie
alla sua robustezza, alla relativa sempli-

cit rispetto a soluzioni simili e ai costi


ridotti dei componenti. Come fatto nelle
puntate precedenti, arricchiremo il tutto
con un progetto pratico: realizzeremo un
prototipo di sensore di parcheggio per
autoveicoli.
Controller Area Network (CAN)
Il protocollo CAN nasce negli anni 80 del
secolo scorso dalla Robert Bosch GmbH,
che aveva lesigenza di sviluppare uno
standard per le comunicazioni seriali a
corto raggio tra diverse unit elettroniche
di controllo, di tipo multicast, dotato di
elevata immunit ai disturbi, basso costo
ed elevata affidabilit. Lo standard im-

Elettronica In ~ Novembre 2013

127

Tabella 1 - Data-rate riferito allestensione della rete CAN.


Data-rate(kbps)

Estensione massima (m)

125

500

250

250

500

100

I frame possono essere di quattro tipi:


Data frame, frame contenente i dati che
il nodo trasmette;
Remote frame; richiede la trasmissione di
un determinato identificatore;
Error frame; trasmesso da un qualsiasi
nodo che ha rilevato un errore;
Overload frame; frame che introduce
un ritardo fra data frame e/o remote
frame.
I Data frame sono quelli cui affidata
leffettiva trasmissione dei dati e possono
essere di due tipi, a seconda della versione
dello standard CAN presa in considerazione:
Base frame format; ID ad 11 bit (versione
2.0A);
Extended frame format; ID a 29 bit (versione 2.0B).
I dispositivi standard CAN devono riconoscere il formato base frame e possono riconoscere (ma devono comunque tollerarlo) il formato extended frame format. Il CAN
base permette 211=2048 tipi di messaggi diversi, ma da specifiche Bosch se ne possono usare solo 2031. Nella versione extended
si possono avere fino a 229=536.870.912 tipi
di messaggi. Lextended frame format,
detto anche CAN esteso, oggi il formato
pi diffuso nelle varie applicazioni che
utilizzano questo standard.
Unapplicazione che faccia uso del protocollo CAN necessita di almeno un paio
di componenti elettronici aggiuntivi: un
controller ed un transceiver; questultimo
lelemento che si occupa dellinterfacciamento a livello fisico con il bus. quindi
responsabile della corretta traslazione e
delladattamento dei livelli logici delle
linee. Si interfaccia direttamente con il
controller. Ci sono diverse aziende al
mondo che producono transceiver CAN;
noi utilizzeremo il transceiver della
Microchip, MCP2551.
Il controller lelemento che si occupa
dellimplementazione del livello data link
(livello 2 dello stack OSI); quindi ad esso
demandata la gestione delle principali
logiche del bus, svincolando lutilizzatore
dalla gestione di problematiche di arbi-

cors
o
F
L
O
W
CO

piega come mezzo trasmissivo una linea


differenziale bilanciata (i due terminali
sono indicati come CANH e CANL), esattamente come nel caso dellRS485. Il massimo bit rate raggiungibile di 1Mbit/s,
con estensione massima della rete di circa
100 m. Accontentandosi di velocit inferiori possibile coprire distanze maggiori
(ad esempio con 125 kbit/s si arriva a
500 m). In Tabella 1 sono riportati alcuni
esempi di estensioni massime della rete
rispetto alla velocit trasmissiva.
La tecnica trasmissiva del CAN usa un
modello basato su bit dominanti e recessivi, in cui i bit dominanti sono gli 0
logici ed i bit recessivi sono gli 1 logici. Se,
durante una trasmissione, il nodo A invia
un bit dominante e, contemporaneamente,
il nodo B invia un bit recessivo, allora il
bit dominante vince fra i due. Durante
la trasmissione, ogni nodo che sta trasmettendo verifica lo stato del bus e confronta il bit ricevuto con il bit trasmesso:
se viene rilevato un bit dominante quando
ne viene trasmesso uno recessivo, allora il
nodo che ha rilevato lerrore interrompe
la comunicazione.
Con questa tecnica, se due nodi iniziano
una trasmissione contemporaneamente,
essi si contendono luso esclusivo del bus
(arbitraggio) trasmettendo i propri dati,
bit dopo bit, finch uno dei due non rileva
un errore di trasmissione, autoescludendosi (si dice che il nodo in questione
perde larbitraggio) dal bus. Nella teoria
delle reti di comunicazione, un approccio di questo tipo definito CSMA/BA
(Carrier Sense Multiple Access/Bitwise
Arbitration).
Il protocollo CAN centralizzato sui
messaggi, che sono chiamati in genere
anche frames, identificati per mezzo di un
ID. Ogni nodo gestisce uno o pi frame
in ricezione e/o trasmissione, a seconda
dellarchitettura della network.

DE

128

Novembre 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 1 - Connessioni del componente


Extended CAN.

traggio, di gestione degli errori, di politiche di ritrasmissione, ecc. Il controller


dispone anche di buffer di trasmissione, di
ricezione e di maschere, che permettono di
configurare il set di messaggi in ricezione
e trasmissione, riducendo loverhead della
CPU del microcontrollore a cui interfacciato. Anche per i controller, esistono
diverse aziende produttrici al mondo; nel
nostro caso noi faremo uso del controller
della Microchip MCP2515.
Il componente CAN in Flowcode
Analizziamo adesso il componente
Flowcode che ci permette di semplificare
la gestione di uninterfaccia CAN nelle
nostre applicazioni. Flowcode dispone di
due componenti CAN, uno per la gestione
del base frame format (che si chiama semplicemente CAN) e uno per la gestione
dellextended format (chiamato Extended
CAN) quindi, se decidiamo di sviluppare
unapplicazione CAN, la prima scelta da
fare sar quella relativa al tipo di formato. Nella versione attuale dellambiente, i
controller interni sono supportati solo dal
componente che supporta il base format,
quindi se usiamo il componente extended
saremo vincolati alluso di un controller
SPI esterno. In questa puntata ci occuperemo del componente CAN Extended, e
quindi utilizzeremo il controller MCP2515
nelle nostre applicazioni.
Per inserire il componente CAN allinterno del nostro progetto Flowcode, sele-

Fig. 2 - Propriet extra del componente Extended CAN.

zioniamo il componente dalla barra dei


componenti, cliccando sulla voce Extended
CAN. Una volta inserito, licona relativa
al componente comparir sul pannello,
ed a questo punto possiamo configurarlo
per adattarlo alle esigenze del progetto
specifico.
Per prima cosa analizziamo le connessioni, che nel caso di questo componente si
riducono al pin di CS del controller CAN
(che un SPI slave). Possiamo accedere
alle connessioni cliccando con il tasto destro sullicona del componente e selezionando la voce Connessioni. Apparir la
finestra rappresentata in Fig. 1.
Per impostazione predefinita, il pin di CS
il pin 6 della porta C; se non c lesigenza di cambiarlo (ad esempio nel caso in
cui venga utilizzato lE-block CAN) pu
essere mantenuto cos. Per configurare il
componente clicchiamo con il tasto destro
sulla relativa icona e selezioniamo la voce
Propriet Extra. Comparir la finestra
di Fig. 2. Dalla prima scheda di questa finestra possibile selezionare le principali
opzioni di configurazione del bus, come il
baud-rate, il sample point ed altri ancora.
Questi parametri dipendono a loro volta
dalle caratteristiche proprie della rete,
come la sua estensione, il numero di nodi,
il bus load, ecc. I tab successivi permettono di configurare i vari buffer di ricezione e trasmissione. Nel progetto pratico,
vedremo un esempio di configurazione
dei buffer.

Elettronica In ~ Novembre 2013

129

Tabella 2 - Macro disponibili per il componente CAN.


Nome Macro

Descrizione

Init

Inizializza il componente CAN.

SendBuffer

Invia il messaggio contenuto allinterno del buffer di trasmissione (passato come parametro)

CheckRx

Controlla se ci sono messaggi ricevuti su un determinato buffer di ricezione (passato come parametro).

ShowLEDs

Controlla lo stato dei LED della EB018.

ReadSwitches

Legge lo stato degli switch della EB018.

GetRxDataCount

Riceve il conteggio dei byte del messaggio contenuto in un determinato buffer (passato come parametro).

GetRxData

Estrae un determinato byte dal messaggio presente in un determinato buffer di ricezione. Riceve come parametro
sia il buffer che lindice del byte.

SetTxStdID

Modifica lo standard ID di un determinato buffer di trasmissione (passato come parametro).

SetTxExtID

Modifica lextended ID di un determinato buffer di trasmissione (passato come parametro) come combinazione
dellID standard e dellID extended.

SetTxExtAsFull

Modifica lextended ID di un determinato buffer di trasmissione (passato come parametro).

GetRxStdID

Estrae un determinato byte di un determinato messaggio con ID standard. Vengono controllati tutti i buffer e viene
passato come parametro lindice del byte.

GetRxExtID

Estrae un determinato byte di un determinato messaggio con ID extended, visto come combinazione di un ID
standard e di un ID extended.. Vengono controllati tutti i buffer e viene passato come parametro lindice del byte.

GetRxExtIDAsFull

Estrae un determinato byte di un determinato messaggio con ID extended.. Vengono controllati tutti i buffer e
viene passato come parametro lindice del byte.

Ora, come di consueto, procediamo con


lanalisi delle macro messe a disposizione
da questo componente, che trovate riepilogate nella Tabella 2.

Nodo Sensore:
Interfacciamento con sensore ad
ultrasuoni SFR02, su bus IC;
Interfaccia CAN 2.0B a 500 kbaud;

Nodo Display:
Interfacciamento con display alfanumerico 16x2;
Interfaccia CAN 2.0B a 500 kbaud;
Lettura e visualizzazione dei dati sulla
distanza;
Lettura e visualizzazione dei dati diagnostici;
Gestione della modalit sleep tramite
pulsante.
Sebbene il CAN sia nativamente una rete
peer-to-peer, possibile forzare delle
relazioni di tipo master/slave, agendo a
livello dellapplicazione; ci che faremo
in questo esempio, dove il nodo display
agisce da nodo master (pu mettere a
dormire lo slave nodo sensore), inviando un messaggio apposito per forzare lo
stato di sleep, in modo da disabilitare il
sistema durante le fasi di guida ed abilitarlo in fase di parcheggio.
Per quanto riguarda la realizzazione
hardware, in questo progetto avremo
bisogno delle seguenti schede:

cors
o
F
L
O
W
CO

Progetto pratico: sensore di parcheggio


Passiamo adesso al progetto pratico relativo a questa puntata. Come abbiamo gi
accennato, abbiamo pensato di realizzare
un progetto pratico un po pi impegnativo, proprio per evidenziare le potenzialit
di rapid development offerte da flowcode,
che permette la realizzazione di progetti
anche piuttosto complessi in tempi ridottissimi e con un ottimo risultato finale.
Nel caso specifico ci cimentiamo nella
realizzazione di un prototipo di sensore
di parcheggio per auto, costituito da due
nodi: un nodo sensore ed un nodo display,
collegati tra di loro tramite bus CAN.
Quindi realizzeremo due progetti Flowcode distinti, che utilizzeremo per generare
gli eseguibili binari con cui programmare
le due schede. Come di consueto, analizziamo le specifiche di progetto, in questo
caso raggruppate per nodo.

Invio dati sulla distanza espressa in cm;


Autodiagnosi su stato batteria e stato
link I2C con il sensore;
Modalit sleep attivabile tramite messaggio da nodo display.

DE

130

Novembre 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 3a
Prototipo del nodo sensore.

- 2x EB006 USB PICmicro multiprogrammer board (PIC18F4580 e quarzo da


12MHz);
- 2x EB018 CAN bus Board;
- 1x EB005 LCD board;
- 1x EB016 Prototypeboard.
Non disponendo di un e-block specifico,
per interfacciare lSRF02 ci serviremo,
come gi fatto in passato, della EB016, che
colleghiamo sulle porte A e B. Posizioniamo lSRF02 sulla breadboard e colleghiamo i terminali di alimentazione e quelli
di comunicazione SDA ed SCK del bus.
Non potendo utilizzare la porta hardware
IC (perch, per interfacciare lMCP2515
usiamo la MSSP in modalit SPI), emuliamo il collegamento I2C a livello software,
e quindi usiamo RB0 ed RB1, rispettivamente per SCK ed SDA. Oltre allSRF02,
sulla EB016

dobbiamo posizionare anche un partitore


di tensione con rapporto di partizione 1:4,
allo scopo di leggere lo stato della batteria, che colleghiamo allingresso analogico
An0. Completiamo il nodo sensore collegando la EB018 sulla porta C.
Per il nodo display, colleghiamo la EB018
sulla porta C e la EB005 sulla porta B.
Per entrambi i nodi, limpostazione dei
jumper della EB018 la seguente:
J4 su A;
J5 inserito;
J6 e J7 disinseriti.

Fig. 3b
Prototipo del
nodo display.

Poi, assicuriamoci di chiudere su entrambe le schede J8, in modo da terminare la


linea da entrambi i lati e collegare i cavetti
per lalimentazione.

Elettronica In ~ Novembre 2013

131

Tabella 3a - Caratteristiche messaggio 0xC40A5.


ID

0xC40A5

Type

Periodico

Tx

Nodo_Sensore

Rx

Nodo_Display

Periodo

250ms

Byte 0

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

DistHighByte

DistLowByte

DiagSts

Not Used

Not Used

Not Used

Not Used

Not Used

Distanza in cm

0 = No fail
1 = Battery fail
2 = IC fail
3 = Mult. fail

Tabella 3b - Caratteristiche messaggio 0xC40A4.


ID

0xC40A4

Type

Ad evento

Tx

Nodo_Display

Rx

Nodo_Sensore

Periodo

NA

Byte 0

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

SystemSts

Not Used

Not Used

Not Used

Not Used

Not Used

Not Used

Not Used

0 = Sleep Mode
1 = Awake Mode

La configurazione hardware dei due nodi


riportata nelle Fig. 3a e Fig. 3b.
Mappa Messaggi
Prima di passare ai dettagli software analizziamo un punto fondamentale di ogni
rete basata su protocollo CAN, ossia la
mappa messaggi: in un CAN Bus, essa
il documento che descrive le principali caratteristiche dei messaggi che si scambiano i vari nodi allinterno della network.
In questo documento sono indicati le
tipologie dei messaggi, i relativi indirizzi,
il significato dei byte che li compongono,
quali nodi trasmettono e quali sono i destinatari di ogni singolo messaggio.
Nel nostro caso, abbiamo un totale di due
messaggi, uno trasmesso dal nodo sensore e ricevuto dal nodo display, ed uno che
transita nel verso opposto.
In Tabella 3a e Tabella 3b sono riporta-

te le caratteristiche dei due messaggi.


Passiamo ora alla descrizione dellimplementazione software, con la premessa
che, data la complessit del progetto, la
descrizione di alcune parti non fondamentali verr omessa o sar trattata solo
marginalmente.
Nodo Sensore
Secondo le specifiche, questo nodo deve
acquisire i dati relativi alla distanza dal
sensore ad ultrasuoni, effettuare lautodiagnosi su livello batteria e stato del bus
IC e comunicare queste informazioni al
nodo master tramite messaggio CAN.

Task

Periodo [ms}

Descrizione

CanTxTask

250

Gestisce la trasmissione del


messaggio CAN del nodo
sensore.

CanRxTask

50

Gestisce la ricezione del messaggio CAN dal nodo display.

DiagTask

50

Gestisce la diagnostica del


sistema.

SensorRangingTask

10

Gestisce la comunicazione
con il sensore ad ultrasuoni
SRF02.

Fig. 4
Main del progetto
in Flowcode.

cors
o
F
L
O
W
CO

Tabella 4 - Periodicit e descrizione dei task


del software del nodo sensore.

DE

132

Novembre 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 5 - Configurazione dellinterrupt del timer2.

Per configurare linterrupt clicchiamo due


volte allinterno del blocco, in modo da
accedere alle finestre di configurazione,
riportata in Fig. 5.
In questa finestra selezioniamo lopzione Abilita Interrupt, e tra le sorgenti
del menu a tendina selezioniamo la
voce TMR2. Poi, nella sezione Verr
chiamata la macro, inseriamo la macro

Fig. 6 - Impostazione dei registri del timer 2.

Deve inoltre essere gestita una modalit


sleep, su richiesta del nodo master.
Per cominciare, esaminiamo limpostazione dellarchitettura di base del sistema. Il
firmware in questione ha diversi task da
eseguire in maniera simultanea; scegliamo
quindi di servirci di uno scheduler per
gestire le chiamate ai vari task. Decidiamo di generare uno scheduler con un tick
a 10ms e di generare le altre periodicit
attraverso dei contatori incrementati ad
ogni tick di sistema. In Tabella 4 sono
riportati i task gestiti con le descrizioni e le
relative periodicit. Per la generazione del
tick base di sistema (sul quale basato il
funzionamento dello scheduler), ci serviamo di un interrupt sul timer 2. Come detto
nella seconda puntata di questo corso, per
inserire un blocco interrupt trasciniamo
dalla barra delle icone un blocco interrupt
allinterno del nostro main, come visibile
in Fig. 4 (nello schema a blocchi gi stata
effettuata la chiamata alla funzione di inizializzazione per i componenti utilizzati).

Fig. 7 - System scheduler.

Elettronica In ~ Novembre 2013

133

Tabella 5 - Registri interni del sensore SRF02


in modalit I2C.
Locazione
di memoria

Accesso
in lettura

Accesso
in scrittura

Software Revision

Command Register

Unused (reads 0x80)

N/A

Range High Byte

N/A

Range Low Byte

N/A

Autotune Minimum - High Byte

N/A

Autotune Minimum - Low Byte

N/A

MainScheduler (che possiamo creare al


momento o aver gi creato in precedenza). In questo modo, ad ogni occorrenza
dellinterrupt verremo indirizzati alla
macro contenente lo scheduler di sistema.
Non ci rimane che impostare il timer per
avere il tick di sistema a 10ms; allo scopo,
clicchiamo sul tasto Propriet... Si aprir la finestra di Fig. 6.
Per avere un interrupt ogni 10ms occorre
generare una frequenza di circa 100Hz,
per ottenere la quale, con un sistema che
gira a 12MHz, selezioniamo un prescaler
di 16, un postscaler di 8 e un rollover di
234. Clicchiamo su OK e procediamo.
Ora abbiamo il nostro tick di sistema
configurato; ci che rimane da fare
generare il codice dello scheduler in
modo da avere le periodicit elencate in
Tabella 3 (a e b). Per farlo, generiamo tre
variabili globali, ossia CanRxTaskCounter,
CanTxTaskCounter e DiagTxTaskCounter,
che utilizzeremo come contatori per determinare le periodicit dei task a partire
Tabella 6 - Set di comandi dellSRF02.
Comando (Hex)

Descrizione

0x50

Esecuzione di un ranging risultato in pollici.


Esecuzione di un ranging risultato in cm.
Esecuzione di un ranging risultato in microsecondi.

0x56

Esecuzione di un fake ranging risultato in pollici.

0x57

Esecuzione di un fake ranging risultato in cm.

0x58

Esecuzione di un fake ranging risultato in


microsecondi.

0x5C

Trasmissione di 8 cicli a 40kHz (ultrasonic burst).

Come si pu vedere, il task CanRx non


vincolato alla variabile SystemStatus
per garantire la possibilit di risvegliare
il sistema tramite messaggio CAN, ed il
task SensorRanging non ha un contatore
per la periodicit, in quanto il periodo di
chiamata di questo task proprio 10ms.
Analizziamo adesso come stata implementata la lettura del sensore ad
ultrasuoni: per interfacciarsi con il dispositivo che lo utilizza, lSRF02 ha la capacit di utilizzare sia linterfaccia seriale
che lI2C. Nel nostro caso, come interfaccia
di comunicazione abbiamo scelto lI2C.

Tabella 7 - Macro scritte per la gestione dellSRF02.


Nome Macro

Descrizione

Sensor_SendCommand

Invia al dispositivo con indirizzo 0xE0 il comando 0x51 in scrittura.

Sensor_RequestReadResult

Invia al dispositivo con indirizzo 0xE0 la richiesta di lettura a partire dallindirizzo 2.

Sensor_ReadResult

Legge i byte allindirizzo 2 (Range High Byte) e 3 (Range Low Byte) e chiude la transazione.

cors
o
F
L
O
W
CO

0x51
0x52

dal tick base di sistema. Ricordiamoci che


alcuni task sono vincolati ad andare in
sleep su richiesta del nodo master, quindi
in questa condizione non devono essere
eseguiti. Per implementare tale caratteristica creiamo una variabile globale che
chiamiamo SystemStatus (essa pu assumere due valori: SYSTEM_ACTIVE e SYSTEM_NOT_ACTIVE), che sar, insieme
alla periodicit, una delle condizioni di
attivazione della chiamata al task. Lunico task che non controllato da questa
variabile CanRx, usato per consentire il
risveglio del sistema da messaggio CAN.
Limplementazione dello scheduler (senza
le chiamate ai task per il momento) descritta nella Fig. 7.
I contatori sono incrementati ad ogni ciclo
e le condizioni di attivazione dei vari task
(allinterno dei blocchi decisione) sono:
- CanRx CanRxTaskCounter >=
TASK_CAN_RX_TIMEOUT;
- CanTx (CanTxTaskCounter >=
TASK_CAN_TX_TIMEOUT) && (SystemStatus = SYSTEM_ACTIVE);
- Diag (DiagTxTaskCounter >=
TASK_DIAG_TIMEOUT) && (SystemStatus = SYSTEM_ACTIVE);
- SensorRanging SystemStatus = SYSTEM_ACTIVE.

DE

134

Novembre 2013 ~ Elettronica In

corso F L O
WCOD

Fig. 8
Macro SensorRangingStateMachine.

Nel caso di interfacciamento di tipo I2C,


lSRF02 funziona in modo molto simile
ad una memoria EEPROM della famiglia
24xx: il dispositivo si presenta come un
set di registri con accesso in lettura o in
scrittura, come riassunto dalla Tabella 5.
Laccesso in scrittura alla locazione 0
permette di eseguire una delle operazioni
riportate in Tabella 6 (sono riportati solo i
comandi principali).
Nel nostro caso utilizziamo i comandi di
ranging, che eseguono sia loperazione
di invio del burst ad ultrasuoni che la
successiva rilevazione del tempo di volo
delleco ed il conseguente calcolo della
distanza. In questo caso il risultato del
ranging viene salvato nei registri 2 e 3
(Range High Byte e Range Low Byte), dai
quali pu successivamente essere recuperato con unoperazione di lettura. Oltre al
comando, sul bus deve essere inviato lindirizzo del dispositivo (quello predefinito
in caso di interfaccia I2C 0xE0) ed il bit
di read/write. Quindi, per ogni trasmissione viene inviato un totale di due byte.
La procedura per ottenere il dato sulla
distanza la seguente:
1) invio del comando 0x51 in scrittura (ri-

Fig. 9a - Tab general della finestra di


configurazione del componente CAN.

chiesta di ranging con risultato in cm);


2) invio dellindirizzo del registro contenente il risultato in lettura;
3) ricezione dei due byte del registro
contenente il risultato.
Per realizzare queste tre operazione sono
state scritte tre macro, riportate nella
Tabella 7.
Queste macro sono utilizzate dalla macro
SensorRangingStateMachine, che viene
chiamata dallo scheduler principale e
che fornisce, come output per il resto del
sistema, la variabile globale SensorResult
pi alcune informazioni sulla diagnostica
del collegamento IC. In Fig. 8 riportato
il diagramma a blocchi Flowcode della
macro SensorRangingStateMachine.
Questo flowchart implementa una macchina a stati che esegue in sequenza e
con le corrette temporizzazioni le tre
macro riportate in Tabella 6, in modo
da ottenere il risultato del ranging. Per
farlo, viene utilizzato il contatore SensorRangingCounter, incrementato ad ogni
ciclo (ricordiamo che la macro chiamata
direttamente dallo scheduler principale,
quindi ha un tempo di chiamata di 10ms).

Fig. 9b - Tab tx buffer 0 della finestra


di configurazione del componente CAN.

Fig. 9C - Tab rx buffer 0 della finestra


di configurazione del componente CAN.

Elettronica In ~ Novembre 2013

135

Fig. 10
Propriet della macro SetTxData
del componente CAN.

La prima macro chiamata la Sensor_


SendCommand (dopo 10ms dallavvio
della macchina a stati). La seconda chiamata avviene dopo 250ms (ossia quando
il contatore raggiunge il valore della
constante TIMING_REQ_READ, pari a
25) e viene chiamata la macro Sensor_RequestReadResult. Il ritardo di 250ms serve
a fare in modo che lSRF02 riceva leco
del burst ad ultrasuoni inviato in seguito
alla ricezione del comando 0x51 e faccia
i necessari calcoli. A questo punto, dopo
altri 100ms viene letto il contenuto dei
registri contenenti il risultato, tramite
la macro Sensor_ReadResult (contatore
uguale a TIMING_READ_RESULT, pari a
35). Infine, dopo altri 150ms la macchina a
stati si resetta (semplicemente resettando
il contatore) e il ciclo ricomincia dal punto
di partenza. In questo modo si ottiene

un aggiornamento della posizione ogni


500ms circa.
Ora che abbiamo compreso la gestione del
sensore ad ultrasuoni, esaminiamo come
vengono inviati i dati al nodo master tramite il bus CAN. Per prima cosa dobbiamo configurare correttamente il componente, quindi accediamo alla finestra
delle propriet extra. Nel tab principale
inseriamo i settaggi principali, selezionando un bau-rate di 500kB, un sample point
dell80% e SJW pari a 1. Passiamo adesso
al tab TX Buffer 0, dove, nella sezione
frame Identifier, selezioniamo Extended
Frame ed inseriamo nella casella Full
ID lindirizzo 0xC40A5, come riportato
nella mappa messaggi. Infine passiamo
sul tab RX Buffer 0 e impostiamo un filtro
in ricezione, selezionando la spunta Message ID 0 ed inserendo il seguente ID
nella relativa casella Full ID: 0xC40A4.
La configurazione, riportata per comodit
in Fig. 9 (a, b e c) cos completata.
A questo punto possiamo inserire, allinterno del nostro scheduler, il codice
Flowcode per linvio del messaggio contente i dati di distanza e di diagnosi (ID
0xC40A5). Linvio si compone di due macro componente: per prima cosa usiamo
la macro SetTxData, per riempire correttamente il messaggio in trasmissione; tale
macro prende come parametri il buffer di
trasmissione utilizzato, il numero di byte

cors
o
F
L
O
W
CO

Fig. 12
Codice grafico
per la ricezione del
messaggio CAN.

Fig. 11
Codice grafico per linvio del
messaggio CAN.

DE

136

Novembre 2013 ~ Elettronica In

corso F L O
WCOD

Tabella 8 - Periodicit e descrizione dei task del software del nodo display.
Task

Periodo [ms]

Descrizione
Riceve e decodifica il messaggio CAN proveniente dal nodo sensore.

CanRxTask

500

DisplayTask

500

Visualizza i dati decodificati dal task CanRxTask.

SwitchTask

200

Legge lo stato del pulsante ed invia il relativo messaggio CAN ad evento per il nodo sensore.

da inviare (DLC) e gli 8 byte del messaggio. I dati da inviare sono le seguenti
variabili globali:
- SensorResultHighByte Byte 0;
- SensorResultLowByte Byte 1;
- SensorDiagStatus Byte 2.
Le prime due variabili sono ricavate
dalla macro SensorRangingStateMachine,
mentre la variabile SensorDiagStatus
calcolata (e codificata come indicato nella
mappa messaggi) dalla macro DiagnosticTask. In Fig. 10 riportata la finestra
di propriet della chiamata alla macro
componente.
Una volta riempito correttamente il messaggio in trasmissione, per inviare il messaggio sufficiente chiamare la macro
SendBuffer e passare il buffer di trasmissione. In Fig. 11 riportato il frammento
di codice grafico, cos come appare dopo
linserimento delle chiamate alle macro
del componente CAN.
A questo punto la nostra applicazione
lato nodo sensore quasi completa;
rimane da gestire lingresso/uscita dalla
modalit sleep controllata dal messaggio
CAN inviato dal nodo display. Analizzando la mappa messaggi, si vede che
il parametro che determina lo stato del
sistema (sleep o awake) viene impostato dal byte 0 del messaggio con ID
0xC40A4. Bisogna quindi gestire un task
di ricezione allinterno del quale viene
letto questo byte e viene aggiornata una
variabile che usiamo per identificare lo
stato del sistema. Il nostro scheduler ci
offre gi un entry point per la ricezione a
50ms; per completare il codice, introduciamo due chiamate a macro di componente, ed in particolare una CheckRx ed
una GetRxData, entrambe sul buffer 0. Il
risultato della GetRxData viene salvato
allinterno della variabile SystemStatus,
la quale, come abbiamo visto in prece-

denza, controlla lesecuzione di tutti


i task (ad eccezione proprio del task
CanRx). Il frammento di codice grafico
che realizza quanto descritto riportato
in Fig. 12.
Nodo Display
La descrizione del software del nodo
sensore ultimata; passiamo adesso al
nodo display, che eredita molti concetti
del nodo sensore, come ad esempio lo
scheduler (che praticamente identico).
La funzione del nodo display ricevere
il messaggio periodico inviato dal nodo
sensore e visualizzare le relative informazioni sul display LCD. Inoltre il nodo
che pu mandare in sleep o risvegliare
linterno sistema, rilevando la pressione
di un tasto sulla EB018. Il software del
nodo display composto da tre task principali, elencati in Tabella 8.
La filosofia di gestione del sistema
molto simile a quanto visto per il nodo
precedente. A titolo di esempio, descriviamo come viene implementato il task
CanRxTask; questo task ha il compito di
ricevere e decodificare il messaggio con
ID 0xC40A5, proveniente dal nodo sensore. Per prima cosa stato configurato
il componente CAN in maniera analoga
a quanto fatto per il nodo sensore, con
la differenza che lID del messaggio in
trasmissione in questo caso 0xC40A4,
mentre il filtro di ricezione viene impostato sullID 0xC40A5. La ricezione avviene in maniera analoga a quanto visto
nel caso precedente; in particolare, viene
chiamata la CheckRx e per tre volte la GetRxData, per acquisire i due byte di dati
che costituiscono linformazione sulla
distanza ed il byte contenente le informazioni diagnostiche. Infine, il byte 0 ed il
byte 1 del messaggio vengono compattati
in una word, tramite il seguente codice
inserito in un blocco calcolo:

Elettronica In ~ Novembre 2013

137

Fig. 13
Codice grafico
che implementa il
task CanRxTask.

ad analizzare il progetto Flowcode e


cercare di capirne il funzionamento.
A questo punto possiamo anche testare
il nostro sistema, collegando tra di loro i
due nodi con un doppino intrecciato ed
alimentando il sistema con una tensione
di circa 12V.
Sul nodo display vedremo apparire le
informazioni sulla distanza dal sensore
ad ultrasuoni ricevute dal nodo sensore.
In Fig. 14 riportato un tracciato CAN
dellinterscambio di messaggi tra i due
nodi, eseguito usando il CAN Analyzer
Microchip.
Come si pu vedere, il messaggio del
nodo sensore invia sul bus una distanza
rilevata di circa 317 cm (byte 0-1 pari a
0x13D) ed una diagnosi senza fault attivi
(byte 2 pari a 0x00). Alla ricezione della
richiesta di sleep (byte 0 del messaggio
0xC40A4 pari a 0), il sistema interrompe
la trasmissione.
SensorData = ((SensorDataHigh << 8) | SensorDataLow)
Lo schema a blocchi che implementa
quanto descritto in precedenza riportato in Fig. 13.
I task per la gestione del display e per la
lettura del tasto di sleep non presentano
particolarit implementative di rilievo e
non saranno trattati nel dettaglio in questa puntata; vi invitiamo, come esercizio,

Conclusioni
Concludendo questa puntata, possiamo
dire che lapproccio al CAN con Flowcode permette di gestire diverse tipologie
di componenti e periferiche con relativa semplicit, oltre a generare codice
estremamente facile da comprendere e
mantenere.
Nelle prossime puntate esamineremo
altre periferiche complesse, come lUSB,
g
lo ZigBee e la porta Ethernet.

cors
o
F
L
O
W
CO

Fig. 14 - Tracciato CAN del sistema durante in funzionamento fino alla ricezione di una richiesta di sleep.

DE

138

Novembre 2013 ~ Elettronica In

corso F L O
WCOD

Proseguiamo il nostro
viaggio alla scoperta di
Flowcode, affrontando
la gestione dellUSB
e realizzando un
convertitore seriale
RS232-USB, oltre ad un
tastierino numerico e ad
un analizzatore di stati
logici, sempre su USB.
Sesta puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

elle scorse puntate abbiamo parlato


del bus di comunicazione avanzato
CAN ed imparato a gestirlo in modo
semplice e intuitivo grazie a Flowcode. In
questa puntata faremo altrettanto con il bus
USB, spiegando come funziona la comunicazione, in che modo si possa convertire
un progetto RS232 in una periferica USB in
pochi semplici passi e realizzeremo due tipi
differenti di periferiche, ovvero una tastiera
numerica per il PC e un analizzatore di stati
logici.
La porta USB
Linterfaccia maggiormente utilizzata oggigiorno per la comunicazione tra

Personal Computer e periferiche il bus


USB. Esso ha sostituito praticamente tutte
le altre precedenti interfacce sia seriali che
parallele perch permette di trasferire dati
ad una velocit molto elevata e collegare
molti dispositivi (teoricamente fino a 127)
ad ununica porta, mediante uno o pi
hub eventualmente disposti in cascata.
Altra caratteristica fondamentale dellUSB
la possibilit di collegare e rimuovere i
dispositivi senza dover riavviare il computer, il che fa del bus un vero Plug&Play. I
dispositivi collegati possono essere alimentati direttamente dal bus o, qualora richiedano correnti superiori a 500 mA (il limite
erogabile da una porta USB; se si connetto-

Elettronica In ~ Dicembre 2013 / Gennaio 2014

115

Fig. 1
Struttura
di un
pacchetto
trasmesso
sul bus
USB.

Lo standard 3.0 prevede il raddoppio delle


connessioni dati in modo da poter avere
due linee per la ricezione dei dati ad altrettante dedicate unicamente alla trasmissione.
I dati sono trasmessi in modo pseudo-differenziale perch la linea D- ha come valore
lopposto della linea D+, ma ci non vero
nel caso dellidentificatore del termine
pacchetto.
NellUSB, la codifica di tipo NRZ ed il valore zero provoca linversione del valore logico trasmesso. Il segnale di clock trasmesso in modo implicito durante linvio dei dati
perci, per evitare che il bus stia fermo allo
stesso valore per troppo tempo, dopo 6 bit
consecutivi di valore 1 viene trasmesso un
bit aggiuntivo di valore zero.
La comunicazione fisica suddivisa in tre
parti principali:
Pacchetto di start: Viene inviata la sequenza di sincronizzazione 00000001. Nel
caso di pacchetti pi grandi la sequenza
di sincronizzazione di 32bit;
Pacchetto di dato: La lunghezza dipende
dal tipo di connessione, da 1 a 1024 byte,
ed il primo bit trasmesso quello meno
significativo;
Pacchetto di Stop: Viene trasmessa una
sequenza non differenziale in cui entrambi i segnali restano al valore logico basso
per due cicli e poi il segnale D+ torna al
valore logico alto.
In Fig. 1 mostrato un esempio di trasmissione dati sul bus USB nel quale possiamo
identificare le tre parti principali nel quale
suddiviso, la codifica NRZ ed il frame di
stop.
Lo standard USB prevede la classificazione
delle periferiche in classi in modo da facilitare la gestione ed identificazione dei necessari driver; in questo modo i dispositivi
standard come mouse, tastiere e memorie,
non richiedono linstallazione di driver e
sono quindi subito pronti alluso.

cors
o
F
L
O
W
CO

no pi dispositivi, devono spartirsi questa


corrente), devono avere una connessione di
alimentazione a parte.
Lo standard USB 1.0 nacque nel 1996 e
consentiva una velocit di connessione pari
a 1,5 Mbit/s; le successive versioni offrono
velocit di comunicazione maggiori: per
esempio la 1.1 permette di raggiungere i 12
Mbit/s), la 2.0 i 480 Mbit/s e la pi recente
3.0 permette una velocit massima di 4.8
Gbit/s. Mentre dalla prima versione alla 2.0
la connessione rimasta invariata (quattro
contatti) con la 3.0 stato introdotto un
nuovo connettore che ha i contatti sdoppiati
e di fatto prevede un doppio canale dati; la
connessione rimane comunque compatibile
con le vecchie, in quanto una fila di contatti
tocca quelli dello spinotto tradizionale.
Esistono differenti connettori fisici che
permettono la connessione al bus USB:
A, B, mini e micro. Dal 2011 il connettore
micro-USB diventato la porta standard di
comunicazione con tutti i sistemi cellulari,
ma con lavvento degli smartphone sorta
la necessit di sviluppare un protocollo che
permetta di decidere allatto della connessione quale dispositivo diventa il master
e quale lo slave. La soluzione al problema
si chiama USB-On-The-Go e permette di
impostare, allatto della connessione, quale
dei due dispositivi il master e quale lo
slave. Questo accorgimento fa in modo, ad
esempio, che uno smartphone possa essere
visto come uno slave se connesso ad un PC
o come master nel caso sia connesso ad una
periferica di archiviazione di massa come
un hard-disk. Vediamo ora quali connessioni sono disponibili su un connettore USBmini/micro:
VBUS; permette di alimentare le periferiche erogando 5V stabilizzati e una
corrente massima di 500mA;
GND; la massa di riferimento per i
segnali e lalimentazione;
D-; dato -;
D+; dato +;

ID: identifica se il dispositivo funziona


da controllore (master) o periferica (slave); nel connettore di tipo A collegato a
GND per fare in modo che il dispositivo
collegato alla porta mini/micro debba
funzionare da periferica.

DE

116

Dicembre 2013 / Gennaio 2014 ~ Elettronica In

corso F L O
WCOD

Passiamo ora a scoprire come dotare un


nostro progetto di una connessione USB
in modo molto semplice e rapido senza
neppure dover rigenerare il codice del
microcontrollore.
Il chip FT232BL
Il metodo probabilmente pi semplice per
gestire periferiche usare la porta seriale:
ci, sia per la semplicit del firmware da
caricare nel micro che governa la periferica,
sia per il software di gestione lato personal
computer. Il problema che attualmente
pochi PC hanno ancora il connettore DB9
della COM e i notebook non lhanno pi da
tempo. Per questa ragione possiamo realizzare la periferica gestendo unicamente
la connessione RS232 ed utilizzando un
componente che si occupi della conversione
di protocollo da RS232 ad USB. In questo

Fig. 3
Connessioni
progetto convertito
da seriale in USB.

modo vedremo dal punto di vista del PC


una seriale che potremo gestire normalmente con il microcontrollore che ricever
i dati attraverso la seriale senza doversi
occupare della complessa gestione del bus
USB. Questa metodologia di lavoro molto
funzionale ed utilizzata soprattutto per la
rigenerazione di vecchi progetti perch non
richiede la modifica del codice sorgente.

Per far ci possiamo avvalerci del componente FT232BL fornito dalla FTDI Chip, che
si accoller tutte le procedure di gestione
del protocollo USB. In Fig. 2 mostrato lo
schema ed il pin-out.
Nel seguente progetto pratico esamineremo nel dettaglio come trasformare il
progetto realizzato nella 4 puntata per il
controllo di una batteria di rel rendendolo
utilizzabile anche su computer sprovvisti
di connettore DB9.
Progetto pratico:
convertire da RS232 a USB
Questo semplice esempio ci permetter di
capire in modo approfondito come dotare
di una pseudo-connessione USB un progetto basato unicamente su una connessione
RS232 senza dover modificare radicalmente
il codice sorgente.

Elettronica In ~ Dicembre 2013 / Gennaio 2014

117

Fig. 2
Piedinatura
e schema di
riferimento per
il componente
FT232BL
di FTDI.

Fig. 4 - Nuova configurazione


componente RS232.

automaticamente le seriali virtuali eventualmente connesse al PC.

I componenti necessari per la realizzazione


sono i seguenti:
EB006 USB PICmicromultiprogrammerboard (PIC18F4580 e quarzo 12MHz);
EB038 Relay Board;
EB039USB232 Board.

Dicembre 2013 / Gennaio 2014 ~ Elettronica In

Il componente USB-HID
contenuto allinterno della barra dei
componenti nel sotto-menu periferiche e
permette di gestire un dispositivo di tipo
Human interface device. Dopo aver inserito il componente allinterno del pannello
possiamo esaminare le propriet del componente. Essendo abbastanza complesso,
a differenza degli altri componenti pi
semplici, necessita di tre pagine di configurazione. Iniziamo ad analizzare la prima,
illustrata nella Fig. 5.
Il parametro VID il cosiddetto VendorIdentifier ed , in pratica, lidentificativo
univoco del venditore della periferica;
viene assegnato a fronte del pagamento

DE

118

La scelta di uno tra i sopraelencati tipi


dipende dalla funzionalit che la nostra
periferica implementa. La pi semplice
e intuitiva da utilizzare quella di tipo
seriale perch vista dal calcolatore come
una semplice porta COM, come per il caso
del chip della FTDI che abbiamo precedentemente utilizzato, ed i comandi che
abbiamo a disposizione dal punto di vista
del microcontrollore sono quelli standard
di una comunicazione seriale limitandosi
allinvio e alla ricezione di caratteri e stringhe. Se volessimo realizzare un mouse o
comunque un dispositivo standard di input
dovremmo scegliere il tipo HID, in modo
da poterlo utilizzare senza dover installare
alcun driver aggiuntivo mentre negli altri
casi dovremmo avvalerci del tipo slave.

cors
o
F
L
O
W
CO

La scheda EB039 sostituisce la EB015 sulla


porta C (Fig. 3) ed al posto della connessione di uscita su DB9 presente la porta USB
di tipo B.
Le modifiche, a parte quelle allhardware,
sono davvero poche. Vediamo dunque
come realizzare il nostro progetto passo
passo: apriamo il progetto RS232.fcf, che
avevamo salvato al termine della 4^ puntata, e modifichiamo le impostazioni del
componente RS232 come mostrato in Fig. 4.
La connessione RS232 deve essere impostata a 9.600 baud, 8bit e il controllo di flusso
deve essere gestito mediante il pin RTS sulla
porta C0 e il pin CTS sulla porta C4. Ricompiliamo il progetto e ricarichiamo il tutto
sulla scheda di sviluppo, per vederne i risultati. Collegando il connettore USB tipo B,
mediante un cavo, al connettore USB tipo A
del nostro PC, il sistema operativo rilever
un nuovo hardware, corrispondente al componente FTDI, del quale dovremo installare
il driver come indicato nel box installiamo
il driver del componente FTDI. Per questa
variante del progetto stata aggiornata linterfaccia software presentata a corredo della
4 puntata , permettendone lutilizzo anche
con una porta COM virtuale.
Il funzionamento rimane sostanzialmente invariato, con la differenza che ora la
selezione della porta di comunicazione
viene fatta tramite una combo box che rileva

Il componente USB in Flowcode


Flowcode permette di utilizzare principalmente tre tipi di configurazione per il bus
USB:
Serial; permette di gestire la porta USB
come se fosse una normale connessione
seriale;
HID; permette di creare un dispositivo
di tipo Human interface devicecome
ad esempio un mouse, una tastiera, un
joystick, ecc.;
Slave; permette di creare un dispositivo custom.

Tabella 1

corso F L O
WCOD

Nome macro

Fig. 5

Descrizione

RetVal = Initialise_HID()

utilizzata per inizializzare il driver USB per la comunicazione ed attivare il servizio di enumerazione delle periferiche. Restituisce zero se la procedura termina senza errori.

SetDataByte(idx, value)

utilizzata per scrivere uno specifico byte sul vettore che verr inviato via USB. In ingresso
necessita dellindice del byte da scrivere ed il valore che si vuole scrivere. Questa macro non
invia fisicamente i dati ma li immagazzina nel buffer di trasmissione senza trasmetterli.

SendData()

Quando viene chiamata trasmette sul bus USB i dati che sono stati caricati nel buffer dalla
funzione SetDataByte.

SendDataDirect(String)

Invia i dati contenuti allinterno della stringa passata come parametro sul bus USB.

NumBytes =CheckRx()

Aggiorna i dati che sono stati ricevuti dal canale USB. Restituisce la lunghezza dei dati
presenti allinterno del buffer.

Value = ReceiveByte(idx)

utilizzata per leggere un byte indentificato dallindice passato come parametro dal buffer di
lettura dei dati ricevuti. Il primo dato identificato dellindice zero.

String =ReceiveString(NumBytes)

utilizzata per leggere lintera stringa ricevuta sul bus USB. Richiede che gli sia passato come
parametro il numero di byte da leggere e caricare sulla stringa restituita dalla funzione.

della quota associativa al consorzio USB.


Coloro che producono in grandi quantit
dispositivi USB hanno un loro VID, mentre
le piccole aziende e gli hobbisti possono utilizzare il VID del costruttore del chip, che
nel nostro caso quello della Microchip.
Per luso personale del dispositivo realizzato, non necessario avere un VID valido.
Il parametro PID lidentificativo del
dispositivo realizzato. A fronte dellacquisto di un VID possiamo quindi avere a
disposizione 65.535 differenti prodotti. Se
volessimo vendere piccole/medie quantit
di dispositivi USB potremmo domandare
alla Microchip, mediante un particolare
richiesta scritta disponibile sul sito www.
microchip.com, lautorizzazione ad utilizzarne uno.
Allinterno del campo Name e Manufacturer possiamo inserire il nome della nostra
applicazione ed il nostro nome mentre
come versione indichiamo 1.0.

In Fig. 6 vediamo le altre configurazioni


specifiche al dispositivo che intendiamo realizzare. I parametri principali che dobbiamo impostare sono:
Maximum current; corrente massima
che il dispositivo abilitato ad assorbire tramite la tensione di alimentazione
dellUSB;
Transmitpacketsize; dimensione dei pacchetti trasmessi al computer dal dispositivo durante linterrupt sul bus;
Transmitpacketperiod; numero di
millisecondi che intercorrono tra due
trasmissioni di dati;
Receivepacketsize; dimensione dei
pacchetti ricevuti dal dispositivo durante
linterrupt del bus;
Receivepacketperiod; numero di
millisecondi che intercorrono tra due
ricezioni di dati;
Subclass; la sottoclasse dei dispositivi
USB ed valida unicamente per mouse e

Elettronica In ~ Dicembre 2013 / Gennaio 2014

119

Fig. 6

Fig. 7

tastiere (HID);
Interface; utilizzata per definire la
classe del dispositivo.
Il tab HID Descriptor visibile in Fig. 7
permette di descrivere in modo dettagliato
la comunicazione ed il significato di ogni
singolo byte trasmesso. La descrizione dei
dispositivi standard quindi, qualora volessimo ad esempio realizzare un gamepad,
ci baster cercarne la sua descrizione su
Internet ed inserirla allinterno della nostra
finestra. In modo automatico, appena
connesso il dispositivo al calcolatore, verr
riconosciuto come tale senza bisogno di
altre configurazioni ed installazioni. Le
macro che Flowcode ci mette a disposizione
sono riassunte nella Tabella 1.
Grazie a queste semplici funzioni possiamo
realizzare qualsiasi tipo di dispositivo HID
ma per meglio capirne il funzionamento proviamo ora a mettere in pratica questi concetti
realizzando un tastierino USB.

Colleghiamo la scheda EB014 alla porta D e

Fig. 8
Configurazione
hardware per
realizzare il
tastierino
numerico.

cors
o
F
L
O
W
CO

Progetto pratico:
realizziamo un tastierino numerico USB
Il dispositivo che stiamo realizzando sar
riconosciuto in automatico dal PC al quale
verr collegato come una normale tastiera
USB. Per realizzarlo abbiamo bisogno dei
seguenti componenti:
EB006 USB PICmicromultiprogrammerboard (PIC18F4450 e quarzo 12 MHz);
EB014Keypadboard;
EB055USB interfaceboard.

la EB055 alla porta C, come mostrato in Fig.


8. Per poter utilizzare il componente senza
doverlo alimentare esternamente, come
le normali tastiere USB, basta collegare il
morsetto V+ della scheda EB006 al morsetto
+5 della scheda EB055. In questo modo il
microcontrollore viene alimentato direttamente dalla porta USB. La connessione
effettuata mediante il filo giallo mostrato
nella stessa Fig. 8.
inoltre necessario, come visto nelle
precedenti puntate, configurare la scheda
in modo da avere la frequenza adatta per
poter utilizzare correttamente il bus USB.
Ogni volta che necessario gestire un
bus a frequenza fissa bisogna stare molto
attenti nel configurare correttamente tutti
i parametri; nel nostro caso la configurazione mostrata in Fig. 9. La frequenza di
oscillazione del PLL quindi 96 MHz, ma
le periferiche interne lavorano a 24 MHz in
modo da poter supportare la connessione
USB Low-Speed.
Ora che lhardware pronto, possiamo dedicarci alla realizzazione del software di controllo: per prima cosa dobbiamo capire quali
dati vengono scambiati tra PC e tastiera in
modo da poterla emulare; allo scopo, possiamo andare sul sito ufficiale USB e scaricare
i file Hut1_12v2.pdf e HID1_11.pdf.
Analizzandoli, riusciamo a capire cosa viene
trasmesso e cosa ricevuto. In Fig. 10 sono
riassunti i dati trasmessi tra PC e tastiera
USB. Sempre nel file, troveremo la codifica

DE

120

Dicembre 2013 / Gennaio 2014 ~ Elettronica In

corso F L O
WCOD

Fig. 10 - Riassunto dati scambiati


con la tastiera USB.

Fig. 9 - Configurazione del microcontrollore per la realizzazione


del tastierino numerico.

dei caratteri da trasmettere perch questi


non seguono la normale tabella ASCII. I valori numerici dalluno al 9 partono dal valore
esadecimale 0x1E mentre lo zero ha codifica
0x27. In questo semplice esempio trasmetteremo unicamente un carattere per volta e
non saranno quindi possibili combinazioni
di tasti premuti in contemporanea. Per questa ragione ci baster valorizzare unicamente
il byte 2, lasciando gli altri al valore predefinito 0x00.
Ora che abbiamo tutte le informazioni necessarie possiamo trascinare nel pannello il
componente Keypad ed il componente USBHID. Il componente Keypad richiede una
corretta configurazione delle connessioni.
Nel nostro caso dovranno essere impostate
come mostrato in Fig. 11.
Per quanto riguarda la configurazione del
componente HID, necessario scegliere nella pagina HID descriptors lopzione Keyboard mentre configurare il tab HID options
come indicato in Fig. 12.
Lapplicazione potrebbe sembrare complessa, per il fatto che utilizza il bus USB, ma il
diagramma di controllo risulta semplice e
non richiede neppure di realizzare macro
di supporto. Come primo passo necessario inizializzare la periferiche HID e
successivamente, mediante un ciclo infinito,

scandire il tastierino numerico e trasmettere periodicamente, mediante la macro


di aggiornamento della periferica HID, le
informazioni sul tasto premuto. Se nessun
tasto premuto, viene trasmesso il valore
0x00 altrimenti il codice relativo al tasto.
Per evitare di sovraccaricare il bus di dati
non utili, qualora il tasto premuto risulti
sempre lo stesso, i dati vengono trasmessi
unicamente a seguito di una variazione del
tasto premuto ed il tempo minimo di ritardo tra una trasmissione e laltra di 10 ms.
Per ovviare a problemi di inizializzazione
stato aggiunto un ritardo di inizializzazione
pari a 100 ms.
Le variabili utilizzate sono le seguenti:
DatiUSB[8]: un vettore di 8 byte nel quale vengono memorizzati i dati da trasmettere sul bus;
EsitoInizializzazione : variabile byte che
serve per memorizzare lesito dellinizializzazione della periferica USB;
Keypad : memorizza il valore letto dal
Keypad in una variabile di tipo byte;
Keypad_precedente : utilizzata per
memorizzare lo stato precedente letto sul
keypad ed di tipo byte.
Il flusso di programma completo mostrato
in Fig. 13.

Elettronica In ~ Dicembre 2013 / Gennaio 2014

121

Installiamo il driver
del componente FTDI
Per poter funzionare correttamente, il PC al quale
colleghiamo il convertitore FTDI, deve avere installati i driver necessari. Per far ci inseriamo il CD fornito assieme alla scheda EB001 a fronte della richiesta
del PC di installare il driver e indichiamo di volerlo
cercare nel computer (Fig. A); inseriamo lindirizzo
alla cartella \drivers\EB-O39 contenuta allinterno
del nostro lettore CD e procediamo premendo il
pulsante Avanti.

pulsante Generate Driver File che si trova


in essa serve per generare il file .inf che viene richiesto quando colleghiamo la periferica ad un PC per linstallazione del driver.
necessario rigenerare il driver ogni qualvolta, nella finestra di dialogo, modifichiamo
i parametri di configurazione. Le macro a
disposizione sono elencate in Tabella 2.
Con queste semplici macro possiamo
realizzare qualsiasi tipo di periferica USB
che emuli una comunicazione seriale. Per
meglio capirne il funzionamento passiamo
ora alla realizzazione di un semplice analizzatore di stati logici.

Fig. A indicazione del percorso di ricerca del driver USB.

Al termine della procedura di installazione otterremo


lindicazione che il driver stato aggiornato ed
quindi pronto alluso come indicato in Fig. B.

Fig. 11 - Configurazione Keypad.


Fig. B Installazione driver completata con successo.

Fig. 12 - Configurazione USB-HID.

cors
o
F
L
O
W
CO

Il componente USB-Serial
Questo tipo di controllo permette di gestire
in modo molto semplice una connessione
USB perch vista sia lato PC che lato Sistema embedded come una comunicazione
di tipo seriale RS232. Il componente si trova
nella barra dei componenti allinterno del
menu periferiche dove avevamo precedentemente visto gli altri componenti USB.
Come possiamo osservare nella finestra di
dialogo visibile in Fig. 14, i parametri che
possiamo configurare sono gli stessi che
avevamo visto per il componente HID; il

DE

122

Dicembre 2013 / Gennaio 2014 ~ Elettronica In

corso F L O
WCOD
Fig. 13
Diagramma
completo per la
realizzazione di
una tastiera USB.

Progetto pratico: realizziamo


un analizzatore di stati logici
Un analizzatore di stati logici permette di
visualizzare gli stati di una serie di connessioni in modo da poter debuggare sistemi
digitali. molto utile per la lettura di comunicazioni su bus paralleli. Il materiale di
cui abbiamo bisogno il seguente:
EB006 USB PICmicromultiprogrammerboard (PIC18F4550 e quarzo 12MHz)
EB055 USB interfaceboard
EB016Prototypeboad
In Fig. 15 sono visibili le interconnessioni
tra le schede della MatrixMultimedia per la
realizzazione del progetto. La scheda EB055
connessa alla porta C mentre la EB016 alla
porta A e B.
Per poter funzionare correttamente, il
microcontrollore deve esse configurato
come mostrato in Fig. 16 in modo da poter
operare a una frequenza di clock di 48
MHz.
In pratica il sistema embedded legge il
valore della porta B e lo invia in modo
seriale. Dal lato PC possibile realizzare un
programma terminale che legge i dati e li

stampa a video in modo da poterli analizzare semplicemente. Dato che la comunicazione USB non real-time, aggiungeremo
alla stringa inviata serialmente anche il
cosiddetto TimeStamp in modo che si
possa sapere quando i dati sono stati campionati. La sequenza trasmessa sar quindi: <xxxxxx-yyy> dove xxx rappresenta il
TimeStamp mentre y il valore della porta
B. Ogni 100ms verr inviato un dato sulla
comunicazione e quindi potremo avere una
risoluzione massima di 0.1 secondi sullasse
dei tempi. Il timestamp rappresentato in
decimi di secondo mentre il valore della
porta B in decimale. In questo modo anche
con un semplice terminale possibile interpretare il segnale. Se per esempio volessimo
trasmettere il valore 236 al tempo 1,5 secon-

Elettronica In ~ Dicembre 2013 / Gennaio 2014

123

Fig. 15 Configurazione
HW per analizzatore
di stati logici.

Fig. 14
Finestra delle
propriet del
componente
USB seriale.

di invieremo la stringa <000015-236>. Il


tempo massimo di 99999.9 secondi (27,7
giorni) dopo il quale, si ha la ripetizione del
valore di TimeStamp.
Generare la stringa a lunghezza fissa, cio
con laggiunta dello zero per mantenere la
lunghezza fissa, probabilmente la parte
pi difficile di tutto il progetto perch il
comando per la conversione da numero a
stringa inserisce unicamente le cifre significative. Per questa ragione realizzeremo una
macro che avr il compito di convertire un
numero e di portarlo a lunghezza fissa. La
macro si chiama ConvertiInStringaFissa e
necessita dei seguenti parametri:
ValoreNumerico: il valore che vogliamo convertire;
LunghezzaFissa: la lunghezza della
stringa in uscita.
Il primo ciclo si occupa della formattazione
della stringa mediante laggiunta del carat-

tere che identifica lo zero mentre il secondo carica allinterno del valore di ritorno
il valore convertito mediante la funzione
Length$ con allineamento a destra come
mostrato in Fig. 17.
Ora che la nostra macro pronta possiamo
passare alla realizzazione del programma principale. Per prima cosa inseriamo
allinterno del pannello il componente
USB-Seriale e lo configuriamo come visto
nel paragrafo precedente. Come di routine
suddividiamo il programma in due parti
principali: linizializzazione del sistema
ed il ciclo principale. Nellinizializzazione
inseriamo lazzeramento delle variabili e
la macro Intitialize_Serial() per la connessione USB. Il ciclo principale si occupa invece della sequenza di lettura della
portaB, Conversione del valore letto e del
TimeStamp, generazione della stringa da
trasmettere e infine trasmissione del dato
su bus USB. Per fare in modo che i dati ven-

Tabella 2 - Macro disponibili per la gestione della connessione USB-Seriale.


Descrizione
utilizzata per inizializzare la comunicazione USB avviando il servizio di enumerazione in modo che
il PC possa identificare il dispositivo. Restituisce come valore di ritorno 0 qualora venga eseguita
correttamente mentre 255 in caso di errore.

Send_Byte(Byte)

Trasmette il byte passato come parametro inserendolo nel buffer di scrittura.

Send_String(String, Length)

Invia la stringa passata come parametro String. Il parametro Length deve contenere la lunghezza
dei caratteri da trasmettere contenuti nella stringa.

Read_Byte(timeout_ms)

Legge dal buffer di lettura un byte e lo restituisce come valore di ritorno. Il parametro timeout_ms serve per stabilire un timeout massimo, in millisecondi, per il quale la macro deve attendere in attesa di
un dato. Qualora venga posto al valore 255 lattesa non termina fino a quando un dato non disponibile nel buffer di ricezione. Nel caso nessun dato venga ricevuto entro il timeout il valore di ritorno 255.

Read_String(timeout_ms, String, Length)

Legge dal buffer di lettura una sequenza di caratteri la cui lunghezza fissata dal parametro Length e la restituisce come valore di ritorno della funzione. Come per la macro Read_Byte il parametro
timeout_ms serve per permettere alla macro di restituire il controllo alla funzione chiamante senza
che nessun dato sia stato ricevuto.

124

Dicembre 2013 / Gennaio 2014 ~ Elettronica In

DE

Initialise_Serial()

cors
o
F
L
O
W
CO

Nome Macro

corso F L O
WCOD

Fig. 17 - Macro
ConvertiInStringaFissa
utilizzata allinterno
dellanalizzatore
di stati logici.

Fig. 16 Configurazione microcontrollore per analizzatore di stati logici.

Fig. 18
Diagramma
del Main
dellanalizzatore
di stati logici.

gano campionati e trasmessi ogni 100ms


necessario inserire un ritardo di 100ms. Il
ciclo principale , come sempre, racchiuso
allinterno di un ciclo infinito per evitare
che il programma termini dopo il primo invio di dati. I pi esperti nella realizzazione
di sistemi embedded si saranno sicuramente accorti del fatto che utilizzare un delay
per cadenzare una misurazione per periodi
cos lunghi porta ad un accumulo dellerrore sul timestamp. Per ovviare a questa problematica comunque sufficiente utilizzare
un timer. In questo esempio stato scelto
di non utilizzarlo unicamente per poterci
soffermare maggiormente sullimpiego
del bus di comunicazione piuttosto che
sulle altre problematiche di contorno che, a
questo punto del corso, dovreste essere gi
in grado di risolvere in modo autonomo. In
Fig. 18 mostrato il diagramma principale
per la realizzazione dellanalizzatore di
stati logici.
Per testare il programma possiamo utilizzare un qualsiasi terminale per porte
COM che supporti le comunicazioni seriali
virtuali.
Bene, anche con questa puntata abbiamo
concluso. Nelle prossime conosceremo altri
componenti forniti da Flowcode, tra i quali
g
lo ZigBee e lEthernet.

Elettronica In ~ Dicembre 2013 / Gennaio 2014

125

corso F L O
WCOD

Continuiamo il
nostro viaggio alla
scoperta di Flowcode,
linnovativo sistema
di sviluppo grafico
per microcontrollori
proposto dalla Matrix
Multimedia. In questa
puntata analizzeremo
una periferica
wireless: ZigBee.
Settima puntata.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

elle puntate precedenti ci siamo


occupati di diverse periferiche di
comunicazione, che avevano una
caratteristica comune, ossia quella di essere
tutte periferiche di comunicazione cablate.
Analizziamo adesso limplementazione
Flowcode di una periferica wireless, ossia
interfacciamo il nostro microcontrollore
con una periferica ZigBee.
Il Protocollo ZigBee
Il protocollo ZigBee nasce ufficialmente il
14 dicembre 2004, giorno in cui la ZigBee Alliance (consorzio di aziende che si
occupano dello sviluppo e dellaggiornamento dello standard e della promozione

della tecnologia su di esso basata) rilascia


le specifiche 1.0. Come era gi avvenuto in passato per la definizione di altri
standard, il lavoro relativo allo standard
ZigBee stato diviso in due tronconi. Al
task group IEEE 802.15.4 (parte del work
group IEEE 802.15) stato assegnato il
compito di definire le specifiche relative
al livello fisico e MAC dello standard,
mentre la ZigBee Alliance stata incaricata di arrivare alla definizione delle
specifiche di alto livello (livelli Network
e Application). La relazione che esiste
tra 802.15.4 e ZigBee la stessa che esiste
tra 802.11 e WiFi e tra 802.15.1 e Bluetooth. Non bisogna quindi confondere le

Elettronica In ~ Febbraio 2014

129

Tabella 1 - Confronto tra le pi diffuse tecnologie wireless.


ZigBee 802.15.4

Bluetooth 802.15.1

Wi-Fi 802.11b

GPRS/GSM 1XRTT/CDMA

Application Focus

Monitoring & Control

Cable Replacement

Web, Video, Email

WAN, Voice, Data

System Resource

4KB-32KB

250KB+

1MB+

16MB+

Battery Life (days)

100-1000+

1-7

1-5

1-7

Nodes Per Network

255/65K+

30

1,000

Bandwidth (kbps)

20-250

720

11,000+

64-128

Range (meters)

1-75+

1-10+

1-100

1,000+

Key Attributes

Reliable, Low Power,


Cost Effective

Cost, Convenience

Speed, Flexibility

Reach, Quality

Fig. 1
Logo della
ZigBee
Alliance.

specifiche dello standard IEEE 802.15.4


con lo standard ZigBee: con il primo ci
si riferisce ad un insieme di specifiche di
basso livello sulle quali si basa il secondo
per la definizione di uno standard pi
complesso. Sulle specifiche indicate dallo
standard ZigBee si basano i costruttori
per la realizzazione del silicio. Chi a sua
volta acquista i chip dai produttori, li
ingloba in un sistema pi complesso,
il quale aggiunge un ulteriore strato a
livello applicativo, caratteristico dellapplicazione finale vera e propria.
Come stato gi accennato nellintroduzione il protocollo ZigBee un protocollo
wireless caratterizzato da bassi consumi
energetici, semplicit nellimplementazione del codice (generalmente indicata
come consumo approssimativo di memoria programma per la realizzazione di un
nodo) ed elevato numero di nodi costituenti la rete; la velocit di comunicazione relativamente bassa.

La Tabella 1 mette a confronto lo


standard ZigBee con alcune tra le pi
diffuse tecnologie wireless esistenti.
Il data-rate tipico dichiarato sul canale radio 250 kbps, mentre il data rate
dellinterfaccia pu assumere valori che
variano da 1.200 a 115.200 bps; tale parametro non sempre si trova nei data-sheet
dei dispositivi, in quanto lo ZigBee non
stato specificamente studiato per lo scambio di grosse moli di dati, come potrebbe
invece essere per il WiFi.
La portata dipende dal dispositivo considerato, dallantenna e dalla potenza
irradiata in trasmissione: valori tipici
sono compresi tra le decine e le centinaia
di metri. In Fig. 2 riportato un grafico
che mette a confronto diverse tecnologie
wireless in funzione del range trasmissivo
e del data rate (in Mbps). Come si vede
Bluetooth e ZigBee occupano zone molto
vicine nel grafico, ma mentre il primo

cors
o
F
L
O
W
CO

Fig. 2 - Confronto tra tecnologie


wireless in funzione di portata
trasmissiva e data-rate.

I dispositivi facenti parte di una PAN


ZigBee si chiamano nodi; i nodi non sono
tutti uguali ma lo standard ZigBee ne
prevede tre tipi:
Coordinator; il nodo centrale della rete
e ad esso sono demandate le funzioni
pi importanti, come ad esempio la
creazione della rete stessa, lassegnazione degli indirizzi, la scelta del canale RF ed altro ancora; ne pu esistere al
massimo uno per rete e pu fungere da
ponte tra reti diverse ( anche chiamato
Gateway);
Router; agisce come router intermedio, passando i dati da e verso altri
dispositivi;
End Device; include le funzionalit
minime per dialogare con il loro nodo
padre (Coordinator o Router), non
possono trasmettere dati provenienti
da altri dispositivi.

DE

130

Febbraio 2014 ~ Elettronica In

corso F L O
WCOD

Fig. 3 - Esempio
di Mesh ZigBee.

privilegia la velocit in trasmissione, il


secondo la sacrifica in funzione di una
maggiore portata trasmissiva.
Oltre a ci, ZigBee presenta una interessante caratteristica che lo differenzia da
Bluetooth e da altri protocolli wireless,
e gli permette di estendere il suo range
utile a valori molto superiori rispetto alla
portata di un singolo dispositivo. Infatti
lo standard permette di mettere in comunicazione due nodi qualsiasi anche se
non posti in collegamento radio diretto,
sufficiente che tra i due nodi in questione
esista almeno un percorso costituito da
nodi intermedi, che in questo caso fungono da routers. Questa interessante caratteristica viene generalmente indicata come
Mesh Networking, una cui rappresentazione grafica riportata in Fig. 3.
La gestione di reti Mesh una prerogativa
del protocollo, che viene implementata
adottando i pi recenti algoritmi di routing, oltre ad un efficiente sistema di indirizzamento dei dispositivi, che si avvale
di due indirizzi, un indirizzo denominato
MAC ed uno denominato Short.
Il MAC un codice identificativo a 64
bit (8 byte), univoco per ogni dispositivo
prodotto al mondo.
Tale codice memorizzato allinterno di

unapposita memoria ROM e non pu


essere modificato.
Invece lo Short un codice identificativo
a 16 bit (2 byte) che permette di identificare univocamente un dispositivo allinterno di una rete ZigBee. Viene memorizzato in unarea di memoria protetta,
ma riscrivibile, quindi pu cambiare, in
seguito, ad esempio, allassociazione del
dispositivo con unaltra rete. Gli indirizzi Short sono assegnati dal Coordinator
allatto della creazione della rete.
Per quanto riguarda le bande radio utilizzate, lo standard sfrutta le frequenze
assegnate nella banda ISM (Industrial,
Scientific, Medical), che variano a seconda
del paese considerato. In particolare pu
usufruire delle frequenze radio a 433MHz
e 868 MHz in Europa e a 315 MHz e 915
MHz negli USA. Inoltre pu usufruire
della banda radio a 2,4 GHz praticamente
in tutto il mondo. Su questa frequenza
sono disponibili ben 16 canali e quindi, a
meno di casi particolari, questa risulta essere la scelta pi frequente dei costruttori.
Le caratteristiche intrinseche di ZigBee
rendono questo standard la scelta ideale
per un gran numero di applicazioni. Si
va dalla building automation al controllo
industriale, dalle periferiche wireless per
PC (come tastiere e mouse) ad applicazioni wireless di sicurezza. Un importante
segmento sicuramente costituito dalla

Fig. 4
Applicazioni
tipiche del
protocollo
Zigbee.

Tabella 2 - Applicazioni del protocollo ZigBee.


Settore di applicazione

Possibili applicazioni

Termoregolazione

HVAC, controllo temperatura, controllo umidit

Monitoraggio ambientale

Terra, qualit aria, qualit acqua.

Automazione industriale

Accelerometri, Vibrazioni, Pressione, Spostamenti

Monitoraggio strutturale

Monitoraggio gallerie, Monitoraggio ponti, Monitoraggio dighe, Monitoraggio edifici a rilevanza storica o artistica

Domotica

Sistemi di sicurezza e controllo

Elettronica In ~ Febbraio 2014

131

Fig. 5 - Modulo
Xbee Serie 2.

Fig. 6 - Possibili scelte per lantenna dei moduli Xbee.

Nei data-sheet sono definiti una serie di


frame utilizzabili, divisi per funzione,
e caratterizzati da differente numero di
byte, codice identificativo ed altro ancora.
Il componente ZigBee in Flowcode
Analizziamo adesso il componente ZigBee integrato in Flowcode. Il componente
si trova sotto il gruppo dei componenti
wireless, allinterno della barra dei componenti. Per inserirlo nel nostro progetto
sufficiente trascinarlo sul pannello,

Tabella 3 - Caratteristiche moduli Standard e PR.


Xbee
30 m

Xbee PRO
100 m

Outdoor Range

100 m

1500 m

Transmit Power Output

1 mW (0 dBm)

100 mW (20 dBm)

RF data rate

250 kbps

250 kbps

Interface Data Rate

1200 115200 bps

1200 115200 bps

Receiver Sensitivit

- 92 dBm

- 100 dBm

Supply Voltage

2.8 3.4 V

2.8 3.4 V

Transmit Current

45 mA

270 mA

Receive Current

50 mA

55 mA

Febbraio 2014 ~ Elettronica In

DE

132

Specification
Indoor/Urban Range

cors
o
F
L
O
W
CO

realizzazione di reti che vengono generalmente indicate come WSN (Wireless Sensor Network) ossia reti di sensori wireless
custom per applicazioni di monitoraggio
di vario tipo. La Fig. 4 illustra alcune delle applicazioni tipiche del protocollo.
La Tabella 2 elenca sinteticamente alcune
delle pi comuni applicazioni del protocollo. Tra i vari dispositivi ZigBee presenti al mondo hanno acquisito una certa
fama (specialmente nel mondo hobbistico) i dispositivi Xbee, prodotti dalla Digi/
Maxstream. Si tratta di una famiglia di
radiomodem con interfaccia seriale, il
cui esemplare riportato in Fig. 5. Tali
disposivi sono stati scelti anche dalla Matrix come modulo hardware ZigBee per i
dispositivi e-block.
Lhardware molto semplice, e consiste
in un piccolo PCB, allinterno del quale
trova posto tutta lelettronica necessaria
al funzionamento, inclusa lantenna che
pu essere a chip, a filo o con connettore
RPSMA. La Fig. 6 illustra le diverse possibili scelte per lantenna dei moduli Xbee.
Linterfacciamento verso lesterno
affidato a due file di 10 pin a passo 2 mm.
Linterfaccia di comunicazione una
seriale standard UART, con baud rate selezionabile da 1200 bps a 115200 bps, sicch il collegamento minimo richiesto per
il funzionamento dei moduli consiste nelle due linee della seriale, TX ed RX e nelle
due linee di alimentazione. Sono previste

due modalit di funzionamento, modalit


trasparente (denominata normalmente
modalit AT) e modalit API. In modalit trasparente tutto ci che viene inviato
sulla seriale del modulo viene ritrasmesso
sul canale radio e viene successivamente
ritrasmesso in uscita sulla porta seriale
del modulo ricevente. I radiomodem
aggiungono alla sorgente e tolgono alla
destinazione tutto lheader necessario alla
comunicazione, ecco perch la modalit
viene definita trasparente. Non possibile intervenire sullheader, che contiene
informazioni quali indirizzo destinazione, lunghezza campo dati, checksum, etc.
In modalit API, invece, la gestione dei
pacchetti decisamente pi complicata.

corso F L O
WCOD

Fig. 7 Propriet extra.

come pi volte abbiamo fatto in precedenza. Una volta posizionato il componente possiamo esaminarne le propriet
extra, cliccando con il tasto destro. La
finestra delle propriet extra del componente riportata in Fig. 7. Come si pu
vedere possibile scegliere che tipo di
componente si vuole implementare (Coordinator, Router, End node), impostare
la PAN id (random e impostata dallutente), impostare il numero massimo di
hops, i canali da includere allinterno
della procedura di scan ecc.
Come per gli altri componenti, sono
disponibili delle API che ne facilitano
lutilizzo, sinteticamente riportate in
Tabella 4.
Progetto pratico:
nodo wireless per controllo rel
Passiamo adesso al progetto pratico
relativo a questa puntata. Questa volta ci
proponiamo di realizzare una mesh ZigBee costituita da nodi in grado di controllare una batteria di 4 rel. Ogni nodo sar
identificato allinterno della mesh tramite
un indirizzo costituito da due cifre numeriche codificate ASCII. Sar possibile
modificare lindirizzo del nodo tramite
il canale wireless e sar inoltre possibile
intervenire su alcuni parametri di funzionamento. I vari parametri saranno memorizzati allinterno della EEPROM del
dispositivo, in modo che possano essere
recuperati anche nel caso in cui il nodo
venga privato della sorgente di alimentazione, in modo da non dover ripristinare

la configurazione in futuro.
Come gi fatto per gli altri progetti pratici, esaminiamo le specifiche di progetto,
elencate di seguito.
Controllo di ogni singolo nodo tramite
indirizzo in formato ASCII su due cifre.
Attivazione/disattivazione di 4 rel.
Gestione delle seguenti opzioni:
- abilitazione/disabilitazione LED
funzionamento;
- abilitazione/disabilitazione Eco
comando;
- selezione periodo lampeggio LED.
Memorizzazione delle opzioni di sistema su memoria EEPROM.
Il nostro progetto prevede quindi lutilizzo di un protocollo livello applicazione
che si appoggia sul protocollo ZigBee. La
definizione del protocollo di livello applicazione riportata di seguito.
La stringa di comando inviata dal
master una stringa ASCII composta
da 7 caratteri.

Tabella 4 - Macro del componente ZigBee Flowcode.


Nome Macro

Descrizione

Init_Network

Inizializza il modulo Xbee e prova ad eseguire il setup della network (coordinator) oppure ad effettuare il join ad una
network eseistente (router o end device).

Restart_Network

Re-inizializza la network Zigbee.

Scan_Network

Esegui uno scan per individuare una rete associabile.

Connect_To_Address

Connette il modulo ad uno specifico indirizzo allinterno della network.

Connect_To_Coordinator

Connettiti al coordinator.

Connect_To_All

Connettiti a tutti i nodi (trasmissione broadcast)

Node_Configure_Sleep

Imposta la modalit sleep del nodo (applicabile solo agli end device). Prende in ingresso due parametri, la modalit
di sleep (1=Hibernate, 2=Doze, 4=Cyclic Sleep, 5=Cyclic Doze) e il timeout in ms.

Node_Wake

Risveglia i nodi figli dallo sleep mode.

Get_Signal_Level

Leggi il livello del segnale radio

Send_Char

Invia un byte sul canale radio.

Receive_Char

Restituisci il carattere ricevuto dal canale radio.

Elettronica In ~ Febbraio 2014

133

La stringa di comandi divisa in due


sezioni, una sezione di identificazione
ed una sezione di controllo, separate
dal carattere ASCII -.
La sezione di identificazione serve ad
indirizzare il nodo che si vuole controllare. composta da 3 caratteri ASCII:
un primo carattere S (Slave) seguito da
due caratteri numerici ASCII da 0 a
9. Quindi per identificare il nodo 01,
si invier la stringa S01.
La sezione di controllo divisa in 3
sottofunzioni:
- sottofunzione R, usata per il
controllo diretto dei rel. In questa
sottofunzione la lettera R seguita
da un carattere numerico ASCII da
1 a 4, usato per identificare il rel e
dai caratteri a e d usati, rispetti-

Fig. 8
Connessione
E-Block per
progetto pratico.

vamente, per abilitare/disabilitare il


rel (ad esempio per abilitare il rel 1
sul nodo 15 si user la stringa S15R1a);
- sottofunzione I, usata per impostare un nuovo indirizzo del nodo. In
questa sottofunzione, la lettera I
seguita da due caratteri numerici da
0 a 9, che costituiscono la nuova
coppia di valori per lindirizzo del
nodo(Es. per cambiare lindirizzo del
nodo 0 in 35 si user la stringa S00I35);
- sottofunzione C , usata per impostare la configurazione del sistema.
Le opzioni di configurazione attualmente disponibili permettono di abilitare/disabilitare il working LED e
selezionarne il periodo di lampeggio
ed abilitare/disabilitare leco.
La lista degli e-block necessari per la
realizzazione di un nodo slave riportata
di seguito:
1x EB006 USB PICmicro multiprogrammer board (PIC18F4580 e quarzo a 12
MHz);
1x EB051 ZigBee board (configurazione Router/End Node);
1x EB030 Relay board;
1x EB004 LED board.
Per quanto riguarda il nodo Coordinator, possiamo utilizzare una delle tante
board di interfacciamento per nodi Xbee,
come ad esempio la Xbee explorer USB,
distribuita da Futura Elettronica. Quanto
alle connessioni, dovremo collegare la
EB051 sulla porta C (in modo da poter
utilizzare la porta USART hardware per

cors
o
F
L
O
W
CO
DE

134

Febbraio 2014 ~ Elettronica In

corso F L O
WCOD

Tabella 5 - Periodicit e descrizione dei task del software del nodo ZigBee slave.
Task

Periodo [ms]

Descrizione

RxTask

1 (attivo), 1000 (riposo)

Riceve e decodifica i dati sul canale wireless.

RelayTask

500

Attua lo stato dei rel impostato dai comando wireless.

EepromTask

100

Aggiorna i parametri su memoria non volatile.

LedTask

Impostabile

Gestisce il working LED.

parlare con il modulo Xbee), e la EB030


sulla porta D. Infine colleghiamo la EB004
sulla porta A.
Non dimentichiamo che sia la EB051 che
la EB030 necessitano anche dei collegamenti di alimentazione. In Fig. 8 sono
rappresentati i collegamenti hardware
dei vari E-block.
Implementazione software
A questo punto possiamo iniziare ad
esaminare i dettagli implementativi del
software del nodo slave. Secondo le specifiche che ci siamo forniti, il nodo slave
deve essere in grado di gestire i 4 rel,
prevedere una gestione della memoria
non volatile, gestire il working LED
(LED che segnala che il nodo connesso
alla rete ed operativo) e, naturalmente,
gestire il protocollo applicazione che
abbiamo descritto in precedenza.
Larchitettura utilizzata per limplementazione del nodo prevede lutilizzo di
uno scheduler ad 1 ms, ed un totale di 4
task, riportati per completezza in Tabella
5, insieme alle relative periodicit.
Limplementazione dello scheduler di
sistema del tutto simile a quella vista
nella puntata 5, con la differenza che questa volta stato impostato un interrupt
sul timer 2 con periodo di 1ms, in modo
da avere la granularit richiesta. Si noti la
differenza di tempistiche del task RxTask.
Questo il task pi delicato dellintero
sistema, e quello che occupa maggiori
risorse. Si quindi deciso di diminuire
lintervallo tra le chiamate quando non ci
sono dati in transito sul canale wireless
ed aumentarla al massimo durante la fase
di ricezione attiva. Analizzeremo in seguito il meccanismo software implementato per ottenere questo comportamento.
Limplementazione del main scheduler
riportata in Fig. 9.
Come si pu vedere, le chiamate ai vari
task sono scandite dallo stato delle 4
variabili:
- TSK_RelayTaskCounter;

- TSK_EepromTaskCounter;
- TSK_LedTaskCounter;
- TSK_RxTaskCounter.
Non potendo analizzare tutti i task implementati in quanto una singola puntata
non sarebbe sufficiente, ci soffermeremo

Fig. 9 - System scheduler.

Elettronica In ~ Febbraio 2014

135

Fig. 10 Task RxTask.

PACKET. Contestualmente viene attivato


un timer (PacketCheckTime) che rimane
attivo per tutta la fase di trasmissione.
Scopo del timer evitare che pacchetti
tronchi blocchino il task in attesa di una
parte del pacchetto. Dopo 200ms si resetta tutto e si ricomincia daccapo. Infine,
quando il pacchetto ricevuto completamente si resettano contatori e flag e
viene chiamata la funzione di decodifica
(RxDecodeFn).
La RxDecodeFn una funzione (non
un task, quindi la sua esecuzione non

cors
o
F
L
O
W
CO

solo sui task pi importanti. Prendiamo


ad esempio il task RxTask, che esegue
uno dei compiti pi importanti del sistema, ossia la decodifica del pacchetto dati
inviato dal Coordinator.
Poich questo task risulta essere piuttosto
pesante per la CPU durante lesecuzione,
anche senza pacchetti in arrivo, si scelto
di dargli una periodicit differente in
caso di ricezione dati e non. In sostanza,
in caso di assenza di attivit RF il task
esegue una volta al secondo, mentre se
c attivit sul canale radio, il tempo di
esecuzione passa ad 1ms, in modo da
decodificare immediatamente il pacchetto
e passare nuovamente allo stato di attesa
(con conseguente sovraccarico minimo
della CPU). Questo tipo di comportamento stato realizzato gestendo un flag
globale denominato IncomingPacket,
che pu avere due valori: NEW_INCOMING_PACKET e NO_INCOMING_PACKET. Normalmente il valore NO_INCOMING_PACKET, ma in caso di inizio
di una procedura di ricezione, il task
RxTask lo forza al valore NEW_INCOMING_PACKET fino al termine della
ricezione. Se andiamo a controllare la
condizione di chiamata del task RxTask
sullo scheduler, noteremo che essa vale:
(TSK_RxTaskCounter >= TASK_RX_TIMEOUT) || (IncomingPacket = NEW_
INCOMING_PACKET)
Ossia, se il valore di IncomingPacket
diverso da NEW_INCOMING_PACKET
(situazione di attesa), il task viene eseguito con la sua periodicit classica (TASK_
RX_TIMEOUT), altrimenti si passa ad
una esecuzione veloce ad ogni chiamata
dello scheduler stesso (ossia una volta al
ms).
Lo schema a blocchi del task RxTask
riportato in Fig. 10. Come si pu vedere
dallo schema a blocchi, se c un byte
in ricezione sul canale, lo si acquisisce
facendo uso della macro Receive_Char(),
messa a disposizione dal componente
ZigBee. Dopo aver ricevuto il byte su un
buffer di servizio, lo si sposta sul buffer
di ricezione (e si aumenta lindice associato al buffer) e si setta il flag IncomingPacket al valore NEW_INCOMING_

DE

136

Febbraio 2014 ~ Elettronica In

corso F L O
WCOD

periodica ma event tiggered) che ha il


solo scopo di decodificare il pacchetto
in ricezione e impostare correttamente il
valore delle variabili globali affinch gli
altri task compiano correttamente i loro
compiti. Lo schema a blocchi della RxDecodeFn riportato in Fig. 11.
Descriviamo brevemente limplementazione. In pratica la prima operazione
eseguita lassegnamento dei vari byte
del pacchetto a delle specifiche variabili,
in maniera da agevolare la fase succes-

Function_Parameter2 = RxBuffer[.DEC_
PAR_2]
Il primo controllo effettuato sulla prima
parte del pacchetto, quella contenente
lindirizzo del nodo. Il controllo effettuato il seguente:
(NodeType = NODE_TYPE_SLAVE) &&
(Packet_IDMajor = EEP_Id_NodeMajor)
&& (Packet_IDMinor = EEP_Id_NodeMinor)
Quindi si controlla che il nodo sia uno
slave (S) e che lID corrisponda con I
valori caricati dalla memoria EEPROM.

Fig. 11 - Schema a blocchi della funzione RxDecodeFn.

siva. Nello specifico viene utilizzato un


blocco calcolo che esegue le seguenti
assegnazioni:
NodeType = RxBuffer[.DEC_NODE_TYPE]
Packet_IDMajor = RxBuffer[.DEC_ID_
MAJ]
Packet_IDMinor = RxBuffer[.DEC_ID_
MIN]
Function_MainFunction = RxBuffer[.DEC_
MAIN_FUNCT]
Function_Parameter1 = RxBuffer[.DEC_
PAR_1]

Se il controllo ha esito positivo si prosegue, altrimenti il pacchetto viene scartato.


Dopo aver effettuato questo check preliminare si passa alla decodifica dellistruzione vera e propria del pacchetto. Prima
di farlo per, si controlla se lopzione
Eco attiva (EEP_Conf_EcoEnabled =
ECO_ENABLED?) e, in caso positivo, si
trasmette leco del pacchetto ricevuto.
Successivamente, un blocco selezione
multipla decodifica il campo dati effettivo del pacchetto, impostando adeguatamente le variabili globali utilizzate dagli

Elettronica In ~ Febbraio 2014

137

Fig. 12 Schema a blocchi del task RelayTask.

Fig. 13 - Schema a blocchi del task EepromTask.

altri task per lesecuzione delle azioni


specifiche.
In particolare, la sezione relativa al controllo dei rel, una volta verificato che il
byte Function_MainFunction corrisponda
al valore ASCII R, effettua le seguenti
assegnazioni:

da aggiornare, si utilizza una variabile


globale. Cos, ad esempio, per aggiornare
il parametro di configurazione relativo
allabilitazione delleco, il relativo blocco
calcolo imposta:

Queste informazioni vengono poi utilizzate dal task RelayTask per il controllo
effettivo dei rel. Una parola a parte merita la gestione della memorizzazione dei
parametri in EEPROM (questo riguarda,
ad esempio, tutte le opzioni di configurazione). Tale gestione demandata al relativo task, ma, anche in questo caso, per
sapere se i parametri in memoria sono

EEP_Conf_EcoEnabled contiene il valore


del parametro, mentre il flag EepUpdateRequest segnala al task EepromTask che
deve essere eseguito un aggiornamento
dei parametri in memoria.
Passiamo ora ad esaminare il task di controllo dei rel, che risulter di semplice
comprensione, ora che stata esaminata
la logica di comunicazione tra i task. Lo

cors
o
F
L
O
W
CO

RelayNumber = Function_Parameter1
RelayStatus = Function_Parameter2

EEP_Conf_EcoEnabled = Function_Parameter2
EepUpdateRequest = UPDATE_EEP_REQUEST

DE

138

Febbraio 2014 ~ Elettronica In

corso F L O
WCOD

Fig. 14 - Esempio di comunicazione.

schema a blocchi del task RelayTask


riportato in Fig. 12. Questo task gira a
500ms e non fa altro che monitorare lo
stato delle due variabili globali RelayNumber e RelayStatus. La prima dice
qual il rel da controllare, mentre la seconda ne indica lo stato. Come abbiamo
potuto esaminare in precedenza, queste
variabili sono impostate dal task RxTask,
ed in particolare dalla RxDecodeFn. Una
volta determinato il rel da controllare
ed il suo stato si agisce opportunamente
sulla porta D tramite dei blocchi di uscita. Vediamo adesso come viene gestita la
memoria non volatile, elemento fondamentale nel funzionamento del sistema,
dato che contiene lindirizzo del nodo ed
anche i parametri di configurazione. Ci
sono diversi modi di gestire una memoria EEPROM in un progetto embedded,
e la scelta della modalit non mai una
questione banale. In questo progetto si
deciso di utilizzare una gestione di
tipo mirror. Ossia, i dati immagazzinati
nella memoria EEPROM sono copiati in
opportune locazioni di memoria RAM
allavvio del sistema (mirror della EEPROM). Se durante la vita operativa del
sistema, uno di questi parametri cambia,
viene avviata una procedura che aggiorna la EEPROM (il mirror viene ricopiato
sulla EEPROM). In questo modo, al successivo riavvio verranno caricati i dati
aggiornati. Quindi il blocco EEPROM
allinterno di questo progetto costituito
da due parti distinte. Una funzione di
inizializzazione, che copia il contenuto
della EEPROM allinterno delle variabili mirror, ed un task run time che si
occupa dellaggiornamento, quando necessario. La funzione di inizializzazione
non particolarmente complessa, quindi
la tralasciamo. Esaminiamo invece il
task, il cui schema a blocchi riportato
in Fig. 13. Come abbiamo spiegato in
precedenza, il compito del task quello
di aggiornare i dati in EEPROM copiandovi il contenuto delle rispettive variabili mirror. Per evitare di gravare troppo
sulla CPU i dati non sono copiati tutti
insieme, ma stata costruita una sequenza che copia un dato per ciclo di schedu-

ling, se la procedura attiva. In questo


modo riduciamo al minimo indispensabile il carico di lavoro in fase di aggiornamento dei dati in EEPROM, al prezzo
di un tempo complessivo maggiore per
eseguire lintera operazione. Limplementazione molto semplice: allinizio
il task controlla se c stata una richiesta
di aggiornamento della memoria non
volatile (EepUpdateRequest = UPDATE_EEP_REQUEST?). In caso affermativo viene avviata la procedura e i dati
sono salvati in sequenza, uno per ciclo.
La sequenza stata realizzata facendo
uso di un blocco selezione multipla e di
una variabile globale (EepromUpdateSequence). Al termine della sequenza viene
resettato anche il flag EepUpdateRequest
(EepUpdateRequest = UPDATE_EEP_
COMPLETE). Con questultima analisi i
task pi significativi sono stati analizzati.
Possiamo adesso testare il nostro sistema,
usando un qualsiasi programma terminale
per comunicare con il coordinator. Per
eseguire i nostri test abbiamo utilizzato
X-CTU, il software fornito dalla Digi per
lo configurazione dei radiomodem Xbee.
In Fig. 14 possibile vedere uno screenshot di comunicazione nel quale era stata
precedentemente attivata la funzione
eco (vengono attivati e poi disattivati in
sequenza i quattro rel).
In questa settima puntata abbiamo analizzato in dettaglio il componente ZigBee,
oltre a presentare un progetto pratico di
una certa complessit, che ci ha permesso
di fissare alcuni importanti concetti visti
nelle puntate precedenti. Nella prossima
e ultima puntata analizzeremo (e proveremo con un progetto pratico) i componenti
g
TCP/IP e il Webserver.

Elettronica In ~ Febbraio 2014

139

corso F L O
WCOD

Concludiamo il
nostro viaggio alla
scoperta di Flowcode,
linnovativo sistema
di sviluppo grafico
per microcontrollori
che consente di
scrivere il codice
facendo uso di oggetti
grafici. In questa
ottava ed ultima
puntata spiegheremo
come connettere
allethernet sistemi
embedded mediante
protocollo TCP/IP.

corso di programmazione in

F L OWCODE
di Francesco Ficili e Daniele Defilippi

ella scorsa puntata abbiamo


introdotto la periferica wireless
che consente la comunicazione
secondo lo standard ZigBee, ed illustrato
la relativa implementazione in flowcode.
Ora, a conclusione del corso, parleremo di
come realizzare sistemi embedded connessi alla rete ethernet, in grado di gestire
protocolli complessi come quello TCP/IP.
Questo tema ci apre le porte alla gestione
e alla realizzazione di sistemi domotici che
oggigiorno tendono ad essere sempre pi
connessi alla rete globale del world wide
web. Inizieremo il nostro percorso parlando del protocollo TCP/IP e al termine della puntata realizzeremo in pochi semplici

passi un Web Server integrato in grado di


inviare dati dinamici sulla rete.
Sviluppo di applicazioni Internet
con Flowcode
Gestire sistemi integrati connessi alla rete
Ethernet molto complesso ed implica una
profonda conoscenza di molteplici protocolli di comunicazione, ma Flowcode ci
mette a disposizione i componenti necessari per risolvere questo problema in modo
semplice e intuitivo. Mediante i componenti TCP/IP, UDP e WebServer possiamo
realizzare praticamente qualsiasi applicazione che contempli una comunicazione
ethernet senza costringerci ad approfondir-

Elettronica In ~ Marzo 2014

129

ne tutte le problematiche. I componenti in


libreria ci permettono di gestire lintegrato
W5100, grazie al quale ci si pu connettere
direttamente alla Ethernet. Come punto di
partenza iniziamo ad esaminare il protocollo TCP/IP.

Dato che lindirizzo IP pu cambiare in


modo dinamico, necessario basarsi su un
qualcosa di fisso ed immutabile che possa
identificare un sistema connesso sulla rete.
Per questa ragione utilizzato lindirizzo
MAC: esso univoco per ogni scheda in
grado di collegarsi alla rete ed perci
fissato in fase di produzione della scheda ed
assegnato in modo automatico a fine linea.
Tornando al livello pi alto, possiamo
trovare un ulteriore livello di astrazione:
le cosiddette porte di comunicazione.
Ogni porta adibita ad un particolare tipo
di protocollo ma possibile utilizzarle
anche in modo differente; quella pi nota
e comunemente utilizzata la 80, usata per
la comunicazione http, ma ve ne sono altre
come la 20,21 per lFTP, la 53 per il DNS e
molte altre ancora.
Con queste nozioni basilari possiamo ora
accingerci ad esaminare il componente che
Flowcode ci mette a disposizione per gestire
il protocollo TCP/IP, UDP e MAC.
Il componente TCP/IP per Flowcode
Nella barra dei componenti nel menu Periferiche troviamo il componente TCP/IP
che ci permette di gestire i protocolli TCP/
IP, UDP e MAC. Per poterlo utilizzare
sufficiente inserirlo nel pannello e successivamente procedere alla configurazione.
In Fig. 2 mostrata lunica pagina di configurazione delle propriet del componente.
Innanzitutto dobbiamo scegliere quale
versione della scheda EB023 abbiamo a
disposizione; troviamo facilmente questa
indicazione sulla scheda che abbiamo acquistato (se stiamo realizzando una scheda
custom, la deduciamo dal componente utilizzato). ora necessario inserire le informazioni riguardanti la connessione di rete.

cors
o
F
L
O
W
CO

Il protocollo TCP/IP
TCP/IP lacronimo di Transmission Control Protocol / Internet Protocol; il protocollo
corrispondente racchiude tutte le specifiche
necessarie per comunicare correttamente
attraverso la rete Internet. suddiviso in
strati detti Layer (Fig. 1). Ciascuno dei
layer dipende da quello che sta al di sotto
e pu comunicare solamente con quelli
confinanti; ognuno ha un compito differente e i pacchetti, durante il transito verso gli
strati inferiori, vengono sempre pi incapsulati e, viceversa, man mano che risalgono
vengono ripuliti dai dati di incapsulamento
non pi necessari. Questo tipo di architettura permette di poter trasferire in modo
sicuro i dati tra un calcolatore ed un altro.
Il protocollo IP si occupa della corretta
ricezione/trasmissione di dati; attualmente
esistono due versioni di IP: IPv4 e IPv6. La
differenza principale tra i due il numero
di byte utilizzati per codificare in modo univoco gli indirizzi di rete. Il protocollo TCP
invece incaricato del riordino dei pacchetti
e della ricomposizione del dato originale
senza perdita di dati. Ogni computer
identificato da un indirizzo IP che lo identifica in modo univoco allinterno della rete
internet. Lassegnazione di questo indirizzo
pu essere di tipo dinamico oppure statico;
solitamente possiamo decidere se assegnarne uno di un tipo oppure di un altro perch,
essendo collegati ad un ISP (Internet Service
Provider), lindirizzo effettivo visto dalla
rete sar quello dellISP e non quello scelto
da noi. Quando vogliamo raggiungere un
calcolatore collegato a Internet mediante
un browser, digitiamo un nome, ad esempio www.futuranet.it, e questo, mediante
il servizio di DNS, verr trasformato nel
corrispondente indirizzo IP utilizzabile
con il protocollo TCP/IP. Questo processo
permette cos di utilizzare dei nomi che
sono pi facili da ricordare rispetto ad una
sequenza di 4 o 6 numeri a tre cifre.

Fig. 1
Suddivisione
in Layer del
protocollo
TCP/IP.

DE

130

Marzo 2014 ~ Elettronica In

corso F L O
WCOD

Tabella 1 - Macro utilizzabili con il componente TCP/IP


Nome macro

Descrizione

Initialize

Resetta ed inizializza la periferica Ethernet.

Create_MAC_Socket

Chiamando questa macro, viene creato un socket in grado di ricevere i dati trasmessi sulla rete ethernet. Impostando ad
uno il valore del parametro:
- Promiscuous mode per leggere tutto il traffico circolante sulla rete senza tener conto dellindirizzo MAC;
- Broadcast mode per leggere anche i pacchetti di tipo Broadcast;
- Error mode per ricevere anche i pacchetti che contengono errori.
Il valore di ritorno, se diverso da zero, indica che loperazione di configurazione andata a buon fine.

Create_UDP_Socket

La macro crea un socket per la ricetrasmissione di dati mediante il protocollo UDP.


necessario indicare come parametri:
- Channel, ossia il canale scelto per la comunicazione (da 0 a 3); possibile utilizzare contemporaneamente canali configurati in modo differente fin ad un massimo di quattro;
- lindirizzo della porta sorgente suddiviso in src_port_hi e src_port_lo.
Il valore di ritorno, se diverso da zero, indica che loperazione di configurazione andata a buon fine.

Create_IP_Socket

Crea un socket per la ricetrasmissione di dati mediante il protocollo IP.


necessario indicare il canale scelto (channel) e il protocollo che si intende realizzare mediante il set dei due parametri interni alla macro. Il valore di ritorno, se diverso da zero, indica che loperazione di configurazione andata a buon fine.

Create_TCP_Socket

Crea un socket di tipo TCP. Necessita delle stesse configurazioni utilizzate con la macro Create_UDP_Socket.

Set_Destination

utilizzata con socket di tipo IP e UDP e serve per impostare lindirizzo IP e la porta verso il quale si vogliono trasmettere i
dati. Richiede come parametri il canale, lindirizzo IP e la porta di destinazione. Per connessioni di tipo IP non necessario
indicare la porta.

Set_My_IP

Questa macro utilizzata per modificare, durante lesecuzione, lindirizzo IP del dispositivo; non necessaria se si desidera
mantenere lindirizzo IP inserito nella finestra di configurazione del componente.

GetSocketStatus

La macro restituisce lo stato attuale del socket. I valori possibili sono diciannove, ma quelli principali sono i seguenti:
- 0 (SOCK_CLOSED) = il socket chiuso (non sono n trasmessi n ricevuti dati);
- 6 (SOCK_ESTABLISHED) = il socket pronto e la comunicazione attiva in modalit passiva;
- 7 (SOCK_CLOSE_WAIT) = il socket in fase di chiusura;
- 14 (SOCK_INIT) = il socket in fase di inizializzazione.

TCP_Listen

Imposta il canale scelto (indicato come parametro) in modalit passiva in modo che possa essere pronto a ricevere dei dati.

TCP_Connect

Imposta il canale scelto (indicato come parametro) in modalit attiva in modo che possa essere pronto per trasmettere dei
dati sul canale di comunicazione. Necessita come parametri il valore del canale, lindirizzo IP e la porta di destinazione. Se
il valore restituito differente da zero vuol dire che la comunicazione stata stabilita con successo e che possono quindi
essere trasmessi dei dati.

TCP_Close

Chiude la connessione TCP mediante unoperazione attiva e porta il socket in attesa di terminazione.

Tx_start

Avvia la trasmissione di dati sul canale specificato dai parametri ma, per funzionare correttamente necessita delle macro
successive (Tx_sendbyte, Tx_sendmymac, Tx_sendmymac e Tx_end) . La sequenza corretta inizia con un comando di Tx_start,
prosegue con sequenze di Tx_sendbyte, Tx_sendmymac, Tx_sendmymac nellordine prescelto (pu anche solo essere utilizzata una sola macro delle tre) e termina con Tx_end per effettuare linvio dei dati sul canale di comunicazione.

(segue)

In base alla tipologia di rete impostiamo


lindirizzo IP, che deve essere di tipo statico, e la Subnet Mask. Il gateway Address
deve essere impostato uguale allindirizzo
del router o del modem con il quale si accede a Internet, almeno se vogliamo inviare
pacchetti al di fuori della rete LAN; qualora
questo indirizzo fosse sbagliato, non sarebbe possibile comunicare con computer non
direttamente collegati a Intranet.
Il settaggio dellindirizzo MAC (Hardware
Address) la parte pi delicata: tale valore
dovrebbe essere univoco sullintera rete
Internet. Per fare delle prove allinterno
della rete LAN possiamo impostarlo ad
un valore qualsiasi: basta che differisca
da quello di tutte le altre schede di rete
wireless ed ethernet affacciate su di essa.
Per utilizzarlo su Internet bisogna essere
certi di assegnare un indirizzo che non
corrisponda ad alcuna periferica ethernet affacciata al momento su Internet nel

mondo; il modo migliore per fare ci


prendere lindirizzo di una scheda di rete
attualmente non utilizzata, cos si certi
che il relativo IP non sia attivo.
Ulteriore passo la configurazione delle
connessioni; per poter funzionare correttamente necessario impostare i pin sul quale vengono mappati il piedino di interrupt
ed il c.s. Questa configurazione varier
in base a come colleghiamo la scheda alla
nostra piattaforma oppure su come realizziamo il PCB in caso di progetti Custom.
Passiamo ora ad esaminare le macro che
Flowcode ci mette a disposizione per gestire le comunicazioni su rete ethernet. Nella
Tabella 1 sono descritte le principali.
Queste macro permettono di gestire in
modo molto semplice comunicazioni sulla
rete ethernet utilizzando socket a differenti
livelli: MAC, UDP e TCP/IP.
Il componente TCP/IP quello che ci
permette di gestire i principali protocol-

Elettronica In ~ Marzo 2014

131

Tabella 1 - Macro utilizzabili con il componente TCP/IP (seguito)


Nome macro

Descrizione

Tx_sendbyte

Invia i dati al buffer di trasmissione per il canale specifico. Oltre al canale deve essere indicato il parametro di dato. Come
dato possono anche essere utilizzate stringhe.

Tx_sendmymac

Invia nel buffer di trasmissione, del canale selezionato, lindirizzo MAC attuale della scheda.

Tx_sendmyip

Invia nel buffer di trasmissione, del canale selezionato, lindirizzo IP impostato nella finestra di configurazione della scheda.

Tx_end

la macro che permette di inviare fisicamente I dati sulla linea di comunicazione.

Rx_data_available

Controlla se vi sono dati disponibili nel buffer di ricezione del canale. Il valore di ritorno, se differente da zero, indica che vi
sono dati disponibili. Questa macro anche utilizzata per inizializzare il buffer per la ricezione dei dati qualora non lo fosse
gi. In pratica azzera lindice con il quale viene scandito il buffer con la macro Rx_data_size.

Rx_data_size

Macro utilizzata per sapere quanti byte sono disponibili allinterno del buffer di ricezione.

Rx_readheader

Macro utilizzata per leggere lheader dei dati ricevuti.


Richiede come parametri di ingresso il canale di comunicazione e lindice idx del byte che si vuole leggere. In base al tipo di
comunicazione utilizzata sul canale scelto si possono avere le informazioni seguenti.
- UDP mode
Idx 0 - 1: Dimensione del pacchetto (MSB idx=0);
Idx 2 - 5: Indirizzo IP sorgente (MSB idx=2);
Idx 6 - 7: indirizzo della porta (MSB idx=7).
- IP mode
Header size = 6;
Idx 0 - 1: Dimensione del pacchetto (MSB idx=0);
Idx 2 - 5: Indirizzo IP sorgente (MSB idx=2).
- MAC mode
Header size = 3;
Idx 0 - 1: Dimensione del pacchetto (MSB idx=0);
Idx 2: Stato del pacchetto ricevuto:
Bit 7 = 1 indica che il MAC di destinazione equivale allindirizzo della scheda;
Bit 5 = 1 indica che lindirizzo di tipo broadcast;
Bit 4 = 1 indica che il pacchetto contiene degli errori.

Rx_readbyte

Legge dal buffer di ricezione del canale scelto un byte che viene restituito come valore di ritorno.

Rx_skipbytes

Permette di saltare dei dati dal buffer di ricezione.

Rx_match2bytes
Rx_match4bytes
Rx_match6bytes

Legge 2/4/6 byte dal buffer di ricezione e li confronta con quelle indicate nei parametri con la quale viene chiamata. Restituisce un valore differente da zero se i valori coincidono.

Rx_match_mymac

Legge 6 byte dal buffer di ricezione e li confronta con lindirizzo MAC con il quale stata configurata la scheda. Restituisce
un valore differente da zero se i valori coincidono.

Rx_match_myip

Legge 4 byte dal buffer di ricezione e li confronta con lindirizzo IP con il quale stata configurata la scheda. Restituisce un
valore differente da zero se i valori coincidono.

li di comunicazione su rete ethernet,


tuttavia per realizzare un Web Server
in modo ancora pi semplice abbiamo a
disposizione un componente specifico;
tale componente, a patto di sottostare ad
alcune limitazioni, ci permette di realizzare il Web Server in modo ancora pi
semplice e intuitivo.

cors
o
F
L
O
W
CO

Fig. 2 - Finestra delle propriet del componente TCP/IP.

Il componente Webserver
La maniera pi immediata per poter
comunicare con sistemi remoti, anche a
migliaia di chilometri di distanza, quello
di utilizzare semplici pagine web, perch
necessitano unicamente che entrambi i
sistemi siano connessi alla rete Internet.
Lintero sistema veramente economico
ed molto intuitivo da utilizzare. Realizzare un Web Server su un calcolatore abbastanza semplice, ma su una piattaforma
embedded con potenza di calcolo limitata
diventa assai pi complesso. Per queste
ragioni, Flowcode ci viene in soccorso
fornendoci un componente specifico che
troviamo nella barra dei componenti nel
menu Periferiche con il nome Webserver.
Nelle puntate precedenti abbiamo visto
come periferiche o sistemi molto complessi possano essere realizzati in modo molto
semplice grazie allutilizzo del programma; cos anche in questo caso. Come

DE

132

Marzo 2014 ~ Elettronica In

corso F L O
WCOD

Tabella 2 - Macro utilizzabili con il componente WebServer


Nome macro

Descrizione

Initialize

Resetta ed inizializza la periferica Ethernet. Questa macro deve essere chiamata prima di ogni qualsiasi altra macro per la
gestione del Web Server.

CreateServerSocket

La macro crea un socket per la ricetrasmissione di dati su Web Server.


necessario indicare come parametri:
- Channel il canale scelto per la comunicazione (da 0 a 3); possibile utilizzare contemporaneamente canali configurati in
modo differente fin ad un massimo di quattro;
- lindirizzo della porta dal quale trasmettere e ricevere i dati suddiviso in src_port_hi e src_port_lo.
Il valore di ritorno, se diverso da zero, indica che loperazione di configurazione andata a buon fine.

CheckSocketActivity

Richiede in ingresso il canale sul quale si vuole effettuare il controllo di attivit.


Deve periodicamente essere richiamata in modo da permettere la gestione delle richieste entranti.

vediamo in Fig. 3, la finestra di configurazione del componente semplice e intuitiva: notiamo che esattamente identica al
componente TCP/IP e quindi pu essere
configurata allo stesso modo. Ci dovuto
al fatto che il componente webserver non

Fig. 3 - Propriet del componente Webserver.

Fig. 4 - Propriet del componente Webserver


per la descrizione delle pagine HTML.

altro che un gestore preconfigurato di


pagine web basato su TCP/IP.
Le differenze risiedono nei successivi
tab di configurazione, mostrati in Fig. 4.
In alto dobbiamo inserire il nome delle
pagine, mentre nello spazio centrale
necessario editare il codice che intendiamo visualizzare sulla pagina richiesta da

remoto. Il codice deve essere compatibile


con lo standard HTML, ma ci non vieta di
inserire comandi JavaScript o altri linguaggi interpretati dal browser remoto.
La caratteristica fondamentale del componente Webserver la possibilit, che offre,
di inserire nel codice HTML il valore dinamico di alcune variabili; in questo modo
possibile monitorare da remoto le variabili
volute (al massimo quattro). Allo scopo basta fare riferimento, allinterno del codice
HTML, al nome della variabile, inserendolo tra %. I nomi delle variabili utilizzabili
sono quindi B001, B002, B003 e B004. Vi
sono alcune limitazioni sulla tipologia
delle variabili scelte perch non possono
essere di tipo stringa o virgola mobile.
Nellesempio pratico utilizzeremo questo
semplice stratagemma allo scopo di realizzare una centralina per il monitoraggio
della temperatura.
Progetto Pratico: Centralina per
il monitoraggio della temperatura
mediante Web Server
Il Web Server integrato che realizzeremo ci
permetter di monitorare da remoto, tramite una connessione a Internet, le ultime
quattro temperature misurate dal nostro
sistema.
Per realizzare il progetto abbiamo bisogno
dei seguenti componenti:
- EB006 USB PICmicromultiprogrammerboard (PIC18F4685 e quarzo 19,6608
MHz);
- EB023 Internet board;
- EB016 Prototype board;
- sensore di temperatura LM35.
Colleghiamo le schede come mostrato
in Fig. 5 posizionando la scheda EB023
sulla porta C e la scheda di prototipazione EB016 sulle porte A e B. Alimentiamo
il sensore, come indicato nella seconda

Elettronica In ~ Marzo 2014

133

Listato 1
<!DOCTYPE html>
<HTML>
<HEAD><title>Esempio web-server</title>
<script language=JavaScript type=text/javascript>
var Temperature = new Array();
Temperature[0] = %BOO1% - 128;
Temperature[1] = %BOO2% - 128;
Temperature[2] = %BOO3% - 128;
Temperature[3] = %BOO4% - 128;
function Temp(x) {
if (x/20<=1) return Temperature[0];
else if (x/20<=2) return Temperature[1];
else if (x/20<=3) return Temperature[2];
else return Temperature[3];
}

Fig. 5
Connessione
delle schede
per realizzare
la centralina di
monitoraggio
temperatura.

function funGraph (ctx,axes,func,color,thick) {


var xx, yy, dx=1, x0=axes.x0, y0=axes.y0, scale=axes.scale;
var iMax = Math.round((ctx.canvas.width-x0)/dx);
var iMin = axes.doNegativeX ? Math.round(-x0/dx) : 0;
ctx.beginPath();
ctx.lineWidth = thick;
ctx.strokeStyle = color;
for (var i=iMin;i<=iMax;i++) {
xx = dx*i;
yy = scale*func(xx/scale);
if (i==iMin) ctx.moveTo(x0+xx,y0-yy);
else
ctx.lineTo(x0+xx,y0-yy);
}
ctx.stroke();

// Disegna gli assi


function showAxes(ctx,axes) {
var x0=axes.x0,w=ctx.canvas.width; scale=axes.scale;
var y0=axes.y0, h=ctx.canvas.height;
var xmin = axes.doNegativeX ? 0 : x0;
var Hline = 0;
ctx.beginPath();
ctx.strokeStyle = rgb(128,128,128);
ctx.moveTo(xmin,y0); ctx.lineTo(w,y0);
ctx.moveTo(x0,0);
ctx.lineTo(x0,h);

// X axis
// Y axis

ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.strokeStyle = rgb(128,128,128);
for (var i=-20;i<=50;i= i + 10) {
yy = i*scale;
ctx.moveTo(xmin-5,y0-yy); ctx.lineTo(w,y0-yy);
ctx.font=15px Georgia;
ctx.strokeText(i + C,xmin-50,y0-yy+5);

puntata per la realizzazione del termometro LCD, e colleghiamo luscita alla


porta A piedino numero 2 in modo da
stimolare il canale analogico An2 del
microcontrollore.
Configuriamo il progetto in modo da ottenere una frequenza di clock del PIC pari
a 19.660.800 Hz, impostando i parametri
come mostrato in Fig. 6.
Ora che lhardware pronto possiamo

Tabella 3 - Dati di configurazione componente WebServer


GatewayAddress

192.168.0.10

SubnetMask

255.255.255.0

IP Address

192.168.0.5

HardwareAddress

0:8:220:0:0:0

Maximum number of WebPages

dedicarci alla stesura del diagramma di


controllo. Inseriamo quindi dalla barra dei
componenti il componente Webserver e
il componente ADC configurato in modo
che legga lingresso An2 collegato al sensore di temperatura LM35. Passiamo ora
ad impostare il componente Webserver:
indichiamo i seguenti valori allinterno dei
parametri (Tabella 3).
Il codice html che verr visualizzato sulla

cors
o
F
L
O
W
CO

(segue)

Fig. 6 - Configurazione del componente.

DE

134

Marzo 2014 ~ Elettronica In

corso F L O
WCOD

Listato 1 (seguito)
}
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = rgb(80,80,80);
yy = 0;
ctx.moveTo(xmin,y0-yy); ctx.lineTo(w,y0-yy);
ctx.stroke();

function draw() {
var canvas = document.getElementById(canvas);
if (null==canvas || !canvas.getContext) return;
// Imposta larea di disegno
var axes={}, ctx=canvas.getContext(2d);
axes.x0 = 50;
//.5 + .5*canvas.width; // x0 pixels from left to x=0
axes.y0 = 12/16*canvas.height;
//.5 + .5*canvas.height; // y0 pixels from top to y=0
axes.scale = 7;
// 7 pixels from x=0 to x=1
axes.doNegativeX = false
showAxes(ctx,axes);
funGraph(ctx,axes,Temp,rgb(66,44,255),4);

function clear(ctx) {
ctx.fillStyle = rgb(255,255,255);
ctx.fillRect(0, 0, 500, 500);
}
</script>
</HEAD>
<body onload=draw()>
<script>
</script>
<p><center>
<font face=Verdana size=+2>
Temperature misurate<br><br>
<canvas id=canvas width=600 height=400></canvas>
<br><font face=Verdana size=-2>Web Server by <br>
<a href=http://www.eletronicain.it/>ElettronicaIN</a></font>
</center><p>
</body></HTML>

pagina deve essere indicato nel tab Web


page 1 con il titolo index.htm. Il testo del
codice html che ci permette di visualizzare
le ultime quattro temperature e plottarne il
grafico contenuto nel Listato 1; per poterlo utilizzare ci baster inserirlo (mediante
copia/incolla) allinterno della finestra di
configurazione della pagina.
Dato che abbiamo da svolgere due task
principali, possiamo dividere il nostro
flusso di programma in due macro. La
prima, il main in Fig. 8, si occuper di
inizializzare il sistema e controllare le
richieste del socket al quale collegato il
webserver, mentre la seconda macro in
Fig. 7, chiamata dallinterrupt del timer, si
occuper della lettura periodica del sensore di temperatura e dellaggiornamento
dellarray di temperature da visualizzare
in remoto. Le variabili utilizzate sono quelle descritte qui di seguito.

- ContatoreTimer di tipo Grande+


inizializzato a -1 in modo da forzare la
lettura della temperatura allaccensione
del sistema.
- ADC_Temp di tipo Virgola mobile per
poter leggere la tensione del sensore
LM35.
- Temperatura_1 / Temperatura_4 di tipo
intero per la memorizzazione delle temperature.
- B001 / B004 di tipo intero per la
visualizzazione sulla pagina HTML dei
valori di temperatura.
Sono state inoltre utilizzate due costanti
globali per la conversione degli impulsi del
timer in valori di tempo:
- IMPULSI_OGNI_SECONDO vale 75
perch la frequenza di interrupt del
timer0 prefissata a 75 Hz (questo valore
dovuto al fatto che il prescaler del

Elettronica In ~ Marzo 2014

135

tuito, con alcune limitazioni, fornito ad


esempio da www.dyndns.it. Baster quindi
configurare il modem in modo da comunicare correttamente con uno di questi server, scegliere lacronimo con il quale verr
identificato il nostro sistema embedded ed
il gioco fatto: abbiamo reso accessibili,
da qualsiasi parte del mondo, i dati forniti
dalla nostra scheda embedded.
Utilizzare MPLAB per integrare
il codice generato da Flowcode
Utilizzare Flowcode per realizzare progetti sempre pi complessi porta ad un
incremento della difficolt del debug del
codice generato soprattutto se vi sono
blocchi con allinterno del codice C. Il Debugger classico di Flowcode ci permette
di monitorare le variabili e gli stati del sistema ma non possibile, in alcun modo,

Fig. 7 - Macro per


la lettura della
temperatura ogni
quattro ore.

timer fissato a 256 e loscillatore configurato per lavorare a 19.660.800 Hz;


- SECONDI_OGNI_ORA vale 3600 ed
la costante che permette di sapere quanti secondi vi sono per ogni ora.

Fig. 8 - Flusso
principale di
programma.

cors
o
F
L
O
W
CO

Per poter effettuare un semplice test,


possiamo collegare il sistema mediante il
cavo ethernet al router con il quale ci connettiamo in rete e dal browser del nostro
computer e digitare lindirizzo del Web
Server, che in questo caso 192.168.0.5. La
pagina che si aprir mostrata in Fig. 9.
Permettere laccesso del web server
dallesterno della nostra rete locale pi
complicato, perch implica lottenimento
di un IP fisso oppure poter avere a disposizione un modem in grado di utilizzare
servizi di DNS dinamico. Un servizio gra-

DE

136

Marzo 2014 ~ Elettronica In

corso F L O
WCOD

Il linguaggio HTML

Fig. 9 - Pagina inviata dal Web Server.

visualizzare direttamente i registri del


microcontrollore. Per queste operazioni,
che potrebbero risultare complesse per un
principiante, ma che sono essenziali per un
utilizzatore esperto, possiamo avvalerci di
MPLAB e del compilatore C BoostC. Sono
entrambi scaricabili da Internet in versione
free rispettivamente allindirizzo www.
microchip.com e www.sourceboost.com.
Per integrare i due sistemi necessario
prestare molta attenzione ai passi con il
quale viene istallato il compilatore: per
prima cosa occorre installare, se non gi
presente, MPLAB IDE, quindi il compilatore BoostC, seguendo attentamente la procedura. Al passo in cui viene visualizzata
limmagine in Fig. 11 necessario scegliere
la cartella dove stato installato MPLAB
IDE e fare clic sul pulsante Integrate;
solo in questo modo sar possibile scegliere dallIDE il compilatore BoostC.
Al termine dellinstallazione necessario
aprire MPLAB IDE e impostare, dal menu
Project->Set Language Tool Locations, correttamente le informazioni sul compilatore,
come indicato in Fig. 12 e Fig. 13.
Impostare anche gli altri indirizzi per il
BoostC Compiler for PIC18 per poterlo
utilizzare anche su microcontrollori della
famiglia 18. In questo caso, bisogna scegliere il boostc_pic18.exe. Utilizzando la versione gratuita di BoostC si possono compilare solo progetti che non superino i limiti
di memoria RAM e ROM, mentre con la
versione PRO, acquistabile dal produttore,
non vi sono limitazioni di alcun tipo.
Prendiamo come esempio il diagramma
che abbiamo realizzato nella puntata 4
per pilotare dei rel tramite RS232. Apriamo MPLAB IDE e dal menu scegliamo il

Il linguaggio HTML, acronimo di HyperText Markup


Language, il linguaggio base con le quali vengono
realizzate le pagine web. basato sullutilizzo di Tag
che permettono di formattare il testo nel modo desiderato. Non pu essere considerato un linguaggio di
programmazione perch non possono essere definite
alcune variabili e cicli di controllo ma unicamente un
linguaggio di formattazione testuale. Per ovviare a
questa limitazione per possibile inserire allinterno
della pagina dei contenuti esterni come immagini,
video o script in altri linguaggio di programmazione
come ad esempio il JavaScript. I tag sono racchiusi
tra parentesi angolate ed ogni volta che un tag viene
aperto deve poi anche essere chiuso inserendo prima
del nome la barra. Ad esempio, per inserire il testo
Testo formattato in grassetto dovremo scrivere:

Fig. 10
Pagina
inviata dal
Web Server.

<b>Testo Formattato</b>
La struttura base di un file Html raffigurata in
Figura 10. Partendo dalla testa del file, si ha una
descrizione del documento, alcune informazioni di
servizio ed il corpo del documento nel quale viene
formattato lintero contenuto della pagina.
Figura 10 - Struttura base di un file HTML

Per vedere alcuni esempi di codice HTML basta che


apriamo una pagina web e, nel caso il browser sia
Firefox, cliccare con il tasto destro sullarea centrale e
scegliere dal menu Visualizza sorgente pagina.

Project->Project Wizard per creare un nuovo


progetto; scegliamo il microcontrollore
che avevamo scelto in Flowcode (il PIC18F4580), impostiamo come compilatore
il BoostC per i pic della famiglia 18 ed
aggiungiamo il file Rs232.c generato da
Flowcode.

Elettronica In ~ Marzo 2014

137

Fig. 11 - Indicazione cartella Microchip MPLAB.

Fig. 12 - Configurazione eseguibile


compilatore BoostC per PIC16.

Marzo 2014 ~ Elettronica In

Ora che il codice compilato non ci


resta che scegliere il debugger dal menu
Debugger, programmare il dispositivo ed eseguire i test in MPLAB come se
avessimo scritto a mano il codice.
Qualora vengano trovati errori o imperfezioni consigliabile effettuare
le dovute correzioni su Flowcode, e
non direttamente sul codice, in modo
che, ad una successiva generazione
di codice, vengano automaticamente
corretti gli errori e non si debba ritoccare a mano il codice. Questo semplice
stratagemma ci permette di utilizzare
tutte le potenzialit di Flowcode anche
in progetti molto complessi, avendo
per a disposizione, per la risoluzione
dei problemi, uno strumento completo e
g
dettagliato come MPLAB.

DE

138

Fig. 14 - Configurazione del progetto di debug.

cors
o
F
L
O
W
CO

Fig. 13 - Configurazione eseguibile


liker BoostC per PIC16.

Per poter completare il progetto dobbiamo ancora aggiungere le librerie che


utilizziamo allinterno di Flowcode: allo
scopo entriamo nella cartella del compilatore, che nel nostro caso in C:\Program
Files\SourceBoost, apriamo la cartella
Lib e scegliamo i file .lib che sono necessari per questo progetto. In questo caso sono
float.pic18.lib e libc.pic18.lib, ma in progetti
pi complessi potrebbero esserne necessari altri per supportare tutte le funzioni
richieste dal codice. Con il Drag&Drop
portiamoli allinterno di MPLAB nellalbero di progetto, come indicato in Fig. 14.
Con la scorciatoia da tastiera CTRL+F10,
avviamo la compilazione e se abbiamo
svolto tutte le operazioni correttamente
lesito sar positivo.

Potrebbero piacerti anche