Pullup resistors when using TWI (I2C)

I notice that internal pullups on SCL and SDA are activated by default when initiating I2C communication with the Wire library (cf twi_init in twi.c). According to ATMEL datasheets internal pullups are 20-50 kOhm. According to the I2C bus specification only one pair of pullups should be used on an I2C bus. By activating internal pullups as default we get a system where the combined I2C pullups varies with the number of devices on the bus? Two devices wil get a combined pullup of 2 resistors (~10 kOhm), three devices will have ~6.7 kOhm, four devices ~5 kOhm etc. How can this be correct?

Opto - your reasoning assumes that every device connected to I2C has its own pull-up resistors, in addition to the Arduino. That is however usually not the case.

On the other hand, the pull-up resistors on an I2C-bus need to be small enough to drive the lines HIGH fast enough, overcoming the capacity of the line. In this respect, the internal pull-ups of the Arduino in the 10k range are a rather low value. Indeed, some people go add on and add external pull-ups down to a few kOhm.

From my experience, the Wire-library which activates the pull-ups in the Arduino works generally quite well with I2C-devices. Sometimes traces on an oscilloscope do not really look great, but the communication is anyway working quite well. Probably due to the fact that this is primarily done in hardware, not software. That is the reason you can not change the I2C-pins on an Arduino. However, if I discover bad signal shapes on the I2C-bus (that would be basically slow rise times), I tend to add 4.7k pull-ups to the line.

  • cpixip.

Thanks for your reply cpixip, I was just a little surprised to see this beiing done as default in twi_init. I would have preferred this beiing available as an input parameter e.g :

Wire.useInternalPullups(true/false);

But, its not a big problem as long as I know this is beiing done....

Hi Opto - I must correct myself in one point. Doing a quick survey of Sparkfun breakout boards I have around here, it actually appears that about 50% of these do have pull-ups, usually around 10k. So the situation you described is somewhat correct, that the pull-up values on the I2C-lines will vary widely, depending on the type of sensors you connect to this line.

Actually, I think it is a better practice to use just use a pair of pull-ups on the Master (i.e. the Arduino) only. This is exactly what the Wire-library is doing/assuming.

One the other hand, having multiple parallel pull-up resistors on various slave devices shouldn't do too much harm as long as the current involved is kept low enough. As remarked, I2C "works better" with smaller values of pull-up resistors. If you however connect a lot of I2C-devices, it is probably a good idea to check the schematics of the devices and calculate the overall resistance. If it's too low, you can always desolder some of them.

  • cpixip

If throughput is a concern then you'll definitely want to have external pullups on the line...4k7 values are typically a good starting point.

Some I2C module/devices use jumper clips to enable/disable the pull-ups for the data and clock lines, so you have the option of using them or not.

Lefty

It is much better from a signal point of view if you just have one set of pull up resistors at the end of the line and not scatter them about the place.

Grumpy_Mike:
It is much better from a signal point of view if you just have one set of pull up resistors at the end of the line and not scatter them about the place.

Which end is 'the end of the line' as both clock and data lines are bidirectional?

Lefty

The end of the line is "traditionally" the furthest point from the processor.

WillR:
The end of the line is "traditionally" the furthest point from the processor.

Understood, but electrically does it matter which end the pull-ups are? And considering that the internal pull-ups will be enabled by the library code (for both master and slave if both ends are arduino boards?) it's still not clear what electrical set-up is best. I've only used I2C on a RTC module I have and it has jumpers for pull-ups but it seens to work fine if they are enabled or not.

Lefty

WillR:
The end of the line is "traditionally" the furthest point from the processor.

You can connect two Arduinos together using I2C in which case they both have processors. The internal pullups are around 33K so I wouldn't get too excited about them. I did some measurements here:

(near the bottom of the page).

That was based on work found here: