Showing posts with label I2C bus. Show all posts
Showing posts with label I2C bus. Show all posts

Sunday, October 18, 2015

I2C pull-up resistors on modules and breakout boards

I no longer maintain this page due to issues with SVG drawings on Blogspot.

The maintained copy of this page is here:
http://www.prolifictec.com/blog/2015/10/i2c-pull-up-resistors-on-modules-and-breakout-boards.html .

- Nick

 

Some of the modules and breakout boards for I2C slave devices contain I2C pull-up resistors. When multiple such modules are connected to the same I2C bus, their pull-up resistors appear in parallel.  That results in a stronger effective pull-up resistance, which may prevent communication on the I2C bus.

You have to have pull-ups on the I2C bus.

Somewhere on the  I2C bus you have to have pull-ups in order to be able to communicate on the I2C bus.  The pull-ups may reside on the microcontroller board, or on the I2C slave device's breakout board, or anywhere else on the I2C bus.

Some microcontrollers have internal pull-ups.  It's not recommended to use the microcontroller's internal pull-ups for I2C.  Still, internal pull-ups is much better than no pull-ups at all.

Watch out, though - you may end-up with pull-up that's too strong.

If pull-up resistors are too strong, that can prevent communication on the I2C bus.

Strong pull-up means that the current through the resistor is relatively large.  Stronger pull-up translates into smaller resistor value.  Weak  pull-up translates into a larger resistor value. 
(Stiff means the same as strong, when describing pull-up resistors.  This terminology is not limited to I2C.  It applies to pull-up and pull-down resistors in other types of circuits too.)

The unwanted pull-up resistors are shown in red.  These may create a pull-up that's too strong, which can prevent the communication on the I2C bus.

Suppose all three boards in this diagram came with pull-up resistors installed. The 2.2 kΩ value is common for an I2C bus running at +5V.  Notice however that R2, R4, R6 all are connected between SCL and Vdd.  They are in parallel, and they act as one 733 Ω resistor.  This combined pull-up is too strong I2C.  That can prevent communication on the I2C bus.  (Similar for the pull-up resistors on the SDA line.)

If these resistors can spoil the I2C bus, then why are they designed into the breakout boards in the first place?  I'm guessing that it must have been a compromise to create an easy out-of-the-box experience.  A lot of I2C first-timers don't know that pull-ups are required.  Some Arduino boards don't have I2C pull-up resistors nor pads for them (Arduino Uno, Arduino Pro, for example).  Some Arduino boards have unpopulated pads for I2C pull-up resistors (Arduino Mini Pro, for example).  A breakout board provides the pull-ups, and "it just works".  That is, until too many breakout boards are connected in parallel.

Remedies

Of course, as soon as you realize that there are extra pull-up resistors you can simply remove them.

Some breakout board suppliers are aware of the possible parallel pull-up scenario.  Many of the newer breakout boards have been designed with that in mind.
  • Perhaps to partially address this, some of the breakout boards have I2C pull-ups which are half strength.  They are weaker than the correct values for the I2C, but stronger than the internal pull-ups of a μC.  A typical such value is 4.7 kΩ .  This is a compromise.  The number of modules that can be connected in parallel without removing resistors is still limited. But a greater number of modules may be connected before combined parallel pull-up becomes too strong.
  • On some of the breakout boards, pull-up resistors are connected to Vcc through solder blobs.  A solder blob is easy to remove, then pull-up resistors will not affect the I2C bus.  (For example, see SJ1 in this SparkFun breakout board.)
  • Some breakout boards have unpopulated pads for pull-ups.  (For example, see R1 and R2 on this board.)

Related

I2C bus specification and user manual.  Anyone working with I2C should at least skim through it.
How to deal with multiple pull-up resistors on modules?  That forum question was a point of departure for writing this post.
A case when ATmega's internal pull-ups were used for I2C.  The oscilloscope screenshots show I2C waveforms with internal pull-ups, and with proper external pull-up resistors.
Forum thread Is there a correct resistance value for I2C pull-up resistors? and application note I2C Bus Pullup Resistor Calculation.
EDN article Design calculations for robust I2C communications.  Concise article with diagrams showing I2C physical layer principles of operation.
Effects of varying I2C pull-up resistors.  The article shows oscilloscope screenshots of good and bad I2C signals.
Pull-up resistor and pull-down resistor explained

Friday, August 14, 2015

When does the Arduino Wire library actually transmit on the I2C bus ?

I wanted to better understand the inner workings of the Wire library (the I2C library that comes with Arduino IDE).  The detailed reference and source code were helpful.  To check my understanding, I made a simple oscilloscope experiment, which I would like to report in this post.

Setup

Straightforward test code, which creates a write transaction on the I2C bus.  To know when the calls to the Wire library methods happen, each one is preceded by a strobe on pin 13.  These strobes will be seen with an oscilloscope.   To know when the I2C activity actually occurs, SDA and SCL (the I2C data and clock lines) are too observed with the oscilloscope.

  void strobe() {
    digitalWrite(13, HIGH);           // Strobe for oscilloscope
    digitalWrite(13, LOW);
  }
 
  void loop() {
    strobe();
    Wire.beginTransmission(0x4C);     // Set the address of the target device  
                                      // which we want to write to
    strobe();
    Wire.write(0x07);                 // Payload: set the address of the register inside
                                      // of the external device, which we want to write to
    strobe();
    Wire.write(0x01);                 // Payload: value to write to the register

    strobe();
    Wire.endTransmission();           // Actually do the transmission.

    delay(1000);
  }

This code ran on Arduino LilyPad USB (my clone thereof).  It should work the same on any Arduino that's based on AVR and has got hardware I2C.

(The addressee of this I2C transaction is an MMA7660 accelerometer.  It could have been just about any I2C slave device.)

Results and discussion

Debug strobes and the I2C activity.  All I2C activity takes place after the strobes.

As you can see, all of the I2C activity happens after all the calls to the Wire library methods have been made.
Wire.beginTransmission(...) doesn't actually begin the transmission, it only sets the I2C slave address for the forthcoming transmission.
Wire.write(...) doesn't actually transmit, it writes to a buffer in the Arduino's RAM.
Wire.endTransmission() actually causes the whole I2C transaction to happen from beginning to end.

Perhaps, the Wire Library functions could have names that better reflects inner workings.

References

[1]  Wire Library superficial reference
[2]  Wire Library detailed reference
[3]  Source code for Wire Library on GitHub