ALL POSTS BY

Blog

The IoT candle Hardware Tutorial

This simple holiday project exemplifies how easy getting into the Internet of Things can be. With some inexpensive sensors and basic programming, we connected flame sensors to the internet and were able to publish their current readings. To make things more interesting, we connected candles around Berlin, and published their current states to a map.

 

There are two parts to this tutorial. We'll start with setting up the hardware, but you can jump to the software tutorial. The whole project is also up in our GitHub repository.

 

If your family is across the city, country or world this holiday season, you can keep track of one another (and when the candles are lit) on this interactive map.

 

IoT_Candle_Map

 

 

This could also be the beginning of any IoT project. Switch the candles for vending machines and the flame sensors for gyroscopes and you can set up vandalism detection on machines around the country or globe. Scale up and add more sensors and features for full scale, interactive maps that give you up to date information on whatever you're interested in.

 

IoT Candle Hardware Supply List

  • Candle
  • Grove Flame Sensor
  • Publishing board: we used a Particle.io Photon (but any other board can be used)
  • Text editor

Flame Sensor

The flame sensor is a simple digital sensor which detects a fire source or other light sources whose wavelength ranges between 760nm - 1100 nm. Connect the Flame Sensor to your board. We've used a Photon so the following first steps are relevant for the photon alone. We've used the basic mqtt/relayr example code.

 

The Process

  • Create a relayr account
  • In your Devices page click the 'Add a Device' button and select the Add new device option
  • Give your prototype a name and hit Start Prototyping
  • Make a note of your received credentials.
  • Create a Particle account and go to the build section
  • Start a new App

Include the Mqtt and SparkJson library

Below the library inclusions define the relayr-mqtt credentials in the following manner:

#define DEVICE_ID "ef805ac8-74b1-4ad9-874f-d08c9f99f20c"
#define MQTT_USER "ef805ac8-74b1-4ad9-874f-d08c9f99f20c"
#define MQTT_PASSWORD "mperTu8HFWlp"
#define MQTT_CLIENTID "T74BayHSxStmHT9CMn5nyDA" //can be anything else
#define MQTT_TOPIC "/v1/ef805ac8-74b1-4ad9-874f-d08c9f99f20c/"
#define MQTT_SERVER "mqtt.relayr.io"

 

Define your sensor pin

//pins
 const int FireSense = A0;

 

Define additional variables for mqtt publishing

//for publish mutiple times
char message_buff[100];
char meaning_buff[50];
const int meaningLen = 50;

//mqtt stuff
//define LED and Mqtt
const int led = D7;
int ledState = LOW;
unsigned long lastPublishTime = 0;
unsigned long lastBlinkTime = 0;

                                                // Set here the time in milliseconds between publications
int publishingPeriod = 400;             // ATTENTION !!!
                                                // DO NOT try to set values under 200 ms of the server
                                                // will kick you out

void callback(char* topic, byte* payload, unsigned int length);

//create our instance of MQTT object
MQTT client(MQTT_SERVER, 1883, callback);

 

Implement a callback

//implement our callback method thats called on receiving data from a subscribed topic
void callback(char* topic, byte* payload, unsigned int length) {
  //store the received payload and convert it to string
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  //print the topic and the payload received
  Serial.println("topic: " + String(topic));
  Serial.println("payload: " + String(p));
  //call our method to parse and use the payload received
  handlePayload(p);
}

void handlePayload(char* payload) {
  StaticJsonBuffer<200> jsonBuffer;
  //convert payload to json
  JsonObject& json = jsonBuffer.parseObject(payload);
  if (!json.success()) {
    Serial.println("json parsing failed");
    return;
  }
  //get value of the key "command"
  const char* command = json["command"];
  Serial.println("parsed command: " + String(command));
  if (String(command).equals("color"))
  {
    const char* color = json["value"];
    Serial.println("parsed color: " + String(color));
    String s(color);
    if (s.equals("red")){
      RGB.color(255, 0, 0);
    }
    else if (s.equals("blue"))
      RGB.color(0, 0, 255);
    else if (s.equals("green"))
      RGB.color(0, 255, 0);
  }
}

 

In the setup() define the following

void setup() {
       RGB.control(true);
  Serial.begin(9600);
  Serial.println("Hello There, I'm your photon!");
   //setup our LED pin and connect to mqtt broker
  pinMode(led, OUTPUT);
    //set 200ms as minimum publishing period
    publishingPeriod = publishingPeriod > 200 ? publishingPeriod : 200;
    mqtt_connect();
}

 

In the loop call publish and check whether publishing is allowed

void loop() {
if (client.isConnected()) {

    client.loop();
    //publish within publishing period
        if (millis() - lastPublishTime > publishingPeriod) {

            lastPublishTime = millis();

            publish();
        }

        blink(publishingPeriod / 2);
    }
    else {
    //if connection lost, reconnect
        Serial.println("retrying..");
        mqtt_connect();
    }
}

 

Connect to the cloud:

void mqtt_connect() {
  Serial.println("Connecting to mqtt server");
  if (client.connect(MQTT_CLIENTID, MQTT_USER, MQTT_PASSWORD)) {
    Serial.println("Connection success, subscribing to topic");
    //subscribe to a topic
    client.subscribe("/v1/"DEVICE_ID"/cmd");
  }
  else {
    Serial.println("Connection failed, check your credentials or wifi");
  }
}

 

Read the data and publish it onto the cloud

void publish() {
  //create our jsonArray
  StaticJsonBuffer<300> pubJsonBuffer;
  JsonArray& root = pubJsonBuffer.createArray();

  //First object is value of Fire Sensor
  JsonObject& leaf1 = root.createNestedObject();
  //define a meaning for what we're sending
  leaf1["meaning"] = "Fire";
  //set our value key to the sensor's reading
  leaf1["value"] = digitalRead(FireSense);

  char message_buff[128];
  root.printTo(message_buff, sizeof(message_buff));
  client.publish("/v1/"DEVICE_ID"/data", message_buff);
  Serial.println("Publishing " + String(message_buff));
}

 

You probably want to know the location of your friends. We could use a GPS sensor but in order to keep things simpler, we've decided to hardcode our location and publish it to the cloud.

 

Use http://www.latlong.net, type in your address and copy and paste your latitude and longitude values. Create two more Json leafs under the digtialRead.

 

  //First object is value of Fire Sensor
  JsonObject& leaf2 = root.createNestedObject();
  //define a meaning for what we're sending
  leaf2["meaning"] = "Lat";
  //set our value key to the sensor's reading
  leaf2["value"] = 52.498526;

      //First object is value of Fire Sensor
  JsonObject& leaf3 = root.createNestedObject();
  //define a meaning for what we're sending
  leaf3["meaning"] = "Lon";
  //set our value key to the sensor's reading
  leaf3["value"] = 52.13.383368;

 

Use the following to make the LED blink

void blink(int interval) {
  if (millis() - lastBlinkTime > interval) {
    // save the last time you blinked the LED
    lastBlinkTime = millis();
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    // set the LED with the ledState of the variable:
    digitalWrite(led, ledState);
  }
}