The Wio Terminal is an integrated IoT device built by Seeedstudio. This small form factored device holds a 2.4” LCD Screen, IMU, microphone, buzzer, microSD card slot, light sensor, and infrared emitter, and of course, WiFi and Bluetooth connectivity. A great thing about it is that it can be programmed through the Arduino IDE or using MicroPython.
Following this guide you will be able to PUBLISH and SUBSCRIBE data to/from Ubidots using the Wio Terminal without a hassle.
Requirements
Arduino IDE, version 1.8.13 or higher
1. Firmware setup
For the correct use of this device its firmware must be up to date. Please follow the steps presented in the Seeedstudio Wiki to update the Wireless Core Realtek RTL8720, responsible for the WiFi and Bluetooth connectivity.
IMPORTANT NOTE: Install the update and all dependency libraries to ensure connectivity.
2. Setting up the Arduino IDE
To be able to work with the Wio Terminal in the Arduino IDE, you will need to install the Wio Terminal board using Arduino’s Board Manager. If you are not familiar with adding a board to Arduino IDE, refer to this article for additional guidance.
1. Launch Arduino and Open a Blink example in your Arduino IDE from File > Examples > 01.Basics > Blink.
2. Go to File > Preferences and copy the following URL into the Additional boards manager URL, as shown in the image below.
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
3. Install the Wio Terminal library from Tools > Boards > Boards Manager.
4. At last, you will need to select your board from Tools > Board and select the correct COM port.
5. Upload the code to your Wio Terminal to make sure that it is connected properly. You should see the blue LED blinking at the bottom of the device.
3. Sending (PUBLISH) Data to Ubidots
In this example, we will use the internal Light sensor located in the back of the Wio Terminal to obtain real-time values and send them through the PUBLISH method to Ubidots.
Step 1: Open Arduino IDE and paste the sample code below.
Step 2: Assign your unique Ubidots TOKEN.
Step 3: SSID (WiFi Name) and Password of the available network.
Step 4: Assign the Device and Variable Labels where the data is to be sent. Remember that if the Device or the variable don’t exist before the first dot is sent, Ubidots will create them automatically.
Step 5: The final constant needed is the MQTT_CLIENT_NAME, this is special because it is the ID with which your device will be identified by the broker so it MUST be unique. If your device tries to connect with the same ID that has already been taken by another device, the connection will be refused. Please create your own all alphanumeric 8-12+ character MQTT_CLIENT_NAME and input into the code accordingly.
Hint: Need some help creating a unique MQTT_CLIENT_NAME, check out this random ascii builder, or simply use the MAC address of your device as every MAC address is globally unique.
/****************************************
* Include Libraries
****************************************/
#include <PubSubClient.h>
#include <TFT_eSPI.h>
#include <rpcWiFi.h>
TFT_eSPI tft;
/****************************************
* Define Constants
****************************************/
#define WIFISSID "<YOUR-WIFISSD>" // Put your WifiSSID here
#define PASSWORD "<YOUR-WIFI-PASSWORD" // Put your wifi password here
#define TOKEN "<YOUR-UBIDOTS-TOKEN>" // Put your Ubidots' TOKEN
#define VARIABLE_LABEL "light" // Assign the variable label
#define DEVICE_LABEL "wio-terminal" // Assign the device label
#define MQTT_CLIENT_NAME "r6y1ax7mq8" // MQTT client Name
#define LCD_BACKLIGHT (72Ul)
char mqttBroker[] = "industrial.api.ubidots.com";
// Space to store values to send
char str_light[6];
char payload[700];
char topic[150];
/****************************************
* Initialize constructors for objects
****************************************/
WiFiClient wifiClient;
PubSubClient client(wifiClient);
/****************************************
* Auxiliar functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length){
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(MQTT_CLIENT_NAME, TOKEN,"")) {
Serial.println("connected");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 2 seconds");
// Wait 2 seconds before retrying
delay(2000);
}
}
}
/****************************************
* Main Functions
****************************************/
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(3);
tft.setTextSize(2);
tft.fillScreen(TFT_BLACK);
digitalWrite(LCD_BACKLIGHT, HIGH);
pinMode(WIO_LIGHT, INPUT);
// Set WiFi to station mode and disconnect from an AP if it was previously connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
tft.drawString("Connecting to WiFi...",20,120);
WiFi.begin(WIFISSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
tft.drawString("Connecting to WiFi...",20,0);
WiFi.begin(WIFISSID, PASSWORD);
}
tft.fillScreen(TFT_BLACK);
tft.drawString("Connected to the WiFi network",20,120);
tft.fillScreen(TFT_BLACK);
delay(1000);
client.setServer(mqttBroker, 1883);
client.setCallback(callback);
}
void loop() {
float light = analogRead(WIO_LIGHT);
dtostrf(light, 4, 2, str_light);
tft.fillRect(140,110,100,15,TFT_BLACK);
tft.drawString(str_light,140,110);
if (!client.connected()) {
reconnect();
}
//***Publish***
// Builds the topic
sprintf(topic, "%s", ""); // Cleans the topic content
sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
//Builds the payload
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{\"%s\":", VARIABLE_LABEL); // Adds the variable label
sprintf(payload, "%s%s", payload, str_light); // Adds the value
sprintf(payload, "%s}", payload); // Closes the dictionary brackets
tft.drawString("Topic",0,140);
tft.drawString(topic,0,160);
tft.drawString("Payload",0,190);
tft.fillRect(100,210,100,15,TFT_BLACK);
tft.drawString(payload,0,210);
client.publish(topic, payload);
delay(10000);
client.loop();
}
After uploading and running the code, you should be able to see your new device “wio-terminal” on your device list with values from 0 to 1023. You can test the values by pointing a flashlight or by exposing the back of the Wio Terminal to a light source.
4. Receiving (SUBSCRIBE) Data from Ubidots
With the following sample code you will be able to subscribe values from Ubidots to start controlling any asset remotely. In this example we will simply make the Wio Terminal’s screen go green or grey depending on the value of an On/Off variable (0 for Off, 1 for On) in Ubidots.
Step 1: Open Arduino IDE and paste the sample code below.
Step 2: Assign your unique Ubidots TOKEN.
Step 3: SSID (WiFi Name) and Password of the available network.
Step 4: At last, you need to assign the Device and Variable Labels to be subscribed to. Remember that in this case, the Device and the Variable must exist to subscribe.
Step 5: The final constant needed is the MQTT_CLIENT_NAME, this is special because it is the ID with which your device will be identified by the broker so it MUST be unique. If your device tries to connect with the same ID that has already been taken by another device, the connection will be refused. Please create your own all alphanumeric 8-12+ character MQTT_CLIENT_NAME and input into the code accordingly.
Hint: Need some help creating a unique MQTT_CLIENT_NAME, check out this random ascii builder, or simply use the MAC address of your device as every MAC address is globally unique.
/****************************************
* Include Libraries
****************************************/
#include <PubSubClient.h>
#include <TFT_eSPI.h>
#include <rpcWiFi.h>
TFT_eSPI tft;
/****************************************
* Define Constants
****************************************/
#define WIFISSID "<YOUR-WIFISSD>" // Put your WifiSSID here
#define PASSWORD "<YOUR-WIFI-PASSWORD" // Put your wifi password here
#define TOKEN "<YOUR-UBIDOTS-TOKEN>" // Put your Ubidots' TOKEN
#define VARIABLE_LABEL "<YOUR-VARIABLE-LABEL>" // Assign the variable label
#define DEVICE_LABEL "<YOUR-DEVICE-LABEL>" // Assign the device label
#define MQTT_CLIENT_NAME "r6y1ax7mq8" // MQTT client Name
#define LCD_BACKLIGHT (72Ul)
char mqttBroker[] = "industrial.api.ubidots.com";
char payload[700];
char topic[150];
/****************************************
* Initialize constructors for objects
****************************************/
WiFiClient wifiClient;
PubSubClient client(wifiClient);
/****************************************
* Auxiliar functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length){
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
// Control routine
if ((char)payload[0]=='1'){
tft.fillScreen(TFT_GREEN);
}
else{
tft.fillScreen(TFT_LIGHTGREY);
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(MQTT_CLIENT_NAME, TOKEN,"")) {
Serial.println("connected");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 2 seconds");
// Wait 2 seconds before retrying
delay(2000);
}
}
}
/****************************************
* Main Functions
****************************************/
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(3);
tft.setTextSize(2);
tft.fillScreen(TFT_BLACK);
digitalWrite(LCD_BACKLIGHT, HIGH);
pinMode(WIO_LIGHT, INPUT);
// Set WiFi to station mode and disconnect from an AP if it was previously connected
WiFi.mode(WIFI_STA);
WiFi.disconnect();
tft.drawString("Connecting to WiFi...",20,120);
WiFi.begin(WIFISSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
tft.drawString("Connecting to WiFi...",20,0);
WiFi.begin(WIFISSID, PASSWORD);
}
tft.fillScreen(TFT_BLACK);
tft.drawString("Connected to the WiFi network",20,120);
tft.fillScreen(TFT_BLACK);
delay(1000);
client.setServer(mqttBroker, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
// Subscribes for getting the value of the control variable in the light device
char topicToSubscribe[200];
sprintf(topicToSubscribe, "%s", ""); // Cleans the content of the char
sprintf(topicToSubscribe, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(topicToSubscribe, "%s/%s/lv", topicToSubscribe, VARIABLE_LABEL);
Serial.println("subscribing to:");
Serial.println(topicToSubscribe);
client.subscribe(topicToSubscribe);
client.loop();
}
5. Summary
With this simple tutorial you are able to PUBLISH & SUBSCRIBE data to/from Ubidots with the ease of the Arduino IDE and a Wio Terminal. If your wish to find more examples to use the other integrated parts in the device, visit the Seeedstudio Wiki here.
Now its time to create Ubidots Dashboards to visualize your data and deploy your IoT solution!