Internet of Things, parte prima.

Le schede compatte con processore permettono di creare dispositivi snelli con i quali interagire attraverso internet.

Schede adeguate allo scopo possono essere quelle  con CPU ARM quali Allwinner A20, doppio core ad 1GHz, o Broadcom BCM 2836, quattro core a 900 MHz.  Sono stabili, poco costose, con dimensioni minime, ben collaudate e documentate. Esiste per loro una distribuzione Linux, in genere derivata da Debian, matura, evoluta ed usabile mediante programmazione perlopiù Python o C++.

La principale questione da affrontare è  costituita dall’interazione della scheda con la realtà locale, mediante specifica elettronica, costruita su misura e scegliendo i componenti più adeguati. Le parti  elettroniche necessarie e la loro documentazione sono facilmente reperibili, anche già pronte all’uso in piccole schede. Queste schede tipicamente aggregano pochi componenti, per esempio un integrato destinato alla saldatura superficiale con qualche componente passivo od un operazionale di supporto. La comunicazione avviene mediante header che espongono segnali ed accettano alimentazioni.  Il mondo Arduino, con i suoi standard, ha contribuito a diffondere questi prodotti.

Strettamente legati all’acquisizione sono le questioni relative al  BUS locale da utilizzare per il trasporto delle informazioni, ad esempio una variante della seriale od I2C o SPI od USB od altro, e del canale di comunicazione verso il middleware, tipicamente nel cloud. Poi si aggiungerà il problema del dialogo tra un dispositivo mobile, per esempio con Android od iOS, verso il middleware stesso.

L’elettronica locale necessaria è strettamente correlata alla realizzazione specifica.

Quindi procediamo scegliendo un tema concreto da affrontare, per esempio le misure di potenza in corrente alternata per il  monitoraggio energetico.

Rileviamo in questo contesto una sola misura, ma la più completa: la  potenza reale in corrente alternata. Esempi di applicazioni  concrete sono la misura dell’assorbimento elettrico di una pompa di calore o di un intero impianto elettrico, ma anche la misura della potenza reale verso un sistema acustico costituito da diffusori sonori. Rimandiamo ad altre letture il chiarimento della differenza della misura di potenza della radice quadrata dei quadrati dei valori, ovvero RMS, e la potenza reale che vede la somma aritmetica tra potenza, per convenzione positiva, assorbita dal sistema e la potenza, negativa, che il sistema stesso produce e rende all’impianto erogatore.

L’esperienza porta presto a fissare come riferimento per le misure di tensione e corrente intervalli temporali del millesimo di secondo.

Quindi la potenza da  integrale, nella teoria, di una funzione continua a tratti, diventa discreta con rettangoli di base un millisecondo. Questa base in realtà è variabile, ma, in questo contesto,  imponiamo il vincolo che sia sempre nel millisecondo. Con questi valori, per dire,  la misura di consumi in kWh risulta estremamente precisa.

Entro tale intervallo temporale, con una sola fase ed allo stesso istante temporale, si devono eseguire  coppie di misure, ovvero una di corrente ed una di tensione.

Per realizzare un dispositivo che compia queste attività,  consideriamo una scheda con processore ARM con il sistema operativo Linux Debian per ARM, la GPIO interna e lo specifico  modulo kernel.

Le schede con processore ARM più diffuse non hanno convertitori ADC. Pertanto abbiniamo alla scheda un circuito integrato che aggiunga otto ADC, per esempio il diffuso  MCP3008, collegati, in questo caso,  mediante il  BUS di comunicazione  SPI.

I data sheet mostrano che la capacità massima  di letture e comunicazione dell’integrato è di 250.000 sps, numero di campioni al secondo, con 5V di alimentazione. Purtroppo tale massimo scende a 75.000 sps,  in quanto la scheda ARM richiede la comunicazione con alimentazione a 3.3V. Quindi abbiamo il limite strutturale di al più 75 campioni nel millisecondo, che se distribuiamo in 8 canali, possiamo esprimere la massima velocità di acquisizione  di ogni campione tra 0.1 e 0.5 ms, sempre leggendo tutti i canali. In definitiva ottimizzando il sistema è auspicabile ottenere tra le due e le tre letture nel millisecondo usando in contemporanea con tutti gli otto canali.

La questione si sposta sui tempi di trasporto, attraverso SPI, sui tempi di processo dei dati, legati ai  core ARM, ed infine sulla memorizzazione temporanea  od il  trasporto diretto, stream,  nel middleware.

Il principale parametro che influisce è la velocità del clock del bus SPI che, di fatto, determina la velocità di computazione del MCP3008. Alcuni semplici test permettono di individuare la velocità ottimale, sopra la quale il degrado del segnale porta a diminuire la velocità di trasporto e sotto la quale semplicemente il sistema va più piano, il fattore ottimale oscilla intorno al default, ovvero 1MHz, quindi si possono provare valori tra 0.8 ed 1.2 MHz.

Altri semplici test mostrano che la lettura di tutti gli 8 canali realizzata in Python sfora il tetto del millisecondo, portanto l’intervallo per la gestione dell’intero processo sull’ordine dei 10ms, che non è per noi accettabile. Se si utilizza GCC con sorgente C++  i tempi per l’intera computazione di tutti gli otto canali, acquisizione, ricalcolo, invio o scrittura, sono inferiori al millisecondo, e quindi ci siamo.

La grande questione è se Debian introduca delle  interruzioni occasionali che facciano sforare il millisecondo, infatti le distribuzioni ARM utilizzabili non sono compilate con il kernel in modalità real time. Proviamo ad aggirare l’ostacolo rimuovendo ogni servizio non indispensabile che possa introdurre interrupt al livello kernel, non avviando il server X, assegnando il miglior  nice al processo di acquisizione, ottimizzando l’utilizzo del modulo kernel dedicato all’interazione con la GPIO, confidando nella generosa potenza di calcolo dei nuovi processori utilizzati ed apportando ogni miglioria suggerita dall’ esperienza.

I risultati sono fortemente motivanti, infatti alcuni test, realizzati con  quad core a 900MHz e compilato C++, mostrano che si possono gestire l’ acquisizione, i calcoli e la scrittura in buffer,  entro tempi tra gli ordini di 10 e 100 micro secondo, quindi ampiamente nei tempi posti come vincolo.

Per sviluppare la nostra applicazione fissiamo il secondo come intervallo per il calcolo della media aritmetica della potenza reale, che sia sommatoria di aree d’altezza i campioni e di base comunque inferiore al millisecondo.

Miglioreremo l’algoritmo con l’esclusione delle misure non sensate, per esempio ricordando le ultime due misure e computando per corrente il valore  intermedio, oppure quello medio od altro. Ma anche la semplice computazione puntuale, come riferimento, può essere molto interessante.

Il processore locale quindi deve spostare dei valori nel middleware con frequenza del secondo.

Purtroppo il buffer temporaneo per i dati ricalcolati non può stare in SD  o mSD per la latenza complessiva rovinosa sull’ordine, ma anche peggiore, del secondo. Altro aspetto, ma non trascurabile, è che lo stream dati verso il middleware deve essere completamente indipendente dal processo di acquisizione e ricalcolo, pertanto il buffer deve permettere l’accesso concorrente da processi diversi. Affronteremo nel dettaglio questi temi in prossimi articoli.

La più naturale soluzione è di costruire il buffer in RAM.

Quindi, come ultima attività, costruiamo un secondo programma per muovere le informazioni dal buffer al middleware. In questo caso è possibile lavorare anche in Python.

Distinguiamo due possibilità:

  1. spostamento in tempo reale
  2. spostamento differito secondo un dato intervallo.

Iniziamo a costruire il processo di spostamento differito. La soluzione più semplice, che ci risparmia di costruire un processo per il controllo del buon funzionamento del trasporto dati verso il middleware, è di usare il servizio cron. Ma con questa scelta ci vincoliamo al minuto come frequenza minima dell’aggiornamento remoto. E’ evidente che per il calcolo di potenze in termini di kWh l’aggiornamento sull’ordine del minuto può essere ben accettato.

Dedicheremo una discussione specifica sulla connettività, tipicamente con ampi tratti internet,  tra il dispositivo di acquisizione ed il middleware.

Alcuni sistemi che abbiamo realizzato secondo le linee guida esposte, risultano stabili e rispettano i vincoli dati, quindi possiamo continuare questa esperienza di progetti e costruzione di sistemi IoT.

Nei prossimi articoli affronteremo la parte di misura, il disaccoppiamento dei sensori da picchi indotti dalle alte correnti e tensioni variabili in ballo, rivedremo l’alimentazione dei dispositivi stessi, alcuni aspetti relativi al middleware nello spazio  cloud,  la gestione dei dati mediante un’app desktop che permetta estrapolazioni, per esempio, nel formato foglio di calcolo ed infine la costruzione di una app mobile per visualizzare informazioni, ma anche interagire, nel middleware.