Experiment #5: Inter-Microcontroller I²C Communication


Following the disappointing results achieved in Experiment #4 which invesitaged using serial communication between microcontrollers it was decided to look for alternatives. One such was to use an I²C bus, and this is what is being investigated here.

As in Experiment #4 an Arduino Uno was used to receive the data and both an Arduino Nano and a ATtiny85 were used to as transmitters.

On the diorama the transmitting microcontroller will be the infra-red subsystem. It will need to initiate data transfer when a command is to be sent, so it was decided to make the transmitting microcontroller the I²C master and the receiver the I²C slave.

Each transmitter runs a loop that sends 6 bytes of data, including an incrementing counter, to the receiver. The receiver then copies this data to its serial port for viewing in a serial terminal.


Each circuit is very similar and varies only in the pins used to manage the I²C bus. The Arduino Nano and Uno have I²C support built in and have dedicated pins to support it. While some versions of the microcontrolers have dedicated pins, some (like mine) use two of the analogue pins. A4 is used for the I²C SDA connection and A5 is used for SCL. The ATtiny does not support I²C natively, so a software implemtation was required. This implementation uses PB0 for SDA and PB2 for SCL.

Connections are:

Transmitter Attached to Notes
ATtiny85 Pin Nano Pin
PB0 A4 Uno pin A4 I²C SDA connection
PB2 A5 Uno pin A5 I²C SCL connection
GND GND Uno GND Common ground connection

The Nano and Uno were each powered via their USB connectors, which the Uno also used for serial output. The ATtiny was powered by an external 5V power supply. Two 4.7kΩ pull-up resistors were used to connect the SDA and SCL lines to 5V.

The following image shows the breadboard connections for the Attiny85 circuit.

I²C connections between Arduino Uno and ATtiny85 on breadboard

The version of the circuit using the Arduino Nano in place of the ATtiny85 has not been illustrated since it is so similar to the above.


All the code used in this experiment is available from the cahamo/diorama project on GitHub, in the research/i2c-tests directory. The code was developed in C++ using PlatformIO. There are three separate programs, each in its own sub-directory. The programs are as follows.

I²C Slave

The I²C slave code that runs on the Arduino Uno can be found in i2c-slave-read-uno.cpp

The code is based closely on that by Nicholas Zambetti. It uses the Arduino Wire library to implement the I²C slave code. An event is registered that is triggered evre time the slave receives data. That data is then written to the hardware serial port for display on a seril terminal. The I²C slave is registered with address 0x04.

I²C Master

The Arduino Nano and the ATtiny that were tested as I²C masters each have their own code. They use different libraries to implement I²C, but they transmit the same data. The data is transmitted in a loop. A counter is incremented each time round the loop and the text “x is ” followed by the counter value is transmitted over I²C. The loop repeats after a specified delay.

The code is:


The tests with both the Arduino Nano and the ATtiny85 concluded successfully, with no dropped dropped or corrupted bytes being detected over several iterations.


The use of I²C communication to send data from the IR control subsystem to the central control microcontroller looks promising. The only downside may be that in this arrangement the central microcontroller is acting as an I²C slave device, which means it can't initiate communication. This may become a problem if any I²C peripherals are attached to the central microcontroller. However, no such devices are planned at the moment.

It is recommended that I²C is adopted as the means of communicating infra-red control data to the central microprocessor.

Back to Central Control page | Main project page