#4_04 Connecting an IOT Device to a Cloud Server - IOTPulse
Posted by Superadmin on November 29 2018 12:36:34

Connecting an IOT Device to a Cloud Server - IOTPulse

 

 

Chapter Goal: Build a Portable IOT Device for Reading Your Pulse

Topics Covered in This Chapter:

This chapter will show the reader how to connect an IOT device to a cloud server, IBM Bluemix. The complexity in this chapter is not building the device, but rather navigating the setup process for adding your device to the cloud.

A major part of designing devices that will connect with the IOT is to determine what to do with the data after you have gathered it. A huge amount of data and no way to store it or analyze it is not very useful. An IOT project device generally is very CPU limited and also only has a limited amount of storage available. You generally have to send the data collected by a sensor-filled IOT device up to a bigger computer and storage cloud to perform complex analysis and determine actions on that data.

In this chapter, we are building a device to collect the pulse rate from a person, and then periodically (every 10 seconds) send it up to a cloud-based storage and analysis system called the IBM Bluemix IOT Foundation.

Before we selected the IBM Bluemix for this chapter, we also looked at three other providers. We determined that the Amazon IOT solution was too “heavy” for these small devices because of the protocol and encryption required. The two other smaller vendors were rejected because of length of time in existence and limited analysis functionality. It should be pointed out that the smaller vendors had distinctly superior display capabilities out of the box from either of the two majors.

The IBM Bluemix system brought a good mix of flexible protocols, a “light” method for sending data, and an amazing collection of analytical tools. Ramifications of the IBM Bluemix methodology on encryption versus the Amazon IOT solution will be discussed in Chapter 7, “Computer Security and the IOT.”

IOT Characterization of This Project

As we discussed in Chapter 1, the first thing to do to understand an IOT project is to look at our six different aspects of IOT shown in Table 5-1. IOTPulse is a more complex project than LightSwarm and is much closer to a production IOT device.

Table 5-1.IOTPulse Characterization (CPLPFC )

Aspect

Rating

Comments

Communications

9

WiFi connection to Internet -

Processor Power

7

80MHz XTensa Harvard Architecture CPU, ∼80KB Data RAM / ∼35KB of Instruction RAM / 200K ROM

Local Storage

8

4MB Flash (or 3MB file system!)

Power Consumption

8

200mA transmitting, ∼60mA receiving, noWiFi ∼15mA, Standby ∼1mA

Functionality

7

Partial Arduino Support (limited GPIO/Analog Inputs)

Cost

9

< $10 and getting cheaper

Ratings are from 1–10, 1 being the least suitable for IOT and 10 being the most suitable for IOT applications.

This gives us a CPLPFC rating of 8.0. Great for learning and experimenting, and it could be deployed for some market applications.

The ESP8266 provides a WiFi transmitter/receiver, a TCP/IP stack, and firmware to support direction connections to a local WiFi access point, which then can connect to the Internet. The data generated by the IOTPulse design will be sent to IBM’s Bluemix Cloud IOT site.

The Internet Of Things on the Global Network

As was stated in the introduction, what do you do with all this data you are gathering? Whether it is the age of your milk in the refrigerator, your current blood sugar or pulse rate, or your home security system, the data needs to be stored and analyzed; or what is the point of gathering it?

Sometimes you don’t need to store the data. Sometimes the local devices can do the necessary actions (like in the LightSwarm project in Chapter 2), but there are many applications that require more computing resources than might be available among the local IOT devices.

This is the situation that has led to the development of server-based (often on a computing cloud) support software for the upcoming IOT explosion. In Chapter 2, we used a Raspberry Pi to gather the data from the LightSwarm and log the rather complex behavior of the cooperative swarm itself for later analysis. If you have a thousand devices, you most likely are not going to be able to host your server on a Raspberry Pi, which has limited CPU power and storage. Another major problem with basing your system on physical servers that you control (like Raspberry Pis, but also rack mount servers with much larger CPU and memory capabilities) is that of scalability. If suddenly you have 10,000 devices connecting to your servers instead of 1,000 devices, you need to be able to scale quickly and effectively.

It is this realization that IOT systems need to scale quickly and efficiently that has moved the IOT back-end applications into the realm of cloud computing. For an IOT application, there are three main areas that need to be addressed. They are the following: Cloud Computing, Application Builders, and Report and Generation software.

Cloud Computing

Cloud computing is evolving quickly to morph into more services, ubiquitous back ends, high-speed network connectivity, and multiple languages and solutions. The National Institute of Science and Technology (NIST) provides a document that defines cloud computing for government purposes [ http://csrc.nist.gov/publications/nistpubs/800-145/SP800-145.pdf ]. While parts of it are already outdated, it does give a good base definition of cloud computing.

NIST defines cloud computing as this: “Cloud computing is a model for enabling ubiquitous, convenient, on-demand network access to a shared pool of configurable computing resources (e.g., networks, servers, storage, applications, and services) that can be rapidly provisioned and released with minimal management effort or service provider interaction.”

The essential characteristics of cloud computing are the following:

 

1.

On-Demand - User can provision computing services as needed without requiring interaction with service provider.

 

2.

High Internet Connectivity - Cloud capabilities are available over the network and accessed through mechanisms that promote multiple platform usage (not just desktops, but many other types of computers and devices).

 

3.

Ability to Pool Resources - Resources such as memory, CPU power, and storage are pooled to support multiple users and customers according to user demand.

 

4.

Rapid Scaling - Capabilities and resources can be provisioned and released automatically or under user control. With the proper system and software, the cloud can look to be virtually unlimited to the user or application.

 

5.

Ability to Limit (or Meter) Resources - A cloud will be able to limit resources and optimize resource use at several levels of abstraction.

 

6.

Ability to Charge for Service - A cloud service is able to account for resource usage, be able to monitor those resources, and report usage in a transparent manner for both the supplier and the user of the system.

 

Application Builders

There is no way that a cloud provider can anticipate every application or use for data that an IOT provider will need. A good cloud provider will support major types of databases and a variety of standard software Application Programming Interfaces (APIs ). It will provide analytical tools for the data and a variety of different services for manipulating that data. A cloud application (or cloud app) is a program that runs in a cloud environment. It has some aspects of a pure local app (for an iPad or a desktop) and some aspects of a pure web-based app. A local app will reside entirely on your local computer, while a web app is generally stored entirely on a remote computer and is delivered via a browser interface. There are web apps that are a hybrid (such as WebEx) that have a very light client on the browser side (still an app, but a small one) that connects up via an API to a much more complex program on the server side. The application builders in IBM Bluemix have a heavier client (running the graphics and editing part of the application) and then deliver the user design to the servers via an API.

In the IOT world, an application often has both aspects, where the local computer contains part of the application (say sensor data gathering) and the cloud contains the back-end heavy metal processing for the full application. The IOTPulse project is one of these mixed types of applications.

Display and Report Generation

Displaying pertinent information to the user about the user’s IOT devices and what actions they are performing on the user’s behalf is an important aspect that will lead to the adoption of widespread IOT applications. It is argued by some that it is important not to overwhelm the user with data about what is going on. However, we believe that the “overwhelming” part of the IOT can be handled with hierarchical interfaces. The top-most level of the user interface may only display the very basic information needed by the user (say temperature and furnace status). The author attended an early meeting on what was to become the IOT at Microsoft in Redmond, Washington, and the speaker called the most basic mode “Grandma Mode” because he felt there was a need to support substantially every type of user that was going to be using the product with a simple interface.

We felt this was true as far as it went, but with the IOT, the ability for a device and software interface to show what is going on with the data being gathered is paramount. A method and interface needs to be provided for the user to really drill down and look at what is happening inside his network and device at several different levels. Not as part of the “Grandma Mode” interface, but another set of interfaces that are accessible to any user if the user should wish.

Doing this hierarchical interface is a key part of establishing the necessary trust between the user and the IOT device.

A well-designed cloud-based application and report generation system needs to provide the application developer many different ways of analyzing the data, acting on the data, and displaying the data. The cloud developer will never be able to supply all the possible build interfaces that the app developer will need for every application.

The IBM Bluemix Internet Of Things Solution

Bluemix (Figure 5-1) is an IOT-focused implementation of IBM's Open Cloud Architecture that enables you to create, deploy, and manage cloud applications for the Internet Of Things.

Figure 5-1.The IBM Bluemix Logo

There is a growing ecosystem of runtime frameworks and services, including non-IBM third-party solutions and applications. Bluemix provides a dashboard for you to create, view, and manage your applications, IOT devices, and desired services The Bluemix dashboards also provide the ability to manage organizations, spaces, and (very importantly!) user access.

We did find that the “dashboard” paradigm in the Bluemix system somewhat of a misnomer and a bit confusing. Instead of having one dashboard, you have dashboards for every service that you attach. It's easy to get lost in the sequence. But with some perseverance we got through the learning curve.

Bluemix provides access to a wide variety of services that can be incorporated into an application from multiple vendors.

For more complex applications than the IOTPulse device, you have a set of application libraries that you can build your applications connecting to a variety of databases functions and frameworks. Here are some of the more common ones:

All in all, Bluemix is a good implementation of a cloud-based IOT platform to build upon.

Note that Bluemix is an evolving platform, and there will be changes going forward in their product maturation process.

There are many features that are free for prototypes (such as IOTPulse), and all of the features mentioned in this chapter are free for use on Bluemix. Looking through the paid services and rates, it seems that they are reasonable for both small and large applications .

The IOTPulse Design

The IOTPulse design consists of three blocks. The first block is the ESP8266 and the 9V battery, which contains the computer; the WiFi interface; and a single Analog to Digital Converter (ADC ) pin, called A on the ESP8266 board and A0 inside the Arduino IDE software. The ESP8266 is responsible for doing the signal processing and translation of the incoming analog heartbeat signal to a digital heartbeats per minute (BPM) and then will periodically send the latest BPM up to the Bluemix IOT cloud.

The second block is the Pulse Sensor Amped, which is an open source hardware design by www.pulsesensor.com . Figure 5-2 shows the schematic for the Pulse Sensor. The key thing to take away from the pulse sensor is that it is designed to get an approximate measure of heart rate through the skin in a non-invasive way. It works by shining a bright green LED into your skin and then detecting the relative changes in light intensity to the sensor. With a small amount of signal shaping, you can detect pulse rate via an analog output signal.

Figure 5-2.Schematic for the Pulse Sensor

For more information on the technique, see photoplethysmogram [ https://en.wikipedia.org/wiki/Photoplethysmogram ].

The third block is a resistor-based voltage divider. The issue that we are solving with this voltage divider is that the signal output from the Pulse Sensor is about 1.5V and the ADC input on the ESP8266 only goes up to 1V. For a full description on how a voltage divider works, check out the Wikipedia article [ https://en.wikipedia.org/wiki/Voltage_divider ].

We need to take 1.5V down to about 0.6V for the ESP8266 and the software to work. The Pulse Sensor provides a signal that on the average is about 1.5V, which is too high for the ESP8266 ADC to work correctly. With the choice of a 26K Ohm resistor for R1 in Figure 5-3 and an 18K Ohm resistor for R2 in Figure 5-3, we get the following ratio of input to output voltage:

Figure 5-3.Simple Voltage Divider

Vout = Vin * R2/(R1 + R2)

Vout = 1.5V * 18K/(26K + 18K) = 0.6V

The 0.6V is comfortably in the 0.0 - 1.0V range of the ESP8266 ADC and works well. There is virtually no current drain through this voltage divider because of the high resistance of the voltage divider (44K Ohms).

Why does this work? It is because the software in the ESP8266 is calculating the heartbeat by looking at relative changes in the light intensity and not the absolute voltage. As long as the input value is changing, the ESP8266 will pick up the pulse.

If we did not put the voltage divider on the output of the Pulse Sensor, then the ADC in the ESP8266 would always be pegged to the highest level (1.0V) and the sensor software would not be able to pick up a pulse.

Because the ESP8266 ADC is so limited, there are better solutions out there for an ADC. Two of the easier to use boards are these:

Figure 5-4 shows the block diagram, including the voltage divider, of the IOTPulse project. The completed IOTPulse device, including the 3D Printed case is shown in Figure 5-5.

Figure 5-4.Block Diagram of IOTPulse

Figure 5-5.IOTPulse in Case

Building the IOTPulse

The parts list is shown in Table 5-2, followed by the wiring list. The parts for the IOTPulse device are readily available and only the voltage divider will require any soldering.

Table 5-2. Parts List

Part Number

Count

Description

Approximate Cost per Board

Source

ESP8266 Huzzah Board

1

CPU / WiFi board

$10

http://www.adafruit.com/products/2471 

Pulse Sensor Amped

1

I2C Light Sensor

$25

www.Pulsesensor.com 

FTDI Cable

1

Cable for programming the ESP8266 from PC/Mac

$11

http://www.switchdoc.com/inexpensive-ftdi-cable-for-arduino-esp8266-includes-usb-cable/ 

26K Ohm Resistor

1

1/4 watt

$17 for a large mix of resistors (Joe Knows Electronics)

http://​amzn.​to/​1QCASLB 

18K Ohm Resistor

1

1/4 watt

$17 for a large mix of resistors (Joe Knows Electronics)

http://amzn.to/1QCASLB 

Plugging the FTDI Cable into the ESP8266

An FTDI cable is plugged into the end of the Adafruit Huzzah ESP8266. Make sure you align the GND pin on the FTDI Cable with the GND pin on the ESP8266 breakout board as shown in Figure 5-6.

Figure 5-6.FTDI Cable Plugged into the Huzzah Board. Note GND Connection

Table 5-3 contains the wiring list for the IOTPulse project.

Table 5-3.IOTPulse Wiring List

From

To

Description

 

ESP8266/GND

PulseSensor / GND (Black Wire)

Ground for Pulse Sensor

 

ESP8266/3V

PulseSensor / 3.3V (Red Wire)

3.3V Power for Pulse Sensor

 

PulseSensor/Output (Purple Wire)

26K / Port A

Top of the Resistor Divider

 

26K/Port B

18K / Port A

Middle of the Resistor Divider

 

18K/Port A

ESP8266 / GND

Ground for bottom of Resistor Divider

 

26K/Port B

ESP8266 / A0

A0 - Analog to Digital Converter input on ESP8266

 

3D Printing Files for the IOT Case

Finding a case for a custom project can always be a problem. All of the projects in the chapters have suggested using 3D Printing to build cases that fit the project, and the IOTPulse project is no different. The most interesting part of this case is the way we designed a bevel that goes around the base so the top case will snap onto the bottom case (Figure 5-7).

Figure 5-7.IOT Case

We have introduced openSCAD , a free code-based 3D Modeler in previous chapters. There are hundreds of example models on Thingverse.com and the openSCAD web site to choose from and to learn from. Listing 5-1 contains the code that builds the case shown in Figure 5-7.

//

// IOTPulse Case

//

// SwitchDoc Labs

// August 2015

//

include <RoundedRect.scad>

module rcube(size=[30, 20, 10], radius=[3, 2, 1], center=true)

hull() {

translate( center ? [0,0,0] : size/2 ) {

cube(size-2*radius+[2*radius[0],0,0],center=true);

cube(size-2*radius+[0,2*radius[1],0],center=true);

cube(size-2*radius+[0,0,2*radius[2]],center=true);

for(x = [-0.5,0.5], y = [-0.5,0.5], z = [-0.5,0.5])

translate([x * ( size[0] - 2*radius[0]),

y * ( size[1] - 2*radius[1]),

z * ( size[2] - 2*radius[2])])

scale([radius[0], radius[1], radius[2]])

//                       sphere(1.0,$fn=4*4);

sphere(1.0,$fn=6*6);

}

}

module IOTPulseTopCase()

{

difference()

{

//cube([82,62,25]);

rcube(size=[82,62,30],radius=[5,5,5],center=false);

#translate([2,2,2])

cube([78,58,25]);

#translate([-10,-10,25])

cube( [100,100,50]);

// hole for pulse meter 18mm

translate([-5,62/2,12.5])

#rotate([0,90,0])

cylinder(h=10,r=10,10);

// hole for seeing light

#translate([82-20,10,-2])

cylinder(h=10,r=5,10);

// hole for seeing wifi light

#translate([82-43,10,-2])

cylinder(h=10,r=5,10);

}

}

union()

{

cube([78,58,4]);

translate([-2,-2,0])

cube([82,62,2]);

// Mount for Battery

translate([40-2,2,0])

cube([40-2,1.35,20]);

translate([40-2,26.10+3.3,0])

cube([40-2,1.5,20]);

// lips for battery

translate([79-2,3,0])

cube([1,28,6]);

// plyons for ESP8266

translate([70-1.0,35,0])

cylinder(h=10,r1=2.2, r2=1.35/2, $fn=100);

translate([70-1.0,56,0])

cylinder(h=10,r1=2.2, r2=1.35/2, $fn=100);

translate([70-34,35,0])

cylinder(h=10,r1=2.2, r2=1.35/2, $fn=100);

translate([70-34,56,0])

cylinder(h=10,r1=2.2, r2=1.35/2, $fn=100);

// plyons for resistors for divider

// gap of 2.3mm

translate([15,35,2])

cube([1,5,5]);

translate([15+3,35,2])

cube([1,5,5]);

translate([15,45,2])

cube([1,5,5]);

translate([15+3,45,2])

cube([1,5,5]);

// top case

translate([0,70,0])

IOTPulseTopCase();

}

Listing 5-1.openSCAD code for the IOT Case

The code for the IOTPulse case is broken into two main sections. The main program builds the lower part of the case while the top of the case is located in the function IOTPulseTopCase(). When building models with openSCAD, it is a good idea to break different parts into functions even if you are only calling them once. It simplifies the code. Now, let us look at the software for IOTPulse.

Software Needed

For you to program the IOT Pulse board you will need a Mac or PC to program the ESP8266 via the Arduino IDE. See Chapter 2 for how to set up the Arduino IDE with the ESP8266 libraries.

The IOTPulse Code

There are three files that are part of the build for the IOTPulse software. The IOTPulse.ino is the main Arduino IDE file (in the C language), and the other two files (Interrupt.h and AllSerialHandling.h) are included in the main file. While the code is fairly straightforward, comments need to be made for each module.

IOTPulse.ino

IOTPulse.ino is the main program for IOTPulse (Listing 5-2). It consists of two major functions, setup() and loop() . The setup() function initializes the ESP8266 WiFi code, reads an IP address using DCHP from the local wireless access point, and initializes variables for containing micros(), which is a function returning the number of microseconds since the reboot of the ESP8266 micros() is a timekeeping function. Note that the ESP8266 does not have a real-time clock on board and really doesn’t know what time it is. It only knows how long it has been running. If you wish to set the time of day in the ESP8266, please check out the NTP protocol in this Instructable[ http://www.instructables.com/id/Internet-time-syncronized-clock-for-Arduino/ ].

In the IOTPulse project, we really don’t care what time it is. When we send a sample to the Bluemix IOT Platform, our friend IBM will timestamp the reception of the data. If we cared about our time, we could build an NTP receiver and synchronize it to network time at a specific NTP server. We are much more interested in intervals of time (specifically 2 milliseconds and 10 seconds intervals) rather than absolute time.

The loop() function contains the code for ongoing operation of the IOTPulse data-gathering operation. We basically do four things in the loop() function:

Note at the end of the loop() function, there is a yield() function. This MUST be called periodically for the ESP8266 software to continue running the WiFi interface and other housekeeping functions. Remember, unlike a regular Arduino, there is a great deal going on in the background to keep this chip running and connected to the network.

One limitation of the current ESP8266 software is that you can’t use the timers [ http://www.switchdoc.com/2015/10/iot-esp8266-timer-tutorial-arduino-ide/ ] to generate interrupts without causing the WiFi to fail and stop connecting to the local WiFI access point and the Internet.

This makes it very difficult to generate an interrupt to the computer every 2ms as is called for by the PulseSensor. You could generate an interrupt every 2ms by using an external hardware timer and then connecting the output of the hardware timer to one of the GPIO pins on the ESP8266, which can all be programmed to generate an interrupt to the CPU.

To solve this issue, we use a scheduling technique that is more CPU intensive (read uses more power) than the interrupt scheme. We check the time periodically and run the PulseSensor software every 2ms and also connect to the IBM Bluemix every 10 seconds.

The biggest disadvantage of this is that we cannot “sleep” the processor very easily. We are looking for an alternative architecture for this problem and are watching the ESP8266 development web sites for solutions.

However, with the exception of power consumption, the current solution works well.

/*

SwitchDoc Labs Code for IOT Pulse

Connects Pulse detector to the IBM Bluemix IoT using a ESP8266 processor

based on pulsecounting code from www.pulsesensor.com

November 2015

----------------------  Notes ----------------------  ----------------------

This code:

1) Blinks an LED to User's Live Heartbeat   PIN 0

2) Determines BPM

3) Sends information to the IBM Bluemix IOT

*/

extern "C" {

#include "user_interface.h"

}

#include <ESP8266WiFi.h>

#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient/releases/tag/v2.3

//----------------------------------------------------------------------

//Local WiFi Variables

const char* ssid = "yourssid";

const char* password = "yourpassword";

#define IOTPULSEVERSION 004

// IBM BlueMix IOT Foundation Data

#define ORG "XXXXX"

#define DEVICE_TYPE "IOTPulse-01"

#define DEVICE_ID "1"

#define TOKEN "YYYYYYYYY"

// setup for IOT IBM

char server[] = ORG ".messaging.internetofthings.ibmcloud.com";

char topic[] = "iot-2/evt/status/fmt/json";

char authMethod[] = "use-token-auth";

char token[] = TOKEN;

char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;

//----------------------------------------------------------------------

//  Variables

int pulsePin = A0;                  // Pulse Sensor purple wire connected to analog pin 0

int blinkPin = 0;                   // pin to blink led at each beat

int fadePin = 5;                    // pin to do fancy classy fading blink at each beat

int fadeRate = 0;                   // used to fade LED on with PWM on fadePin

// Volatile Variables, used in the interrupt service routine!

volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS

volatile int Signal;                // holds the incoming raw data

volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!

volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".

volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

// Regards Serial OutPut  -- Set This Up to your needs

static boolean serialData = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor data

#include "AllSerialHandling.h"

#include "Interrupt.h"

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

Serial.println("callback invoked from IOT BlueMix");

}

WiFiClient wifiClient;

PubSubClient client(server, 1883, callback, wifiClient);

unsigned long oldPulseTime;

unsigned long oldIOTTime;

void setup() {

pinMode(blinkPin, OUTPUT);        // pin that will blink to your heartbeat!

Serial.begin(115200);             // we agree to talk fast!

Serial.println("----------------");

Serial.println("IOTPulse IBM Bluemix IOT");

Serial.println("----------------");

Serial.print("Connecting to ");

Serial.print(ssid);

// NOTE below:  Newer versions of the ESP8266 Libraries may require the following statement

// instead of the other statement.  WiFi.SSID() has changed definitions in new versions

// if (strcmp (WiFi.SSID().c_str(), ssid) != 0) {

if (strcmp (WiFi.SSID(), ssid) != 0) {

WiFi.begin(ssid, password);

}

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

delay(500);

Serial.print(".");

}

Serial.println("");

Serial.print("Local WiFi connected, IP address: ");

Serial.println(WiFi.localIP());

// interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS

// Note:  Interrupts based on os_timer seems to break the ESP8266 WiFi.  Moving to micros() polling methodology

oldPulseTime = micros();

oldIOTTime = micros();

}

int sampleCount = 0;

int beatCount = 0;

int beatValue = 0;

unsigned long newPulseDeltaTime;

unsigned long newIOTDeltaTime;

//  Where the Magic Happens

void loop() {

//serialOutput() ;

if (QS == true) {    // A Heartbeat Was Found

// BPM and IBI have been Determined

// Quantified Self "QS" true when arduino finds a heartbeat

digitalWrite(blinkPin, LOW);    // Blink LED, we got a beat.

beatCount++;

seria