Chip McClelland
Published © GPL3+

Arduino I2C Multi-Master Approach - Why and How

The Arduino is simple, cheap and power efficient but has limitations. Sometimes, you may want to have more than one access your I2C bus.

EasyProtip1 hour10,117
Arduino I2C Multi-Master Approach - Why and How

Things used in this project

Hardware components

Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×1
Sparkfun Simblee BLE Breakout - RFD77101
Sparkfun Simblee BLE Breakout - RFD77101
×1
Texas Instruments FRAM
×1
Maxim DS3231 Temperature Compensated - Real Time Clock with integrated crystal
×1

Story

Read more

Schematics

High-Level Schematic

System Diagram

Code

Sample Code for Master-Master Arbitration

C/C++
These functions make sure that one or the other microcontroller but not both can control the i2c bus.
// Example of how to use the functions
unsigned long FRAMread32(unsigned long address)
{  
  long four;
  long three;
  long two;
  long one;
  if(TakeTheBus()) {  // Request exclusive access to the bus 
    //Read the 4 bytes from memory.
    four = fram.read8(address);
    three = fram.read8(address + 1);
    two = fram.read8(address + 2);
    one = fram.read8(address + 3);
  }
  GiveUpTheBus();// Release exclusive access to the bus
  //Return the recomposed long by using bitshift.
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}



// Function that takes control of the i2c bus
boolean TakeTheBus() 
{
  int timeout = 10000;  // We will wait ten seconds then give up
  unsigned long startListening = millis();
  //Serial.println("Simblee has the Bus");
  while(digitalRead(SQWPin)) {} // The Simblee will wait until the SQW pin goes low
  while (!digitalRead(TalkPin))  { // Only proceed once the TalkPin is high or we timeout
    if (millis() >= timeout + startListening) return 0;  // timed out
  }
  pinMode(TalkPin,OUTPUT);  // Change to output
  digitalWrite(TalkPin,LOW);  // Claim the bus
  
  return 1;           // We have it
}

// Function that gives up control of the i2c bus
boolean GiveUpTheBus() 
{
  
  pinMode(TalkPin,INPUT);  // Start listening again
  //Serial.println("Simblee gave up the Bus");
  
  return 1;
}

Credits

Chip McClelland

Chip McClelland

6 projects • 78 followers
I build connected sensors.
Contact
Thanks to Pete Soper.

Comments