Exploring Edison - I2C Bus
Written by Harry Fairhead   
Monday, 23 November 2015
Article Index
Exploring Edison - I2C Bus
I2C MRAA Functions
Waiting for data

The I2C bus is one of the most useful ways of connecting moderately sophisticated sensors and peripherals to the Edison. The only problem is that it can seem like a nightmare confusion of hardware, low level interaction and high level software. There are few general introductions to the subject because at first sight every I2C device is different, but here we present one.

This is a chapter from our ebook on the Intel Edison. The full contents can be seen below. Notice this is a first draft and a work in progress. Use the comments or email harry.fairhead@i-programmer.info with your queries or suggestions.



Now On Sale!

You can now buy a print edition of Exploring Intel Edison.
You can buy it from:

USA and World  Amazon.com
Canada              Amazon.ca
UK                      Amazon.co.uk
France                Amazon.fr
Germany            Amazon.de
Spain                  Amazon.es
Brazil                  Amazon.br
Italy                    Amazon.it
Japan                 Amazon.co.jp
Mexico               Amazon.com.mx 

Chapter List

  1. Meet Edison
    In this chapter we consider the Edison's pros and cons and get an overview of its structure and the ways in which you can make use of it. If you have ever wondered if you need an Edison or an Arduino or even a Raspberry Pi then this is the place to start. 

  2. First Contact
    When you are prototyping with the Edison you are going to need to use one of the two main breakout boards - the Arduino or the mini. This chapter explains how to set up the Edison for both configurations. 

  3. In C
    You can program the Edison in Python, JavaScript or C/C+ but there are big advantages in choosing C. It is fast, almost as easy as the other languages and gives you direct access to everything. It is worth the effort and in this chapter we show you how to set up the IDE and get coding. 

  4. Mraa GPIO
    Using the mraa library is the direct way to work with the GPIO lines and you have to master it. Output is easy but you do need to be aware of how long everything takes. Input is also easy but using it can be more difficult. You can use polling or the Edison interrupt system which might not work exactly as you would expect.

  5. Fast Memory Mapped I/O
    There is a faster way to work with GPIO lines - memory mapped I/O. Using this it is possible to generate pulses as short at 0.25 microsecond and read pulse widths of 5 microseconds. However getting things right can be tricky. We look at how to generate fast accurate pulses of a given width and how to measure pulse widths.

  6. Near Realtime Linux 
    You need to be aware how running your programs under a non-realtime operating system like Yocto Linux effects timings and how accurately you can create pulse trains and react to the outside world. In this chapter we look the realtime facilities in every version of Linux. 

  7. Sophisticated GPIO - Pulse Width Modulation 
    Using the PWM mode of the GPIO lines is often the best way of solving control problems. PWM means you can dim an LED or position a servo and all using mraa. 

  8. Sophisticated GPIO -  I2C 
    I2C is a simple communications bus that allows you to connect any of a very large range of sensors. 

  9. I2C - Measuring Temperature  
    After looking at the theory of using I2C here is a complete case study using the SparkFun HTU21D hardware and software. 
  10. Life At 1.8V
    How to convert a 1.8V input or output to work with 5V or 3.3V including how to deal with bidirectional pull-up buses.

  11. Using the DHT11/22 Temperature Humidity Sensor at 1.8V 
    In this chapter we make use of all of the ideas introduced in earlier chapters to create a raw interface with the low cost DHT11/22 temperature and humidity sensor. It is an exercise in interfacing two logic families and implementing a protocol directly in C. 

  12. The DS18B20 1-Wire Temperature 
    The Edison doesn't have built in support for the Maxim 1-Wire bus and this means you can't use the very popular DS18B20 temperature sensor. However with a little careful planning you can and you can do it from user rather than kernel space. 

  13. Using the SPI Bus 
    The SPI bus can be something of a problem because it doesn't have a well defined standard that every device conforms to. Even so, if you only want to work with one specific device it is usually easy to find a configuration that works - as long as you understand what the possibilities are. 

  14. SPI in Practice The MCP3008 AtoD 
    The SPI bus can be difficult to make work at first, but once you know what to look for about how the slave claims to work it gets easier. To demonstrate how its done let's add eight channels of 12-bit AtoD using the MCP3008.

  15. Beyond mraa - Controlling the features mraa doesn't. 
    There is a Linux-based approach to working with GPIO lines and serial buses that is worth knowing about because it provides an alternative to using the mraa library. Sometimes you need this because you are working in a language for which mraa isn't available. It also lets you access features that mraa doesn't make available. 



The I2C bus is a serial bus that can be used to connect multiple devices to a controller. It is a simple bus that uses two active wires - one for data and one for a clock. Despite there being lots of problems in using the I2C bus because it isn't well standardized and devices can conflict and generally do things in there own way it is still commonly used and too useful to ignore. 

The big problem in getting started with the I2C bus is that you will find it described at many different levels of detail - from physical bus characteristics, the protocol, the details of individual devices. It can be difficult to relate all of this together and produce a working anything.

In fact you only need to know the general workings of the I2C bus, some general features of the protocol and know the addresses and commands used by any particular device. 

To explain and illustrate these idea we really do have to work with a particular device to make things concrete. However the basic stages of getting things to work - the steps, the testing and verification - are more or less the same irrespective of the device.  

I2C Hardware Basics 

The I2C bus is very simple.

Just two signal lines SDA and SCL the data and clock lines respectively.

The each single line is pulled up by a suitable resistor to the supply line at what ever voltage the devices are working at 3.3V and 5V are common choices but it could be 1.8V as well, The size of the pullup resistors isn't critical, but 4.7K is typical as shown.  i2cblock

You simply connect the SDA and SCL pins of each of the devices to the pull up resistors. Of course if any of the devices have built-in pullup resistors you can omit the external resistors. More of a problem is if multiple devices each have pull ups. In this case you need to disable all but one set. 

The I2C bus is an open collector bus.

This means that it is actively pulled down by a transistor set to on. When the transistor is off, however, the bus returns to the high voltage state via the pullup resistor. The advantage of this approach is that multiple devices can pull the bus low at the same time. That is an open collector bus is low when one or more devices pulls it low and high when none of the devices is active. 

The SCL line provides a clock which is used to set the speed of data transfer - one data bit is presented on the SDA line for each pulse on the SCL line. 

In most cases the I2C bus has a single master device - the Edison in our case - which drives the clock and invites the slaves to receive or transmit data. Multiple masters are possible, but this is advanced and not often necessary. The Edison cannot work with multiple masters.

At this point we could go into the details of how all of this works in terms of bits. However, the Edison and the mraa software handles these details for us. All you really need to know is that all communication occurs in 8-bit packets.

The master sends a packet, an address frame, which contains the address of the slave it wants to interact with. Every slave has to have a unique address - usually 7 bits but it can be 11 bits and the Edison does support this.

One of the problems in using the I2C bus is that manufacturers often use the same address or same set of selectable addresses and this can make using particular combinations of devices on the same bus difficult or impossible.

The 7-bit address is set as the high order 7 bits in the byte and this can be confusing as an address that is stated as 0x40 in the data sheet results in 0x80 being sent to the device. 

After sending an address frame it then sends or receives data frames back from the slave, There are also special signals used to mark the start and end of an exchange of packets but the Edison takes care of these. 

This is really all you need to know about I2C in general to get started but it is worth finding out more of the details as you need them - you almost certainly will need them as you debug I2C programs. 

Edison I2C 

The Edison supports two I2C buses but only one is usable on the Arduino breakout board. For this reason it is better to use I2C-1 unless you have a very good reason not to. 

The pins used on the mini-breakout board, including ground and power lines that are concerned with I2C:  

MRAA NumberPhysical PinEdison Pin
6 J17-7 GP27 GPIO-27 I2C-6-SCL
7 J17-8 GP20 GPIO-20 I2C-1-SDA
8 J17-9 GP28 GPIO-28 I2C-6-SDA
19 J18-6 GP19 GPIO-19 I2C-1-SCL
29 J19-2 V_V1P80
30 J19-3 GND
42 J20-1 V_VSYS
43 J20-2 V_V3P30


As we are going to use a 1.8V sensor and I2C bus 1 the pins that we are going to use are:

Physical Pin 
J17-8 I2C-1-SDA
J18-6 I2C-1-SCL
J19-2  V_V1P80
J19-3  GND

Last Updated ( Monday, 23 November 2015 )