Adafruit IO is the new cloud platform (at the moment still in beta) by Adafruit, designed to allow simple data connections using standard APIs and web-based dashboards.
This new platform exposes MQTT APIs, you can therefore apply what you learned in my previous posts to create a complete project that takes advantage of all its features.
The project
Goal of the project is to connect the Arduino to a dashboard hosted on Adafruit IO:
- Arduino reads the room temperature (thanks to the DHT11 sensor already used in a previous tutorial) and sends its value every t seconds to Adafruit IO
- Arduino is also able, using an external relay module, to turn on/off an heater
- The dashboard on Adafruit IO displays the temperature values on a chart and has a toggle button to turn the heater connected to the Arduino on and off
Adafruit IO
Let’s see how to create the dashboard using Adafruit IO.
First, you need to subscribe to the open beta program using the button on the official website https://io.adafruit.com:
After having logged in with your Adafruit account (or having created a new account) you’ll be redirected to the default dashboard.
Click on My dashboards:
next click on Create dashboard:
give a name to the new dashboard, then click on Create dashboard:
you’ll see a completely empty dashboard. To add new elements (charts, buttons…) click on Create a new block:
choose line chart among the available elements and click on Create:
you have to link the chart to a feed (= topic, in the MQTT language). Create a new feed named temperature:
once created, you can link it to the chart (choose), then click on next step:
you can change some chart settings (for example type °C as y-axis label), then complete the wizard with create block:
You’ll see a new block in your dashboard that represents the chart, empty for the moment. Using the drag’n’drop you can move the block in the page or resize it.
Now add the toggle button, again using Create a new block:
create a new feed named control:
and link it to the button:
give a label to the button and to the two possible values, then create the new block:
Your dashboard is now complete!
Feeds, topics and MQTT APIs
As explained above, each element of your dashboard can be linked to one or more feeds, that are data flows. For example you linked to the chart a feed named temperature, while the button is linked to another one named control.
If you use the MQTT APIs, each feed corresponds to a topic named as it follows:
<username>/f/<feedname>
where username is the name of your Adafruit account.
Hence, my two feeds correspond to the following two topics:
[checklist]
- lucadentella/f/temperature
- lucadentella/f/control
[/checklist]
To connect to the Adafruit’s MQTT broker (address io.adafruit.com) you need to specify a username and a password.
The username is the name of your Adafruit account (lucadentella for me), while the password is your Adafruit IO key, that can be retrieved using a button in the dashboard:
You can test your dashboard using the mosquitto_sub command to subscribe to the topic linked to the toggle button. Every time you click on the button, the dashboard sends to that topic a message with the actual status of the button (ON or OFF):
mosquitto_sub.exe -h io.adafruit.com -u <username> -P <AIOkey> -t <username>/f/control
Arduino
The sketch for Arduino is available in my Github repository.
First, some constants are defined: the parameters for the Adafruit IO service (username, password, topics…) and the PINs the DHT11 sensor and the relay are connected to:
#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 |
In the setup(), the MQTT client is configured. Unlike the previous example, this time I also define the callback function that is called every time the client receives a new message from a topic that was subscribed:
// setup mqtt client mqttClient.setClient(ethClient); mqttClient.setServer("io.adafruit.com", 1883); mqttClient.setCallback(mqttCallback); |
Indeed, when the sketch connects to the broker it subscribes the topic linked to the button in the dashboard to be notified when a user clicks on it:
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); } } } |
The callback function checks if the message received is ON or OFF and changes the relay status accordingly:
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); } } |
The following video shows the project in action:
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!