Impariamo a utilizzare Antennino per creare una comunicazione IoT

Iniziamo a utilizzare le nostre schede per l’IoT basate su architettura Arduino.

Quando in questi post (Antennino: l’Arduino con l’antenna e Antennino: l’Arduino con l’antenna – Carichiamo il bootloader) vi abbiamo presentato Antennino, ossia una speciale scheda Arduino dotata di connettività e capace di operare in modalità Periferica o Gateway, ci siamo fermati alla descrizione dell’hardware e alla configurazione, promettendovi di ritornare sull’argomento per farvi vedere in pratica un esempio di utilizzo applicabile al mondo reale.

Abbiamo messo in evidenza le peculiarità di Antennino, spiegato cosa sono e come si configurano i FuseBit, conducendovi fino al caricamento di un bootloader su Antennino.

Ora è arrivato il momento di passare alla pratica, realizzando la comunicazione tra due moduli: uno configurato come sensore remoto (Periferica) e l’altro da Gateway; quest’ultimo avrà a bordo il piccolo display OLED, mentre l’altro sarà il nodo sensore.

Per quest’ultimo utilizzeremo due diverse configurazioni di Antennino e di conseguenza due sketch: il primo farà uso della modalità LowPower associata all’impiego del chip TPL5110, quindi durante il periodo di riposo del nodo sensore, l’unico chip che rimarrà attivo sarà il TPL5110, riducendo così l’assorbimento a 29 nA. Nel secondo esempio utilizzeremo invece la seconda modalità LowPower di Antennino, quella propria dell’ATmega328P.

Concluderemo con l’esecuzione dell’aggiornamento OTA dei moduli Antennino.

Carichiamo il primo Sketch

Antennino, contrariamente alle schede Arduino cui siamo abituati, non possiede un connettore USB a bordo e quindi per poterlo programmare è necessario dotarsi di un adattatore USB/TTL.

L’adattatore deve avere un connettore micro o mini USB femmina ed un connettore con passo 2.54 mm con il classico pin-out [GND-CTS-VCC-TX-RX-RTS].

Quando lo collegherete la prima volta alla porta USB del vostro PC vi verrà richiesto di installare i driver, i quali possono essere reperiti dal sito del rivenditore dell’adattatore oppure dal produttore del chip.

Nel caso in cui abbiate scelto un adattatore con chip FT232 i driver si trovano alla pagina del produttore.

Il dispositivo presente nello shop qui a destra UC00A è un buon candidato.

Terminata l’installazione se tutto è andato a buon fine dovreste trovare una nuova porta COM virtuale pronta per l’uso.

Attenzione: prima di collegare l’adattatore ad Antennino, verifichiamo che l’adattatore sia configurato per lavorare con una tensione di 3,3V e non 5V.

Hello Antennino

È sempre bene ricevere una piccola gratificazione immediata ed allora facciamo una cosa. Essendo Antennino a tutti gli effetti un Arduino, vediamo se il classico Sketch Blink funziona sulle nostre due schedine (Listato 1).

Listato 1

#define LED 9
void setup() {
  pinMode(LED, OUTPUT);
}
void loop() {
  digitalWrite(LED, HIGH);
  delay(1000);
  digitalWrite(LED, LOW);
  delay(1000);
}

 

Unica accortezza è definire il PIN associato al LED in modo corretto. Ricordiamo che su Antennino il LED si trova sul PIN 9.

Per poter iniziare a programmare con Antennino dobbiamo indicare alla IDE di Arduino quale Board stiamo usando. Antennino è compatibile con Arduino/Genuino Uno, quindi selezioniamo dal menu (Fig. 1)
Tools>Board> “Arduino/Genuino Uno”.

 

Fig. 1 Selezione Board

 

Per poter caricare gli Sketch su Antennino, non è obbligatorio rimuovere le batterie, ma è una procedura consigliata per evitare che una configurazione errata dei jumpers possa creare dei problemi.
Per programmare la scheda è necessario settare i ponticelli come in Fig. 2, in modo di poter alimentare Antennino dal cavo dell’adattatore USB.

Fig. 2 Configurazione jumper per alimentare la scheda da adattatore USB

 

In questo modo la scheda viene alimentata tramite il regolatore lineare MCP1703. Per quanto riguarda la piedinatura del connettore per la programmazione fate riferimento alla Fig. 3.

Fig. 3 Connettore Seriale per caricamento Sketch

 

La disposizione dei pin è pensata in modo che una eventuale inversione non crei dei danni, ma è sempre buona norma prestare la massima attenzione nella fase di collegamento dei connettori. Siete pregati di fare riferimento a questa configurazione per il caricamento degli altri Sketch nel corso dell’articolo.

Colleghiamo infine l’adattatore USB al PC e al connettore di Antennino e clicchiamo sul pulsante a forma di Play della IDE per compilare e caricare il nostro primo Sketch sulla nostra Board.

Se tutto funziona a dovere dovreste vedere lampeggiare velocemente il led a bordo dell’adattatore USB e al termine se non ci sono stati errori il led a bordo di Antennino dovrebbe iniziare a lampeggiare al ritmo di circa un impulso al secondo. Bene, ora che abbiamo testato le nostre schede possiamo dedicarci a qualcosa di più impegnativo e gratificante.

Ora iniziamo a fare sul serio…

Come avrete notato, nello Sketch Blink che abbiamo appena caricato non sono state definite delle librerie particolari.

Gli sketch che impiegheremo ora, utilizzano librerie che normalmente non si trovano nelle installazioni standard, dovremo scaricarle, scompattarle ed inseribile nella opportuna cartella libraries della IDE di Arduino.
Ad onore del vero esiste un’altra modalità di scaricamento delle librerie, ma per il momento preferiamo usare questa prassi manuale, ma che ci permette di avere più consapevolezza di dove andranno a finire le librerie scaricate.

Nel caso abbiate già una o più delle librerie che vi indichiamo sotto, provate ad usare quelle già presenti e solo in un secondo momento se incontraste un problema di compilazione di Antennino relativo alle librerie “vecchie” andate a sostituirla con quella da noi proposta.

Scarichiamo quindi dalle seguenti URL le librerie elencate:

https://github.com/LowPowerLab/SPIFlash
https://github.com/PaulStoffregen/OneWire
https://github.com/milesburton/Arduino-Temperature-Control-Library
https://github.com/GreyGnome/PinChangeInt
https://code.google.com/p/u8glib/

Per comodità, a questo link https://github.com/open-electronics/antennino sono disponibili le librerie e i sorgenti.

Una nota che potrebbe essere banale per i più esperti ma che molte volte fa perder un sacco di tempo ai neofiti: raggiungendo il link Github della prima libreria, atterreremo nella pagina simile a quella riportata in (Fig. 4).

 

Fig. 4   GitHub, come scaricare una libreria dal repository

 

A questo punto, per scaricare la libreria necessaria dovremo cliccare sul pulsante “Clone or download”.

Unzippiamo il file che abbiamo scaricato.

Il file conterrà una cartella con il seguente nome (in questo caso): SPIFlash-master.

Rimuoviamo il suffisso “-master”, lasciando solo la prima parte del nome della cartella: SPIFlash.

Ripetiamo lo stesso procedimento per le successive librerie da scaricare. A questo punto abbiamo diverse cartelle distinte: RFM69, SPIFlash, ecc.

Ora dobbiamo individuare dove L’IDE di Arduino conserva le librerie. Normalmente la cartella si trova nel seguente percorso:

C:\Program Files (x86)\Arduino\libraries

Andremo quindi ad inserire le cartelle delle nuove librerie scaricate nella cartella libraries di Arduino. Riavviamo l’IDE Arduino e saremo pronti a lavorare.

 

Primo test con Antennino:
Nodo modalità Lowpower-TPL5110

In questo primo test utilizzeremo una scheda Antennino su cui andremo a caricare lo Sketch Node-TPL5110.ino. In Fig. 5 vediamo come dovremo configurare i jumper una volta terminato il caricamento del firmware.

Fig. 5 Configurazione jumper per nodo TPL5110

 

Gli sketch corrispondenti sono piuttosto lunghi, per cui non li riporteremo integralmente, ma metteremo in evidenza solo le parti salienti; chi vorrà potrà scaricarli qui sotto nella sezione download.

Dopo la parte iniziale in cui si definiscono le librerie da includere, abbiamo inserito la definizione di due parametri molto importanti per quanto riguarda la possibilità di aggiornare il modulo da remoto. Vedere il Listato 2.
FAMILY specifica la tipologia di nodo.

Mentre FIRMWAREVERSION definisce la versione attuale del firmware caricato sul nodo. Vedremo poi come vengono impiegate queste informazioni per l’aggiornamento OTA.

Parte comune a tutti gli Sketch che andremo ad utilizzare d’ora in poi è la configurazione della sezione RF che deve essere personalizzata nel valore del NODEID.

Nel nodo sensore che andremo ad utilizzare abbiamo settato il valore come riportato nel listato.

Sempre da Listato 2 abbiamo riportato le quattro variabili principali che definiscono i settaggi di rete del nodo.

Listato 2

byte FAMILY =1;
byte FIRMWAREVERSION = 1;

byte NODEID = 1; 
byte NETWORKID = 1;
byte DATA_GATEWAY_ID = 253;
byte OTA_GATEWAY_ID = 254;

 

Questi parametri verranno caricati nella EEPROM del chip ATMEGA328p per evitare che in seguito all’aggiornamento OTA possano essere sovrascritti. Quindi l’aggiornamento modificherà il funzionamento del nodo ma non i parametri di rete del nodo in modo da preservarne l’identità in rete.

Lo sketch del nodo sensore è strutturato nel modo classico, con una parte iniziale in cui vengono definiti gli import, le variabili globali e alcune funzioni usate ripetutamente: ReadLux(), ReadBatteryLevel(), ReadTrigger(), sendData() etc..

Naturalmente abbiamo la parte comprendente il Setup che inizializza il funzionamento e il ciclo Loop che viene ripetuto finché il dispositivo non viene resettato.

Particolare attenzione va posta alla funzione ReadTrigger() che riportiamo per esteso nel Listato 3.

Listato 3

int ReadTrigger() {
  // Leggo la tensione presente sulla capacità C1
  int v = analogRead(TRIGGER_INPUT);
  delay(50);
  // Scarico il condensatore portando il PIN in modalità OUTPUT
  // e poi ad un livello Basso
  pinMode(TRIGGER_INPUT, OUTPUT);
  digitalWrite(TRIGGER_INPUT, LOW);
  return v;
}

 

Ricordiamo brevemente che nella modalità Lowpower che usa il TPL5110 il microcontrollore non è alimentato e quindi i classici interrupt non funzionano.

Inoltre non è sufficiente risvegliare il Microcontrollore, ma è necessario informarlo che il risveglio è stato causato da un segnale di allarme che deve essere intercettato dal codice al momento del risveglio.

È qui che entra in gioco la funzione ReadTrigger(). Questa funzione viene invocata nella fase di setup di Antennino.

Normalmente Antennino si risveglia secondo l’impostazione del trimmer collegato al timer TPL5110 ma questo risveglio programmato serve a notificare al gateway che il nodo è ancora in “buona salute” e ad inviare alcune informazioni come lo stato della batteria, la luminosità ecc…

Quindi il risveglio programmato non deve scatenare alcun allarme sul Gateway.

Se quindi il risveglio è dovuto ad un evento schedulato il valore letto dalla funzione ReadTrigger() sarà un valore molto basso se non proprio 0.

Se invece il risveglio del nodo sensore è stato causato portando a massa il pin WUP, questo provocherà il risveglio immediato del TPL5110 anche se non è scaduto il tempo programmato e contestualmente il caricamento del condensatore C1 il qual essendo collegato ad un ingresso analogico ad alta impedenza permarrà carico per un certo tempo e sicuramente nel momento in cui la funzione ReadTrigger() andrà a leggere il valore lo troverà alto e questo permetterà di capire che il risveglio è stato causato da una situazione di allarme.

Appena eseguita la lettura analogica del valore presente sulla capacità la modalità del PIN viene modificata per settarlo come PIN di OUTPUT a valore LOW, questo determina la scarica quasi immediata della capacità allo scopo di evitare che al prossimo risveglio programmato del timer venga trovata ancora un valore alto in conseguenza della carica residua della capacità C1.

In seguito al rinvenimento di un valore alto della carica della capacità C1, nella fase di Loop, il valore della struttura di payload viene caricato con il valore allarme = 1, con gli altri valori acquisiti dai sensori e viene inviato immediatamente un pacchetto di dati al Gateway_Dati.

Dall’estratto di codice del Listato 4 vediamo che viene invocato l’invio tramite la funzione radio.sendWithRetry, la quale si attende un ACK (segnale di feedback) da parte del nodo Gataway, se il nodo non risponde vengono fatti tentativi successivi.

Listato 4

if (radio.sendWithRetry(GATEWAYID, (const void * )( & amp; theData), sizeof(theData), ACK_TIME)) {
  Serial.println(“- & gt; Reply OK!”);
  packet_sent_correctly = true;
  Serial.println(F(“--STOP TASK--”));
  // Disabilito l’alimentazione
  digitalWrite(DONE_TASK, HIGH);
} else {
  Serial.println(“- & gt; NO reply...”);
  number_of_attempts = number_of_attempts + 1;
}

Nel momento in cui risponde, il codice digitalWrite(DONE_TASK, HIGH); Porta High il pin Done del timer TPL5110 il quale in seguito a questo determina la rimozione immediata della tensione al Microcontrollore ed il ciclo si ripete in attesa dello scadere del tempo del timer o di un evento di allarme sul pin di risveglio.

Negli esempi si è fatto uso di una struttura dati che si chiama “struct” vedi Listato 5 che verrà utilizzata per contenere il Payload (carico utile), cioè il dato informativo da inviare al gateway.

Listato 5

typedef struct {
  unsigned long uptime;
  float temp; 
  float battery_level;
  int lux;
  int allarm;
} Payload_t;

 

Questa struttura dati è definita in un file MyTypes.h a parte che deve essere messo nella cartella dello sketch principale e che deve essere poi incluso nello sketch stesso tramite l’istruzione #include “MyTypes.h”. Poi vedremo che lo stesso file contiene in effetti un’altra struttura dati che verrà usata per la programmazione OTA.

Una nota sul chip TPL5110: la modifica del valore del trimmer affinché si rifletta su una modifica dell’intervallo temporale necessità il riavvio dell’alimentazione.

Secondo test con Antennino:
Nodo modalità Lowpower-ATMega328P

In questo secondo esercizio utilizzeremo una scheda Antennino in modalità Lowpower. In Fig. 6 vediamo come dovremo configurare i jumper una volta terminato il caricamento del firmware.

Fig. 6 Configurazione Jumpers per modalità Lowpower classica

In questo caso caricheremo lo Sketch Node-LowPower.ino.

Anche per questo Sketch andremo ad analizzare solo le parti più interessanti. Nel Listato 6 vediamo una parte del loop ed in particolare la gestione del passaggio in modalità LowPower, l’intercettazione di un allarme tramite interrupt e l’invio di un pacchetto informativo periodico di dati al Gateway_Dati.

Listato 6

 if (TriggerDetected) {
   batteryReportCycles = 0;
   TriggerStatus = digitalRead(TRIGGER_INPUT);
   sendData();
   Blink(LED, 3);
 } else if (batteryReportCycles & gt; = BATT_CYCLES) {
   // invio le notifiche sullo stato della batteria solo se sono in modalità LowPower
   if (Sleep_Time & gt; 0) {
     sendData();
     Blink(LED, 3);
   }
   batteryReportCycles = 0;
 }
 if (Sleep_Time & gt; 0) {
   for (byte i = 0; i & lt; Sleep_Time; i++) {
     LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
   }
 }
 batteryReportCycles++;

 

Notiamo che se viene intercettato un interrupt la variabile TriggerDetected viene posta a true nel loop e questo determina l’invio di informazioni al Gateway_Dati tramite la funzione sendData(), la quale invia la struttura dati Payload_t valorizzata con i dati ricevuti dai sensori e lo stato dell’allarme.

Se durante il funzionamento normale non si verifica alcun allarme, allora l’invio di dati avviene quando batteryReportCycles >= BATT_CYCLES in pratica ogni risveglio viene incrementata la variabile batteryReportCycles e quando viene raggiunta la soglia BATT_CYCLES viene inviato un pacchetto di dati al Gateway_Dati.

Il cuore della temporizzazione è la funzione LowPower.powerDown che permette di portare a basso consumo il microcontrollore, in questo caso per un tempo di 8 Secondi. Si può ovviare al limite degli 8 secondi inserendo come nel blocco di codice di fig. 7 la funzione all’interno di un loop. In questo caso se Sleep_Time =1 il periodo di temporizzazione sarà di 8 secondi altrimenti sarà pari a 8S * Sleep_Time.

Fig. 7 Configurazione per alimentazione continua usando batterie AA a bordo

 

Se portassimo il valore di Sleep_Time=0 come risultato avremmo un nodo sensore che non andrà mai in modalità basso consumo.

Per triggerare un allarme è necessario portare basso il PIN D7. Questo evento farà risvegliare il nodo, determinerà l’invio di una struttura dati contenente il valore di allarme=1 e poi il nodo tornerà in modalità LowPower.

Gateway Dati

Possedere una rete di sensori senza poter elaborare le informazioni che gli stessi raccolgono è di scarsa utilità e quindi si rende necessario avere un nodo Gateway Dati che funga da concentratore per tutti i nodi sensori.

Allo scopo dobbiamo caricare su un modulo Antennino lo Sketch Gateway_Dati.ino

Anche in questo caso non riporteremo il listato completo ma solo le funzionalità più importanti.

Il Gateway_Dati deve poter ricevere le informazioni provenienti dai nodi sensori, quindi deve fare riferimento alla struttura dati trasmessa dai nodi, dovremo quindi includere MyTypes.h (vedi Listato 5).

Il gateway avrà come NODEID = 253 e quindi questo id non potrà essere usato da altri nodi della rete, mentre dovrà essere configurato in tutti i nodi sensori nella variabile DATA_GATEWAY_ID.

Sul modulo abbiamo previsto la possibilità di visualizzare i dati ricevuti in tempo reale tramite un piccolo display Oled.

Se ritenessimo di non volerlo utilizzare potremmo rimuovere tutti i riferimenti nel codice compresa l’importazione della libreria ed utilizzare solo la porta seriale per visualizzare i dati ricevuti sul monitor seriale collegato al PC.

Se invece intendiamo avvalerci del display Oled, dovremo sincerarci per prima cosa che il pinout dello stesso sia compatibile con quello di default del modulo Antennino, altrimenti si renderà necessario invertire le tracce sotto il connettore del display Oled. Non inserite un display con una piedinatura invertita perché rischiate di compromettere il funzionamento del display o del regolatori a bordo di Antennino.

Inoltre dovremo verificare il chip utilizzato sul display.

Nel codice sono previste già due opzioni: una configurazione relativa al chip SH1106 ed una relativa al chip SSD1306.

In mancanza di informazioni puntuali sul modulo è necessario andare a tentativi, ma non succederà nulla di grave: al massimo il display rimarrà nero.

Il Gateway_Dati non permette di memorizzare le informazioni pervenute dai sensori e quindi l’ideale sarebbe collegare tramite porta seriale il Gateway ad un Raspberry Pi dotato di un software specifico che permetta di storicizzare i dati ricevuti su un dB MySql ed eventualmente visualizzarli tramite una interfaccia Web.

Questa opzione è già in cantiere e vedremo di spiegarla eventualmente in un altro articolo. Per il momento potremmo intercettare l’arrivo di un allarme da un nodo ed attivare un pin di uscita dal Gateway collegato ad un allarme.

Dobbiamo decidere come alimentare il Gateway_Dati. Consideriamo due Opzioni.

Usiamo le batterie a bordo del modulo impiegando il regolatore Step-Up Max856. Questa naturalmente è una opzione di test ma che non ha senso usare in un ambito reale (Fig. 7).

L’altra opzione è quella che utilizza un’alimentazione esterna da applicare ai pin Vin del modulo antennino e che verrà portata a 3.3 V dal regolatore lineare MCP1703 a bordo del Modulo Fig. 8

Il funzionamento dello Sketch è veramente molto semplice, come di consueto è presente una sezione di definizione variabili, e delle funzioni comuni, una funzione di setup ed una di loop che è quella in cui vengono intercettati i dati ricevuti dai nodi sensori.

Fig. 8 Configurazione per utilizzare una alimentazione esterna

 

Il seguente spezzone di codice propone il Loop del Gateway_Dati.

Qui gestiamo la visualizzazione dei dati sul display; in alternativa possiamo gestire la ricezione di una condizione di allarme da un nodo, utilizzando allo scopo curData.allarm:

} else {
  Serial.print(F(“Invalid payload: “));
  Serial.print(‘[‘); Serial.print(radio.SENDERID, DEC); Serial.print(“]“);
  for (byte i = 0; i & lt; radio.DATALEN; i++) {
    Serial.print((char) radio.DATA[i]);
  }
  Serial.print(F(“[RX_RSSI: ”)); Serial.print(radio.RSSI); Serial.print(“]”);
  Serial.println(“”);
}

Analizzando il codice è evidente che il dato ricevuto dal sensore viene preso in considerazione solamente se ha una dimensione consona a quella della struttura dati che ci si attende Payload_t altrimenti viene emesso un messaggio con il testo: “Invalid payload”.

Se la dimensione del messaggio soddisfa questo primo filtro, il messaggio stesso viene “convertito” tramite la funzione Cast_To_Struct(curData , myOwnBuffer) nella struttura dati che ci si attende, per poterne estrarre le informazioni necessarie per poi visualizzarle sul display, attivare dei pin oppure inviarle ad un eventuale Raspberry pi tramite seriale.

Aggiornamento del Firmware di Antennino OTA

Durante il funzionamento normale i nostri nodi sensori, sia che utilizzino la modalità LowPower nativa oppure quella associata al chip TPL5110 si troveranno per la maggior parte del tempo in modalità basso consumo e quindi non saranno raggiungibili dal Gateway.

Dovrà quindi essere il nodo sensore a richiedere l’aggiornamento del Firmware nel momento in cui si risveglia dalla modalità LowPower.

Per implementare questa funzionalità abbiamo modificato il comportamento della libreria RFM69_OTA.cpp di programmazione wireless aggiungendo delle funzioni specifiche ed abbiamo realizzato una applicazione Windows AntenninoFlashProgrammer.exe

A tal fine è necessario caricare lo sketch Gateway_OTA.ino su un modulo Antennino che dovrà essere dedicato a svolgere la funzione di Gateway_OTA.

L’applicazione Windows in concerto con lo sketch caricato sul modulo Gateway_OTA permette di leggere un file binario .hex originato dalla compilazione eseguita con l’IDE Arduino e consente di caricarlo sulla FLASH memory a bordo del modulo Gateway_OTA.

Fatto questo il modulo viene posto in modalità Programmazione remota e sarà in grado di ricevere richieste di aggiornamento dai nodi Sensori che si trovano in modalità Lowpower.

Oppure se abbiamo dei nodi che sono sempre accesi potremmo uplodare direttamente l’aggiornamento definendo il node_id target sulla interfaccia della applicazione Windows ed inviare il nuovo firmware al nodo. In questo caso spetta a noi assicurarci che il nodo che abbiamo individuato come target sia adatto a ricevere la versione del Firmware che abbiamo pronta sulla Flash del nodo Gateway_OTA.

Se sbagliassimo non succederebbe nulla di grave, a patto che il nuovo firmware rispetti lo standard dei Nodi Antennino. Se per errore caricassimo sulla Flash del modulo Gateway_OTA uno sketch come il Blink.ino l’aggiornamento avverrebbe ma poi sarebbe impossibile effettuare un ulteriore aggiornamento OTA del nodo e saremmo costretti a smontare il nodo dalla sua sede e riprogrammarlo tramite seriale.

Nel caso della programmazione di nodi Lowpower, per assicurarsi che l’aggiornamento avvenga in modo corretto per ogni nodo viene indicata la famiglia di appartenenza e la versione del firmware corrente.

Al momento del risveglio il nodo sensore invia una richiesta di aggiornamento verso il Gateway_OTA, fornendo la versione attuale del firmware (FIRMWAREVERSION) e la famiglia di appartenenza del nodo (FAMILY) in modo che il firmware venga caricato sulla tipologia corretta di nodi remoti.

Le variabili relative all’ID del nodo remoto (NODEID), ID della rete (NETWORKID), ID del Gateway dati (DATA_GATEWAY_ID) e Gateway OTA (OTA_GATEWAY_ID) sono salvati in EEPROM, in modo che non vengano sovrascritte dall’aggiornamento del Firmware.

Il gateway riceve la richiesta di aggiornamento remoto, verifica se il firmware a disposizione è adatto al nodo richiedente. Esegue un confronto tra la famiglia del richiedente e quella assegnata al firmare sul gateway e verifica se la versione del firmware del nodo richiedente è inferiore a quella presente sul Gateway.

Se queste due condizioni sono soddisfatte viene iniziata la procedura di aggiornamento e al termine il nodo Sensore viene riavviato e fatto ripartire con la nuova versione del firmware. Al nuovo risveglio dallo stato Lowpower, se la versione sul gateway non viene aggiornata e di conseguenza incrementato in numero di versione, non si verificherà alcun successivo processo di aggiornamento. Per capire dove Arduino salvi i file binari .hex delle compilazioni che esegue, dobbiamo abilitare una opzione nella IDE.

Andiamo quindi sotto File/preferenze e spuntiamo “Show Verbose Output” (Fig. 10).

Fig. 10 Settaggio modalità Verbosa del log

 

Mandiamo quindi in compilazione uno sketch e andiamo a leggere (Fig. 11) il percorso nella parte di log della IDE di Arduino.

 

Fig. 11 Percorso di salvataggio dei binari degli sketch nell’IDE Arduino

 

Nello specifico abbiamo ottenuto il seguente percorso: C:\Users\AppData\Local\Temp\arduino_build_113078/Node-TPL5110.ino.hex

Purtroppo ogni volta che chiudiamo l’IDE e la riapriamo per compilare, la parte arduino_build_XXXXX cambia in modo random.

A noi però interessa la parte iniziale del percorso. Lanciamo l’applicazione Windows Antennino Flash Programmer.exe ed apriamo File/Settings (Fig. 12) ed inseriamo il BaudRate predefinito (115.200) e il percorso di ricerca dei file binari compilati dalla IDE di Arduino.

 

Fig. 12   Settings dell’applicazione

 

Per testare il funzionato di questa funzionalità, apriamo l’IDE di Arduino, mandiamo in compilazione uno sketch. Al termine della compilazione, lasciando aperta l’IDE Arduino, lanciamo l’applicazione Antennino Flash Programmer e clicchiamo sulla Combo Box “File to Upload” (Fig. 13) questo richiamerà una funzione che ci fornirà come primo elemento il percorso dell’ultimo file binario compilato dalla IDE di Arduino.

Fig. 13 Selezione dell’ultimo file binario compilato dalla IDE

 

Comodo, no?! Questo ci eviterà di dover ogni volta andare a leggere il lungo e verboso log di compilazione della IDE alla ricerca del file binario compilato.

Ora vediamo come caricare il file .HEX binario nella memoria Flash del Gateway_OTA. Dovremo preventivamente aver caricato lo sketch Gateway_OTA.ino sul modulo Antennino deputato a tale scopo.

Colleghiamo l’adattatore USB RS232 al modulo, selezioniamo la porta corretta, lasciando gli altri parametri invariati.

Clicchiamo sul pulsante “Load to Local Flash” (Fig. 14).

Fig. 14 Fase preparatoria per caricamento binario su Flash Locale

 

Dopo qualche secondo verrà mostrata una finestra di dialogo (Fig. 15) che richiede il consenso al caricamento. Selezionando Yes si inizia la procedura di caricamento del file binario nella Flash Memory del Gateway_OTA.

Fig. 15 Finestra di conferma per caricamento Flash in locale

 

Completata la procedura (Fig. 16), per poter inviare altri comandi dobbiamo attendere che si verifichi il Timeout (30 secondi).

Fig. 16 Caricamento file binario in Flash completato

 

A questo punto possiamo verificare il contenuto della memoria Flash (Fig. 17) al termine ripuliamo la finestra di Log della Applicazione cliccando sul pulsante “Clear”.

Fig. 17 Verifica del caricamento del binario sulla Flash Memory del Gateway_OTA

 

Ora testiamo l’aggiornamento OTA di un nodo. Per farlo ci servirà oltre al nodo Gateway_OTA anche un nodo Antennino con a bordo lo sketch di un nodo, per esempio TPL5110.ino. S

e usiamo il nodo TPL5110 dobbiamo settare i jumpers come abbiamo già visto nella Fig. 5. Per comodità (ma non è essenziale) potremmo collegare anche il nodo sensore tramite seriale al PC (ci servirebbero però due adattatori USB).

Una volta collegato il nodo alla seriale apriamo il Monitor Seriale relativo alla porta a cui è collegato il modulo e dovremmo vedere un Log simile a quello riportato in Fig.18.

Fig. 18 Log del modulo TPL5110

 

Notiamo che il nodo, circa ogni 8 secondi cerca prima di contattare il Gateway_OTA inviandoli la famiglia del nodo e la versione del Firmware. E poi cerca anche di inviare dati al Gateway_Dati per aggiornalo sullo stato dei sensori.

Ora colleghiamo al PC tramite adattatore USB anche il modulo Antennino che svolge il compito di Gateway_OTA. Mandiamo in esecuzione l’applicazione Antennino Programmer.exe e dalla scheda dello stesso settiamo il Gateway_OTA in modalità download (Fig. 19).

 

Fig. 19   Modalità di Aggiornamento di nodi Remoti LowPower

 

Apriamo quindi la connessione seriale con il modulo Gateway, inseriamo la famiglia del Firmware e la versione relativa al binario caricato nella Flash del Gateway e clicchiamo sul pulsante “Set Download Mode”.

Appena fatto vedremo arrivare le richieste di aggiornamento del nodo e se le condizioni sono corrette il nuovo firmware verrà scaricato e al termine il nodo remoto si riavvierà con la nuova versione.

A questo punto se abbiamo mantenuto invariate le condizioni del Gateway vedremo che alle nuove richieste di aggiornamento il Gateway_OTA risponderà che non è necessario alcun aggiornamento per il nodo perché la versione attualmente presente sul nodo remoto è uguale a quella presente sul Gateway.

È possibile aggiornare anche un nodo di tipo attuatore. Quindi un nodo che non si trovi a lavorare in modalità LowPower. In questo caso è sufficiente, una volta caricato il File binario del nuovo firmware sul Gateway_OTA, inserire il target ID del nodo da aggiornare e cliccare su “Flash to Remote Target”.

Il file binario verrà inviato al nodo remoto che, completata la procedura si riavvierà con la nuova versione del Firmware (Fig. 20).

Fig. 20 Update firmware di un nodo remoto in modalità Lowpower

Conclusioni

In questo articolo abbiamo inizialmente caricato uno sketch di test e poi siamo passati a testare le funzionalità di comunicazione tra un nodo sensore ed un nodo Gateway.

Abbiamo poi visto come utilizzare l’aggiornamento remoto OTA utilizzando un gateway specifico ed una Applicazione Windows che ci permette di caricare il binario nella Flash del nodo Gateway e di settare la modalità di aggiornamento dei nodi.

Nel prossimo Numero vedremo come realizzare un Gateway Raspberry Pi per storicizzare le informazioni sui sensori e visualizzare i dati su una interfaccia web.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Menu