Scheda di controllo IoT su LAN con 4 relé, 8 I/O programmabili e 4 ingressi analogici

Interfaccia LAN dotata di 4 relé, 8 I/O programmabili e 4 ingressi analogici, pronta per l’IoT.

Quante volte avete letto o sentito parlare di Internet of Things (IoT)? Internet delle cose è un’espressione che sta divenendo molto popolare negli ultimi anni; essa rappresenta l’estensione di Internet al mondo degli oggetti e dei luoghi concreti.

Con questa tecnologia molti oggetti, un tempo esclusivamente passivi, possono diventare interattivi coordinandosi tra di loro e interagendo con l’utente; acquisiscono intelligenza e grazie al collegamento ad Internet consentono di condividere i dati generati con un utente o un’altra scheda collocata anche in un altro continente.

Tuttavia, in questo scenario il termine “intelligenza” è a volte abusato. Spesso l’IoT ingloba non solo articoli elettronici capaci di prendere decisioni autonome al fine di semplificarci la routine quotidiana, ma anche quella vastità di prodotti che un tempo erano stand-alone. Per fare questo è sufficiente dotare i nostri vecchi dispositivi di un collegamento Internet.

Il nostro sistema

Il progetto che presentiamo in questo articolo vuole assolvere a tale compito creando, tramite opportuni collegamenti, la possibilità di controllare in remoto il proprio cancello, l’acquario di casa, la luce del giardino, l’impianto di irrigazione e così via con numerosi esempi. Si tratta di una scheda a relé controllata via ethernet, che può essere impiegata come attuatore per controllare direttamente carichi alimentati a 220V, per comandare segnali digitali tra 0V ÷ 5V oppure per poter leggere lo stato di ingressi digitali o analogici; il tutto da remoto, tramite una LAN affacciata ad Internet.

Oggigiorno esistono molte alternative per avvalersi di controlli remoti, tuttavia, la scheda che proponiamo si presenta semplice sia dal punto di vista dei collegamenti elettrici sia dal punto di vista dell’interfaccia utente.

La scheda è dotata di un potente Web Server integrato che tramite Browser consente l’accesso al pannello di controllo. Inoltre, consente di impostare un nome utente ed una password al fine di proteggere l’accesso tramite login.

In questo modo cambiare lo stato delle uscite (relé o segnali digitali) e controllare lo stato degli ingressi (digitali od analogici) diventa un’operazione semplice ed immediata. Infine, l’implementazione del Web Server consente la creazione di interfacce di controllo alternative (ad esempio app per smartphone) in quanto tutte le funzioni del pannello di controllo sono disponibili tramite apposite API Web.

Schema elettrico della ethernet board

In questa sezione vedremo lo schema elettrico della scheda proposta e quindi capiremo quali sono i limiti e le potenzialità dal punto di vista elettrico ed elettronico.

Il cuore della board è rappresentato dal microcontrollore PIC18F67J60 (U5) il cui compito è di controllare lo stato dei relé tramite i MOSFET Q5, Q10, Q15 e Q20, controllare gli ingressi o le uscite digitali, effettuare il campionamento analogico digitale dei segnali provenienti dagli appositi ingressi analogici ed infine effettuare il collegamento ad Internet tramite una porta Ethernet a 10 Mbps.

Tale microcontrollore della Microchip, con architettura ad 8 bit, opera con un clock di 41,666 MHz ottenuti tramite il quarzo a 25 MHz (X2) ed il PLL interno. Inoltre, il quarzo X2 con il moltiplicatore hardware consente di generare il clock adatto al PHY Ethernet integrato.

Proseguendo con ordine troveremo le uscite e gli ingressi digitali; la “direzione” di tali I/O si può configurare da software. Per ognuno degli 8 segnali digitali il microcontrollore impiega due linee di I/O, che in relazione alla configurazione scelta tramite software consentono di cambiare dinamicamente la direzione della porta da uscita a ingresso e viceversa.

Tale funzionalità è particolarmente apprezzabile perché in base alle esigenze del momento si può riassegnare un I/O senza fermare il sistema.

Ciò è possibile grazie alla particolare circuitazione degli otto I/O, che analizziamo con riferimento all’IO1, che è composto da due MOSFET (Q1 e Q3 rispettivamente per l’I/O 1) due resistori di pull-up (R39 e R40) un LED di segnalazione (D14 con R36 resistore di limitazione) e un diodo (D11) per cortocircuitare i picchi di sovratensione generati dal cambiamento di stato dei relé.

La logica di funzionamento prevede che l’uscita digitale sia normalmente tenuta a livello alto tramite il resistore di pull-up (R39) il cui riferimento in tensione è scelto manualmente dall’utente tramite il jumper VDD SEL fra tre possibili valori (3,3V, 5V o VIN). La porta digitale può diventare bassa tramite due opzioni: pilotando Q1 nel caso in cui il controllo dell’uscita sia delegato al microcontrollore, oppure tramite il segnale esterno collegato alla morsettiera DIGITAL. Questo cambiamento di stato è amplificato da Q3 sul LED di controllo e letto opportunamente dal microcontrollore come corrispondente valore di ingresso. Questa configurazione consente di controllare la direzione delle porte da Web e prevenire danni in caso di errata configurazione.

Per quanto riguarda gli ingressi analogici, abbiamo quattro porte collegate ad un convertitore Analogico Digitale che può discriminare valori analogici con un’accuratezza di 10 bit. I valori di tensione ammessi dalla scheda sono compresi tra 0V÷5V. Dato che il microcontrollore consente di campionare segnali elettrici con un valore massimo di 3,3V abbiamo impiegato una rete di resistori (R43 e R46 per l’ingresso 1) che funziona da partitore di tensione riducendo i 5V ad un valore tollerabile da U5.

I diodi D9 e D10 normalmente operano in polarizzazione inversa e contribuiscono alla protezione del microcontrollore in caso di sovratensioni ed infine C45 e C49 stabilizzano il segnale in ingresso consentendo un campionamento più accurato. Per quanto riguarda la tensione di alimentazione, essa può essere fornita tramite connettore PWR e può essere compresa tra 7 e i 15V.

Sarà il componente U1, uno Step-Down switching converter a 800kHz, a produrre i 5V necessari al funzionamento delle principali parti della scheda compresi i relé. Per il microcontrollore e gli altri componenti funzionanti a 3,3V verrà impiegato U2, che è un Low Dropout Linear Regulator capace di fornire fino a 300 mA di corrente in un package molto ridotto.

Un altro componente fondamentale per il funzionamento della board è la memoria U7: si tratta di una EEPROM con interfaccia di comunicazione I²C da 1.024 kbit ovvero 128 kbyte. Questa memoria seriale consente di memorizzare le pagine Web e le impostazioni dell’utente.

Infine abbiamo U4, che è un Real-Time Clock/Calendar che tramite batteria di backup B1 consente di conservare le impostazioni di ora e data assegnate alla scheda anche in assenza di alimentazione elettrica principale.

In sede di progetto abbiamo previsto che la scheda fosse espandibile e allo scopo abbiamo inserito il connettore I²C, che fornisce all’esterno un accesso alla porta I²C del microcontrollore, nonché il connettore per il modulo opzionale U3, cui si può applicare un modulo WiFi basato su ESP8266 (ad esempio l’ESP03) che (previo aggiornamento del firmware del microcontrollore U5) consente di rendere wireless la scheda.

Come funziona la ethernet board

Giunti a questo punto, dopo una panoramica sulle caratteristiche della scheda, possiamo presentarvi brevemente il principio di funzionamento e le modalità d’uso. Come anticipato, la scheda è dotata di un Web Server integrato che consente l’accesso alle configurazioni tramite Browser.

Le pagine Web presentano un’estetica basilare e sono pertanto consultabili sia da computer che da smartphone o tablet, quindi anche da dispositivi con display di ridotte dimensioni. A questo punto non ci resta che scendere nel dettaglio e spiegare come usare la scheda. La prima operazione consiste nel collegare la scheda ad una rete LAN tramite cavo RJ45.

La scheda si presenta con il DHCP Client abilitato. Il DHCP, per chi non lo sapesse, è quel servizio di rete che consente di assegnare automaticamente i parametri di rete ai dispositivi connessi alla LAN facilitando le operazioni di configurazione.

L’inconveniente del DHCP per dispositivi che sono privi di display è la difficoltà nel reperire l’indirizzo IP assegnato. Dato che per accedere alla scheda è necessario conoscere l’indirizzo IP assegnato dal DHCP Server (che tipicamente è in esecuzione sul router di casa) è necessario ottenere quest’informazione.

Per conosce l’IP possiamo usare due alternative. La prima consiste nel navigare tra le pagine del router cercando l’elenco degli IP assegnati in rete.

Questa operazione però cambia da router a router e spesso anche dispositivo a dispositivo dello stesso brand.

Quindi a meno di non avere una certa familiarità con le impostazioni di rete del vostro router l’operazione potrebbe risultare scomoda.

L’alternativa consiste nell’utilizzare l’applicazione Broadcaster Discoverer di Fig. 1 che forniamo per computer con sistema operativo Windows. L’applicazione è scritta in Java ed è quindi facilmente eseguibile senza installazione se si dispone di una Java Virtual Machine, in caso contrario bisogna prima installare questo componente.

L’applicazione proposta è un semplice eseguibile che si limita ad inviare un messaggio di benvenuto in broadcast sulla rete locale, la porta è la 30303. Ogni dispositivo che implementa questa funzionalità risponderà con alcune informazioni tra cui il proprio indirizzo IP.

A questo punto, dopo l’interrogazione, nell’applicazione Broadcaster Discoverer compariranno tante righe quante sono le schede connesse alla rete locale.

Fig. 1 Broadcaster Discoverer è l’applicazione per PC Windows disegnata per facilitare il riconoscimento delle schede connesse alla rete locale LAN.

 

Cliccando su una riga della tabella si aprirà la pagina iniziale della scheda che apparirà simile alla Fig. 2.

La home è una pagina di benvenuto contenente una serie di pulsanti interattivi ed un riepilogo delle funzionalità offerte dalla scheda.

Questa pagina non contenendo informazioni sensibili è consultabile da chiunque e pertanto non necessita di autenticazione.

Le successive pagine web consentono di modificare le impostazioni della scheda e sono protette da un nome utente e da una password.

 

Fig. 2 Welcome page. Pagina iniziale di benvenuto con il riepilogo delle caratteristiche della board.

 

Proseguendo per ordine, la prima pagina che troviamo è Authentication, visibile in Fig. 3.

Questa pagina consente di visualizzare il nome utente corrente e la password, inoltre consente di modificare questi parametri e di effettuare il logout.

Dato che tutte le schede hanno la stessa coppia username e password predefiniti (username e password sono: ‘admin’ e ‘password’ rispettivamente), viene suggerito di modificare questi parametri sin dalla prima accensione.

Fig. 3 Authentication page. Questa pagina consente di modificare i dati per l’autenticazione e di effettuare il logout chiudendo la sessione di lavoro corrente.

 

La pagina successiva è Local LAN Configurations, riportata in Fig. 4.

Da questa pagina è possibile modificare le impostazioni di rete, configurare le notifiche tramite email e impostare il servizio Dynamic DNS.

Innanzitutto nella sezione Internet è possibile effettuare dei test preliminari per misurare l’intervallo di tempo necessario per effettuare un ping o testare il funzionamento dei DNS server assegnati dal servizio DHCP inserendo un URL nel campo DNS test.

Nella sezione Local network è possibile modificare le impostazioni di rete, come il MAC address e l’Host name (in ambiente Windows è possibile usare questa stringa per l’identificazione della board al posto dell’indirizzo IP).

Inoltre è possibile abilitare o disabilitare l’ICMP server per rispondere alle richieste di ping oppure l’abilitare o disabilitare il servizio DHCP per la configurazione automatica dei parametri di rete.

Fig. 4 Local LAN Configurations. Questa pagina Web consente di modificare i parametri di rete, di configurare le notifiche tramite email e di impostare il servizio Dynamic DNS.

Passiamo all’ultimo insieme di campi, che è relativo alla sezione Dynamic DNS. Questa consente di usufruire di quei servizi per l’associazione di indirizzi pubblici dinamici ad un URL di vostra scelta.

Un esempio tipico sono gli indirizzi IP assegnati alle comuni ADSL domestiche che cambiano ad ogni riavvio del router di casa. Seguendo questa soluzione sarà compito della board e del servizio DDNS mantenere aggiornato l’URL in modo da puntare sempre all’indirizzo IP assegnato alla vostra linea ADSL.

La pagina successiva riguarda l’I/O Management. Da questa pagina di configurazione è possibile impostare la direzione delle porte, in ingresso o in uscita, lo stato corrente nel caso in cui si sceglie di usare l’I/O come uscita e lo stato iniziale dell’uscita all’accensione.

La sezione Output status raggruppa queste funzionalità con una semplice interfaccia che consente di impostare la direzione dell’I/O in uscita o in ingresso, di visualizzare o modificare lo stato corrente, ON per un segnale logico alto ed OFF per un segnale logico basso e di impostare lo stato che l’I/O configurato in uscita deve assumere all’accensione.

Inoltre, dato che le board rispondono alle richieste GET del protocollo HTTP, è possibile configurare il controllo di una board remota in corrispondenza di un cambiamento di stato di un ingresso.

In questo caso, nella sezione Remote commands, per ogni riga di Input è possibile associare un’azione da intraprendere quando si verifica un cambiamento di stato dell’ingresso associato: ad esempio, nella Fig. 5 l’Input 1 controllerà il relé 2 di una scheda remota raggiungibile tramite URL assegnato.

 

Fig. 5 IO Management. Questa pagina Web consente di controllare e configurare lo stato degli ingressi e delle uscite digitali. Inoltre consente di pilotare un scheda remota in relazione allo stato dei propri ingressi.

 

La pagina successiva consente di controllare i relé; la Fig. 6 fornisce un’anteprima delle possibili impostazioni.

Come accade nel caso delle uscite digitali, dalla pagina web è possibile controllare lo stato corrente dei relé e lo stato desiderato all’accensione.

Inoltre nella sezione Timer functions è possibile associare degli eventi quotidiani ad ogni relé. Selezionando l’orario di attivazione e di disattivazione il corrispondente relé si attiverà o disattiverà automaticamente.

Fig. 6 Relay Management. Questa pagina Web consente di controllare lo stato dei relè e di impostare i tempi di accensione e spegnimento automatici.

 

La pagina Analog Management di Fig. 7 consente di visualizzare lo stato relativo agli ingressi analogici in tre diversi formati.

La prima rappresentazione riporta visivamente l’intervallo di valori campionato colorando il riempimento di una barra orizzontale; la seconda vista riporta esattamente il valore campionato a 10 bit compreso tra 0 e 1.023.

Infine, la terza vista riporta il corrispondente valore in misurato in tensione tra 0V e 3,3V. La scheda, inoltre, consente di definire due soglie per controllare le uscite digitali o i relé.

Fig. 7 Analog Management. Questa pagina Web consente di visualizzare in 3 diversi formati lo stato degli ingressi analogici e di impostare delle soglie per poter controllare le uscite digitali o i Relè.

 

Nella sezione Advanced functions, è possibile associare degli eventi al superamento delle soglie desiderate; ad esempio, è possibile settare una soglia corrispondente ad un valore di minimo ed una soglia corrispondente ad un valore di massimo in modo da creare un’isteresi e prevenire continui cambiamenti di stato quando si oltrepassa la soglia stessa.

Questa funziona è utile nel caso all’ingresso analogico è associato un trasduttore che consente la misura di grandezze analogiche, come la pressione atmosferica, la temperatura, l’umidità ecc.

Le soglie impostate consentono di controllare sia gli I/O configurati come uscita, che i relé presenti sulla scheda. In questo modo, ad esempio, è possibile collegare un fotoresistore ad uno degli ingressi analogici ed usare la board come interruttore crepuscolare.

L’ultima pagina che proponiamo è nominata Date & Time ed è riportata in Fig. 8.

Questa pagina consente di visualizzare l’orario corrente presente nel circuito di RTCC della board e di modificarlo.

La modifica può avvenire manualmente impostando tutti i campi di data ed ora oppure abilitando il Network Time Protocol (NTP).

Quest’ultimo è un servizio che consente di ottenere l’orario corretto tramite un server dedicato in Internet. Inoltre da questa pagina Web è possibile selezionare l’uso dell’ora legale ed impostare il proprio time zone relativo al proprio fuso orario. L’ultima nota riguarda la procedura di reset delle impostazioni.

Fig. 8 Date and Time setting. Questa pagina Web consente di impostare l’orario e la data della scheda nonché di configurare l’ora solare o legale e la posizione rispetto al proprio fuso orario.

 

Nel caso in cui risulta necessario impostare nuovamente l’username o la password predefiniti, oppure si desidera resettare tutte le scelte relative ai parametri di rete (ad esempio per un’errata configurazione la board non è più raggiungibile tramite il proprio indirizzo IP) si può ricorrere alla procedura di reset.

Per fare questo è necessario tenere premuti, all’accensione e per più di 4 secondi, entrambi i pulsanti presenti sulla scheda. La modalità di reset sarà segnalata dal LED System D8 che lampeggerà velocemente durante i 4 secondi necessari a fornire il consenso e rimarrà acceso nell’attesa che l’utente rilasci i pulsanti. Al rilascio il software provvederà a sovrascrivere i parametri forniti dall’utente con i parametri predefiniti.

Al termine dell’operazione, il LED D8 tornerà a lampeggiare con un intervallo di circa 1 secondo per indicare il normale funzionamento.

Richiesta GET alla ethernet board

L’Hypertext Transfer Protocol (HTTP) consente di abilitare la comunicazione tra un client ed un server.

Tipicamente il client è rappresentato dal Browser Web del vostro computer ed il server è ospitato da un servizio remoto, come ad esempio Google. Nel caso specifico il server è in esecuzione all’interno della board ed è raggiungibile direttamente dalla vostra rete LAN.

La consultazione delle pagine Web di un server Web avviene tramite due metodi di base identificati con le sigle GET e POST.

Tipicamente una GET rappresenta una richiesta di risorse da parte del client al server, mentre una POST è un modo per inviare un form di dati al server. In entrambi i casi il client specifica qual è la risorsa con cui si interagisce inserendola subito dopo l’indirizzo del server.

Ad esempio la stringa http://192.168.3.10/index.htm digitata nel vostro browser produrrà una richiesta GET, chiedendo al server identificato dall’indirizzo IP 192.168.3.10 di rispondere restituendo la risorsa (file) index.htm.

Nella pratica GET consente di specificare anche una serie di parametri opzionali separando la risorsa dai parametri con un ‘?’ come nell’esempio seguente:
http://192.168.3.10/index.htm?name1=value1&name2=value2

I parametri sono specificati in coppie chiave=valore e sono separati l’uno dall’altro da un &.

In genere il numero massimo di parametri non è definito a priori, ma dipende dalla configurazione del server. Tipicamente si usa un limite in byte per tagliare le richieste eccessivamente lunghe e prevenire problemi di buffer overflow.

Queste coppie chiave valore posso essere usate dal server come input per fornire una risposta dinamica.

Stesso risultato si potrebbe ottenere usando una richiesta POST; la differenza è che una GET tipicamente è molto più leggera in termini di byte consumati e questa caratteristica la rende interessante nel nostro caso dove le risorse di memoria del server sono limitate. Usando questa tecnica è inoltre possibile controllare lo stato delle uscite digitali ed i relè, semplicemente salvando l’indirizzo nell’elenco dei preferiti del proprio browser.

Per essere precisi, bisogna aggiungere che la scheda implementa un meccanismo di autenticazione chiamato Basic Access Authentication (BA); tale meccanismo è una soluzione molto semplice per autenticare un client con una coppia di informazioni (nome utente e password). L’esempio seguente mostra come funziona il BA: http://username:[email protected]/index.htm

In realtà la coppia username:password non è trasmessa in chiaro, ma viene mascherata codificandola in base64 e poi passata al server che effettuerà l’operazione in versa per verificare l’autenticità del richiedente.

Usando questa tecnica, la board fornisce una semplice interfaccia d’accesso che può essere implementata in svariate applicazione dagli utenti tramite lo sviluppo di app per smartphone o di appositi programmi per computer.

Per commutare lo stato di un I/O sarà quindi possibile invocare la seguente richiesta GET
http://username:[email protected]/prt/io.cgi?io=2&act=1
dove io=2 specifica l’IO numero 2 e act=1 lo pone a livello logico alto.

Similmente, per modificare lo stato di un relé il comando sarà:
http://username:[email protected]/prt/relay.cgi?relay=3&act=0
dove i parametri relay=3 e act=0 dicono al server di rilasciare il relé 3.

Le informazioni relative agli input sono invece codificate in un file XML seguendo una semplice logica chiave/valore. Per conoscere e consultare il file XML generati bisogna richiedere tale risorsa al server come nell’esempio seguente:
http://username:[email protected]/prt/io.xml
Alla richiesta, il server risponderà con un file formattato come segue:

<r>
<io1>1</io1>
<io2>1</io2>
<io3>1</io3>
<io4>1</io4>
<io5>1</io5>
<io6>1</io6>
<io7>1</io7>
<io8>1</io8>

<in1>1</in1>
<in2>1</in2>
<in3>1</in3>
<in4>1</in4>
<in5>1</in5>
<in6>1</in6>
<in7>1</in7>
<in8>1</in8>

<is1>0</is1>
<is2>0</is2>
<is3>0</is3>
<is4>0</is4>
<is5>0</is5>
<is6>0</is6>
<is7>0</is7>
<is8>0</is8>
</r>

Dove la stringa ioX rappresenta la direzione dell’I/O numero X, la stringa inX rappresenta lo stato corrente dell’I/O ed infine la stringa isX rappresenta lo stato da attivare all’accensione della scheda. Similmente, i file relay.xml e analog.xml conterranno lo stato corrente dei relé e degli ingressi analogici.

Piano di montaggio

Elenco componenti

C1, C2: 10 µF 25 VL ceramico (1206)
C3÷C5, C11, C13, C14, C16, C18, C20, C22, C25, C27, C31, C32, C35÷C48: 100 nF ceramico (0603)
C6÷C9: 47 µF ceramico (1206)
C10: 3,3 nF ceramico (0603)
C12, C30: -
C15, C17, C29: 10 µF ceramico (0805)
C19, C21: 10 pF ceramico (0603)
C23, C24: 56 pF ceramico (0603)
C26, C28: 33 pF ceramico (0603)
C33, C34: 47 µF ceramico (1206)
R1, R22, R27, R33: 0 ohm (0603)
R2, R38, R49, R60, R71: 1 kohm (0603)
R3, R18, R20, R21, R12, R13, R25, R28, R29, R36, R37, R44, R45, R47, R48, R55, R56, R58, R59, R66, R67, R69, R70, R77, R78: 470 ohm (0603)
R4: 62 kohm (0603)
R5: 11,8 kohm (0603)
R6: 25 kohm (0603)
R7, R8, R10, R16, R34, R35, R39÷R42, R50÷R53, R61÷R64, R72÷R75: 10 kohm (0603)
R9, R11: 100 ohm (0603)
R14: 10 ohm (0603)
R15: -
R17, R19, R23: 100 kohm (0603)
R24, R26, R30, R32: 49,9 ohm (0603)
R31: 2,26 kohm (0603)
R43, R54, R65, R76: 10 kohm 1% (0603)
R46, R57, R68, R79: 5,1 kohm 1% (0603)
Q1÷Q20: DMG2302U-7 
U1: RT7247C
U2: AP7333
U3: ESP8266
U4: MCP79402
U5: PIC18F67J60 (MF1333)
U6: SST25VF016B
U7: 24FC1025-I/SN
X1: Quarzo 32.768 kHz
X2: Quarzo 25 MHz
D1: B340LA
D2, D3: LED verde (0603)
D4, D5, D14÷D16, D22÷D24, D30÷D32, D38÷D40: LED rosso (0603)
D6, D7, D9÷D13, D17÷D21, D25÷D29, D33÷D37: CDSU4148
D8: LED giallo (0603)
L1: Bobina 6,8 µH
L2, L3: Ferrite 600 ohm/100 MHz (0603)
P1, P2: Microswitch
RL1÷RL4: Relé 5V/5A
B1: Porta batteria CR1220 da CS
LAN: Presa LAN RJLD-260TC1
ICSP: Strip maschio 6 vie
RESET: Strip maschio 2 vie
I2C: Strip maschio 4 vie
ON/OFF: Strip maschio 2 vie
VDDSEL: Strip maschio 3x2 vie
Varie: 
- Jumper (2 pz.)
- Plug alimetnazione
- Morsetto 6 vie passo 3,5mm
- Morsetto 10 vie passo 3,5mm
- Morsetto 12 vie passo 3,5mm
- Strip femmina 4x2 vie
- Circuito stampato S1333 (100x80 mm)

Il software

In questo paragrafo ci occuperemo di descrivere il software impiegato per realizzare il firmware del progetto.

L’impiego del compilatore C18 invece del nuovo XC8 è necessario per poter usare le librerie legacy fornite dalla Microchip che contengono lo stack TCP/IP necessario al funzionamento della rete Ethernet.

Le librerie impiegate ed il compilatore sono scaricabili dal sito www.microchip.com.

A questo punto possiamo fornire una panoramica sulle routine base del software.

La prima funzione da analizzare è il main visibile anche nel Listato 1. In questa funzione sono raggiunti due obiettivi: l’inizializzazione delle principali funzionalità (compresa l’inizializzazione delle periferiche hardware) ed il polling periodico di ognuno degli handler associati alle diverse funzionalità.

La tecnica di invocare periodicamente i gestori di ogni funzione consente di realizzare con pochissime risorse un programma multitasking. La difficoltà di questa tecnica sta nel dividere le funzionalità in più task di ridotte dimensioni (in termine di tempo di esecuzione).

Se ogni task impiega pochi millisecondi e il partizionamento avviene correttamente, quindi senza creare frazioni troppo lunghe o troppo corte, il microcontrollore sarà in grado di eseguire più “programmi” contemporaneamente.

D’altro canto l’incorretta suddivisione dei task può provocare dei problemi specialmente per quelle funzioni che necessitano di essere chiamate con regolarità, ad esempio StackTask() che gestisce tutti i protocolli di basso livello per l’accesso ad Internet.

Listato 1

void main(void) {
  static DWORD t = 0;
  static DWORD dwLastIP = 0;

  // 1 - Initialize application specific hardware
  InitializeBoard();
  // 2 - TickInit must be the one of the first initialization to use the software timeouts
  TickInit();
  // 3 - Initialize I2C used by ExtRTCC
  InitI2C();
  // 4 - Initialize External RTCC (MAC Address)
  InitExtRTCC();
  // 5 - Initialize MPFS file system linked to internal Flash
  MPFSInit();
  // 6 - Check user restore trigger
  checkManualRestoreDefault();
  // 7 - Initialize Stack and application related NV variables
  InitAppConfig();
  // 8 - Initialize core stack layers (MAC, ARP, TCP, UDP) and application modules (HTTP, SNMP, etc.)
  StackInit();
  // 9 - NTP Client initialization
  NTPInit();
  // 10 - Ping handler
  InitPing();
  // 11 - Reboot manager
  rebootInit();
  // 12 - Do a DDNS connection
  ddnsInit();
  // 13 - Initialize HTTP Client
  HTTPClientInit();
  // 14 - Initialize EMail
  EmailInit();
  // 15 - Initialize relay
  InitRelaies();
  // 16 - Initialize IO
  InitIO();
  // 17 - Initialize Input
  InitInput();
  // 18 - Initialize ADC
  InitADC();

  // Now that all items are initialized, begin the co-operative
  // multitasking loop. This infinite loop will continuously
  // execute all stack-related tasks, as well as your own
  // application’s functions. Custom functions should be added
  // at the end of this loop.
  // Note that this is a “co-operative multi-tasking” mechanism
  // where every task performs its tasks (whether all in one shot
  // or part of it) and returns so that other tasks can do their
  // job.
  // If a task needs very long time to do its job, it must be broken
  // down into smaller pieces so that other tasks can have CPU time.
  while (1) {
    // Blink LED0 (right most one) every second.
    if (TickGet() - t & gt; = TICK_SECOND / 2 ul) {
      t = TickGet();
      LED_0_INV();
    }

    // This task performs normal stack task including checking
    // for incoming packet, type of packet and calling
    // appropriate stack entity to process it.
    StackTask();
    // This tasks invokes each of the core stack application tasks
    StackApplications();
    // Ping request task handler
    PingTask();
    // NTP Handler
    UDPClientNTPHandler();

    InputTask();
    IOTask();
    ADCTask();
    RelayTesk();

    ExtRTCCSetTimeFromNTPTask();
    rebootTask();
    HTTPClientTask();
    sendEmailTask();

    // If the local IP address has changed (ex: due to DHCP lease change)
    // write the new IP address to Announce service
    if (dwLastIP != appConfig.ip.fields.MyIPAddr.Val) {
      dwLastIP = appConfig.ip.fields.MyIPAddr.Val;
      #if defined(STACK_USE_ANNOUNCE)
      AnnounceIP();
      #endif
    }
  }
}

Un altro esempio esplicativo del principio di funzionamento implementato riguarda il gestore delle richieste GET per l’IO. L’esempio riportato nel Listato 2 è facilmente generalizzabile anche ad altri casi, come per il controllo degli ingressi analogici e dei relé, quindi ci limiteremo a descrivere solo il caso per dell’IO. La funzione HTTPAppGetIO(HTTP_CONN * curHTTP) viene invocata quando il Browser Web effettua una richiesta GET verso il server richiedendo la pagina “prt/io.htm”. Al suo interno le funzioni parametrizzate come HTTPGetROMArg(curHTTP->data, (ROM BYTE *) “io”) consentono di ritornare il puntatore alla coppia chiave=valore individuata nell’esempio dalla stringa “io”. In questo modo la parte di codice successivo può interpretare la richiesta dell’utente ed eventualmente invocare il codice che controlla lo stato degli ingressi.

Listato 2

void HTTPAppGetIO(HTTP_CONN * curHTTP) {

  BYTE * io, * action, * direction, * startup;

  io = HTTPGetROMArg(curHTTP - & gt; data, (ROM BYTE * )“ io”);
  action = HTTPGetROMArg(curHTTP - & gt; data, (ROM BYTE * )“ act”);
  direction = HTTPGetROMArg(curHTTP - & gt; data, (ROM BYTE * )“ dir”);
  startup = HTTPGetROMArg(curHTTP - & gt; data, (ROM BYTE * )“ st”);
  if (io & amp; & amp; action) {
    setOutputStateIO( * io - ‘0’, * action - ‘0’);
  }
  if (io & amp; & amp; direction) {
    setDirectionIO( * io - ‘0’, * direction - ‘0’);
  }
  if (io & amp; & amp; startup) {
    setStartupIO( * io - ‘0’, * startup - ‘0’);
  }
}

.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Menu