Multi-Master, Multi-Slave I2C Communication - Arduino, RTC, and EEPROM

Hello everyone,

I have a question regarding the I2C bus communication between multiple Arduino boards, an RTC (Real-Time Clock), and an EEPROM. I understand that with a single Arduino board, I can send or receive data from both the RTC and EEPROM using the I2C protocol. However, I'm a bit confused about how this communication works when I introduce another Arduino board to the bus.

To provide a bit more context, here's the setup:

Arduino Board 1 (Master 1):

  • Can initiate communication as a master on the I2C bus.
  • Can communicate with both the RTC and EEPROM.

Arduino Board 2 (Master 2):

  • Another master on the same I2C bus.
  • I want this Arduino board to communicate with the RTC only.

RTC (Slave 1):

  • Connected to the I2C bus.
  • I want both Arduino boards to communicate with this device.

EEPROM (Slave 2):

  • Also connected to the I2C bus.
  • I want both Arduino boards to communicate with this device.

How does the RTC know which Arduino board to send data to?

It doesn't know it just answers the request, it doesn't care which master is listening .

But that's the theory. In theory the I2C bus is multi-master capable. In reality I never saw a multi-master setup working reliably. The Wire library of the Arduino IDE doesn't support multi-master anyway. So you will have a hard time setting up such a project and I forecast it won't ever run reliable.

My proposal: turn one Arduino into a slave and send the necessary information from the other Arduino. Or connect the two Arduinos by other means (p.e. UART).

2 Likes

Since it is a bus there are some rules. First the device does not know or care about its requester. With this in mind the slave (RTC or EEPROM) responds to the buss when addressed, it does not know nor care who or what receives the data. Everything on the bus will actually get the data and ignore it if it is not addressed to them. Therefore it must be addressed by a master, devices such as RTC, memory, etc are slaves only.

To communicate on the bus it is controlled by the master which generates all of the clocks. The slave responds on the master clock signals only and cannot generate a clock. The only thing a slave can do is to cause the transfer to be extended by holding the clock line.

Second, every device on the I2C bus has its own address and only responds when addressed. For example if somebody were to ask me a question you would not respond as your physical address is different and you were not asked.

The I2C bus was designed for on board communications. Extending the length of the bus decreases reliability and the integrity of it.

1 Like

You could always run some digital lines between both arduinos and work out a negotiation procedure for them, this way you can ensure at any given time one will be master and the other will release its hold on both the clk and data lines and let them float up to VCC so the one which is master can use them without complications. You could simplify the negotiation by deciding for those purposes alone, though not for the I2C bus, that one arduino will be "master" and the other "slave", in this context meaning when the master takes the negotiation line high the slave must finish anything it is doing on I2C (work out the longest possible time for this to be done and have the master wait that long before doing anything on i2C itself) and release the I2C pins, and when the master takes the negotiation line low the "slave" can become a master OF THE I2C BUS ONLY and knows it can safely act because the master will have released the I2C lines.

1 Like

Each device on the I2C bus is a slave by default. A slave can become a master when instructed so in code, for the duration of a transmission. Afterwards it's a slave again and another device can become the bus master for its own transmission time.

The first byte of a transmission signals the target address and a read/write bit. The addressed slave becomes active and reads or writes data on the SDA line, at the SCL pulses created by the master. A slow slave can stretch the clock pulses, if required.

Please, indicate:
Arduino-1 type -- UNO, NANO, MEGA?
Atduino-2 type?

RTC type -- DS3231, DS1307?
EEPROM type -- 24C32, 24C512?

That's wrong. By default one device on the bus is the master, all the others are slaves. The master is responsible to generate the clock signal. And the master requests information from the slaves, the slaves are allowed only to answer if they were addressed to do so. A slave never gets a master.

Nonsense :frowning:

Any device on the bus can take bus mastership, whenever required, at any time. Until then it behaves as a slave.

Problems arise when multiple devices request bus mastership at the same time. Then arbitration is required to determine which of those devices can become the single active master. IMO that situation can arise only if multiple devices start the same type of transaction (r/w) on the same target address. Otherwise each device should follow all ongoing traffic and try to start a transaction only if the bus is idle.

1 Like

Arduino-1 MEGA
Atduino-2 MEGA

RTC type -- DS1307
EEPROM type -- 24C02

I don't agree to that but it depends on what you define to be a slave. If you call a device not doing anything on the bus to be slave you're right. In my definition a slave is listening on the bus for it's address being sent. A device connected to the bus to provide the clock signal later on is the master in my opinion even if it's currently not sending a clock signal.

I again don't agree. The target address is irrelevant. That situation arises if there are multiple devices on the bus that behaves as a master and start any activity on the bus at the same time.

By the standard a master device is only passively listening to a bus shortly before it wants to start a transaction. The rest of the time there's absolutely no need to listen on the bus.
Most master implementations ignore that part of the standard and simply start to transmit assuming they're the only master on the bus. This isn't correct by the standard but as multi-master setups don't work anyway (in my experience), I can live with it.

It can become a master by taking bus mastership.

Please rewrite your opinion so that it takes into account that multiple devices on the bus can provide clock signals.

No, it's significant. A master can determine that another device is communicating at the same time if the bus is LOW while he tries to transmit a HIGH bit. Then it has to abort its transmission immediately.

Wrong. Each device has to listen for broadcast transmissions all the time. It has to watch Start and Stop states in order to know when the bus is free for its own transactions.

Please study the I2C spec again, in order to find out your misunderstandings. I told you already where you are wrong.

Or have some practice in the use of the I2C bus with multiple masters. E.g. a bus master can have a slave address as well and has to react on all bus traffic to that address. Having a slave address does not prevent a device from taking mastership for its own transactions.

I know that multiple devices theoretically can be master on the bus. But in reality they never do (in my experience). And no professional will ever design a system where a slave gets master on the same bus.

Please explain in what way that procedure is dependent on the target address. That's why the target address is completely irrelevant. If a master is following the standard by the letter it must do that before every single time it acquires the bus no matter what other traffic was on the bus before. If the target address is equal bus arbitration may expand into data transmission but the procedure is the same.

I agree that this might be the easier way to check if the bus is free to communicate but it's not necessary. Checking for activity for some time and if found waiting for a stop condition is sufficient.

Does that mean you did systems outside academic researches that relied on multi-master and worked reliable? I mean without synchronization with other signal lines.
I know the theory but I never saw such a system in reality.

I did and you obviously don't understand how the I2C bus works. I'm willing to assist you in finding out your misunderstandings, but you have to understand my explanations yourself. Stop spreading biased opinions about the I2C bus and everything is fine.

How?

"By default" refers to the states of the IO pins of UNO after power up reset and no instruction has yet been executed. At this time, the A4, A5 pins of UNO are corrected with the IO lines of Port-C Register.

When this instruction: Wire.begin(0x23); is included in the sketch and uploaded, the A4, A5 pins of UNO are connected with internal interface logic of the I2C Bus and NOT with the I2C Logic.

If a Master executes this code: Wire.beginTransmission(0x23);, the above UNO immediately responses as Slave by asserting ACK signal.

Argh, another mess of alternative facts :frowning:

A slave does not try to pull the I2C lines LOW unless told so by a master.

Wire.beginTransmission() does nothing, the entire transmission occurs only in endTransmission(). The slave assures ACK on receipt of its address. If not then endTransmission() terminates immediately with an error code.

No! It queues "SLA + W/-bit" which gets transmitted after the issuance of endTransmission() method - a known fact to all UNO users.

The following setup (Fig-1) will allow both UNOs to take I2C Bus Mastership through mutual negotiation using DPin-8/9 IO lines.


Figure-1:

How do you want to prevent or resolve a deadlock?

1. Do you have any suggestion which, for sure, I will experiment?

2. MEGA (UNO) will check if the bus is available and then it will lock UNO (MEGA) until it finishes acquiring DateTime from DS1307, saving into EEPROM, and showing on Serial Monitor.

3. The job will be interesting if OP uses both the cores of ESP32S Board for independent operation but sharing the common hardware resources; where mutex and semaphore will resolve deadlock situation at software level and the APB bus will take care at hardware level during the access of the common resources (RTC, EEPROM, and SM).

What if both try that at the same time?
Chances for arbitration are better if they try to acquire bus mastership instead.