Arduino : howto master to master I2C

I’ve been working since many weeks (months) on designing a home automation “box” project, and could hardly find a way to get my Arduinos (actually bare ATMega328 + Arduino’s Optiboot bootloader) communicating together without having the (physical) master poll all the other µCs continuously.

After lots of googling, I finally got an answer thanks to the official Arduino Forum : I should use multi-master I2C to allow all my Arduino’s to talk to each other (and that doing, interrupting receivers as it would be the case with slaves).

IC logo

Doing this is in fact pretty simple : you only to use the Arduino’s official Wire (I2C) library as following.

Master #1

#include <Wire.h>

#define I2C_ADDRESS_OTHER 0x2
#define I2C_ADDRESS_ME 0x1

void setup() {
 Serial.begin(9600);
 Wire.begin(I2C_ADDRESS_ME);
 Wire.onReceive(receiveI2C);
}

void loop() {
 delay(5000);
 Wire.beginTransmission(I2C_ADDRESS_LCD);
 Wire.write("hello world from 0x1 to 0x2");
 Wire.endTransmission();
}

void receiveI2C(int howMany) {
 while (Wire.available() > 0) {
  char c = Wire.read();
  Serial.print(c);
 }
 Serial.println();
}

Master #2

#include <Wire.h>

#define I2C_ADDRESS_OTHER 0x1
#define I2C_ADDRESS_ME 0x2

void setup() {
 Serial.begin(9600);
 Wire.begin(I2C_ADDRESS_ME);
 Wire.onReceive(receiveI2C);
}

void loop() {
 delay(5000);
 Wire.beginTransmission(I2C_ADDRESS_LCD);
 Wire.write("hello world from 0x2 to 0x1");
 Wire.endTransmission();
}

void receiveI2C(int howMany) {
 while (Wire.available() > 0) {
  char c = Wire.read();
  Serial.print(c);
 }
 Serial.println();
}

That’s all, now connect Arduino Uno’s I2C pins (A4 [SDA] and A5 [SCL]) between each board, not forgetting the pull-up (1.2kΩ is fine) resistors for both SDA & SCL.

You should then see “hello world” messages sent through serial on both of your Arduino masters.

About 

Freelance PHP Symfony2 & Magento developer, passionate about programming and electronics.

  • googleplus
  • twitter
  • Pingback: Arduino multimaster I2C | 42()

  • Varut Gap Rintanalert

    hey what if you have 3 arduino. How would u set the address?

    • Alex Mackinnon

      You add to the defines, you could also if you have 20 of them , use a .h to list them all. I also write EEPROM position 0 the i2c id and read it on start. So two start process – the .h config can also be written to tell which board does which service an Arduino with a Mutt shield and sensors , motor drivers, etc.. All depends really on what you wish to do, a great link is this one. http://www.i2c-bus.org/multimaster/

  • Hey there!

    This is exactly what I am after. Have you got it working already? Is it working OK?

    I am also doing some home controlling stuff with mega boards. But having more than 50 input buttons and even more outputs (all binary for now) requires at least 2 Arduino Mega boards. So I figured I need to use multi master to avoid constant polling.

    But there are some pitfalls when using the Arduino Wire library. They are nicely laid out here: http://forum.arduino.cc/index.php?topic=92406.0

    So I am currently thinking about tweaking native Arduino Wire library to my needs.

    (BTW – I am trying to document the things I am doing on http://racooncircuits.com/ …)

  • Lele Mosina

    Hi, can i use Wire.write() in onReceive function, to send received data to another arduino?