All Things Talk with XinaBox Starter Kit XK01

This article explains how you can connect your XinaBox Starter Kit XK01 to the AllThingsTalk Cloud and send weather measures to it, while also visualizing data on the mini-OLED screen. 

What will you need

  • An ATT IoT Cloud account
  • 1 x CW01 - Wi-Fi Core (ESP8266/ESP-12F)
  • 1 x IP01 - USB Programming Interface (FT232R)
  • 1 x MD01 - Blank
  • 1 x OD01 - OLED Display 128x64 (SSD1306)
  • 1 x SL01 - UVA, UVB, Light (VEML6075 & TSL4531)
  • 1 x SW01 - Advanced Weather Sensor (BME280)
  • 1 x XC10 - 10-Pack xBUS Connectors
  • Arduino IDE installed
  • Your WiFi access credentials
  • Support for CW01(ESP8266) xChip in your Arduino IDE

Install the libraries

Download these libraries:

And add these libraries into Arduino IDE by going into Sketch>Include Library>Add .ZIP Library and select each of these libraries.

Collecting Weather data

Connect hardware

Connect all the XK01 xChips together as shown:

Please see this guide on how to assemble xChips generally.

Setup your device

  • Open your Arduino IDE:
    • Go to Tools > Board and select the CW01
    • Under Tools > Port select the USB port to which your device is connected

Authenticate your device

  • Open your playground and click on previously created device.
  • Click the Setting button on your top right and Note down DEVICE_ID and DEVICE_TOKEN

Code

Update TOKEN and DEVICE_ID in the code with the values you noted earlier.

String TOKEN="Your DEVICE TOKEN";
String DEVICE_ID="Your DEVICE ID";

… and replace SSID and PSK with your Wi-Fi SSID and PSK

setupWiFi("SSID", "PSK");

Complete Code

#define JSON

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <xCore.h>
#include <xSW01.h>
#include <xSL01.h>
#include <xOD01.h>

// Define http and mqtt endpoints
#define http "api.allthingstalk.io"  // API endpoint
#define mqtt "api.allthingstalk.io"  // broker
#include <ATT_IOT.h>
#include <SPI.h>  // required to have support for signed/unsigned long type.

String TOKEN="Your DEVICE TOKEN";
String DEVICE_ID="Your DEVICE ID";

byte mac[6];
long rssi;

WiFiClient espClient;

void callback(char* topic, byte* payload, unsigned int length);
PubSubClient pubSub(mqtt, 1883, callback, espClient);
ATTDevice device(DEVICE_ID,TOKEN);

xSW01 SW01;
xSL01 SL01;
xOD01 OD01;


void setup()
{
  Serial.begin(115200);  // Init serial link for debugging
    // Set the I2C Pins for CW01
  #ifdef ESP8266
    Wire.pins(2, 14);
    Wire.setClockStretchLimit(15000);
  #endif
  
  // Start the I2C Communication
  Wire.begin();
  
  // Start the  SW01 Sensor
  SW01.begin();
  SL01.begin();
  OD01.begin();

  OD01.println("Weather Station");
  OD01.println("Loading please wait...");
  
  // Enter your WiFi credentials here!
  setupWiFi("", "");

  rssi = WiFi.RSSI();
  WiFi.macAddress(mac);

  Serial.println();
  
  while(!device.connect(&espClient, http))  // Connect to AllThingsTalk
    Serial.println("retrying");
  // Create device assets
  device.addAsset("1", "1", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("2", "2", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("3", "3", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("4", "4", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("5", "5", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("6", "6", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("7", "7", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("8", "8", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("9", "9", "", "sensor", "{\"type\": \"string\"}");
  device.addAsset("10", "10", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("11", "11", "", "sensor", "{\"type\": \"number\"}");
  device.addAsset("12", "12", "", "actuator", "{\"type\": \"string\"}");

   while(!device.subscribe(pubSub))  // Subscribe to mqtt
    Serial.println("retrying"); 
}
void setupWiFi(const char* ssid, const char* password)
{
  delay(10);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.println("WiFi connected");
}

unsigned long prevTime;
unsigned int prevVal = 0;

void loop()
{
   float tempC,pres,hum;
   float lux,uva,uvb;
   float alt,dew,cloudBase;
   
   SW01.poll();
   SL01.poll();

   rssi = WiFi.RSSI();
   
   tempC = SW01.getTempC();
   pres = SW01.getPressure();
   hum = SW01.getHumidity();
   alt = SW01.getQNE();
   dew = SW01.getDewPoint();
   cloudBase = ((tempC - dew)/4.4)*1000 + alt;
   lux = SL01.getLUX();
   uva = SL01.getUVA();
   uvb = SL01.getUVB();
   
  unsigned long curTime = millis();
  if (curTime > (prevTime + 5000))  // Update and send counter value every 5 seconds
  {
    device.send(String(alt), "1");
    device.send(String(tempC), "2");
    device.send(String(pres), "3");
    device.send(String(hum), "4");
    device.send(String(lux), "5");
    device.send(String(uva), "6");
    device.send(String(uvb), "7");
    device.send(String(rssi), "8");
    device.send(String((char*)mac), "9");
    device.send(String(dew), "10");
    device.send(String(cloudBase), "11");

    OD01.home();
    OD01.print("Temp.: ");
    OD01.print(tempC);
    OD01.println(" C");
    OD01.print("Press.: ");
    OD01.print(pres);
    OD01.println(" Pa");
    OD01.print("Hum.: ");
    OD01.print(hum);
    OD01.println(" %");
    OD01.print("LUX: ");
    OD01.print(lux);
    OD01.println("LUX");
    OD01.print("UVA: ");
    OD01.print(uva);
    OD01.println(" uW/cm^2");
    OD01.print("UVB: ");
    OD01.print(uvb);
    OD01.println(" uW/cm^2");
    prevTime = curTime;
  }
  device.process();
}

void callback(char* topic, byte* payload, unsigned int length) 
{ 
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");

  // Convert payload to json
  StaticJsonBuffer<500> jsonBuffer;
  char json[500];
  for (int i = 0; i < length; i++) {
    json[i] = (char)payload[i];
  }
  json[length] = '\0';
  
  JsonObject& root = jsonBuffer.parseObject(json);

  // Do something
  if(root.success())
  {
    const char* value = root["value"];
    OD01.clear();
    OD01.println(value);
    device.send(value, "toggle");  // Send command back as ACK using JSON
    delay(2000);
  }
  else
    Serial.println("Parsing JSON failed");
}