I2C 16bit Address && I2C Address clash

I have been working on a project that uses <Wire.h> library between multiple Arduinos. Their I2C addresses are randomly generated in void setup().

BUT SOMETIMES TWO ARDUINOS SHARE THE SAME I2C ADDRESS and that cause me problems. My questions would be:

  1. Is there anyone can help me out to reduce their clash possibility by EXTEND THE I2C ADDRESS TO UINT16 OR 16BITS in the library.

  2. Is their any way to fix the i2c address clash problem?

I will be very grateful!

  1. No.
  2. No, avoid it.

The I2C on a Arduino board is part hardware (inside the microcontroller) and part software (the Wire library). The hardware checks for the 7-bits address and I think an interrupt is generated if that matches. As far as I know it is not possible to extend that to 16 bits.

You could write the I2C addres in EEPROM, and make sure that every Arduino has a different I2C address.

There is a global broadcast I2C address, address zero. That can be used to send a broadcast something to every Arduino. But I don't know how that can help to give every Arduino its own specific I2C address.

I have tried to extend the I2C address from only one 8bit to two of 8bit addresses by using software I2C. But I want to try it on TWI bus and I am seeking a way to do so.

Here is a topic about the ATmega : http://www.avrfreaks.net/forum/i2c-twi-and-10-bit-addressing-problem-addressing

An USI inside an ATtiny can do a lot more. Perhaps then 10-bit addressing is possible. Also newer processors might support it. According to that topic, 10-bit addressing might work for an ATmega as well, but I see a lot of troubles. There is clock-pulse-stretching for an Arduino as I2C Slave and I wonder if the ACK/NACK for the first byte will always work.

In the end, what use would it be ? A random address with 7-bit address might result in two Arduino Slaves having the same I2C address. That can still happen with a 10-bit I2C address or a 16-bit address. If you want it to be safe and reliable, you have to think of another way.

The SMBus can dynamically assign an address : https://en.wikipedia.org/wiki/System_Management_Bus#Address_Resolution_Protocol

So far, you have not told what the project is and why you want this solution. Can you tell more ? Perhaps there are other ways, or perhaps I2C is not the best solution. The random I2C address is not nice, and I can think of even more ugly solutions. For example: it might be possible to use the hardware TWI to set an Arduino as Slave, and use software I2C (Master) in the same Arduino to chain-link to the next Arduino. Then every Arduino has the same I2C address.

Thank you for your reply.

Acctually I am working on a project that requires a master MEGA328P chip talk to many slave MEGA328P chips as part of its body and I am using I2C as their communication protocol. Since I am planning to add serveral more soldered MEGA328P chips and they are bootloaded with random I2C addresses, it is very common to have I2C address clash in this case.

I am trying to minimize their address clash rate or even to avoid clashes. I am glad to have your help. THANKS!

I have looked through SMBus. It seems ideal for my project and I am wondering is their any SMBus library that use TWI and AVR chips ? :o :o

As far as I know, there is no full SMBus library for ATmega chips.

Atmel has a document : "AVR316: SMbus Slave Using the TWI Module". But about the dynamic I2C address, it says : "The SMBus device default address is different from the general call address. The AVR TWI module cannot be set up to listen to two different slave addresses, unless one is the general call address. ARP is thus not supported" :(

The "general call address" is the global broadcast I2C address, address zero, that I mentioned.

Is it possible to add a dipswitch to every Arduino ?

The dipswitch/jumper scheme works nicely as it allows you to assign the address you want to each added 328. The chip finds it's address during setup() by reading the switches. If you're running out of digital pins then some of the analogue pins can be used as digital inputs. Treat the pins as binary bits so that three will get you eight addresses. You can also shift the address group up by adding a constant to the calculated value thereby avoiding zero as one of the possibilities.