I2C – Squaring up multi device communications
UART and SPI communication have benefits and limitations. UART is confined to point to point links, whereas SPI requires additional slave select channels from the master. Both do not scale well for multiple devices. For that reason, I2C was developed with the introduction of device addressing in the data channel.
I2C stands for Inter-integrated Circuit and it uses a clock channel to synchronize its data channel. Only two wires are required to achieve this. They are defined as SDA for the data channel and SCL for the clock channel. I2C can support up to 1008 slave devices with same 2 wires. The protocol can also support a multi-master setup. I2C can send data at a rate of 100Khz to 400Khz, depending on the physical environment it’s deployed in. There is some hardware overhead required to operate I2C links. However it is simpler than UART and not much more complex that SPI.
One of the most exciting features of I2C is Arduino natively supports the protocol with the WIRE library. This will be essential as we begin to interconnect micro controllers and Raspberry Pi devices together. The Arduino also supports software defined I2C addressing. I’ll cover addressing more later, but do note that this is significant. As with any interconnecting technology, level shifting might be needed for platforms of differing voltage levels.
Now lets cover some details about the two channels that I2C uses. The clock channel, referred to as SCL, is an oscillating digital signal that is generated by the bus master. The data channel, referred to as SDA, is held high through a pullup resistor to VCC. When data needs to be sent, the devices bring SDA low as needed. This method eliminates the potential from damage should bus contention occur since a multi device low state doesn’t produce an over voltage condition. SCL also is held high through a pullup resistor to VCC and brought low by the bus master while generating clock ticks.
The distances between I2C devices can be influenced by the value of the pullup resistor. If higher resistor values are used, lower standby power is used but the distance is limited. Conversely, if lower resistor values are used, more power is consumed but greater distances are allowed. It should also be noted that the more I2C devices that connect to the bus, the lower the pullup resistor values should be.
Data is structured as frames on the SDA channel. There are at least two frames initially sent when I2C communication begins. The master device always initiates data communication. First it sends an address frame which is then followed by a data frame. All slave devices on the I2C bus await the detection of the SDA line going low. When it does, they start to listen for that address frame from the master. If the address frame matches the address in the slave’s register, that device continues to listen. The remaining slave devices that do not have that address match return to standby mode.
Address frames are mostly 7-bit addresses. They start with the MSB and end with the LSB. The frame also contains 2 additional bits. The next bit is a read/write instruction for the slave. The last bit is instruction for the slave to either acknowledge or not acknowledge it received the frame, commonly refereed to as ACK/NACK
However, there are 10-bit addresses. To send these 10-bit addresses, the master has to send 2 address frames. The first frame has a standard Bx11110 address header that will be ignored by all 7-bit address devices. This eliminates the chance that a 7-bit slave will perceive the second 10-bit address frame as data. The first 10-bit frame also contains the first 2 MSB, most significant bits, of the 10-bit slave address. It also contains a read/write bit. The remaining 10-bit address is sent in the second frame.
Once all address and data frames are sent by the master, the slave device will either send data back to the master or not, depending on the instruction it received. When all communications are done, the SDA is allowed to return to a high state and all slave devices return to standby.
The I2C protocol is going to be central in the interconnecting of smart sensors in my up coming posts. The ease and scalability of it make it a preferred method for this application. This should cover all the fundamentals we’ll need in order to move forward. Thank you for joining me and I hope you have found the information useful.