Monday, 21 March 2016

View Live data on your phone with Node-Red and Thingstud.io

Some time ago I came across a blog run by Pete Scargill (tech.scargill.net) which dealt with many tech gadgets to do with IOT and home automation.

There were a couple of subjects I found very interesting, Node Red and MQTT, these seemed to very useful tools to help develop home automation solutions.

Node Red turned out to be pivotal in my ability to glue everything together, there are so many different nodes that can be used to link into different services.

I'm running Node Red on my Raspberry Pi but it can also be installed on your PC and there is also a hosted installation of Node Red found here that allows to to try out an instance of node red without installing it on any platform at all, it runs in your browser and there is free account option.

The FRED Node Red runs even when your PC is switched off, there are some limitations around hardware inputs that would normally come from your PC like serial data and data from your OS, also you cannot install any of your own nodes.

Another important aspect of home automation was remote access to the data, whilst you are in your home on your own network this is not too difficult but when you are out and about and want to know what you hot water temperature is or if your central heating is on then it's a bit trickier, unless you expose your network to the outside world that is.

This is where cloud hosted MQTT servers came in for me, they allow me to send and receive data to and from the outside world easily and securely (at least I hope it's secure).

So to learn how to use the tools I set a goal to measure the hot water temperature in my storage tank and transmit an MQTT topic via WiFi and using Node Red to receive it and process it, if required before displaying it on my phone using Thingstud.io, the next step will be to have a button in the app to switch the hot water heating on/off manually and/or automatically switch it on from Node Red.

Step1 - Measure the hot water temp and send via an MQTT topic

For this I used and ESP-12 mounted on a development board I bought from AliExpress
There are also other boards that can be used
WeMos D1 Mini
Witty Cloud
The Fritzing circuit looks like this

In the Fritzing diagram above I've shown a battery for the supply but I actually use a 5V mains USB supply plugged into the USB connector and the DS18B20 Temperature sensor I used is the probe version so that the sensing part can be fed through the tank's insulation to touch the copper tank near to the top.

Before writing the sketch for the ESP-12 I tried out a couple of different MQTT providers: -
  • Mosquitto installed on my raspberry Pi
  • CloudMQTT.com private broker with password access.
  • HIVEMQ - free public access MQTT broker (no password)
I settled on Cloudmqtt using a free account but found that the app I created in Thingstud.io wouldn't work on my Android phone, I got in touch with the thingstud.io support and they were very helpful and said it worked on their Android phone and offered to help debug my phone to find out why but I didn't really want to spend the time trying to fix it so I tried the public server version of HIVEMQ and that worked great.

If you are new to MQTT then HIVEMQ have some really good introduction documents here that explain everything.

Before using the Arduino IDE to program your ESP12 you will need to add the details to your boards manager, details can be found here.

Then you can program your ESP with this sketch, don't forget to edit the SSID and passwords sections in the code to suit your network and mqtt broker.

This sketch uses the Cloudmqtt broker.

/*
 Basic ESP8266 MQTT example
 This sketch demonstrates the capabilities of the pubsub library in combination
 with the ESP8266 board/library.
 It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic" every two minutes
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off
- Read the temperature of a single DS18B20 device and publish it to the MQTT broker
- Read the battery supply voltage and publish it to the MQTT broker
 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.
 After publishing the data it will then go to sleep for nnn seconds  (set nnn in the int interval)
 For the ESP-12 to wake up after the nnn interval you will need to connect D0 to the reset pin
 or if supplied from a mains adapter you can remove the sleep command altogether.
 I have also commented out the code that switches on the LED.
 To install the ESP8266 board, (using Arduino 1.6.4+):
  - Add the following 3rd party board manager under "File > Preferences -> Additional Boards Manager URLs":
       http://arduino.esp8266.com/stable/package_esp8266com_index.json
  - Open the "Tools > Board > Board Manager" and click install for the ESP8266"
  - Select your ESP8266 in "Tools > Board"
*/

#include "esp8266wifi.h"
#include "onewire.h"
#include "dallastemperature.h"
#include "pubsubclient.h"

// Update these with values suitable for your network.
const char* ssid = "#######";
const char* password = "#######";
const char* mqtt_server = "m20.cloudmqtt.com";
const char* mqttUser = "#######";
const char* mqttPass = "#######";
float temp; //store temperature value
float BattLevel; //Store Battery voltage
int interval = 120;//Interval between messages in seconds
char msg[50];

ADC_MODE(ADC_VCC);//Set the ADCC to read supply voltage.

WiFiClient espClient;
PubSubClient client(espClient);
#define ONE_WIRE_BUS 2  // DS18B20 pin (D4)
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);

void setup() {
  Serial.begin(115200);
  setup_wifi();
  delay(5000);
  client.setServer(mqtt_server, 10388);
  client.setCallback(callback);
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  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");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    //    digitalWrite(LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    //digitalWrite(LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client",mqttUser, mqttPass)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  //Read Temperature from DS18B20
  DS18B20.requestTemperatures();
  temp = DS18B20.getTempCByIndex(0);
  //Read supply voltage
   BattLevel= ESP.getVcc();
  /*Print Temp and Battery level [optional]
  Serial.print("Temperature: ");
  Serial.println(temp);
  Serial.print("Supply Voltage: ");
  Serial.println(BattLevel);  
  delay(200);
  */
  //Publish Data to MQTT
  dtostrf(temp, 4, 2, msg); //Convert float to string
  client.publish("Temperatures/HotWater/Temp", msg, true);
  Serial.print("Published message Temp: ");
  Serial.println(msg);
  dtostrf(BattLevel, 3, 1, msg); //Convert float to string
  client.publish("Temperatures/HotWater/Battery", msg, true);
  Serial.print("Published message Batt Level: ");
  Serial.println(msg);

  //Disconnect from WiFi before sleep
  client.disconnect();
  WiFi.disconnect();
  delay(100);

  Serial.print("Entering deep sleep for ");
  Serial.print(interval/60);
  Serial.println(" Minutes");
  ESP.deepSleep(interval * 1000000, WAKE_RF_DEFAULT);
  //ESP.deepSleep(10 * 1000, WAKE_NO_RFCAL);
  delay(500);   // wait for deep sleep to happen
}
To test the sketch you can use the Websocket UI in the Control panel
In the next part I'll go through setting up Thingstud.io to display the data on your phone.

No comments:

 Time for another post. A while ago I bought a new Oscilloscope, a RIGOL DHO914, but this scope doesn't have WiFi built in just a LAN co...

Popular Posts