I2C pullup resistors on multiple devices question

First, this may not be the right place to post this. I'm using a knock-off Nano, DS3231, and a 4x20 LCD (all Amazon), so this isn't for "official" hardware. I think "Device Hacking" is appropriate as I believe I will need to modify some hardware surgically.

Prior to posting this I searched for "I2C pullup resistors" but did not find posts about dealing with multiple I2C devices with pullups on the same bus. My apologies if I searched poorly or overlooked an answer and if this has been posted and discussed ad nauseum; please link me to the right thread.

Reading online says that the Nano does not have internal/on-board pullup resistors for SDA and SCL. The DS3231 board I am using does: a) it works with just the Nano (only two devices in the solution), b) it shows about 45k ohms from SDA to GND and the same from SCL to GND. The 4x20 display has similar readings, of course while all devices are not connected in any way. I read and believe that too many devices with pullup resistors will overwhelm any devices attempts to pull the lines low, and that having only one pullup resistor for each, SDA and SCL, is advisable.

The DS3231 I have seems to have an 8 pin DIP bank of resistors which also includes a pullup resistor for the SQW which would be important if I ever wanted the alarm to be able to wake up the Arduino, so removing that 8 pin DIP seems ill-advised.

I'm about to throw the multimeter at the 4x20 display to see if I can ID which of the resistors acts as the pullup for the SDA and SCL on it. I expect that checking VCC to one end of one of the resistors will give zero or near-zero Ohms and checking the other end of that resistor to SDA or SCL will also yield zero or near-zero ohms. I should then be able to remove that resistor and repeat the process for the other I2C line.

Of course that will mean that I will never be able to use that 4x20 display again without having a device on the I2C bus with pullups or without adding external pullups. I'm fine with that.

I'm pretty sure I have a solid idea of what I'm doing but I'm not so confident that I won't ask here first.

Thank you for your time.

--HC

What's your question? Is it "is it appropriate to remove builtin pull up resistors on I2C modules and use 1 external pair of your own?"?

(If so, yes is my answer.)

Thank you for the reply. The answer is "sort of". Maybe more precisely it was: will it be necessary to remove pullup resistors from additional devices if there are other devices which already have them.

--HC

To keep it simple: pull-up resistors are for the bus , not individual devices. They control the rise time of the signal when the bus returns to a high level. The most significant factor in selecting pull-up resistor values is the total capacitance on the bus.

As a general rule, I use:
4.7kΩ for 5V systems
3.3kΩ for 3.3V systems
This works well whether you have a single module or several on the same I²C bus.

Without schematics or technical documentation, I can’t tell you whether the devices you're using include pull-up resistors or what their values might be. Many modules use 10kΩ pull-ups, which is usually acceptable when several are connected together. Some modules allow you to enable or disable them; others have none at all.

Simple Tests to Check for Pull-ups:

1. Blink Test (Using Arduino Blink Example):

  • Upload the basic Blink sketch to your Arduino.
  • Measure the voltage on the SCL and SDA pins.
  • If these lines measure close to Vcc , there are likely pull-up resistors on the bus.
  • The*Blink sketch helps because I²C pins should default to input mode or be floating.

2. Divider Test (No Arduino Connected):

  • Power up the I²C modules without connecting them to the Arduino .
  • Connect a 10kΩ resistor from SDA or SCL to ground*, then measure the voltage on the line.
  • If the voltage reads around half of Vcc , there's likely a 10kΩ pull-up present (forming a voltage divider).
  • If the voltage reads 0V , then no pull-up is present.
  • Other voltage readings may indicate different pull-up values.

These basic tests help you understand what’s already present on the bus and allow you to size your external pull-ups appropriately.

4 Likes

No, device hacking is where an original device is modified to do something other than it was designed to do. Like make a toy produce unexpected noises.

It is not appropriate to your question where you want advice on using a normal feature of a device like you are asking about here. Therefore I have moved it to this location.

The pull up resistors on the bus can be per device or per bus. When using more than one the combined value of each one is the result of all the resistors being connected in parallel. Therefore the more you have the lower is the effective value.

The I2C standard says the required current these should use is 4mA, so most of the time people are under running the required value.

3 Likes

Using a Nano at 5V, and 4 mA as the maxcurrent to strive for, you'll want at least 1.25 kOhm pullup. So in theory, one could have up to 8 10k pullups in parallel before overloading the bus. Obviously, the lower the pullup resistance values, the fewer one can have. In general, I aim for a combined effect of 4 or 5 kOhm, and spend my time worrying about other things.

2 Likes

Hi,
With your multimeter, measure on each I2C module,
the resistance from SDA to Vcc (5 or 3V3)
and
the resistance from SCL and Vcc (5 or 3V3).

That will tell you if the modules have pull ups in them.

Tom.... :smiley: :+1: :coffee: :australia:

1 Like

And if I were doing that test, I would repeat it with the multimeter probes reversed, just to see if I get the same reading both ways. If they aren't the same, the higher one is probably the resistance.

You want to measure the resistance between the SDA line and Vcc, not ground, and the same for SDA. If your DS3231 module is like mine, with a 24C32 eeprom also onboard, that 8-pin pullup chip is probably marked "472", which would be 4.7K, which is what my meter says when I measure SDA to Vcc, both ways.

You also have the builtin pullup resistors of the Nano, which are probably around 30K. So with the two extra devices, you'll have three sets of pullups, one for each device, and one for the Nano. Then you need to calculate the effective resistance of three resistors in parallel, and tell us what that number is. Of course you can just turn off the Nano's internal pullup in software.

If it were me, I would not try to mess with removing pullups from the LCD. With any luck it will all work as is.

Leave them alone. The most common value resistor used is 10K. The measurements you noted just looks like two 10K resistors in parallel (with tolerance and actual values, you'll never get a perfect 5K reading). As pointed out, you can go lower and still have good performance.

1 Like

Wrong. The classic Nano has software enabled weak internal pull up (~30k).

It's best to calculate the combined resistance before you remove anything.
Default I2C is specified for 3mA max, which is 5/.003= 1k66 minimum.
Which is six slaves with 10k pull up or three with 4k7 pull up.

The problem is the slaves, not the Arduino which can sink 20mA.
Slaves can also be FastMode+ I2C, which is 30mA max. Consult the datasheet.
Leo..

1 Like

Do all of the libraries turn them on?

wire.begin(); does.
Leo..

1 Like

But you can turn them off immediately after invoking Wire:

  Wire.begin();
  pinMode(A4,INPUT);      // Disable internal pullups on SDA and SCL
  pinMode(A5,INPUT);
2 Likes

Correct, but I don't see why OP needs to do this.
Two slave devices, even with 4k7 pull ups on each should not be a problem.
Leo..

2 Likes
  • I’ve used a DS3231, and an I2C LCD together multiple times, no problems.
    In fact, the SDA and SCL waveforms were properly shaped with no lifting off GND.
1 Like

Most do, but a very few do not. These have a command to turn them on if needed. Unfortunately I can't remember what it is called, you will have to do a search for it.

Otherwise ShermanP's post #14 will also work.

1 Like

Sorry for the delay.

I checked with the DMM between the Vcc and various resistors until I found continuity at one end of the resistor and then checked the other end for continuity to the SDA or SCL pins.

I attempted to test if it mattered but I screwed up the test (stupidly plugging a DuPont wire into the wrong hole) and found it didn't work (having two devices with pullups), removed the two resistors which were pullups on one device, tested again, found my error and...well, yeah...what a mess. But, once I put that wire where it was supposed to be, the device functioned properly on the bus. Of course, there is another device on the I2C bus which has pullups so the modified device works as long as somewhere else in the circuit the pullups exist.

--HC

First, thank you for moving the thread.

There's an LCD with a backpack (...edit, WRONG...) which is using a resistor array in a SMD...yeah, I'm not removing that. For this project, as long as I am using the LCD with its integrated pullups, I'll leave it at that. I removed the pullups from the secondary device and all works well.

(edit: it's not the LCD backpack with the resistor array, it's the DS3231 module which has the resistor array.)

I understand the parallel resistors part. What is very interesting here is the 4mA part. I've not seen (or known to look for) a spec of amperage supplied to the bus. That gives me a more-solid handle on the situation. If these resistors are 4k7 on 5V then it's providing about 1mA which is in-tune with what I believe you're saying that people are under-running the resistors. To provide 4mA, the resistors should be around 1k2 which is far less than what I've seen.

--HC

Thank you, that's helpful.

Understood on the parallel resistors. Now that your post and another pointed out the 4mA limit, I have a solid handle on the situation and what to worry about and not worry about.

"...spend my time worrying about other things." Yes, agreed. Moving on.

--HC

Thank you for the reply. First, I fat-fingered the resistance value: it should have been 4k5.

Ultimately, I found continuity from Vcc to one end of a resistor and also from the other end of the resistor to SDA or SCL. That's how I identified which were the pullups. This approach worked on the LCD backpack which had discrete SMD resistors. I will have to edit one of my other posts here where I mis-identified the backpack has having a resistor array. The DS3231 module has a resistor array. I removed the two resistors with no ill effects.

Now that it's been pointed out that I can have several devices with pullups in parallel yet still not exceed the bus current for pullups, I'm not going to sweat this any further.

--HC