calculating I2C delay when switching slaves? or

I am trying to rapidly send data to several different I2C slaves from one master.

The master device is receiving data at 250kbps (via the serial port) and then quickly parsing the data and sending sets of 3 bytes out to each I2C slave (each slave is another arduino).
I know that the I2C bus runs at 100kHz so if I am sending 3x8bits do I calculate the transfer as 24 bits + ???
The problem I am having is that I was that I needed to add a delay after each call to transmit on the I2C bus. I think this is to account for the time it takes for each transfer to finish so that when the master starts sending to a new slave the last transfer was done.

I am guessing that instead of calculating a delay I should be polling the bus to see when the transfer is done?

I am guessing that instead of calculating a delay I should be polling the bus to see when the transfer is done?

If you use the standard wire library, the transfer should be complete and the I2C bus should be idle when endTranmissions returns. No delay should be needed - so you may have other issues.

Have you tried with a 10k pullup resistor on the SDA/SCL lines respectively?

Total transmission time is the number of bytes + address byte + an ack bit for every byte. So 3 bytes at 100kHz would add up to a minimum of 360 micro seconds ((3+1)*(8+1) * 1/100kHz).

Have you tried with a 10k pullup resistor on the SDA/SCL lines respectively?

I would recommend 4K7 pull ups. Without them the waveforms are very bad and it would not surprise me to find it is limiting the speed.

I would recommend 4K7 pull ups.

So would I for overall I2C bus pullup.

When using Arduino's on both sides and using the wire library, internal pullup will be enabled for both slave and master. Taking this into account you can reduce the external pullup resistors somewhat, save a bit of energy and still benefit from sharp clean pulses. A pair of 10k external resistors should work well in this configuration.

Hey Guys,

Been experimenting with the recommendations and right now I am having problems.

I have 13 arduinos connected via I2C over a distance of about 14".

I put a pair of 10k pullups on the first arduino (sda to +5 and scl to +5).

The symptoms are as follows:
The very last arduino on the bus receives data perfectly and is performing without issue. All the other arduinos in between are losing messages or otherwise behaving more erratically.

The first arduino in the chain is the master and all other 12 are slaves.

Any tips?

Should I try playing with different pullup values?

Should I try playing with different pullup values?

Maybe, and also maybe where the pullups are located. Maybe try two pairs of pull-ups of 20k placed at each end of the whole buss (first and last Arduino). A scope would be the best instrument to show you the shape of the wave forms, if you access to one.

Lefty

I tried putting pullups on the end as well but there was no difference.
I'll try putting them in the middle of the bus next.

Right now all 13 arduinos are powered by one single supply that has a separate +12V cable + GND for each Arduino DC input.

The I2C bus is just the SDA and SCL lines chained but I also connected the grounds of each Arduino. Should I try connecting +5 of each arduino together as well?

The I2C bus is just the SDA and SCL lines chained but I also connected the grounds of each Arduino. Should I try connecting +5 of each arduino together as well?

No, I wouldn't chain the grounds or the +5vdc, they should all be commoned at the single power supply, and the daisy chained grounds could be causing a 'ground loop'. Again you are kind of shooting in the dark without using a scope to actually see what the waveshape and amplitudes of the SDA and SCL lines looks like.

Lefty

I have a scope so I will hook this stuff up right now (just need to move a bunch of stuff around).

What should I be looking for? You already mentioned crisp clock signals and I will measure the amplitude as well.

ok I checked my scope and the waveforms are the right voltage (peaking at 5V) but the leading edge of every square pulse is very curved. In fact they look like rounded sawtooths not squares.

Anyone know how to fix this? This seems like some kind of bus capacitance....

You may have to disable internal pullups for all Arduino's to get this right. As it is now, each tap will add some 30k parallel resistance to the bus and distort your signals. To keep the I2C software the same, I would disable SDA/SCL pullups for all Arduino's (you will have to modify the twi library to do this) and try with a pair of 10k resistors at each end.

The I2C bus should only need 1 set up pullups for the whole bus.

As long as you have only AtMega's on the I2C-bus, you have the capability to sink and source far more current than the general I2C specification allows for. By adding a set of resistors at each end, you should get a stronger pullup along the length of your I2C bus.

With all SDA/SCL pullups disabled, 2 sets of 10k can be a starting point. If there are still issues, I would lower the value (both sides, as low as 1k if need be) until the SCL/SDA pulse trains look clean and sharp.

You may have to disable internal pullups for all Arduino's to get this right. As it is now, each tap will add some 30k parallel resistance to the bus and distort your signals. To keep the I2C software the same, I would disable SDA/SCL pullups for all Arduino's (you will have to modify the twi library to do this) and try with a pair of 10k resistors at each end.

Silly, that the internal pullups are even enabled by default...