RSS

Archive for September, 2014

Using the Electric Imp

Monday, September 1st, 2014

A few weeks ago I acquired and Electric Imp as I was interested in how this could be used to prototype and connect a device to the Internet. Such a device would become part of the Internet of Things.

In order to investigate the possibility of using this device I decided to monitor the temperate of my office and log the data on the Internet.

Electric Imp

Electric Imp offers a starting point for hardware and software engineers wishing to develop for the Internet of Things. The simplest format for prototyping is probably the Imp001 and a breakout board. The Imp001 is an Electric Imp in SD format. The card is fully FCC certified and so offers a simple way of using a wireless network to connect a project to the Internet. The SD card contains a Cortex-M3 processor, 802.11b/g/n transceiver and antenna and once connected to a WiFi network with internet connectivity can be programmed using the cloud based development environment.

The Electric Imp is connected to a WiFi network using an application called BlinkUp. This application is a free download for iPhone and Android. The phone application takes details about the local WiFi network (name, password etc.) and sends this to the Imp001 by blinking the screen (hence the name BlinkUp) whilst the phone is held against the LED on the SD card.

Software for the Electric Imp is developed using the online IDE provided by Electric Imp. The development environment offers the ability to develop code which runs on the Electric Imp (Device code) itself as well as a component which runs in the cloud (Agent code). A user account is setup by following the link to the Log in page from the Electric Imp web site.

Sparkfun Data Logging Service

Sparkfun have recently started to provide a cloud based data logging service which is free to use for a limited amount of data. The system uses a circular 50 MByte data store for each data stream. Sign up is simple, just follow the Create link from the main page. The data streams can be both public and private. If the amount of data storage required is greater than 50MB or the application requires a greater level of privacy then the source is freely available for download by following the DFeploy link from the main page.

Once created, the data stream is accessed using public and private keys, the private keys allow data to be written to the data stream. The public key allows the public data stream to be viewed or data to be retrieved for use in say charting.

Temperature Logging

The principles involved in linking the local hardware to the Sparkfun cloud server will be illustrated by logging the local temperature using a temperature sensor and then sending the data to Sparkfun’s servers. The data will be retrieved and displayed on a web page.

Hardware

The bill of materials (BOM) for this project is as follows:

  1. Electric Imp (Imp001)
  2. Electric Imp Breakout board
  3. LM35 Temperature Sensor
  4. LED and current limiting resistor
  5. Connectors
  6. Breadboard and miscellaneous wire
  7. USB cable and power supply (your computer can act as a power supply if necessary)

Solder the connectors to the breakout board and insert the connectors into the breadboard.

Next, connect the current limiting resistor to Pin 9 on the breakout board and the LED. Connect the other leg of the LED through to ground.

Finally connect the LM35 temperature sensor to Vcc, Ground and the sensor output to Pin 2 of the breakout board.

Follow the instructions on the Electric Imp web site for downloading the BlinkUp software and configuring the Electric Imp. Configure the Imp and connect to the local WiFi network.

Electric Imp Software

The Electric Imp software is split into two components:

  1. Device code running on the Electric Imp hardware
  2. Agent code which runs on the Electric Imp cloud servers

The first step is to register with the Electric Imp web site for a developer account. Once completed you will be presented with the developer IDE.

To record the temperature the Electric Imp will record the temperature every 5 seconds. These readings will be summed and averaged over a one minute period. The average will sent to the Electric Imp servers, the average cleared and the whole process will restart. This will provide a continuous stream of temperature readings while the Imp is powered.

The Electric Imp servers will run Agent code which will listen for data/commands from the Electric Imp device code. The Agent on the server will then post the data to the Sparkfun server.

The code for the Device and the Agent is written in a C like language called Squirrel.

Device Code

The analog port on the Electric Imp returns a value in the range 0 to 65,535. The maximum value represents a voltage of 3.3V. The temperature sensor selected outputs 10mv per degree C. The maximum range of the values for this sensor is 0V to 1.55V given the operating range for the LM35.

The LED has been added to demonstrate when the board is taking a temperature reading. The LED will flash each time a reading is taken.

Firstly, some space in needed for the supporting variables:

//
//  Create a global variable to allow control of the LED.
//
led <- hardware.pin9;
//
//  Create a global variable for the temperature sensor.
//
temperatureSensor <- hardware.pin2;
// 
//  Configure led to be a digital output.
//
led.configure(DIGITAL_OUT);
//
//  Configure the temperature sensor to be an analog input.
//
temperatureSensor.configure(ANALOG_IN);
//
//  This name will be sent to the stream each update:
//
local impName = "Imp%20" + imp.getmacaddress();
//
//  Variables related to averaging the temperature.
//
readingCount <- 0;
readingSum <- 0.0;
// 
//  Create a global variables for the sensor readings.
//
temperature <- 0.0;
sensorValue <- 0;

Next, the main application loop (function), the first thing this should do is to turn on the LED to show that the application is active:

//
//  Main program loop.
//
function main()
{
    led.write(1);

Next, take the temperature sensor reading and convert to centigrade and add to the ongoing sum:

    sensorValue = temperatureSensor.read();
    temperature = ((sensorValue * 3.3) / 65535) * 100;
    readingCount++;
    readingSum += temperature;

Next, check if the number of readings has reached 12 (60 seconds). If we have 12 readings then take the average and send this to the Electric Imp Agent:

    if (readingCount == 12)
    {
        local average = readingSum / readingCount;
        server.log("Average temperature = " + average);
        local data = "";
        data = "Temperature=" + average;
        agent.send("postData", data);
        readingCount = 0;
        readingSum = 0.0;
    }

The server.log statement sends the logging information to the servers. This is not used anywhere, simply logged. The data is sent to the Agent in the agent.send(“postData”, data) statement.

Next, pause and then turn the LED off:

    imp.sleep(0.5);
    led.write(0);

The whole process should be repeated 4.5 seconds later (remember there is a 0.5 seconds pause above) to take readings every 5 seconds.

    //
    //  Schedule imp to wakeup and repeat.
    //
    imp.wakeup(4.5, main);
}

Finally the main loop should be executed:

//
//  Start the main program loop.
//
main();

Agent Code

The Agent code is responsible for listening for data from the device. The code used is actually provided by Sparkfun and is produced here more or less unaltered:

/*****************************************************************
Phant Imp (Agent)
Post data to SparkFun's data stream server system (phant) using
an Electric Imp
Jim Lindblom @ SparkFun Electronics
Original Creation Date: July 7, 2014

Description

Before uploading this sketch, there are a number of vars that need adjusting:
1. Phant Stuff: Fill in your data stream's public, private, and 
data keys before uploading!

This code is beerware; if you see me (or any other SparkFun 
employee) at the local, and you've found our code helpful, please 
buy us a round!

Distributed as-is; no warranty is given.
*****************************************************************/

//
//  Phant Stuff configuration information.
//
local publicKey = "Your-Public-Key-Goes-Here";      // Your Phant public key
local privateKey = "Your-Private-Key-Goes-Here";    // Your Phant private key
local phantServer = "data.sparkfun.com";            // Your Phant server, base URL, no HTTP

//
//  When the agent receives a "postData" string from the device, use the
//  dataString string to construct a HTTP POST, and send it to the server.
//
device.on("postData", function(dataString)
    {
        server.log("Sending " + dataString); // Print a debug message
        //
        //  Construct the base URL: https://data.sparkfun.com/input/PUBLIC_KEY:
        //
        local phantURL = "https://" +  phantServer + "/input/" + publicKey;
        //
        //  Construct the headers: e.g. "Phant-Private-Key: PRIVATE_KEY"
        //
        local phantHeaders = {"Phant-Private-Key": privateKey, "connection": "close"};
        //
        //  Send the POST to phantURL, with phantHeaders, and dataString data.
        //
        local request = http.post(phantURL, phantHeaders, dataString);
        //
        //  Get the response from the server, and send it out the debug window:
        //
        local response = request.sendsync();
        server.log("Phant response: " + response.body);
    }
);

The code is clearly commented and self explanatory.

Results

Building the above in the IDE should deploy the device code to the Electric Imp should result in the temperature being collected by the device, sent to the Electric Imp server and then from there on to Sparkfun’s servers. The data can be viewed in it’s raw form by browsing to your data stream using a URL such as: https://data.sparkfun.com/streams/Your-Public-Key-Here. This URL will have been supplied on the account creation page for the Sparkfun data service.

The data can also be retrieved using Javascript:

<!DOCTYPE html>
<html>
  <head>
    <!-- EXTERNAL LIBS-->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://www.google.com/jsapi"></script>

    <!-- EXAMPLE SCRIPT -->
    <script>

      // onload callback
      function drawChart() {

        var public_key = 'Your-Public-Key-Here';

        // JSONP request
        var jsonData = $.ajax({
          url: 'https://data.sparkfun.com/output/' + public_key + '.json',
          data: {page: 1},
          dataType: 'jsonp',
        }).done(function (results) {

          var data = new google.visualization.DataTable();

          data.addColumn('datetime', 'Time');
          data.addColumn('number', 'Temperature');

          $.each(results, function (i, row) {
            data.addRow([
              (new Date(row.timestamp)),
              parseFloat(row.Temperature),
            ]);
          });

          var chart = new google.visualization.LineChart($('#chart').get(0));

          chart.draw(data, {
            title: 'Room Temperature', height: 500, is3D: true
          });

        });

      }

      // load chart lib
      google.load('visualization', '1', {
        packages: ['corechart']
      });

      // call drawChart once google charts is loaded
      google.setOnLoadCallback(drawChart);

    </script>
  </head>
  <body>
    <div id="chart" style="width: 100%;"></div>
  </body>
</html>

The above uses Google’s chart API to generate a chart from the data stored in the Sparkfun servers (thanks for Sparkfun for the code). Save the above page to a web server and browse to the page and you will see something like the following:

Room Temperature Chart

Room Temperature Chart

The chart shows the fall and rise in temperature in a room over a period of 48 hours.

Conclusion

The Electric Imp offers a simple method for connecting a device to the Electric Imp servers on the Internet. The Agent code can then pass this data on to services provided by additional third parties.

The device options used here would increase the cost of any device produced but as a proof of concept they offer a simple and convenient way of demonstrating how a device can interact with the outside world over the Internet. This example took less than 3 hours to research, build and complete – good going considering how complex this would be if this were completed in a conventional manner (Arduino, WiFly shield etc.).