chipKIT Tutorial 6: Inter-Integrated Circuit (I2C) communication

I2C or IIC (Inter-Integrated Circuit) is a simple bidirectional serial interface, which requires only 2 signal lines for data transfer. It was originally developed by Philips in 1980′s to provide easy on-board communications between a CPU and various peripheral chips in a TV set. Today, it is widely used in varieties of embedded systems to connect many low speed peripherals, such as external EEPROMs, sensors, LCD drivers, port expanders, real-time clocks, etc, to the host microcontroller.chipKIT Tutorial 6: Inter-Integrated Circuit (I2C) communication  In this tutorial, we will explore the chipKIT Wire Library for establishing an I2C communication link between the chipKIT Uno32 board and two I2C sensors. The Uno32 board receives the sensor outputs through the I2C link and displays the results on the serial monitor window on the computer screen.

I2C communication demo
I2C communication demo


An I2C bus consists of two signal lines called SDA (data) and SCL (clock). Just line Arduino Uno, the chipKIT Uno32 board offers the SDA and SCL connections via analogue input pins A4 and A5 respectively. Each device connected to the I2C bus is software addressable by an unique 7-bit address. Multiple I2C devices can be connected to the same I2C bus as long as they have different addresses. A simple Master and Slave relationship exist at all times between the communicating devices. The Master device initiates a data transfer, generates clock signals and terminates the transfer. Any device addressed by the Master at any time is considered a slave. Both SDA and SCL are open-drain lines, and therefore, require two pull-up resistors during operation. A more detail look of the I2C Bus protocol and how the exchange of information takes place between Master and Slave has been discussed in one of my previous tutorials, Inter-Integrated Communication in PIC MCU. So I am not going to repeat that here again.Inter-Integrated Communication in PIC MCU

In this tutorial, we are going to experiment with two digital temperature sensors that support I2C communication. They are Maxim’s DS1631 and Microchip’s TC74 devices.

DS1631 features
DS1631 features

Similarly, the TC74 device is also a serially accessible digital temperature sensor that provides a temperature measurement as an 8-bit word. The resolution is thus 1 degree Celsius. Its features are highlighted below. It should be noted that there are no external pins for configuring the I2C address. This means that the 7-bit I2C address of TC74 is fixed and set by manufacturer. Eight versions of TC74 are available, namely TC74A0 through TC74A7, with different I2C address values. I am using TC74A0, which has the 7-bit address fixed to 1001000 (0x48).

TC74 features
TC74 features

Please read the datasheets of DS1631 and TC74 for more information on these devices.

Circuit Setup

Circuit diagram for connecting DS1631 and TC74A0 to chipKIT Uno32

Complete circuit layout on breadboard

Perhaps you have noticed that the four most significant bits of the I2C addresses of DS1631 and TC74A0 are same (1001). The remaining address bits of TC74A0 are fixed (000). But the same bits are configurable for DS1631 through its hardware pins. We will ground the pins A1 and A2, and pull-up pin A0 to VCC so that the I2C address of DS1631 would be 1001001 (0x49). We build the following circuit on a breadboard and power it through the 3.3V power supply from the Uno32 board. The SDA and SCL signal lines are connected to analog input pins A4 and A5, respectively. Note that the jumpers JP6 and JP8 must be placed in the RG3 and RG2 position in order to use these pins for I2C operation. See Exploring chipKIT Uno32 for more details on the functions of various shunt jumpers on the Uno32 board. The pull-up resistors for the I2C signal lines can be of value anywhere between 1K and 10K, at least for this experiment.Circuit diagram for connecting DS1631 and TC74A0 to chipKIT Uno32Complete circuit layout on breadboard

chipKIT Sketch

The Arduino’s standard Wire library is also implemented in MPIDE, which allows chipKIT Uno32 to communicate with I2C devices. The Wire library uses 7 bit addresses for addressing slave devices on the I2C bus. Following are the main functions available in the Wire library.

Wire.begin() initializes the Wire library and configures analog pins A4 and A5 as I2C pins. This should normally be called only once.

Wire.beginTransmission(address) begins a transmission to the I2C slave device with the given 7-bit address.

Wire.send(data) sends data to the slave device.

Wire.requestFrom(address, count) is used by Master to request a specific number of bytes from a slave device.

Wire.receive() is used by Master to retrieve a byte that was transmitted from a slave device after a call to Wire.requestFrom(address, count)

Wire.endTransmission() ends the data transmission.

Wire.available() returns the number of bytes available for retrieval with Wire.receive().

More details on the chipKIT specific Wire library can be found here.

Here’s the sketch written for requesting temperature readings from the DS1631 and TC74A0 devices and display them on the Serial Monitor window.

  Tutorial 6:  I2C communication demo 
  Description: Explore the I2C serial communication protocol and interface
               two I2C slave devices to chipKIT Uno32 using a common I2C bus.
               Two devices: DS1631 and TC74A0 temperature sensors. 
  Board: chipKIT UNO32
  Connect SDA to Arduino pin A4 (SDA)
  Connect SCL to Arduino pin A5 (SCL) 
  Written by: Raj Bhatt (April 2014) 
#include <Wire.h>
int DS1631_Address = 0x49; // 7-bit I2C address for DS1631
int TC74A0_Address = 0x48; // 7-bit I2C address for TC74A0
// setup loop
void setup(){
  Serial.println("IIC Test: Temperature sensors"); 
// Main Loop
void loop(){
  float temp1 = Read_Temp_DS1631(); 
  Serial.print("DS1631 reading: ");
  Serial.print(temp1, 4);
  Serial.println(" degC");
  float temp2 = Read_Temp_TC74A0(); 
  Serial.print("TC74A0 reading: ");
  Serial.print(temp2, 2);
  Serial.println(" degC");
// Function sub-routine for reading temperature from DS1631
float Read_Temp_DS1631(){
  float tempC1;
  int MSbyte1, LSbyte1;             
  Wire.send(0x51);     // Send Start Convert command      
  delay(1000);         // Wait until temperature conversion is done
  Wire.send(0xAA);     // Send Read Temperature Command
  Wire.requestFrom(DS1631_Address, 2);  // Request two temperature bytes
  while(Wire.available()) //
    MSbyte1 = Wire.receive();
    LSbyte1 = Wire.receive(); 
  LSbyte1 = LSbyte1>>4;
  tempC1 = (float)MSbyte1 + (float)LSbyte1*0.0625;
  return tempC1;
// Function sub-routine for reading temperature from TC74A0
float Read_Temp_TC74A0(){
  float tempC2;
  int MSbyte2;             
  Wire.send(0x00);      // Send Read Temperature command
  Wire.requestFrom(TC74A0_Address, 1);  // Request a temperature byte
  while(Wire.available()) //
    MSbyte2 = Wire.receive();
  tempC2 = (float)MSbyte2;
  return tempC2;


Complete experimental setup

Temperature outputs from DS1631 and TC74A0

Upload the above sketch to the Uno32 board and then open the Serial Monitor window to display the temperature readings from the two sensors.Complete experimental setupThe two temperature sensor readings seem to agree within 2 degree Celsius. DS1631 has better accuracy and resolution than TC74A0.

Temperature outputs from DS1631 and TC74A0

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us: