2
\$\begingroup\$

This question already has an answer here:

I'm planning a hardware design, where I have a main board and multiple peripheral boards. On each of these boards is a microcontroller with I2C, which is the communication bus for the boards. The same kind of a peripheral board can be attached multiple times to the bus.

The microcontroller (will be an ARM, not specified yet) supports dual address.

My idea now is, to set one address to an unique address (with switches for example) and the second to a "group" address, which will be the same for one kind of peripheral.

Is it possible to send commands from my main board to the peripheral, as long it doesn't need a "read back" (only master -> slave)?

For me, it looks like the same functionality as for the general call with address 0x00 except it allows me to make "grouped" general call. But I don't know for sure, if this will work.

\$\endgroup\$

marked as duplicate by Marcus Müller, Elliot Alderson, Dwayne Reid, Edgar Brown, Sparky256 Jan 31 at 1:09

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3
\$\begingroup\$

The I²C specification say about the general call address:

The general call address is for addressing every device connected to the I2C-bus at the same time. However, if a device does not need any of the data supplied within the general call structure, it can ignore this address by not issuing an acknowledgment. If a device does require data from a general call address, it will acknowledge this address and behave as a slave-receiver. The master does not actually know how many devices acknowledged if one or more devices respond. The second and following bytes will be acknowledged by every slave-receiver capable of handling this data. A slave who cannot process one of these bytes must ignore it by not-acknowledging. Again, if one or more slaves acknowledge, the not-acknowledge will not be seen by the master.

At the lowest level, the I²C protocol does not differentiate between slave addresses; all the read/write/ack stuff behaves the same. So your slaves will work for the group address like for the general call address.

\$\endgroup\$
  • \$\begingroup\$ The General call protocol will therefore NOT work for the OP. You cannot discriminate between slaves with it. \$\endgroup\$ – Jack Creasey Jan 30 at 3:22
  • \$\begingroup\$ @JackCreasey The whole point of the question is to send to all slaves in the group without discriminating between them. \$\endgroup\$ – CL. Jan 30 at 7:29
  • \$\begingroup\$ @CL This was excatly what my question was about. As you said, I don't have to discriminating between them, I just want to sent commands to a group of them. Thank you. \$\endgroup\$ – White Wolf Jan 30 at 8:51
  • \$\begingroup\$ Side note. You could also discriminate between I2C nodes on same address in a similar way to dallas 1-wire. Have some sort of unique additional address (UUID?), then send [ADDR, 0x80], and have nodes ACK when UUID[0] <= 0x80, then send [ADDR, 0x40], etc. But if you're implementing all that, might as well just go for 1-wire or I3C. \$\endgroup\$ – domen Jan 30 at 9:05
  • \$\begingroup\$ @domen I can already discriminate between I2C nodes as they support dual address. The point was that all of the same kind of periphal have one shared address, so I can address commands to the hole group. In this case I can't discriminate which slaves sent a NACK and which an ACK. \$\endgroup\$ – White Wolf Jan 30 at 9:31
0
\$\begingroup\$

Rather than deal with the complexities of a General Call type interface, a simple hardware solution may be better.
Since each board you add has an MCU you could easily implement a priority signal through your boards using a Left/Right flag between boards. You control the software so can enable or disable I2C on each board as required.

On each peripheral board if the Left signal is low then it disables the I2C slave interface and sends a low on its Right signal.

schematic

simulate this circuit – Schematic created using CircuitLab

  1. Set all the peripheral boards to the same common I2C address.

  2. All boards set their Right signal low during initialization, and if their respective Left signal is low they DO NOT enable I2C slave hardware.

  3. The Master holds its Right (output) low on powerup, resetting all the Slaves to their common I2C address with the interface disabled.

  4. The Master sets its Right signal high and now only the first physical peripheral board will enable its I2C interface. The interface can accept commands, transfer ID information and finally the Master can tell the Slave its new I2C address.

  5. The First Slave resets its interface and moves to the new allocated I2C address, then sets its Right signal high which will enable the next peripheral board on the common address.

…..and so on down the line of peripheral boards till they all get allocated new I2C addresses.

You can plug new boards on the end of an active system and that board will come up enabled on the common address, so you need to scan for the common address to detect new boards. Any board you add will set its Right flag low while it is using the common address.

Few software changes, and no bit banging the I2C bus. Works well providing you have a couple of spare GPIO bits on your MCUs.

\$\endgroup\$
  • \$\begingroup\$ This is an interessting way to solve the adress conflict. But I also want the peripheral to have a shared group address, where I can send commands for the hole group instead of looping through all of them. \$\endgroup\$ – White Wolf Jan 30 at 8:57
  • \$\begingroup\$ Nothing prevents you from doing this common group address ….it can even be the same one you use for configuration (0x40 in my example). The difference is that in my schema above you HAVE to configure the unique addresses before you could use the common address. You could of course set aside a second group address and use that at any time ….BUT you can't discriminate between slaves using your group address or General Call structure. \$\endgroup\$ – Jack Creasey Jan 30 at 16:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.