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.
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 |
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:
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.
The I2C connections, along with a voltage regulator for the ATmega168, are shown below.
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 master first initializes the MPU-6050. Then at every sampling instant it read the two bytes it sends.
The master passes the two bytes from one slave to another.
The master then needs to write these bytes to the slave Uno, whose clock frequency is MHz.
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.
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 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.
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.
Finally, the device framework can be setup to receive the incoming serial data from the slave.