Connect your Magicbit to ThingsBoard
Send data from sensors to ThingsBoard
Components Required
What is ThingsBoard?
ThingsBoard is an open-source server-side platform that allows you to monitor and control IoT devices. It is free for both personal and commercial usage and you can deploy it anywhere. If this is your first experience with the platform we recommend to review what-is-thingsboard page and getting-started guide.
Introduction
This sample application will allow you to monitor and control GPIO of yourmagicbit device using ThingsBoard web UI and display humidity/temperature data from DHT22 sensor. We will observe GPIO control using LEDs connected to the pins. The purpose of this application is to demonstrate ThingsBoard RPC capabilities and ThingsBoard Telemetry.
The application that is running on Magicbit device is written using ThingsBoard Arduino SDK which is quite simple and easy to understand.
Current GPIO state and GPIO control widget is visualized using built-in customizable dashboard.
Once you complete this sample/tutorial, you will see your sensor data on the following dashboard.
Visit the Thingsboard Demo official page and get signed up.
After Signing in On the Left Side Bar you will see Devices. Click devices and add a new device.
On the credentials tab tick Add credentials tab and choose Access Token from the drop down box. Either you can add your own Access Token or leave blank to auto generate token.
In the Arduino IDE download the following libraries,
The following is the Arduino code you will be using.
Note You need to edit following constants and variables in the sketch:
WIFI_AP
– name of your access pointWIFI_PASSWORD
– access point passwordTOKEN
– the $ACCESS_TOKEN from ThingsBoard configuration step.THINGSBOARD_SERVER
– ThingsBoard HOST/IP address that is accessible within your wifi network. Specifydemo.thingsboard.io
if you are using live demo server.
#include <DHTesp.h> // DHT for ESP32 library
#include <WiFi.h> // WiFi control for ESP32
#include <ThingsBoard.h> // ThingsBoard SDK
// Helper macro to calculate array size
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
// WiFi access point
#define WIFI_AP_NAME "WIFI_AP"
// WiFi password
#define WIFI_PASSWORD "WIFI_PASSWORD"
// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN "TOKEN"
// ThingsBoard server instance.
#define THINGSBOARD_SERVER "demo.thingsboard.io"
// Baud rate for debug serial
#define SERIAL_DEBUG_BAUD 115200
// Initialize ThingsBoard client
WiFiClient espClient;
// Initialize ThingsBoard instance
ThingsBoard tb(espClient);
// the Wifi radio's status
int status = WL_IDLE_STATUS;
// Array with LEDs that should be lit up one by one
uint8_t leds_cycling[] = { 25, 26, 32 };
// Array with LEDs that should be controlled from ThingsBoard, one by one
uint8_t leds_control[] = { 19, 22, 21 };
// DHT object
DHTesp dht;
// ESP32 pin used to query DHT22
#define DHT_PIN 33
// Main application loop delay
int quant = 20;
// Initial period of LED cycling.
int led_delay = 1000;
// Period of sending a temperature/humidity data.
int send_delay = 2000;
// Time passed after LED was turned ON, milliseconds.
int led_passed = 0;
// Time passed after temperature/humidity data was sent, milliseconds.
int send_passed = 0;
// Set to true if application is subscribed for the RPC messages.
bool subscribed = false;
// LED number that is currenlty ON.
int current_led = 0;
// Processes function for RPC call "setValue"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processDelayChange(const RPC_Data &data)
{
Serial.println("Received the set delay RPC method");
// Process data
led_delay = data;
Serial.print("Set new delay: ");
Serial.println(led_delay);
return RPC_Response(NULL, led_delay);
}
// Processes function for RPC call "getValue"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processGetDelay(const RPC_Data &data)
{
Serial.println("Received the get value method");
return RPC_Response(NULL, led_delay);
}
// Processes function for RPC call "setGpioStatus"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processSetGpioState(const RPC_Data &data)
{
Serial.println("Received the set GPIO RPC method");
int pin = data["pin"];
bool enabled = data["enabled"];
if (pin < COUNT_OF(leds_control)) {
Serial.print("Setting LED ");
Serial.print(pin);
Serial.print(" to state ");
Serial.println(enabled);
digitalWrite(leds_control[pin], enabled);
}
return RPC_Response(data["pin"], (bool)data["enabled"]);
}
// RPC handlers
RPC_Callback callbacks[] = {
{ "setValue", processDelayChange },
{ "getValue", processGetDelay },
{ "setGpioStatus", processSetGpioState },
};
// Setup an application
void setup() {
// Initialize serial for debugging
Serial.begin(SERIAL_DEBUG_BAUD);
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
InitWiFi();
// Pinconfig
for (size_t i = 0; i < COUNT_OF(leds_cycling); ++i) {
pinMode(leds_cycling[i], OUTPUT);
}
for (size_t i = 0; i < COUNT_OF(leds_control); ++i) {
pinMode(leds_control[i], OUTPUT);
}
// Initialize temperature sensor
dht.setup(DHT_PIN, DHTesp::DHT22);
}
// Main application loop
void loop() {
delay(quant);
led_passed += quant;
send_passed += quant;
// Check if next LED should be lit up
if (led_passed > led_delay) {
// Turn off current LED
digitalWrite(leds_cycling[current_led], LOW);
led_passed = 0;
current_led = current_led >= 2 ? 0 : (current_led + 1);
// Turn on next LED in a row
digitalWrite(leds_cycling[current_led], HIGH);
}
// Reconnect to WiFi, if needed
if (WiFi.status() != WL_CONNECTED) {
reconnect();
return;
}
// Reconnect to ThingsBoard, if needed
if (!tb.connected()) {
subscribed = false;
// Connect to the ThingsBoard
Serial.print("Connecting to: ");
Serial.print(THINGSBOARD_SERVER);
Serial.print(" with token ");
Serial.println(TOKEN);
if (!tb.connect(THINGSBOARD_SERVER, TOKEN)) {
Serial.println("Failed to connect");
return;
}
}
// Subscribe for RPC, if needed
if (!subscribed) {
Serial.println("Subscribing for RPC...");
// Perform a subscription. All consequent data processing will happen in
// callbacks as denoted by callbacks[] array.
if (!tb.RPC_Subscribe(callbacks, COUNT_OF(callbacks))) {
Serial.println("Failed to subscribe for RPC");
return;
}
Serial.println("Subscribe done");
subscribed = true;
}
// Check if it is a time to send DHT22 temperature and humidity
if (send_passed > send_delay) {
Serial.println("Sending data...");
// Uploads new telemetry to ThingsBoard using MQTT.
// See https://thingsboard.io/docs/reference/mqtt-api/#telemetry-upload-api
// for more details
TempAndHumidity lastValues = dht.getTempAndHumidity();
if (isnan(lastValues.humidity) || isnan(lastValues.temperature)) {
Serial.println("Failed to read from DHT sensor!");
} else {
tb.sendTelemetryFloat("temperature", lastValues.temperature);
tb.sendTelemetryFloat("humidity", lastValues.humidity);
}
send_passed = 0;
}
// Process messages
tb.loop();
}
void InitWiFi()
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
void reconnect() {
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
}
Data visualization and GPIO control
In live-demo server:
- login: your live-demo username (email)
- password: your live-demo password
See live-demo page for more details how to get your account.
Go to “Devices” section and locate “Magicbit”, open device details and switch to “Latest telemetry” tab. If all is configured correctly you should be able to see latest values of “temperature” and “humidity” in the table.
After, open “Dashboards” section then locate and open “Magicbit Dashboard”. As a result, you will see a time-series chart displaying temperature and humidity level (similar to dashboard image in the introduction).
You should also observe a GPIO control for your device. It consists of two widgets: one is for controlling LED blink speed (in milliseconds) and second for turning individual LEDs on and off.
You can switch status of GPIOs using control panel. As a result, you will see LEDs status change on the device. To control LED blink speed, simply turn a knob and observe a speed change.