Skip to content
chuck todd edited this page Jan 2, 2018 · 10 revisions

The following is a partial thread #15

@chinswain commented 20 days ago

Hi Chuck - confirmed - a combination of your library and properly specced pull-ups seems to be the winning combination, if I change either it freaks out and cannot recover without a hard reset (I hope this can be fixed, bit of a nightmare for unattended projects!).

Slightly related, can I ask why you suggested 1mA of drive rather than 3ma?

@stickbreaker

@chinswain The 3mA limit is the minimum drive current that must be met for the device to be 'I2C' compatible. I don't like to expect any device to run at 100% of rated performance continuously. You had stated your circuit was using 10k pullups, (0.33mA) so changing to 3.3k (1mA). this 3x increase in current cased a power consumption increase in the drive sections of your I2C devices in the amount of (I^2 ) * R. where I is current and R is resistance, so Since R is fixed for each device the power changed from (0.33^2 ) * R = 0.109 * R to (1^2) * R or 1.0 * R increasing to 3mA become 9 * R. The current increase from 0.33ma to 3.0mA is an ~10fold increase but 0.109R -> 9R is an 82 fold power increase. The benefit of the extra 2mA was not worth the load. More just makes the drivers work harder, and the increase in current does not translate into an increase in performance. The parasitic capacitance and the clock speed are the design considerations (controlling factors) for choosing the pullup values.

This webpage: RC Discharging Circuit Tutrorial goes into the mathematics.

I2C signals are triggered at the 30%, 70% voltage points along the curve. The formula is an exponential function Vc =Vs * e^(-t/(r * c)) Where Vc is the voltage on the buss, Vs is supply (3.3v), t is time(seconds), r is resistance(ohms), c is capacitance(Farad). You can almost solve this equation, But, that requires to you measure 'c' which is really tough on a digital circuit.

If you start selecting values: the rise time for the voltage to get to a logic High(2.3v) 70% of Vdd (3.3v). with a SCL (clock rate) of 100,000Hz to 1/10 of a clock period, t becomes 1/1,000,000 or 0.0000001S.

Vc = 2.3v
Vs = 3.3v
e = 2.71828
r=3,300 ohm
Solve the equation for 'c'
c=-t/(r * ln(Vc/Vs))
c=8.39 * 10^-10 F or 839pF

So as long as my bus capacitance is less than ~1nf, 1mA of drive current will meet my design goals (10% rise time on a 100kHz clock).

I use 0.050" ribbon cable for my I2C interconnects. Most 28ga flat ribbon cable spec out 15pF/ft. I generally increase it an order of magnitude to 150pf/ft this takes into account the connectors, bends, surrounding objects. So with these rough guesses a 1mA drive current will handle 1m (3ft) of ribbon cable and still meet my 100kHz timing constraints. If I go to 400kHz or 800kHz. I have to adjust things.

Chuck.

@chinswain

@stickbreaker Wow, what an answer! 🥇 I have quite a bit of reading to do to get these 40 devices working...

Are your changes going to be pulled into the main repo? @stickbreaker Owner stickbreaker commented 20 days ago

@me-no-dev Stated about two weeks ago he was reviewing it for inclusion, But My coding style does not match the aesthetics of the project 😀 . So, he was adjusting the spacing and layout. But, he is in the middle of moving his office to a new Country. ( I think one of the Slavic nations?) so it could be delayed.

Before this Fork is merged, the debug and testing routines need to be excised. I am a little verbose in my messages, 😏 .

If you are going to attach 40 devices to the bus, you will need to actually review(measure) the signals. You can use a 'scope to calculate 'c' from the curve. bk00016 This pic shows a START on my test rig. You can see the exponential decay on the rising edge, Those overshoots and ringing are cause by my 12" unterminated flying end of the cable. you can see the cross talk at every negative edge. Based on the 5tau infinity assumption, the 5tau is about 1.3us. currently I have 2.48k of resistance on the bus so 1.3us = 5(2480 * c), therefore c = 104pf bk00017

Chuck.

Clone this wiki locally