Monitor Fire and Temperature Using ARTIK Cloud, Open-Source IoT Hardware and Android

This post updates our previous article to use the ARTIK Cloud endpoint and Java/Android SDK.

In this article we will build a remote monitoring system using ARTIK Cloud, off-the-shelf sensors, Arduino UNO, Raspberry Pi, and an Android application. Using our Android app, we can remotely monitor data from temperature and flame sensors that are connected to ARTIK Cloud via the IoT development platform. Note that if you attended our SAMI Developer Meet-up, you will recognize this IoT setup from the live demo I presented with Dr. Luc Julia.

This is the first in a series of articles exploring the DIY smart home with ARTIK Cloud. Read the second tutorial, An IoT Remote Control. For a basic IoT implementation, see our tutorial Your first IoT device. However, this article can be read independently. You will learn how to do three things:

  • Combine data from multiple sensors on Arduino UNO to send to Raspberry Pi.
  • Set up a WebSocket connection on Raspbery Pi to send data to ARTIK Cloud.
  • Build an Android application to monitor new sensor data via ARTIK Cloud in real-time.

ARTIK Cloud creates an open ecosystem

In a system like this, ARTIK Cloud acts as back-end storage for IoT devices. Meanwhile, application developers use ARTIK Cloud APIs to develop mobile/web applications for these IoT devices.

Device developers do not need to build their own apps. Instead, application developers can learn the device Manifests and build applications for the devices that interest them. Each of the players in the ecosystem can focus on what they do best, instead of building a complicated end-to-end system.

Architecture

The diagram below shows the high-level architecture:

architecture

We use the following hardware components:

  • Raspberry Pi with a network connection
  • Arduino UNO with a breadboard
  • DHT11 temperature sensor
  • IR flame sensor
  • USB and power cables, plus wiring for the breadboard
  • Android phone

We will write the following software:

  • A Sketch program running on the Arduino
  • A Node.js script running on the Raspberry Pi
  • An Android application running on the Android phone

You can check out the code of the above software on GitHub.

Demo video

Note on the above video: SAMI is now known as ARTIK Cloud.

Build the sensor monitor system

Step 1: Connect a device in My ARTIK Cloud

I have published a device type “SAMI Example IoT DIY Sensor” with multiple fields (temperature and flame detection) as below. Any ARTIK Cloud developer can now use this device type as part of an IoT setup. 

device-type-fields

  1. First, sign into My ARTIK Cloud. If you don’t have a Samsung account, you can create one at this step.
  2. On the dashboard, click to connect a new device. Choose the pre-defined device type “SAMI Example IoT DIY Sensor”.
  3. Name this device using your name (e.g., “Yujing IoT Sensor”).
  4. Click “Connect Device…”. You’re taken back to the dashboard.
  5. Click the Settings icon of the device you just added. In the pop-up, click “GENERATE DEVICE TOKEN…”.
  6. Copy the device ID and device token on this screen. You will use these in the code.
    device-info-screen

Step 2: Set up the Arduino

Now let’s wire the sensors to the Arduino.

arduino-breadboard

The two sensors are wired as follows:

sensors-connect-arduino

Next, upload the Sketch program (read_temperature_flame_sensors.ino from GitHub) to the Arduino UNO using the Arduino IDE. This code reads the data from the temperature sensor and IR flame sensor, and then sends them to the serial port every 5 seconds (you can change this parameter in the code later, since ARTIK Cloud has rate limits for the number of messages per day). Below is a data sample:

84,1002,1

The first value is the temperature (in Fahrenheit) from DHT11; the second value is the analog reading ([01023]) from the flame sensor; and the third value is the digital reading ([0,1]) from the flame sensor. For the digital readings, “0” means that a fire is detected and “1” means no fire.

Here is the straightforward code:

#include <DHT.h>

// Delay between reads
const int delayBetweenReads = 5000;//5s

// For temperature sensor
const int DHTPIN = 2;
const int DHTTYPE = DHT11;
DHT dht(DHTPIN, DHTTYPE);

// For flame detector senso
const int flameDigitalPinIn = 3; 

void setup() {
  // initialize serial communication @ 9600 baud:
  Serial.begin(9600);
  dht.begin();
  pinMode(flameDigitalPinIn, INPUT);
}

void loop() {
  // Read data from temperature sensor
  float temp = dht.readTemperature(true);
  if (isnan(temp)) {
    temp = -1;// error`
  } 

  // read the sensor on analog A0:
  int flameAnalogReading = analogRead(A0);

  // HIGH(1) means no fire is detected
  // LOW (0) means fire is detected
  int flameDigitalReading = digitalRead(flameDigitalPinIn);

  // Compose data and send to Serial
  // Data format:     "temperature,flameAnalogReading,flameDigitalReading
  // Data example: "84,1001,1"
  Serial.print(String((int)temp));
  Serial.print(",");
  Serial.print(String(flameAnalogReading));
  Serial.print(",");
  Serial.println(String(flameDigitalReading));

  delay(delayBetweenReads);
}

Step 3: Set up the Raspberry Pi

Connect your Raspberry Pi to a monitor, mouse and keyboard. Ensure that an Ethernet or WiFi connection is working, and make sure the OS is up-to-date:

$ sudo apt-get update
$ sudo apt-get upgrade

If not already installed, install Node.js for ARM, then add the packages ‘serialport’ and ‘ws’ via npm:

$ npm install serialport
$ npm install ws

Now connect the serial port from the Arduino to the USB on the Raspberry Pi.

raspberrypi-arduino-breadboard

Finally, download the Node.js code (send_data_to_artik_cloud.js from GitHub) to the Raspberry Pi. Replace the placeholders in the code with the device token and device ID you collected from My ARTIK Cloud.

var webSocketUrl = "wss://api.artik.cloud/v1.1/websocket?ack=true";
var device_id = "<YOUR DEVICE ID>";
var device_token = "<YOUR DEVICE TOKEN>";

The Node.js code snippet below establishes a device channel WebSocket connection between the Raspberry Pi and ARTIK Cloud:

/**
 * Create a /websocket bi-directional connection 
 */
function start() {
    //Create the websocket connection
    isWebSocketReady = false;
    ws = new WebSocket(webSocketUrl);
    ws.on('open', function() {
        console.log("Websocket connection is open ....");
        register();
    });
    ws.on('message', function(data, flags) {
        console.log("Received message: " + data + '\n');
    });
    ws.on('close', function() {
        console.log("Websocket connection is closed ....");
    });
}

/**
 * Sends a register message to the websocket and starts the message flooder
 */
function register(){
    console.log("Registering device on the websocket connection");
    try{
        var registerMessage = '{"type":"register", "sdid":"'+device_id+'", "Authorization":"bearer '+device_token+'", "cid":"'+getTimeMillis()+'"}';
        console.log('Sending register message ' + registerMessage + '\n');
        ws.send(registerMessage, {mask: true});
        isWebSocketReady = true;
    }
    catch (e) {
        console.error('Failed to register messages. Error in registering message: ' + e.toString());
    }   
}

Each time, the Raspberry Pi reads three data points from the serial port, and then composes and sends one message to ARTIK Cloud via WebSocket as illustrated below:

start(); // create websocket connection

sp.on("open", function () {
    sp.on('data', function(data) {
         if (!isWebSocketReady){
             console.log("Websocket is not ready. Skip sending data to ARTIK Cloud (data:" + data +")");
             return;
         }
         console.log("Serial port received data:" + data);
         var parsedStrs = data.split(",");
         var temperature = parseInt(parsedStrs[0]);
         var flameAnalogValue = parseInt(parsedStrs[1]);
         var flameDigitalValue = parseInt(parsedStrs[2]);

         // flameDigitalValue = 1 ==> no fire is detected
         // flameDigitalValue = 0 ==> fire is detected
         var onFire = false;
         if (flameDigitalValue == 0) {
            onFire = true;
         }
         sendData(temperature, flameAnalogValue, onFire);
    });
});

Here is how each message is composed and sent to ARTIK Cloud over WebSocket:

/**
 * Send one message to ARTIK Cloud
 */
function sendData(temperature, flameAnalogReading, onFire){
    try{
        ts = ', "ts": '+getTimeMillis();
        var data = {
            "temp": temperature,
            "flameAnalogReading": flameAnalogReading,
            "onFire": onFire
            };
       var payload = '{"sdid":"'+device_id+'"'+ts+', "data": '+JSON.stringify(data)+', "cid":"'+getTimeMillis()+'"}';
       console.log('Sending payload ' + payload);
       ws.send(payload, {mask: true});
    } catch (e) {
       console.error('Error in sending a message: ' + e.toString());
    }   
}

Step 4: Fire it up and view the data!

Let’s start the Node.js program on the Raspberry Pi from the terminal:

$ node send_data_to_artik_cloud.js

In the terminal, you should see the payload of the message sent to ARTIK Cloud and the corresponding response from ARTIK Cloud as follows:

Serial port received data:84,1003,1
Sending payload {"sdid":"45176de99e424d98b1a3c42558bfccf4", "ts": 1438722871167, "data": {"temp":84,"flameAnalogReading":1003,"onFire":false}, "cid":"1438722871167"}
Received message: {"data":{"mid":"77b89ba8d8fb41a296403044698de3ac","cid":"1438722871167"}}

Log into My ARTIK Cloud once again.

View your device data as it’s generated by clicking the device name in the device box. This takes you to Data Visualization. From there, click the “+/- CHARTS” button and check “temp” and “onFire” to visualize a chart for each field. (Read this post for more information on Data Visualization.)

 

userportal-chart

Step 5: Build the Android monitoring app

The sensor data is now being sent to ARTIK Cloud. Now we can build an Android app to read the data from ARTIK Cloud in real-time. It’s important to note that any developer can build such a mobile app, since the “SAMI Example IoT DIY Sensor” with the appropriate fields has already been published in the Developer Dashboard. Again, thanks to the openness of the ARTIK Cloud ecosystem, any developer can build an application for any published devices.

Below is a screenshot of our app. The status and time continually refreshes as new data comes in. The Android app uses a firehose WebSocket API /live to listen in real-time for each message sent to ARTIK Cloud by the Raspberry Pi. This type of WebSocket is primarily used by applications with monitoring functionalities.

android-monitor-screen

Check out the Android code on GitHub. Follow the instructions there to build the Android application. Please do remember to replace the placeholders in ArtikCloudSession.java with the device token and device ID you collected from My ARTIK Cloud.

The following snippet shows the WebSocket event handler:

private void createFirehoseWebsocket() {
 try {
     mFirehoseWS = new FirehoseWebSocket(DEVICE_TOKEN, DEVICE_ID, null, null, null, new ArtikCloudWebSocketCallback() {
            @Override
            public void onOpen(int i, String s) {
                Log.d(TAG, "FirehoseWebSocket: onOpen()");
                final Intent intent = new Intent(WEBSOCKET_LIVE_ONOPEN);
                LocalBroadcastManager.getInstance(ourContext).sendBroadcast(intent);
            }

            @Override
            public void onMessage(MessageOut messageOut) {
                Log.d(TAG, "FirehoseWebSocket: onMessage(" + messageOut.toString() + ")");
                final Intent intent = new Intent(WEBSOCKET_LIVE_ONMSG);
                intent.putExtra(SDID, messageOut.getSdid());
                intent.putExtra(DEVICE_DATA, messageOut.getData().toString());
                intent.putExtra(TIMESTEP, messageOut.getTs().toString());
                LocalBroadcastManager.getInstance(ourContext).sendBroadcast(intent);
            }

            @Override
            public void onAction(ActionOut actionOut) {
            }

            @Override
            public void onAck(Acknowledgement acknowledgement) {
            }

            @Override
            public void onClose(int code, String reason, boolean remote) {
                final Intent intent = new Intent(WEBSOCKET_LIVE_ONCLOSE);
                intent.putExtra("error", "mFirehoseWS is closed. code: " + code + "; reason: " + reason);
            LocalBroadcastManager.getInstance(ourContext).sendBroadcast(intent);
            }

            @Override
            public void onError(WebSocketError ex) {
                final Intent intent = new Intent(WEBSOCKET_LIVE_ONERROR);
                intent.putExtra("error", "mFirehoseWS error: " + ex.getMessage());
                LocalBroadcastManager.getInstance(ourContext).sendBroadcast(intent);
            }

            @Override
            public void onPing(long timestamp) {
                Log.d(TAG, "FirehoseWebSocket::onPing: " + timestamp);
            }
        });
    } catch (URISyntaxException | IOException e) {
        e.printStackTrace();
    }
}

Once ARTIK Cloud receives a message from the Raspberry Pi, it notifies the Android app about this message via the firehose WebSocket. This notification invokes the callback method onMessage. The callback eventually triggers the new data to show up on the UI.

Where to go from here?

For a home monitoring system, you may want to monitor locks on your doors, the moisture level in your garden, lights in your rooms, and the earth’s movements under your house (we live in California), etc. For the sake of fun, think of using different IoT open-source development modules (e.g., various Arduino boards, Raspbery Pi, ARTIK modules, Galileo) or using different module combinations to build these DIY devices.

You may be interested in writing an iOS app to do the monitoring. Or how about enhancing the Android app to monitor multiple device types instead of only one type? In addition, beyond monitoring, you may want to use your mobile app to control your DIY devices, such as turning on/off lights. With ARTIK Cloud and various IoT modules, building a comprehensive DIY smart home can be both intuitive and enjoyable.

We will continue building our DIY smart home in the future. Stay tuned for more development blog posts by joining our mailing list at http://developer.artik.cloud/.

You might also like…

Looking to connect many devices to the cloud and build innovative IoT solutions? Click here to get started for free.