🚌 I2C bus and Arduino

🚌 I2C bus and Arduino

Daniil Zhuk
Instructions for using I2C protocol with Arduino
We will need:
  • Arduino UNO or other compatible;
  • digital potentiometer AD5171 or other controlled via IIC;
  • any LED (for example, from this set);
  • 220 Ohm resistor (I recommend a set of resistors with nominal values from 10 Ohm to 1 MΞ©);
  • 2 4.7 kΞ© resistors (from the same set);
  • breadboard;
  • connecting wires (for example, here is a good set).

I2C interface description

The serial communication protocol IIC (also called I2C - Inter-Integrated Circuits, intermicrocircuit connection) uses two bidirectional communication lines for data transmission, which are called the serial data bus SDA (Serial Data) and the clocking bus SCL (Serial Clock). There are also two power lines. The SDA and SCL buses are pulled to the power bus through resistors.

The network has at least one master device (Master), which initiates data transfer and generates synchronization signals. The network also has slave devices (Slave) that transmit data at the request of the master. Each slave device has a unique address at which the master addresses him. The address of the device is indicated in the passport (datasheet). Up to 127 devices can be connected to a single I2C bus, including several hosts. You can connect devices to the bus during operation, i.e. It supports hot-plugging.

Let's take a look at the I2C protocol exchange diagram. There are several different options, consider one of the most common. We use a logic analyzer connected to the SCL and SDA buses.

Master initiates the exchange. To do this, he begins to generate clock pulses and sends them along the SCL line with a pack of 9 pieces. At the same time, on the SDA data line, it sets the address of the device with which it is necessary to establish communication, which is clocked by the first 7 clock pulses (hence the restriction on the address range: 27 = 128 minus zero address). The next sending bit is the operation code (read or write) and one more bit - the acknowledge (ACK) bit that the slave device has accepted the request. If the confirmation bit has not arrived, the exchange ends there. Or the master continues to send repeated requests.

This is illustrated in the figure below. The task is this: connect to the slave device with the address 0x27 and transfer the string "SOLTAU.RU" to it. In the first case, for example, disconnect the slave from the bus. You can see that the wizard tries to communicate with the device with the address 0x27, but does not receive a confirmation (NAK). The exchange ends.

Now we connect a slave device to the I2C bus and repeat the operation. The situation has changed. The first packet with the address received a confirmation (ACK) from the slave. Exchange continued. The information is also transmitted in 9-bit bursts, but now 8 bits are occupied by data and 1 bit is a bit of acknowledgment by the slaves of each data byte. If at some point the connection is broken and the confirmation bit does not come, the master will stop transmitting.

Implementing I2C in Arduino

Arduino uses two ports to work on the I2C interface. For example, in Arduino UNO and Arduino Nano analog port A4 corresponds to SDA, analog port A5 corresponds to SCL.

For other board models, the pin assignment is:

Board Pin SDA Pin SCL
Arduino Uno, Nano, Pro ΠΈ Pro Mini A4 A5
Arduino Mega 20 21
Arduino Leonardo 2 3
Arduino Due 20, SDA1 21, SCL1

Library "Wire" to work with IIC

To facilitate data exchange with devices over the I2C bus for Arduino, the standard Wire library is written. It has the following functions:

Function Purpose
begin(address) library initialization and connection to the I2C bus; if the address is not specified, the attached device is considered the master; 7-bit addressing is used;
requestFrom() used by the master to request a certain number of bytes from the slave;
beginTransmission(address) the beginning of the transfer of data to the slave at a certain address;
endTransmission() termination of data transfer to the slave;
write() recording data from the slave in response to a request;
available() returns the number of bytes of information available for reception from the slave;
read() reading a byte transmitted from the slave to the master or from the master to the slave;
onReceive() indicates the function to be called when the slave receives a transmission from the master;
onRequest() indicates the function to be called when the master receives the transmission from the slave.

Connecting I2C device to Arduino

Let's take a look at how to work with an I2C bus using Arduino.

At first, we will collect the scheme, as in the figure. We will control the LED brightness using a digital 64-position potentiometer AD5171 (see the technical description), which is connected to the I2C bus. The address at which we will refer to the potentiometer is 0x2c (44 in the decimal system).

IIC device control

Consider the diagrams of information exchange with a digital potentiometer AD5171, presented in the technical description:

We are interested here in the data record diagram in the RDAC register. This register is used to control the resistance of the potentiometer.

Let's open a sketch from the examples of the library "Wire": File Samples Wire digital_potentiometer. Load it into the Arduino memory.

#include <Wire.h> 
byte val = 0; 

void setup() {
  Wire.begin();   
}

void loop() {
  Wire.beginTransmission(44); 
  Wire.write(byte(0x00)); 
  Wire.write(val); 
  Wire.endTransmission(); 

  val++; 
  if (val == 63) { 
    val = 0; 
  }
  delay(500);
}

After switching on, you see how the brightness of the LED increases cyclically and then goes out.
In doing so, we control the potentiometer with the Arduino over the I2C bus.

The links at the bottom of the article, in the section of similar materials (by tag), you can find additional examples of interaction with various devices on the IIC interface, including examples of reading and writing.

Add a comment

* Comments must be approved before being displayed.