Month: February 2015

Intel Edison and I2C sensors with XDK

The Intel Edison is becoming a popular system to use for IOT devices. Despite its small form factor it is a surprisingly capable platform. This makes the Edison a good choice for interfacing with sensors.

I like the Edison mini breakout board over the Edison kit for Arduino because of the form factor. The  mini breakout board provides USB connectivity, power input and a battery charging circuit to the Edison that covers most the of my requirements for devices.

The drawback of the mini breakout is that you need to either solder in some wires or add a header to the break out board to access i/o for the Edison. Also, the Edison I/o on this board operates at 1.8 volts while most sensors operate at 3.3 volts or higher so a level converter is needed.

The Intel Edison, on the mini breakout, supports various types of i/o but the one we are interested in today is I2C  Inter-Integrated circuit is a two wire serial protocol that is used by components to transfer data between one-another. On the mini-break out board we will be using I2C bus number 1.

Here the Edison is connected to a breadboard containing the MCP9808. There are other devices on the board.
Here the Edison is connected to a breadboard containing the MCP9808. There are other devices on the board.
Here is one way to make the i/o needed for connection available.
Here is one way to make the i/o needed for connection available.

Parts list:

  1. Intel Edison mini breakout board kit.
  2. Sparkfun bi-directional level shift converter.
  3. Adafruit MCP9808 temperature sensor board.
  4. Mini bread board.
  5. Solderless bread board jumpers. 
  6. Dupont male to female cable. 
  7. 90 degree dual row header. 

Items 6 and 7 are optional – you could just solder some wire onto the Edison if you prefer, or use some other type of pin headers.

Connection:

Edison                     Level Shifter                     MCP9808

J17  – 8                          LV1

NC                                 HV1                                  SDA

J18 – 6                           LV2

NC                                HV2                                   SCL

JP19 – 2                         LV — 1.8 volt

JP20 – 2                         HV — 3.3 volt                   VDD

JP19 – 3                        Both grounds                  Ground

The connection looks something like this. The level shifter and MCP9808 are in the center of the yellow board.
The connection looks something like this. The level shifter and MCP9808 are in the center of the yellow board.

With this connection we are ready to code.

I will be using the Intel  XDK IOT edition  to read values from our temp sensor. If you have not used the XDK you can learn how to get started here. Just create a blank project and paste the following code in. Running the code will display the temperature in the console every second.

function char(x) { return parseInt(x, 16)}; // helper for writing registers

var mraa = require('mraa'); //require mraa
console.log('MRAA Version: ' + mraa.getVersion()); //write the mraa version to the Intel XDK console

var x = new mraa.I2c(1); //We will use a device in I2C bus number 1
x.address(0x18); //Default for MCP9808 is 0x10

//x.writeWordReg(char('0x01'), char('0x0100')); // Controls sleep mode for the temp sensor.

periodicActivity();

function periodicActivity()
{

var t = x.readWordReg(char('0x05')); // 0x05 is the register for the current temp.
//The byte order of words is not the same between Edison and the MCP9808
//The edison stores the most significant byte first - big endian, where the
//MCP9808 stores the lowest byte first -- little endian.
//Here is a wikipedia article on endianness. 
var s = ((t & 0xFF) << 8) | ((t >> 8 ) & 0xFF); //swap the bytes.
var r = s & 0xFFF; // Mask of the control bits to get the temp value
r /= 16.0; // dividing by 16 will give us the temp in celcius as long as the temp is above 0.

s = r * 9 / 5 + 32; //get the farenheit value.

console.log(r + " C " + s + " F"); //log the values

setTimeout(periodicActivity,1000); //do it again in a second.
}

For a more thorough explanation of the MCP9808 control registers see it’s data sheet.

And there we have it. It is not a very complex thing to interface an I2C sensor with the Intel Edison. We just need to use a level shifter and connect the thing up. Using the XDK it is fairly easy to read the temp data and control the MCP9808. The complexity comes in when more complex devices are integrated. It can take some time studying the data sheet of a device to figure out how to get everything working correctly.

There are other options for interfacing with I2C and other devices, but MRAA is the easiest in this case as it is already installed. If our sensor had been in the UPM library we could have used a predefined class to operate it.