Build a Weather Station with XinaBox and Okdo IoT Cloud

Build a Weather Station with XinaBox and Okdo IoT Cloud

Learn how to make your own Weather Station that sends weather readings to OKdo IoT Cloud and displays on OLED xChip OD01.

XinaBox produces a range of 80+ modular xChips, which include cores/CPUs, sensors, power, communication, output, and storage, using a connectivity standard without wires, soldering, breadboards or hardware knowledge.

xChip CW01 (ESP8266 Core) is a microprocessor and Wi-Fi module that enables users to send/receive data from XinaBox's modular xChips to/from the cloud.

xChips SW01 (BME280) and SL01 (VEML6075 & TSL4531) are Advanced Weather Sensors that measures temperature, humidity and atmospheric pressure; UVA/UVB and Ambient Light intensities.

OKdo IoT Cloud is a free IoT cloud which you can use to interact with your sensors and actuators, automating data capture and visualisation.

In this tutorial, we will use HTTP to send weather readings and subscribe using MQTT to OKdo IoT Cloud. By the end of the guide, you will be able to see Weather Station readings in OKdo IoT Cloud and on xChip OD01.

Requirements

Steps

  1. Hardware Setup
  2. Setting up the Arduino IDE
  3. Login to OKdo IoT Cloud
  4. Code
  5. Result
  6. Summary

1. Hardware Setup

Connect xChips CW01, OD01, IP01/IP02, SL01 and SW01 together using the XC10 xBUS connectors. You may connect it as shown in the diagram below. Please see this guide on how to assemble xChips generally.

And then connect your device and PC through the IP01/IP02’s USB.

2. Setting up the Arduino IDE

1. Install Arduino IDE 1.8.8

2. Install these libraries into Arduino IDE:

Note: If you are not familiar with how to install cores/libraries, please refer to the link: Installing Arduino libraries

3. With the ESP8266 platform installed, select “CW01(ESP12F module)”. To select your board from the Arduino IDE, select Tools> Board “XinaBox CW01”.

3. Login to OKdo IoT Cloud

1. Open your OKdo IoT Cloud account.

2. Create a New Device, select Arduino as the device and name it:

3. After creating a device, copy your DEVICE_ID and TOKEN from the Authentication tab.

4. Code

Code C/C++
Send XK01 data to OKdo IoT cloud

/*    _   _ _ _____ _    _              _____     _ _     ___ ___  _  __
 *   /_\ | | |_   _| |_ (_)_ _  __ _ __|_   _|_ _| | |__ / __|   \| |/ /
 *  / _ \| | | | | | ' \| | ' \/ _` (_-< | |/ _` | | / / \__ \ |) | ' <
 * /_/ \_\_|_| |_| |_||_|_|_||_\__, /__/ |_|\__,_|_|_\_\ |___/___/|_|\_\
 *                             |___/
 *
 * Copyright 2018 AllThingsTalk
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define JSON
//#define CBOR

#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   // required to have support for signed/unsigned long type.

void callback(char* topic, byte* payload, unsigned int length);
WiFiClient espClient;
PubSubClient pubSub(mqtt, 1883, callback, espClient);

ATTDevice device("DEVICE_ID","DEVICE_TOKEN");
xSW01 SW01;
xSL01 SL01;
xOD01 OD01;

#ifdef CBOR
  #include <CborBuilder.h>
  CborBuilder payload(device);
#endif

void setup()
{
  Serial.begin(9600);  // Init serial link for debugging

    // Set the I2C Pins for CW01
  #ifdef ESP8266
    Wire.pins(2, 14);
    Wire.setClockStretchLimit(15000);
  #endif
  
  // Start the I2C Comunication
  Wire.begin();
  
  // Start the  SW01 Sensor
  SW01.begin();
  SL01.begin();
  OD01.begin();
  
  // Enter your WiFi credentials here!
  setupWiFi("SSID", "PASS");

  OD01.println("Weather Station");
  delay(2000);

  OD01.clear();
  //
  
  while(!device.connect(&espClient, http))  // Connect to AllThingsTalk
    Serial.println("retrying");

  // Create device assets
  device.addAsset("temperature", "Temperature", "Temperature in Celsius", "sensor", "{\"type\": \"string\"}");
  device.addAsset("pressure", "Pressure", "Pressure in Pascal", "sensor", "{\"type\": \"string\"}");
  device.addAsset("humidity", "Humidity", "Humidity in %", "sensor", "{\"type\": \"string\"}");
  device.addAsset("lux", "Lux", "Ambient light intensity", "sensor", "{\"type\": \"string\"}");
  device.addAsset("uva", "UVA", "UVA", "sensor", "{\"type\": \"string\"}");
  device.addAsset("uvb", "UVB", "UVB", "sensor", "{\"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;
   
   SW01.poll();
   SL01.poll();
   
   tempC = SW01.getTempC();
   pres = SW01.getPressure();
   hum = SW01.getHumidity();
   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
  {
    #ifdef JSON
    device.send(String(tempC), "temperature");
    device.send(String(pres/1000), "pressure");
    device.send(String(hum), "humidity");
    device.send(String(lux), "lux");
    device.send(String(uva), "uva");
    device.send(String(uvb), "uvb");
    #endif

    #ifdef CBOR  // Send data using Cbor
    payload.reset();
    payload.map(1);
    payload.addInteger(counter, "counter");
    payload.send();
    #endif

    OD01.print("Temp.: ");
    OD01.print(tempC);
    OD01.println(" C");
    OD01.print("Press.: ");
    OD01.print(pres/1000);
    OD01.println(" kPa");
    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");

    delay(2000);

    OD01.clear();
    
    prevTime = curTime;
  }
  device.process();  // Check for incoming messages
}

/****
 * Callback function
 * Handle messages that were sent from the AllThingsTalk cloud to this device
 */
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"];
    Serial.println(value);
    if (strcmp(value,"true") == 0)
      digitalWrite(LED_BUILTIN, LOW);   // Turn the onboard LED on
    else
      digitalWrite(LED_BUILTIN, HIGH);  // Turn the onboard LED off

    device.send(value, "toggle");  // Send command back as ACK using JSON
  }
  else
    Serial.println("Parsing JSON failed");
}

5. Result

6. Summary

In this tutorial, we have shown you how to make a Weather station using xChips CW01, SW01 and IP01, connected to the OKdo IoT Cloud. Thus, enabling remote monitoring and sensing.

Previous article Visualizing Vibrations in Real-Time with XinaBox and Ubidots
Next article Build Your Own Digital Compass with XinaBox