All about the Arduino I2C bus

Arduino bus I2C

With Arduino you can create a lot of projects, as you can see if you read OSHardware programming the microcontroller in a simple way. But among the analog and digital connections of this free hardware board, there are some that are still somewhat unknown to many beginners, such as the true potential of the PWM connections, the SPI, the RX and TX pins of the serial port, or the I2C bus itself. So, with this entry you can at least know everything you need from the I2C.

With the I2C bus you can connect and use many third party devices that have this type of protocol to communicate with the Arduino board. Among them, you can connect accelerometers, displays, meters, compasses, and many more integrated circuits thanks to this Philips invention.

What is I2C?

I2C refers to Inter-Integated Circuit, i.e. inter-integrated circuit It is a serial data communication bus developed in 1982 by the company Philips Semiconductors, which today is NXP Semiconductors after disposing of this section. It was originally created for televisions of this brand, to communicate several internal chips in a simple way. But since 1990 I2C has spread and is used by many manufacturers.

It is currently used by dozens of chip manufacturers for multiple functions. Atmel, the creator of the microcontrollers for the Arduino boards, introduced the TWI (Two Wired Interface) designation for licensing reasons, although it is identical to I2C. But in 2006, the original patent expired and is no longer subject to copyright, so the term I2C has been used again (only the logo is still protected, but there are no restrictions on its implementation or use of the term).

Technical details of the I2C bus

bus I2C

The bus I2C has become an industry standard, and Arduino has implemented it for communication with peripherals that need it. It only needs two lines or cables for its operation, one for the clock signal (CLK) and another for the serial data transmission (SDA). This is advantageous compared to other communications over the SPI bus, although its operation is somewhat more complex due to the additional circuitry required.

On this bus, each device connected to it has an address that is used to access these devices individually. This address is fixed by hardware, modifying the last 3 bits by jumpers or switch DIPs, although it can also be done by software. Each device will have a unique address, although several may have the same address and a secondary bus may need to be used to avoid conflicts or to change the address if possible.

In addition, the I2C bus has a master-slave architecture, i.e. master-slave. That means that when communication is initiated by a master device, it will be able to send or receive data from its slaves. The slaves will not be able to initiate communication, only the master can do that, and neither can the slaves talk to each other directly without the intervention of the master.

If you have several masters on the bus, only one can be a master at a time. But it is not worth it, because changing the teacher demands a high complexity, so it is not frequent.

Note that the master provides the clock signal to synchronize all devices on the bus. This eliminates the need for each slave to have its own clock.

The I2C bus protocol also foresees the use of pull-up resistors on the power lines (Vdc), although with Arduino these resistors are not usually used because the programming libraries as Wire activates the internal ones with values of 20-30 k. This can be too soft for some projects, so the signal rising edges will be less fast, so lower speeds and shorter communication distances can be used. To correct this you may need to set external pull-up resistors from 1k to 4k7.

Signal

The communication frame which consists of a signal from the I2C bus consists of the bits or states (those used in Arduino, since the I2C standard allows others):

  • 8 bits, 7 of which are the address of the slave device you want to access to send or receive data from it. With 7 bits you can create up to 128 different addresses, so you could theoretically access 128 devices, but you can only access 112, since 16 are reserved for special uses. And the additional bit that indicates whether you want to send or receive information from the slave device.
  • There is also a validation bit, if it is not active the communication will not be valid.
  • Then would come the data bytes you want to send or receive by the slaves. Each byte, as you know, is composed of 8-bits. Note that for every 8-bit or 1 byte of data sent or received, 18 additional validation bits, address, etc. are needed, which means that the bus is very limited in speed.
  • One final bit of communication validation.

 

In addition, the clock frequency for the transmissions is 100 MHz as standard, although there is a faster mode at 400 MHz.

Advantages and disadvantages of the I2C bus

The advantages are:

  • Simplicity by only using two lines.
  • It has mechanisms to know if the signal has arrived in front of other communication protocols

The downsides are:

  • Quite low transmission speed.
  • It is not a full duplex, that is, it cannot send and receive simultaneously.
  • It does not use parity or any other type of verification mechanism to know if the data bits being received are correct.

 

I2C in Arduino

Arduino bus I2C

In Arduino, depending on the model, the pins that can be enabled to use this I2C bus vary. For example:

  • Arduino UNO, Nano, Mini Pro: A4 is used for SDA (data) and A5 for SCK (clock).
  • Arduino Mega: pin 20 for SDA and 21 for SCK.

Remember that to use it you must use the Wire.h library for your Arduino IDE codes, although there are others like I2C and I2Cdevlib. You can read the documents from these libraries or our articles about the projects you are interested in to get code on how it would be programmed.

How to know the address of a device to use it with I2C?

Just one last warning, when you buy ICs from European, Japanese or American manufacturers, they indicate the address you should use for the device. However, the Chinese sometimes don’t give it to you or it’s not the right one, so it won’t work. This can be easily solved with an address scanner to know which address to refer to in your sketch.

The Arduino Community has created this code to scan the address and identify it easily. Although I show you the code right here:

#include "Wire.h"
  
extern "C" { 
    #include "utility/twi.h"
}
  
void scanI2CBus(byte from_addr, byte to_addr, void(*callback)(byte address, byte result) ) 
{
  byte rc;
  byte data = 0;
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1, 0);
    callback( addr, rc );
  }
}
  
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
  Serial.print(addr,DEC);
  Serial.print( (result==0) ? " Encontrado!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}
  
  
const byte start_address = 8;
const byte end_address = 119;
  
void setup()
{
    Wire.begin();
  
    Serial.begin(9600);
    Serial.print("Escaneando bus I2C...");
    scanI2CBus( start_address, end_address, scanFunc );
    Serial.println("\nTerminado");
}
  
void loop() 
{
    delay(1000);
}

2 thoughts on “All about the Arduino I2C bus”

Leave a Comment

*

*