Back to Acronyms

I2C (Inter-Integrated Circuit)

Date: 2023-12-08Last modified: 2025-01-14

Arduino

Pull up resistor.
Fig. 1 - Pull up resistor.

Start Condition And Stop Condition Transitions

Start condition.
Fig. 2 - Start condition.

Repeated Start

Repeated start.
Fig. 3 - Repeated start.

Start Condition Followed By 7-Bit Address of 0×64 and a Write Command Set. The Slave Responds with an Acknowledgement

Start condition followed by ACK/NACK.
Fig. 4 - Start condition followed by ACK/NACK.

Bit Transition of Data Bits

Bit transition.
Fig. 5 - Bit transition.

Addressing

Fig. 6 -

Slave interprets R/W as:

* 0 ACK: came from slave
Fig. 7 - * 0 ACK: came from slave

Writing to a Device

Writing to a device.
Fig. 8 - Writing to a device.

Reading From a Device

Reading from a device.
Fig. 9 - Reading from a device.

Combining Transmission Protocols

Combining trasmission protocol.
Fig. 10 - Combining trasmission protocol.

LTC2946 Serial Bus SDA Read Byte Protocol

Where

S = Start Bit P = Stop Bit R = Read Bit W\ = Write Bit A = Acknowledge A\ = Not Acknowledge

Master Writing to Two Different Slaves Sequentially

Master writing to two different slaves sequentially.
Fig. 11 - Master writing to two different slaves sequentially.

Multimaster/Multicontroller

Multimaster/Multicontroller.
Fig. 12 - Multimaster/Multicontroller.

Arduino pin

Board SDA pin SCL pin
Arduino UNO A4 A5
Arduino Nano A4 A5
Arduino Mega 2560 20 21
Arduino Micro 2 3
Arduino Leonardo 2 3
Arduino pin.
Fig. 13 - Arduino pin.

I2C Communication between Two Arduino

Communication between two arduino.
Fig. 14 - Communication between two arduino.

Master

{{{code: lang=“cpp” linenumbers=“True” Wire.write(7); //send data byte Wire.write(“i2c”); //send string to slave device Wire.write(a, 6); //here a is an array }}}

{{{code: lang=“cpp” linenumbers=“True” #include <Wire.h>

void setup() { Wire.begin(); // join i2c bus (address optional for master) }

byte x = 0;

void loop() { // 7-bit address of device with which we want to communicate. Wire.beginTransmission(8); // transmit to device #8 Wire.write("x is "); // sends five bytes Wire.write(x); // sends one byte Wire.endTransmission(); // stop transmitting

x++; delay(500); } }}}

Slave

{{{code: lang=“cpp” linenumbers=“True” #include <Wire.h>

void setup() { Wire.begin(8); // join i2c bus with address #8 Wire.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output }

void loop() { delay(100); }

// function that executes whenever data is received from master // this function is registered as an event, see setup() void receiveEvent(int howMany) { while (1 < Wire.available()) { // loop through all but the last char c = Wire.read(); // receive byte as a character Serial.print©; // print the character } int x = Wire.read(); // receive byte as an integer Serial.println(x); // print the integer } }}}

Two-way communication between two Arduino using I2C

Master

{{{code: lang=“cpp” linenumbers=“True” #include <Wire.h>

void setup() { Serial.begin(9600); /* begin serial comm. / Wire.begin(); / join i2c bus as master */ Serial.println(“I am I2C Master”); }

void loop() { Wire.beginTransmission(8); /* begin with device address 8 / Wire.write(“Hello Slave”); / sends hello string / Wire.endTransmission(); / stop transmitting */

Wire.requestFrom(8, 9); /* request & read data of size 9 from slave / while(Wire.available()){ char c = Wire.read();/ read data received from slave */ Serial.print©; } Serial.println(); delay(1000); } }}}

Slave

{{{code: lang=“cpp” linenumbers=“True” #include <Wire.h>

void setup() { Wire.begin(8); /* join i2c bus with address 8 / Wire.onReceive(receiveEvent); / register receive event / Wire.onRequest(requestEvent); / register request event / Serial.begin(9600); / start serial comm. */ Serial.println(“I am I2C Slave”); }

void loop() { delay(100); }

// function that executes whenever data is received from master void receiveEvent(int howMany) { while (0 <Wire.available()) { char c = Wire.read(); /* receive byte as a character / Serial.print©; / print the character / } Serial.println(); / to newline */ }

// function that executes whenever data is requested from master void requestEvent() { Wire.write(“Hi Master”); /*send string on request */ } }}}

Functions for Arduino I2C Master

{{{code: lang=“cpp” linenumbers=“True” int n = Wire.requestFrom(address, size) int n = Wire.requestFrom(address, size, stop) }}}

Parameters Address address of device with which we want to communicate No. of byte no. of byte needs to request Stop It is a Boolean. true - send a stop message after the request, releasing the bus, false - continually send a restart after the request, keeping the connection active

Returns No. of bytes returned from slave device.

Function for Arduino I2C Slave

When master send data to slave

{{{code: lang=“cpp” linenumbers=“True” void setup() { Wire.begin(8); // join i2c bus with address #8 Wire.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output } void receiveEvent (int howmany){ while (1 < Wire.available()) { // loop through all but the last char c = Wire.read(); // receive byte as a character Serial.print©; // print the character } } }}}

When master request data from slave

{{{code: lang=“cpp” linenumbers=“True” void setup() { Wire.begin(8); // join i2c bus with address #8 Wire.onRequest(requestEvent); // register event } void loop() { delay(100); }

// function that executes whenever data is requested by master // this function is registered as an event, see setup () void requestEvent() { Wire.write("hello "); // respond with message of 6 bytes // as expected by master } }}}