Adafruit IO è la nuova piattaforma cloud (attualmente ancora in beta) di Adafruit, realizzata per consentire un semplice scambio di informazioni tra dispositivi e la realizzazione di dashboard web.
Questa nuova piattaforma espone delle API MQTT, possiamo quindi applicare quello che abbiamo imparato nei precedenti articoli per realizzare un completo progetto che ne sfrutti le potenzialità.
Il progetto
Obiettivo del progetto è integrare il nostro Arduino con una dashboard ospitata da Adafruit IO:
- Arduino leggerà la temperatura dell’ambiente (tramite il sensore DHT11 già utilizzato nel precedente esempio) e invierà ogni tot secondi il valore di temperatura ad Adafruit IO
- Arduino sarà inoltre in grado, tramite un modulo relay esterno, di accendere/spegnere un riscaldatore (stufetta, calorifero…)
- La dashboard su Adafruit IO visualizzerà i valori di temperatura in un grafico e metterà a disposizione un pulsante per accendere/spegnere il riscaldatore collegato ad Arduino
Adafruit IO
Vediamo come creare la dashboard su Adafruit IO.
Per prima cosa è necessario iscriversi alla open beta tramite l’apposito pulsante che appare una volta collegati al sito https://io.adafruit.com:
Una volta effettuato il login con il proprio account Adafruit (o creato un nuovo account), verrà visualizzata la dashboard iniziale.
Clicchiamo su My dashboards:
quindi clicchiamo Create dashboard:
diamo un nome alla nuova dashboard, quindi clicchiamo su Create dashboard:
ci verrà presentata una dashboard completamente vuota. Per aggiungere nuovi elementi (grafico, pulsante…) clicchiamo su Create a new block:
selezioniamo line chart tra gli elementi disponibili e clicchiamo il pulsante Create:
dobbiamo associare un feed (= topic nel linguaggio MQTT) al grafico. Creiamo un nuovo feed con nome temperature:
una volta creato, possiamo associarlo al grafico (choose), quindi proseguiamo cliccando next step:
personalizziamo il grafico (ad esempio inseriamo °C come etichetta per l’asse Y), quindi completiamo l’inserimento con create block:
Nella nostra dashboard apparirà un blocco che rappresenta il grafico, per ora ancora vuoto. Tramite drag’n’drop possiamo spostare il blocco o ridimensionarlo.
Aggiungiamo ora il pulsante, sempre tramite Create a new block:
creiamo un nuovo feed chiamato control:
e associamolo al pulsante:
diamo un nome al pulsante e ai due valori possibili, quindi completiamo l’inserimento:
La nostra dashboard è completa!
Feeds, topics e API MQTT
Come abbiamo visto, ad ogni elemento della dashboard è possibile associare uno o più feeds, ovvero flussi di dati. Al grafico ad esempio abbiamo associato un feed chiamato temperature, mentre al pulsante uno chiamato control.
Se utilizziamo le API MQTT, ad ogni feed corrisponde un topic con questo nome:
<username>/f/<feedname>
dove username è il nome dell’account Adafruit.
I miei due feed corrisponderanno quindi ai seguenti topics:
[checklist]
- lucadentella/f/temperature
- lucadentella/f/control
[/checklist]
Il collegamento all’MQTT broker di Adafruit (indirizzo io.adafruit.com) richiede l’autenticazione via nome utente e password.
Il nome utente corrisponde all’account di Adafruit (lucadentella nel mio caso), mentre la password è la Adafruit IO key, visualizzabile tramite l’apposito pulsante:
Possiamo verificare che tutto funzioni correttamente utilizzando mosquitto_sub per sottoscrivere il topic associato al pulsante. Ad ogni click sul pulsante infatti, la dashboard invierà a tale topic un messaggio contenente lo stato attuale del pulsante (ON oppure OFF):
mosquitto_sub.exe -h io.adafruit.com -u <username> -P <AIOkey> -t <username>/f/control
Arduino
Lo sketch per Arduino è disponibile nel mio repository Github.
Per prima cosa, vengono definite alcune costanti relative al servizio Adafruit IO (utente, password, topics…) e i PIN a cui sono collegati il sensore DHT11 e il relay:
#define CLIENT_ID "ArduinoMQTT" #define USERNAME "adafruit_username" #define PASSWORD "adafruit_io_key" #define PUB_TOPIC "username/f/temperature" #define SUB_TOPIC "username/f/control" #define PUBLISH_DELAY 5000 #define DHTPIN 3 #define DHTTYPE DHT11 #define RELAY_PIN 6 |
All’interno del setup() viene configurato il client MQTT. A differenza dell’esempio precedente, questa volta definiamo anche quale è la funzione di callback che verrà chiamata per ogni nuovo messaggio in uno dei topic sottoscritti:
// setup mqtt client mqttClient.setClient(ethClient); mqttClient.setServer("io.adafruit.com", 1883); mqttClient.setCallback(mqttCallback); |
Quando lo sketch effettua il collegamento al broker infatti sottoscrive il topic associato al pulsante della dashboard in modo da essere informato ogni volta che l’utente cambia il suo stato:
void mqttConnect() { while(!mqttClient.connected()) { if(mqttClient.connect(CLIENT_ID, USERNAME, PASSWORD)) { Serial.println(F("MQTT client connected")); mqttClient.subscribe(SUB_TOPIC); Serial.println(F("Topic subscribed")); } else { Serial.println(F("Unable to connect, retry in 5 seconds")); delay(5000); } } } |
La funzione di callback verifica il messaggio ricevuto (ON oppure OFF) e attiva di conseguenza il relay:
void mqttCallback(char* topic, byte* payload, unsigned int length) { if(strncmp((const char*)payload, "ON", 2) == 0) { Serial.println("ON message received, turning relay ON"); digitalWrite(RELAY_PIN, HIGH); } else { Serial.println("OFF message received, turning relay OFF"); digitalWrite(RELAY_PIN, LOW); } } |
Ecco un video che illustra il funzionamento del progetto (sottotitoli italiani disponibili):
Very informative, like always. The sketch indicates Low memory and possible stability problems, but removing print statements (or including those in an #if debug statement), that is quickly remedied
thanks!
Ofcourse one can always make a static IP connection (so without DHCP), disable UDP in the UIPEthernet lib and gain >5k Flash
Ed, thanks for sharing this trick!
Ciao Luca,
Tutto molto interessante, ma vorrei sapere se esiste la possibilità di comandare i relè sonoff tramite arduino.Il problema nasce nel posizionare i relè con i cavi, sarebbe interessante usare arduino
e comandare dei relè o altro tramire wifi.
Ringrazio per l’attenzione
ciao Andrea, sì è possibile… ci sono tantissimi tutorial sui sonoff su Internet quindi ti rimando a quelli
Che parte di codice dovrei inserire se volessi controllare un digitalInput? Ad esempio controllare se una porta è aperta o chiusa. Che blocco dovrei inserire nella Dashboard. Grazie, sto cercando di imparare.
Ciao Giorgio, puoi usare il controllo “indicator”, che cambia colore in base al valore che invii ad un topic… molto semplice!