i2c crash with 10k [ch937] pullups.. ok with 2.2K [ch937]. ???

Hi there, I have 3 I2C sensors (ADXL345, HMC5843, ITG3200) connected on the I2C bus.

In the first implementation of the circuit I used 10K [ch937] as pullup resistor and after 1-2 minutes the I2C communication freezed hanging Arduino.

I then replaced the 10K [ch937] with 2.2K [ch937] resistors and now everything works just fine. I got 20 minutes of working. Anyway, pretty unpredictably the line sometime still hangs.

I'd like to hear your opinions on this. What could cause that and what can I do?

I heard that Wire is quite not tollerant and it would expect a "quite perfect" channel and that it would hangs when there are some communication problems.

Do you guys have any suggestions? Both in software or in hardware?

Thanks a lot,

Fabio Varesano

10k is a bit weak; 2.2k is closer to what I remember the spec calls for.

I read about some device in the past few days (could have been the HMC5843, or one of its cousins) that had it's own pullup resistors. Datasheets for each peripheral should be examined.

-j

The size of the pull-up resistor is a function of the bus capacitance.

A 10K pull-up should be able to handle bus capacitance up to about 120pF. That shouldn't be a problem if all the devices are on the same board right next to each other. You don't say how your bus designed and built. If they are each at the end of a long wire that may be way too high a value.

Do you have an oscilloscope so that you can look at the bus signals? The rise time of the signals is what should dictate your pull-up resistor value.

I must say I am suppressed at this, while 10K is a bit on the high side, I would not have expected a crash. The lower the resistance the more noise immunity you have so you might be in a marginal noise situation. How is the decoupling on the rest of the circuit. If you have none then that is the root cause of your problems.

Thanks guys for the insights. You can have a look at the circuit here. To that circuit I added a 5v -> 3.3v voltage regulator so I'm now taking voltage from the 5V source instead of 3V3.

I'm using homebrew breakout boards for the ADXL345 and ITG3200 (see links for schematics and designs). I'm also using sparkfun HMC5843 breakout board.

Regarding to decoupling, each breakout board has its own decoupling 0.1uF capacitor. Grumpy_Mike, is this what you mean?

Well a photograph of a circuit is better than nothing but it is no schematic.

each breakout board has its own decoupling 0.1uF capacitor.

Yes that's what I meant.

To that circuit I added a 5v -> 3.3v voltage regulator

You have got the right capacitors on the input and output for that have you? See the data sheet for your specific regulator as the requirements vary.

The voltage regulator is a LD1117S33CTR (SOT-223 package - datasheet) ..

According to the datasheet a 100nF cap is needed on the Vin while a 10uF one is needed on the Vout..

Right now I do have the 100nF cap in place but I don't have the 10uF one as I currently don't have one of these at home.

Do you think that not having that one could cause my problems?

I'm willing to prepare a schematic to clarify more my circuit.

Ok, here you have the main schematics.

You'll also need my ADXL345 breakout board schematics, ITG3200 breakout board schematics as well as Sparkfun HMC5843 breakout board schematics.

FYI I also link the datasheets: ADXL345, ITG3200, HMC5843.

Any kind of help really appreciated.

Normally accepted value for 5V I2C Pullups would be 4.7K. I would not go higher... and any lower than 2.2K just makes that parts work to hard... IMHO.

Ok, I added the 10uF cap on the Vout from the voltage regulator and things looks even more stable. I also disabled the raw data ready interrupt that the ITG3200 library I'm using was enabling.. It could be the cause?

My guess: the ITG3200 handles bad the interrupts and stops or delay communication which causes missing or delayed bits on the line..

What do you guys think about this?

For 3.3v Grumpy says 2.7k pullups.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1291086237/1

Make sure internal pullups are off in the arduinos as it may apply +5 to 3.3v parts.

I believe the arduino will be ok with 3.3v logic levels even if run at +5

Make sure internal pullups are off in the arduinos as it may apply +5 to 3.3v parts.

How would you check that?

How would you check that?

Look for digitalWrite statements setting INPUT pins HIGH. Remove them.

To be more explicit, only use pinMode() to drive the pin - switching it from OUTPUT (and thus LOW) to INPUT (and thus high-impedance).

The paranoid would perhaps use

  digitalWrite (pin, LOW) ;
  pinMode (pin, OUTPUT) ;

to drive the line low and

  pinMode (pin, INPUT) ;

to 'drive' it high (via the external 3V3 pullup resistor.) The worst thing would be to select pinMode (pin, OUTPUT) when the output was high - a 3V3 chip has a good chance of surviving the weak internal pull-up, but accidentally driving it to 5V directly would likely fry something. Ideally external circuitry would protect against this - relying on software integrity to protect hardware from being overdriven is not good. Say you connected it up with the wrong sketch loaded into the Arduino....

This is an example but I don’t think those resistor values are proper.

The atmega digital pins are supposed to start in a high impedance state. If it’s possible to load the wrong code I’d start the arduino with nothing connected and load the right code. It would be some odd situation where a pullup could be on and the pin is switched to an output as was said by MarkT. If it’s going to be permanent get or make the sparkfun circuit or try one of the I2C level shifter chips with two channels.

I do have Sparkfun's logic level converter but as devices where working great without it I never plugged it. Should I? @mrmeval Why do you think those resistors values are wrong?

Moreover, I'm using Analog 4 & 5 for I2C.. I don't think I can do a digitalWrite on them and, given that they are input pins, they should start in high impedance mode by default.

Am I missing something?

According to the application note from NXP that’s out there (sorry I don’t have a link) it shows a simple circuit using a 10K pullup on the low voltage side along with a MOSFET that almost matches the Sparkfun logic level converter. On the Sparkfun converter, along with a 10K pullup on the low side, it has an additional 10K pullup on the high voltage side. I’m not sure what impact that will have but if you want to reproduce the exact circuit in the application note you can leave the HV pin disconnected on the converter. Any external pullup you use on the low side should be calculated around the 10K already in place.

You should have a 100nf ceramic or greencap on both the input and out put, as well as the 10uf tantalum or electrolytic cap on the output, other wise the regulator will oscillate like a bitch!

Also remember with linear regulators like the LD1117S33CTR, you need to give it enough voltage to “work” with or it will oscillate like a bitch!