I2C Communication

Basic Operation

Inter-Integrated Circuit (I2C) is also referred to as Two-Wire Interface (TWI).

In I2C communication there is a master device and one or more slave devices. The microcontroller can be configured as either a master or slave device.

1.gif

The clock (SCL) signal is primarily controlled by the master. The data transfer happens on the data (SDA) line. The master communicates to each slave using a unique 7-bit address.

The following I2C specifications can be used:

"START"send a START signal
"STOP"send a STOP signal
"READ"read from I2C device to input channel
"WRITE"write from output channel to I2C device
"data"write data to I2C device
"ACK"send or receive an acknowledged (ACK) signal
"NACK"send or receive a not acknowledged (NACK) signal

I2C specifications.

Only the master device sends the "START" and "STOP" signals. "READ" is used by input channels, "WRITE" by output channels, and data can be used by both input and output channels. The "ACK" and "NACK" signals are sent by the device receiving the data and are read by the device sending the data.

The specifications for the I2C devices that the microcontroller needs to communicate with can be given in the "I2C" option as "I2C"->{name1->{spec11,spec12,},name2->{spec21,spec22,},}. The namei of the I2C device can take the following values:

"addr"microcontroller in master mode, slave with address addr
"Master"microcontroller in slave mode

Possible names of I2C devices connected to the microcontroller.

For slave I2C devices, a "ClockFrequency" suboption can be given along with its specifications.

The microcontroller's I2C channels:

{"SDA pin","I2C","SlaveAddress"->addr,"Conversion"}data sent or received by slave device at address addr, and the microcontroller is the master device
{"SDA pin","I2C","Conversion"}data sent or received by master device, and the microcontroller is a slave device

I2C channels in master and slave modes.

In an input channel, the suboption "Conversion" specifies how the data coming in needs to be converted and assigned to the input.

In an output channel, the suboption "Conversion" specifies how the output needs to be converted and sent out.

If the microcontroller is operating in slave mode, its I2C address must be specified in the second argument that has all the microcontroller details as MicrocontrollerEmbedCode[sys,<|,"I2CAddress"->"addr"|>,].

Example

We are going to use an ATmega168 as a master, an Arduino Uno as the slave, and a slave MPU-6050 temperature sensor. The master receives the reading from slave MPU-6050 and transmits it to the slave Arduino Uno. The slave Uno then sends the data over serial which can be read by the device framework.

2.gif

The I2C connections, along with a voltage regulator for the ATmega168, are shown below.

3.gif

The master needs to know the addresses of the slave devices to communicate with them. From the datasheet of the MPU-6050 we know that its address is 0x68. We can choose any other valid address for the slave Uno.

The slave addresses.
In[2]:=
Click for copyable input

The master first initializes the MPU-6050. Then at every sampling instant it read the two bytes it sends.

The specification for the input from the MPU6050 sensor.
In[4]:=
Click for copyable input

The master passes the two bytes from one slave to another.

The input-output system of the master ATmega168 is an identity matrix.
In[5]:=
Click for copyable input
Out[5]=

The master then needs to write these bytes to the slave Uno, whose clock frequency is MHz.

The specification for the output to the Uno slave.
In[6]:=
Click for copyable input

Pin 27 is the SDA pin on the master ATmega168 through which data is received and transmitted. The input and output byte conversions are identical because the bytes are just passed through.

Set up the input and output channel specifications.
In[7]:=
Click for copyable input
Load the package.
Click for copyable input
Embed to the master.
In[8]:=
Click for copyable input
Out[8]=

The master will transmit the raw bytes from the slave MPU-6050 to the slave Uno and the slave Uno will perform the conversion computations.

We need to set up the slave Uno to read the two bytes from the master.

The specification for the input from the Uno master.
In[9]:=
Click for copyable input

The datasheet of the MPU-6050 specifies how to convert the raw bytes to an actual temperature value. The raw bytes are converted to a 16-bit value and then the converted to the actual value.

The conversion for the input received by the Uno slave.
In[10]:=
Click for copyable input
In[11]:=
Click for copyable input
The systems model to convert it to degrees C.
In[12]:=
Click for copyable input
Out[12]=

Set up the slave to receive the I2C data, do the conversion, and transmit it over the serial port. We must also specify the slave I2C address, so it can respond when called upon by the master.

Embed code to the slave Uno.
In[13]:=
Click for copyable input
Out[13]=

Finally, the device framework can be setup to receive the incoming serial data from the slave.

Open a connection to the Uno slave.
In[14]:=
Click for copyable input
Out[14]=
A function to parse the received data.
In[15]:=
Click for copyable input
Set up a task to read the data.
In[17]:=
Click for copyable input
Remove the task and close the device after some time.
In[20]:=
Click for copyable input
The plot of the received data.
In[22]:=
Click for copyable input
Out[22]=