How to figure out what size pull-up resistor needed for I2C connection?

Hi all:

I'm new to dealing with electronics/hardware, and have an interest in building some meteorological stations that record temperature/humidty/moisture with a time stamp, each of the sensors run using I2C protocol. I've built these before with an EnviroDIY Mayfly datalogger. However this microcontroller had an I2C plug so it was pretty easy to wire my sensors together and plug into the provided I2C connector.

Now I've learned I can reduce the cost of the stations substantially by building just the individual components I need using a 3.3V Arduino Pro Mini build, so I'm exploring that. I know that in order to run I2C off this microcontroller, I'll need to use pull-up resistors on the SDA and SCL lines, but I don't really know enough about electronics to know what size resistor is needed. I'd like to know what size resistors are needed on the SDA and SCL lines, but I also would like some help generally understanding how to figure this out on my own in the future. I've seen some datasheets, but I don't really know what values I'm looking for (average current consumption? idle current consumption?). And when I have these values I'm not so sure what to do with them.. So I'll list my setup as well.

Here is my setup, I plan on connecting 3 devices to the I2C bus

  • Microcontroller: 3.3V Arduino Pro Mini (knockoff)
  • Connected to a solar/lithium battery charger module

The I2C devices that will be connected include:

If it matters, I also plan to connect this SPI SD card reader (But I haven't really looked into how to do that yet).

Any guidance on how to find these data sheets, what values to look for and how to calculate what size resistor is needed would be helpful! Thanks

I2C generally expects the pullups to be about 1ma in strength. (Like highlander, there can be only 1, so if your cards have built in pullups, disable them and install 1 set on the bus signals)

This means the ideal starting value for pullups on the 3V Nano would be 3300 ohms or 3.3K. Ohms.

If your wires start getting long... drop down to 2.2K

Thanks for the information. This raises two more questions

  • How long is a "long" wire? The RTC will be right next to the microcontroller (< 5 cm), the temperature and moisture sensors will each be about 1 m away. Is that getting long enough to matter?
  • How can I look at the datasheets and tell if there is already a pullup resistor? If so, how do I disable it? Adding a jumper or severing a connection? Not sure if I'm brave enough for either of those

1 meter is quite long for I2C already.

It's no problem to have multiple weaker pull-ups spread around your I2C bus. Maybe even better than a single equivalent one. Sensors normally have no pull-ups on board; sensors on breakout boards usually have 10k pull-ups.

jbc165:
Thanks for the information. This raises two more questions

  • How long is a "long" wire? The RTC will be right next to the microcontroller (< 5 cm), the temperature and moisture sensors will each be about 1 m away. Is that getting long enough to matter?
  • How can I look at the datasheets and tell if there is already a pullup resistor? If so, how do I disable it? Adding a jumper or severing a connection? Not sure if I'm brave enough for either of those

The data sheets are for the ic devices, not the breakout boards, so they wouldn't tell you if the boards had resistors. However, the web page for the moisture sensor says "Don't forget to provide pullups for SCL and SDA lines", so no, it does not have them. Looking close up at the RTC board, it has 2 resistors. These are marked 201 and 102. The first being 200 ohms, and the latter is 1000 ohms. Neither is likely to be a pullup resistor, and besides, it would be two of them the same.

The temperature sensor however has two 103 (10K) resistors right next to the SDA and SCL pinouts. So bingo, that sensor has pullup resistors. Since you have (very) long wires, you are going to want to pull it up even more than 10K though. Add a pair of 4.7K resistors to the system to get 3300 total ohms of pullup.

There is a schematic of that RTC module. It has 4k7 for SDA and SCL.

So far: Pro Mini = internal 50k pullup, RTC = 4k7, SHT-31D = 10k.
50k // 4k7 // 10k = 3k (you can check my calculation).
That makes 3.3 / 3k = 1 mA

The I2C bus is specified as 3 mA.
Every device should be able to sink at least 3 mA (more is allowed). That means that if a manufacturer makes a sensor that can sink 3 mA, it is already according to the I2C specifications.
Because of that, the maximum sink current for the I2C bus is 3 mA (even though each device is allowed to be able to sink more current).

When you have 1 meter to a sensor and 1 meter to another sensor, you I2C bus is 2 meters long.

The rule of thumb is maximum of 0.5 meters. But that depends on the used cable. A very bad cable might not even get to 0.5 meters and a very good cable (little capacitance to ground, no crosstalk between SDA and SCL) can go up to 6 meters. But don't try 6 meters, that is silly. The best cable is no cable at all, just a bunch of individual wires that are not near other wires is the best.

I'm a little worried about the power voltage. Do you use the onboard voltage regulator of the Pro Mini board to get 3.3V for the SD card ?
Some newer Arduino board have a battery connector. For example the MKR1000.

Koepel:
There is a schematic of that RTC module. It has 4k7 for SDA and SCL.
...

Oh yeah, I see 'em, long parts, marked 472. Maybe just hook it up and see if it works then.

When you have 1 meter to a sensor and 1 meter to another sensor, you I2C bus is 2 meters long.

The rule of thumb is maximum of 0.5 meters. But that depends on the used cable. A very bad cable might not even get to 0.5 meters and a very good cable (little capacitance to ground, no crosstalk between SDA and SCL) can go up to 6 meters. But don't try 6 meters, that is silly.

When I first used I2C I had no idea there was supposed to be limit to the cable length, so I didn't concern myself with one. My first I2C interface was completely software, written in Z80 assembly language. It was rather slow but it did the job. That project was my long standing obsession, a heating controller. The latest version of my heating controller has 5 Dallas DS1624 temperature sensors, 4 in the house and 1 outside. They are connected to a PIC18F26K22 using I2C and, roughly, 25m of 2 pair telephone cable. They work just fine. The pull up resistors are 1k. It is true I cheated on the speed, I have it running with a clock of about 15kHz, not the standard 100 or 400kHz. I've not actually tried the higher speeds, so I don't know how well they work over a long cable. For my purposes, 15kHz is fine, actually, it's a lot faster than my software I2C interface which was also fast enough for the job it was doing. I've yet to play with an Arduino so I don't know if you can change the speed of the I2C interface, but I'd be surprised if you can't. I suggest that if you want to use long cable then try long cable, whether it works or it doesn't, you will learn something.

The real answer to the problem is "put a scope on the bus and look at the risetimes of the signals,
adjust pullups for adequate risetime" - this also allows issues like reflections and crosstalk to be diagnosed
in long cables.

At such a low bus speed and so strong pull-ups I'm not too surprised it works - that's indeed what it takes to make I2C work over long cables. Nice job, even if it was more based on luck than wisdom :slight_smile:

Nevertheless it's not meant for it, there are better protocols out there for long wires :slight_smile:

wvmarle:
Nevertheless it's not meant for it, there are better protocols out there for long wires :slight_smile:

I'm interested to know what you might consider using, just for interest sake. The temperature sensors I used have I2C built in, which is why I wanted to use I2C. I could have used a serial port but that would have meant a processor co-located with each sensor to convert to serial. Have you any other suggestions?

Serial also won't work over 25 meters. Protocols designed for this are e.g. RS485, a current rather than voltage based protocol.

Wireless solutions may be interesting as well.

PerryBebbington:
I'm interested to know what you might consider using, just for interest sake. The temperature sensors I used have I2C built in, which is why I wanted to use I2C. I could have used a serial port but that would have meant a processor co-located with each sensor to convert to serial. Have you any other suggestions?

Hey, the processor costs $2.30 and makes the link super-reliable. Hardly worth fussing over.

Paul__B:
Hardly worth fussing over.

Are you sure ? Because I could be fussing about 68 cents paying too much. This one is cheaper.

Koepel:
Are you sure ? Because I could be fussing about 68 cents paying too much. This one is cheaper.

Yeah, well if you are going to get fussy, this one appears to be cheaper again!

wvmarle:
Serial also won't work over 25 meters.

Depends very much on the baud-rate (and signal conditioning).... Serial samples mid-bit, so crosstalk and reflection issues have time to die-down before the sample is taken. Boosting to RS232 levels helps of course, but you will still see the bandwidth decrease markedly with distance.

But yes, for solid behaviour, without signal conditioning at both ends there is a modest range limit for any
TTL-level digital communications that's not impedance-matched to its transmission medium.

Hello jbc165

You say you are new to electronics, maybe all the above debate has proved confusing. I think there is a simple message to you and anyone else new to electronics and unsure what to do; TRY IT! If in doubt, give something a try, if it does what you want it to do, good. If it doesn't, try something else. If the magic smoke escapes check carefully what you did and try something different. Whatever you try, whether it works or not, you will learn something.

1 Like