Le reti di sensori ed attuatori sono un argomento tra i preferiti degli appassionati dell’elttronica e dell’informatica orientata ai device. Qui su antima non nascondiamo di essere anche noi sempre attivi in questo campo, e tutti i nuovi e meno nuovi device che escono sul mercato di anno in anno non fanno altro che rendere questa passione più forte e facilmente fruibile.
Uno dei concetti che mi appassionano di più nel settore è quello di creare ecosistemi applicativi dove questi dispositivi agiscono da end device per l’interazione con l’ambiente circostante. Come già discutevo nello scorso articolo sul setup della rete WiFi su ESP8266, sento però sempre il bisogno di potermi mettere a lavorare su una idea senza dover pensare ad alcuni dettagli noiosi e “non importanti”, soprattutto per piccoli progetti casalinghi.
Continuando dai concetti introdotti nell’articolo linkato sopra, oggi voglio approfondire ancora una volta l’argomento dell’ “avere già tutto pronto”. Vi presento quindi una libreria fatta in casa antima.it, per poter scrivere applicazioni per sensori/attuatori basati su ESP8266 concentrandoci solo sulla logica applicativa.
Tutto il resto, dall’interfacciamento con il WiFi, al setup del protocollo applicativo di comunicazione, è incluso nella libreria, di cui oggi vi propongo un tutorial. Come al solito parliamo di librerie basate su framework Arduino.
Link repo github: Antima.it@github – MoodyNodeESP
Il problema e la soluzione
L’ultima volta ho parlato del problema del salvare le credenziali della propria rete WiFi locale, di come sia noioso dover considerare sempre questo task come necessario nelle nostre app. Questa volta voglio trattare dello stesso problema, nel contesto dell’esporre dei servizi da parte del nostro end device.
Ipotizziamo di essere nel tipico caso d’uso di un ESP8266 come nodo sensore, che acquisisce dei dati tramite un sensore e li vuole esporre tramite WiFi.
I tre elementi necessari per costruire questa generica applicazione sono un modo per interfacciarsi con la rete, l’utilizzo di un protocollo applicativo per comunicare con attori esterni ed una funzionalità di acquisizione ed elaborazione dei dati dal sensore.
Dal mio punto di vista solo l’ultimo dei tre è strettamente dipendente dall’applicazione che si sta sviluppando, mentre gli altri due dovrebbero essere qualcosa che possa sempre essere importato senza doverlo reinventare.
L’idea è quindi quella di utilizzare una libreria che fornisca gli strumenti necessari per implementare il blocco rosso, con i blocchi arancioni inclusi al suo interno ed automaticamente impostati e funzionanti.
MoodyNodeEsp – L’idea
Il tutto è molto semplice: voglio avere la possibilità di avere il mio end-device impostato come un server HTTP, con un’interfaccia per ottenere informazioni sulla sua identità, ed un’altra per ottenere le letture dal sensore (o lo stato dell’attuatore, la libreria infatti supporta entrambi i tipi di nodo).
Il setup della connessione alla rete è gestito dietro le quinte dalla libreria EspWifiManager, che avevo introdotto nello scorso articolo.
Gli endpoint che ho deciso di esporre sono i seguenti, per un nodo sensore:
- /api/conn [GET]: che ritorna informazioni riguardo il tipo di nodo, il suo indirizzo mac, il nome del servizio esposto, in formato json.
- /api/data [GET]: che ritorna una lettura da sensore. Il risultato del messaggio è incluso in un oggetto json, nel campo payload.
Mentre per un nodo attuatore avremo:
- /api/conn [GET]: che in maniera simile al nodo sensore, ritorna informazioni sull’identità del nodo.
- /api/data [GET]: che ritorna lo stato attuale del nodo attuatore, sempre usando il campo payload come per il nodo sensore.
- /api/data [PUT]: che serve ad impostare un nuovo stato per il nodo attuatore, che attuerà il comando ricevuto.
Installazione ed istruzioni per l’uso
Ho condiviso la libreria ad inizio articolo, ma la potete trovare anche sul mio registry platformio, ed infatti vi consiglio di utilizzarla con platformio, che rende il tutto ancora più semplice.
Vi basterà quindi aprire un nuovo progetto platformio, ed incollare le seguenti righe nel vostro platformio.ini:
[env:esp01_1m] platform = espressif8266 board = esp01_1m framework = arduino lib_deps = abathargh/MoodyNodeEsp
Una volta fatto ciò, vi basterà installare le librerie con il comando pio lib install e potrete procedere creando le vostre applicazioni.
La libreria è semplice ed intuitiva, ci sono due tipi di oggetti che possono essere creati:
- MoodySensor<T>, che identifica un sensore che legge dati di tipo T, ad esempio MoodySensor<int> leggerà dati di tipo int.
- MoodyActuator<T>, che identifica un attuatore che può attuare dispositivi utilizzando dati di tipo T, ad esempio MoodyActuator<int> potrà mandare comandi di tipo int.
Al momento la libreria supporta solo tipi T che siano numerici. Per poter definire le modalità di acquisizione dati, si creano delle funzioni con delle firme ben precise, che possono essere associate agli oggetti creati.
Ad esempio se un sensore è di tipo MoodySensor<int>, posso usare una funzione int acquisisciDato() per poter leggere i dati di tipo int. Per potere associare la funzione all’oggetto sensore, utilizzo il metodo di MoodySensor setAcquireFunction(acquisisciDato) e l’ESP saprà cosa fare per acquisire dati dal sensore.
Allo stesso modo, per un attuatore di tipo MoodyActuator<int>, posso usare una funzione void attuaComando(int comando) e associarla al nodo utilizzando il metodo setActuateFunction(attuaComando).
Queste operazioni vanno effettuate all’interno della funzione setup, prima di far partire il nodo usando il metodo begin() del sensore o attuatore. Vi riporto qui sotto i due esempi che troverete anche nella repo github:
#include <MoodyNodeEsp.h> MoodySensor sensor("example"); int acquireFunction() { static int i = 0; return i++; } void setup() { sensor.setAcquireFunction(acquireFunction); sensor.begin(); } void loop() { sensor.loop(); }
#include <MoodyNodeEsp.h> MoodyActuator actuator("example"); void acquireFunction(int payload) { Serial.println(payload); } void setup() { Serial.begin(115200); actuator.setActuateFunction(acquireFunction); actuator.begin(); } void loop() { actuator.loop(); }
Notate come l’unica istruzione da invocare nella funzione loop sia il metodo loop dell’oggetto prescelto. Questa operazione è obbligatoria!
Un esempio pratico con un sensore PIR
Per darvi un esempio di quanto sia semplice usare questo approccio per avere veloci applicazioni basate su ESP, ho condiviso sul nostro github un progetto in cui acquisisco dati da un sensore di prossimità PIR. Avevo già parlato di sensori di questo tipo in passato su antima, in particolare nella serie sulla libreria python antimait.
Potete trovare il codice di esempio a questo link, dove, nel file main.cpp, vi sarà possibile osservare in azione quanto introdotto poco fa.
Una volta flashato l’applicativo sul vostro ESP8266, potrete comunicare via HTTP con il vostro dispositivo interrogandolo ad esempio da browser. Nel mio caso ho prima di tutto connesso l’ESP alla mia rete WiFi utilizzando l’interfaccia esposta dalla libreria EspWifiManager. Dopodiché ho trovato l’IP dell’ESP tramite un’app come Net Analyzer (per Android) e ho inserito l’indirizzo http://indirizzoip/api/conn e http://indirizzoip/api/data nel mio browser.
Il risultato è il seguente, ottenuto dall’ESP8266 in figura, montato sulla nostra personale board prototipale!
Conclusioni
Spero che la semplicità di questo approccio vi abbia colpito: per me fare veloci progetti ed interagire con dispositivi nuovi è diventato di una comodità unica con questo tipo di libreria. Ci sono altre funzioni molto interessanti che ho incluso in MoodyNodeEsp di cui parlerò in un paio di prossimi articoli, in particolare in merito al node discovery.
Per questo articolo è tutto, per eventuali approfondimenti o richieste di chiarimenti vi invito come al solito a commentare nella sezione qui sotto!