The I2C bus is one of the most useful ways of connecting moderately sophisticated sensors and peripherals to the any processor. 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.

Now On Sale!

You can now buy a print edition of micro:bit IoT in C.

You can buy it from:

USA and World


 The full contents can be seen below. 

Chapter List

  1. Getting Started With C/C++
    Anyone who wants to use the BBC micro:bit to its full potential as an IoT device needs to look outside the coding environments provided by its own website. As an mbed device, however, the micro:bit  is capable of being programmed in C/C++. Here we look at how to use the mbed online compiler for a simple demo program.

  2. Offline C/C++ Development  
    We have already discovered how to use the online editor to create a C/C++ program. Now we are going to move to the desktop with an offline approach. This has the advantage that we can use any tools we care to select and no Internet connection is needed.
  3. First Steps With The GPIO 
    The most basic task when working with the micro:bit is controlling the I/O lines. This isn't difficult if you use the framework provided but there some subtle points to watch out for. This chapter looks a the basics of using the GPIO.

  4. Working Directly With The Hardware - Memory Mapping. 
    The framework makes working with the GPIO and other devices as easy as it can be but there are many layers of software to go through before you get to the hardware. Writing directly to the hardware can make things up to ten times faster and give you access to things that their framework doesn't. It is also an educational experience to deal with the raw hardware directly.

  5. Pulse Width Modulation, Servos And More
    In this chapter we take a close look at pulse width modulation PWM including, sound, driving LEDs and servos.

  6. I2C
    The I2C bus is one of the most useful ways of connecting moderately sophisticated sensors and peripherals to the any processor. 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.

  7. I2C Temperature Measurement
    Using I2C devices is fairly easy once you have successfully used one - and hence know what information you need and what to look for in a working system. In this chapter we use the HTU21D temperature and humidity sensor as a case study of I2C in action. It also happens to be a useful sensor.

  8. A Custom Protocol - The DHT11/22

  9. The DS18B20 - One Wire Bus

  10. 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. 

  11. SPI MCP3008/4 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.

  12. Serial Connections
    The serial port is one of the oldest of ways of connecting devices together but it is still very, very useful. The micro:bit has a single serial interface but it can be directed to use any of the GPIO piins as Rx and Tx. 

  13. WiFi 
    The micro:bit has a radio that works in Bluetooth LE and point-to-point ad-hoc mode, but at the moment it lacks WiFi connectivity. The solution is to use the low cost ESP8266 to make the connection via the micro:bit's serial port. 

  14. LED Display 
    The micro:bit's LED display may only be 5x5 but it is very versatile. If you want to make use of it directly then you are going to have to master some lower level functions.



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.  

It is worth mentioning that the micro:bit has two devices already connected to its I2C bus - the accelerometer and the magnetometer and we need to look at how these work as a separate topic.

I2C Hardware Basics 

The I2C bus is very simple.

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

Each signal 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, The size of the pullup resistors isn't critical, but 4.7K is typical as shown.  

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 all cases the master drives the clock line to control how fast bits are transferred. The slave can however hold the clock line low if it needs to slow down the data transfer. 

In most cases the I2C bus has a single master device - the micro:bit 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. 

At this point we could go into the details of how all of this works in terms of bits. However, the framework 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 but  the micro:bit does not 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. The low order bit of the address signals a write or a read operation depending on whether it is a zero or a one respectively.  

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 framework 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. 

Micro:bit I2C 

The micro:bit's processor has two built in I2C masters.

Each one can be connected to any of the GPIO pins - that is any two GPIO pins can be used as SCL and SDA. 

However the micro:bit's accelerometer and magnetometer make use of GPIO 0 and 20 which are brought out as edge connector pins P19 SCL and P20 SDA. These pins are configured in mode S0D1 i.e. they are open collector and pull-up resistors are provided on the board. 

You can use one of the I2C devices to work with the accelerometer/magnetometer and the other can be used externally. 

The hardware can work at 100kHz or 400kHz and it supports clock stretching - see later. It isn't possible for another master to be on the bus with the micro:bit.