Ben Dixon
Published © GPL3+

Easy Weather Station Using MQTT, XinaBox And Kibana

I built this weather station using XinaBox xCHIPS, which posts the sensor data to an MQTT broker over WiFi with CW01 (ESP8266 based xCHIP).

IntermediateFull instructions provided6 minutes1,149
Easy Weather Station Using MQTT, XinaBox And Kibana

Things used in this project

Hardware components

XinaBox CW01 ☒CHIP
☒CHIP WiFi Core based on ESP8266
×1
XinaBox SW01 ☒CHIP
☒CHIP environmental sensor based on BME280
×1
XinaBox SL01 ☒CHIP
☒CHIP visible light and UV sensor based on TSL45315 and VEML6075
×1
XinaBox PU02 ☒CHIP
☒CHIP USB power supply
×1
XinaBox XC10 ☒CHIP
☒BUS connectors to interface between ☒CHIPS
×1
XinaBox IP01 ☒CHIP
☒CHIP USB Programming Interface
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

CW01_Simple_Weather_MQTT

C/C++
This is the main file of the Arduino Sketch (ino file). Has to be placed in a folder with the same name.
#include <xCore.h>
#include <xSW01.h>
#include <xSL01.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <NTPtimeESP.h>

#define RED 12
#define GREEN 13
#define BLUE 5

char topic_WS[40];

const char* ssid     = "YourWifiName";
const char* password = "YourWifiPassword";

String    server =  "mqtt.xinabox.cc"; //Use your own mqtt server here
uint16_t  port  =  80;

const char* client_id = "ben_weather_station";
const char* username   = "admin";
const char* MQTT_password = "YourMQTTServerPassword";

String DEVICE = "Hackster_Station";
String ORGANIZATION = "XinaBox";

float SW01_Temperature, SW01_Humidity, SW01_Pressure, SL01_Lux, SL01_UVA, SL01_UVB, SL01_UVIndex;

long tick_sensor_poll = 0, tick_publish_mqtt = 0, tick_serial_print = 0;
int sensor_poll_interval = 1000, publish_mqtt_interval = 5000, serial_print_interval = 5000;

String timeStamp;

// Use WiFiClient class to create TCP connections
WiFiClient CW01_client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
PubSubClient client(CW01_client);

strDateTime dateTime;

/*************************** NTP Server Parameters **************************/
NTPtime NTPch("time.google.com");   // Choose server pool as required

void setup() {
  //Begin Serial bus
  Serial.begin(115200);
  
  //Begin I2C bus
  Wire.begin(2, 14);

  //Set LED Outputs
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);

  //Set up SL01
  SL01.begin();

  //Set up SW01
  SW01.begin();

  //Setup wifi and MQTT Broker
  setup_wifi();

}

void loop() {
  read_sensors();
  publish_mqtt();
  yield();
}

CONNECTIONS

C/C++
Code to connect to WiFi and MQTT broker, also builds JSON to publish to MQTT. Must be in the same folder as the main Arduino sketch. I included it in the project as a tab named "CONNECTIONS".
void setup_wifi(void)
{
  Serial.print("[STATUS] Starting Wifi Connection");

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(RED, HIGH);
    delay(250);
    digitalWrite(RED, LOW);
    delay(250);
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED) {
    digitalWrite(GREEN, HIGH);
  }

  Serial.println();
  Serial.println("[STATUS] WiFi connected.");

  mqtt_connect();
}

void mqtt_connect(void)
{
  Serial.println( "[STATUS] Connecting to MQTT Broker." );

  client.setServer(server.c_str() , port);

  if ( client.connect(client_id, username, MQTT_password) ) {
    Serial.println( "[STATUS] MQTT Broker Connected." );
  }

  //Create MQTT Topic
  sprintf(topic_WS, "xinabox/data/ws/%s", client_id); //Replace with your own topic for MQTT Broker.
}

void publish_mqtt(void)
{
  if ((millis() - tick_publish_mqtt) > publish_mqtt_interval)
  {
    Serial.println("[STATUS] Publishing to MQTT Server...");

    // Prepare a JSON payload string
    String payload = "{";
    payload += "\"Weather_Station\": {";

    payload += "\"SW01\": {";
    payload += "\"Temperature(C)\":"; payload += SW01_Temperature; payload += ",";
    payload += "\"Humidity(%)\":"; payload += SW01_Humidity;payload += ",";
    payload += "\"Pressure(Pa)\":"; payload += SW01_Pressure;
    payload += "}";

    payload += ",";

    payload += "\"SL01\": {";
    payload += "\"Lux\":"; payload += SL01_Lux;  payload += ",";
    payload += "\"UVA(mW/m^2)\":"; payload += SL01_UVA;  payload += ",";
    payload += "\"UVB(mW/m^2)\":"; payload += SL01_UVB;  payload += ",";
    payload += "\"UVI\":"; payload += SL01_UVIndex;
    payload += "}";

    payload += ",";

    // insert user specific data
    payload += "\"Input\": {";

    payload += "\"Unit Name\":\""; payload += DEVICE; payload += "\"";

    payload += ",";
    payload += "\"Organization\":";   payload += "\"";
    payload += ORGANIZATION;  payload += "\"";

    payload += "},";

    // Get TimeStamp
    getTimeStamp();

    payload += "\"Timestamp\":{";
    payload += "\"Created\":\"";
    payload += timeStamp;
    payload += "\"";
    payload += "}";

    payload += "}";
    payload += "}";

    // Send payload
    char demo_data[1024];

    payload.toCharArray(demo_data, 1024);

    Serial.println();
    Serial.println("Publishing to MQTT Server...");
    Serial.print("Connection State :");
    Serial.print(" [RC : ");
    Serial.print(client.state());
    Serial.println("]");
    Serial.print("Topic: ");
    Serial.println(topic_WS);
    Serial.println("loc_payload : ");
    Serial.println(demo_data);
    unsigned int length_WS = strlen(demo_data);
    if (client.publish(topic_WS, demo_data, length_WS)) {
      Serial.println("[PUBLISHED]");
      digitalWrite(RED, LOW);
      digitalWrite(GREEN, HIGH);
    } else {
      Serial.print("[FAILED]");
      Serial.print(" [RC : ");
      Serial.print(client.state());
      Serial.println("]");
      digitalWrite(RED, HIGH);
      digitalWrite(GREEN, LOW);
    }
    Serial.println();

    tick_publish_mqtt = millis();
  }
}

// Get timestamp
void getTimeStamp(void) {
  dateTime = NTPch.getNTPtime(0.0, 0);

  if (dateTime.valid) {
    timeStamp = dateTime.year;
    timeStamp += "-";
    if (dateTime.month < 10) {
      timeStamp += "0";
      timeStamp += dateTime.month;
      timeStamp += "-";
    } else {
      timeStamp += dateTime.month;
      timeStamp += "-";
    }
    if (dateTime.day < 10) {
      timeStamp += "0";
      timeStamp += dateTime.day;
    } else {
      timeStamp += dateTime.day;
    }
    timeStamp += "T";
    if (dateTime.hour < 10) {
      timeStamp += "0";
      timeStamp += dateTime.hour;
      timeStamp += ":";
    } else {
      timeStamp += dateTime.hour;
      timeStamp += ":";
    }
    if (dateTime.minute < 10) {
      timeStamp += "0";
      timeStamp += dateTime.minute;
      timeStamp += ":";
    } else {
      timeStamp += dateTime.minute;
      timeStamp += ":";
    }
    if (dateTime.second < 10) {
      timeStamp += "0";
      timeStamp += dateTime.second;
    } else {
      timeStamp += dateTime.second;
    }
  }
}

SENSORS

C/C++
Very simple code to read the XinaBox sensors. Must be in the same folder as the main Arduino sketch. I included it in the project as a tab named "SENSORS".
void read_sensors(void)
{
  if ((millis() - tick_sensor_poll) > sensor_poll_interval)
  {
    //Get sensor data
    SW01.poll();
    SL01.poll();

    //Move SW01 sensor data into global variables.
    SW01_Temperature = SW01.getTemperature_C();
    SW01_Humidity = SW01.getHumidity();
    SW01_Pressure = SW01.getPressure();

    //Move SL01 sensor data into global variables.
    SL01_Lux = SL01.getLUX();
    SL01_UVA = SL01.getUVA();
    SL01_UVB = SL01.getUVB();
    SL01_UVIndex = SL01.getUVIndex();

    tick_sensor_poll = millis();
  }
}

Credits

Ben Dixon

Ben Dixon

1 project • 1 follower
I am an electronic engineer with a true love for the art of electronics. I live for anything technology. Yes, I'm a geek just like you!

Comments