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.

BeginnerProtip1 hour31,416
Arduino I2C Multi-Master Approach - Why and How

Things used in this project

Hardware components

Arduino UNO
Arduino 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 • 138 followers
I build connected sensors.
Thanks to Pete Soper.

Comments