Build a Weather Station using XinaBox xChips and Azure IoT

Build a Weather Station using XinaBox xChips and Azure IoT

Learn how to make a weather a station that transmits Weather values (Temperature, Humidity and Pressure) to Microsoft Azure IoT.

xChip CW02 (ESP-WROOM-32) is a Wi-Fi & BLE core module. It is based on the ESP32 which is a single 2.4 GHz Wi-Fi and BLE combo chip designed with TSMC ultra-low-power 40 nm technology and an Xtensa® Dual-core 32-bit LX6 microprocessor.

xChip SW01 (BME280) is equipped with a weather sensor that is capable of measuring the temperature, humidity and atmospheric pressure.

In this tutorial we will show you how to build an IoT Weather Station using XinaBox xChip CW02, SW01 and Microsoft Azure IoT.

Requirements

Steps

  1. Hardware Setup
  2. Setting up the Arduino IDE
  3. Create Azure IoT Hub account
  4. Register a new device
  5. Upload the code
  6. Code
  7. Summary

Hardware Setup

Connect CW02, IP01/IP02 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.

Setting up the Arduino IDE

1. Install Arduino IDE 1.8.8

2. Install these cores/libraries into Arduino IDE:

NOTE: If you are not familiar with how to install cores/libraries, please refer to the links: Installing Arduino libraries and Installing cores

3. With the ESP32 platform installed, select “XinaBox CW02 (ESP32)”. To select the board from the Arduino IDE, select Tools >BoardXinaBox CW02”.

3. Create Azure IoT Hub account

1. Login to your Azure IoT account.

2. Create a new IoT Hub resource. See this guide on how to do that.

4. Register a new device

1. Select IoT devices from the menu.

2. Click on +Add button

3. Enter a new name for your device. Click Save

5. Upload the code

1. Link Azure IoT with Power BI to visualize real-time data. See this guide on how to do that.

2. Run Azure Stream Analytics job. Wait a few minutes for it to start.

3. Upload the code to CW02.

4. Click on MyWorkspace>dataset>data. You will see a list of variables in the table column.

5. Select Line chart from VISUALIZATIONS. Drag and drop EventEnqueuedUtcTime into Axis, and select weather variables.

You should be able to see weather values on the chart now.

6. Code

AzureIoTWeatherStation C/C++
Enter your Wi-Fi credentials and connection string where required

#include <WiFi.h>
#include <xCore.h>
#include <xSW01.h>

#include "AzureIotHub.h"
#include "Esp32MQTTClient.h"



//keep alive interval

#define MQTT_KEEPALIVE_INTERVAL_S 120

#define DEVICE_ID "CW02"

#define MESSAGE_MAX_LEN 256

xSW01 SW01;

// Please input the SSID and password of WiFi

const char* ssid     = "";

const char* password = "";



//Set msg_Interval to set transmit frequency
unsigned long msg_Interval = 10000;

unsigned long msg_Timer = 0;



unsigned long stream_Interval = 20000;

unsigned long stream_Timer = 0;

/*String containing Hostname, Device Id & Device Key in the format:                         */

/*  "HostName=;DeviceId=;SharedAccessKey="                */

/*  "HostName=;DeviceId=;SharedAccessSignature="    */



//Connection String to interface your device with IoT hub

static const char* connectionString = "";


//JSON data to transmit Weather readings
const char *messageData = "{\"deviceFormat\":\"%s\",\"deviceId\":\"%s\", \"messageId\":%d, \"TemperatureF\":%.2f, \"Humidity\":%.2f, \"TemperatureC\":%.2f, \"Pressure\":%.2f}";




//variable to keep the count of msg delivered

int messageCount = 1;

static bool messageSending = true;


int k = 10;

int i;



//variable to store temp,humid,press

static float humidity; 

static int16_t cTempint; 

static float cTemp;

static float fTemp;

static float Press;



//Callback to check the confirmation frome azure

static void SendConfirmationCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result)

{

  if (result == IOTHUB_CLIENT_CONFIRMATION_OK)

  {

    Serial.println("Send Confirmation Callback finished.");

  }

}



//payload callback

static void MessageCallback(const char* payLoad, int size)

{

  Serial.println("Message callback:");

  Serial.println(payLoad);

}



static void DeviceTwinCallback(DEVICE_TWIN_UPDATE_STATE updateState, const unsigned char *payLoad, int size)

{

  if(updateState){

     char *temp = (char *)malloc(size + 1);

  if (temp == NULL)

  {

    return;

  }

  memcpy(temp, payLoad, size);

  temp[size] = '\0';

  // Display Twin message.

  Serial.println(temp);

  free(temp);   

    }

    else{

          Serial.println("Device State not updated");

      }

}


void setup()

{

  //Start serial communication
   Serial.begin(115200);
  
  // Start the I2C Comunication
  Wire.begin();
  
  // Start the  SW01 Sensor
  SW01.begin();


  while(!Serial);


  // Initialize the WiFi module

  Serial.println(" > WiFi");
  InitWifi();

  

  Serial.println(" > IoT Hub");

   Esp32MQTTClient_SetOption(OPTION_MINI_SOLUTION_NAME, "GetStarted");
   
  //Connect to IoT Hub
  Serial.println(Esp32MQTTClient_Init((const uint8_t*)connectionString, true, true) ? "Connected to IoT Hub" : "Error Connecting to IoT Hub");

  

  //Set different callbacks

  Esp32MQTTClient_SetSendConfirmationCallback(SendConfirmationCallback);

  Esp32MQTTClient_SetMessageCallback(MessageCallback);

  Esp32MQTTClient_SetDeviceTwinCallback(DeviceTwinCallback);

}



void loop()

{
  
  //Create message payload
  char messagePayload[MESSAGE_MAX_LEN];

  //Poll SW01 sensor
  SW01.poll();

  Press=SW01.getPressure()/1000;

  humidity = SW01.getHumidity();

  cTempint = SW01.getTempC();

  cTemp = (float)cTempint;

  fTemp = cTemp * 1.8 + 32;

  Serial.print("Atmospheric Pressure :");
  
  Serial.print(Press);

  Serial.println(" kPa");

  Serial.print("Relative Humidity :");

  Serial.print(humidity);

  Serial.println(" %RH");

  Serial.print("Temperature in Celsius :");

  Serial.print(cTemp);

  Serial.println(" C");

  Serial.print("Temperature in Fahrenheit :");

  Serial.print(fTemp);

  Serial.println(" F");

  if(millis()-msg_Timer> msg_Interval){

      msg_Timer= millis();

      Serial.println("Sending Message");

      String deviceFormat = "realValues"; 

      

      //snprintf stores the data in char buffer

      //snprintf(char buffer,  size of buffer,   format,         arg1,      arg2,        arg3,       arg4,  arg5,    arg6,  arg7)

      snprintf(messagePayload,MESSAGE_MAX_LEN, messageData, deviceFormat.c_str(), DEVICE_ID, messageCount++, fTemp,humidity,cTemp,Press); 

      Serial.println(messagePayload);

      

      //create an event MESSAGE(message) to send the buffer(messagPayload) to Azure  

      EVENT_INSTANCE* message = Esp32MQTTClient_Event_Generate(messagePayload, MESSAGE);

      

      //send the event to azure

      Esp32MQTTClient_SendEventInstance(message); 

      delay(50);   

  }

else{
      Esp32MQTTClient_Check();
    }

}



void InitWifi(){

  

    Serial.println("Connecting...");

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(500);

    Serial.print(".");

  }

  

  Serial.println("WiFi connected");

  Serial.println("IP address: ");

  Serial.println(WiFi.localIP());

  }

7. Summary

In this tutorial, we have shown you how to make a Weather station using CW02, SW01 and IP01/IP02, connected to Microsoft Azure IoT hub. Thus, enabling remote monitoring and sensing.

Previous article Measure Bike RPM with XinaBox and Magnets
Next article Visualizing Vibrations in Real-Time with XinaBox and Ubidots