Here's a quick multimaster page. As a few others have noted, the arduino Wire library documentation is pretty basic and implies you can join the bus as a master or as a slave. I was working on a project where the "slave" needed to be able to send data back to the "master". After a little searching I learned that in fact, I2C is a multimaster protocol and it's completely acceptable for all nodes to join as slaves but become masters when they want to send data to a peer.

I wrote this sketch to test the theory; here's a picture of my development setup with two USB Boarduino's (which used to be one of my favorite development platforms) and two Sparkfun pocket programmers attached to a USB hub I got at USENIX in 2007 but had never used:

This setup allowed me to talk to and program both arduinos without swapping cables around.

On a atmega328p, the TWI (I2C) clock (SCL) is digital 19, analog 5, and pin 28. The data line (SDA) is d18/a4/pin 27. I like to use green for clock and yellow for data. The I2C bus requires pullup resistors. The specification limits the current to 3 mA; I like to use 3.3K Ω which results in 1.5 ma.

The sketch is pretty straightforward; after setting up serial, I2C, and the SCK LED, it copies characters received by the I2C onreceive interrupt handler to serial and then copies any characters it can read from serial to I2C. To avoid race conditions with the onreceive interrupt handler, a circular buffer is used with two end pointers.

By compiling two binaries with TWI_MASTER and TWI_SLAVE defined to reciprocal values, two arduinos will echo characters between the serial ports in both directions. Note that I2C addresses are 7 bit values however 0-7 and 120-127 are reserved.

I later used this sketch to test higher speed I2C. By defining TWI_FREQ to 400000L you can increase the bus speed from 100 kHz to 400 kHz.

Visit the downloads directory.

Copyright © 2012, 2013, 2015, 2017, 2018, 2019, 2021, 2023
Craig Leres