I2C is a popular communication protocol in embedded systems.  When interfacing with the slave device a pull-up resistor is needed on each bi-directional line.  One common question that arises is "what size pull-up resistor should I use?".  Instead of going through a bunch of theory and calculations I thought it would be easier to show what happens to the signals when different resistor values are used.

Since the Arduino is a popular micro-controller among hobbyists we'll use it for the following examples.  We'll interface the Arduino to a DS3231 Real Time Clock, which is a 5 volt device.  We'll also look at the effects on the signal with varying speeds of I2C (100 and 400kHz clock signals).

We'll set up our oscilloscope to measure rise time, frequency and peak voltage.  Frequency? Why do we want to measure frequency, I thought the clock frequency was running at 100kHz...well let's just see what the scope says.  Since the capacitance is roughly the same for the SDA (data) and SCL (clock) lines we'll only vary the resistance on the SCL line and keep a standard 4.7k ohm resistor on the SDA line.  It's just easier to analyze a repetitive clock signal on the oscilloscope than a data pattern.  

Let's take an initial reading using just the Arduino's internal pull-up resistors.  As you can see in Figure 1 the clock signal has a very long rise and only reaches a maximum voltage of 3.76 volts before falling back to zero.  While the circuit does function I wouldn't want to rely on it outside the lab.  As you can see the frequency measured is closer to 87kHz due to the slow rise time.  The circuit still works but if your application is time sensitive it's not generally a good idea to use the internal pull-up resistors.   Anyway let's disable the Arduino's internal pull-up resistors and install our own pull-ups and see how they affect the signal.  We'll start with a 68k ohm resistor followed by 47k, 33k, 10k, 6.8k,4.7k, 3.3k, 2.2k and finally 1.5k.  Progression100kHzAs you can see in Figure 2, the signal eventually takes on a square shape which is what we like to see.  Notice how the measured frequency approaches our desired clock frequency between 33k and 10k ohms.  You can also see how the rise time decreases as our resistance decreases.  As you can see, 4.7k yields a good looking signal with a rise time around 1 microsecond .  You'll find that 4.7k is a pretty common resistance used in a lot of single slave setups.  Of course as you add more and more devices to the lines the bus capacitance will increase and that means you'll have to start decreasing your resistance (t = RC) if you want to maintain your signal integrity.  Each design will be unique and the capacitance referenced in the datasheet is not guaranteed so it's always good practice to look at the signals on an oscilloscope.  So why not just use a very low resistor to start off with, shouldn't that reduce the rise time to give us the squarest signal possible?  Well yes and no.  The I2C standard sets some limits that need to be followed, luckily these limits help us narrow the range of resistance values.  A simple formula for calculating the smallest pull-up resistor is Rp = (Vcc - 0.4)/3mA, which for a 5V system comes out to be about 1.5k ohms. The formula for calculating the largest resistor is actually based off a maximum rise time for standard mode (100kHz) which is 1 microsecond and that formula is Rp = 1us/Cb, where Cb is the total bus capacitance for one signal line. So for our example the total bus capacitance would be about 20pF (Arduino is 10pF, per the datasheet, and the DS3231 is also 10pF per the datasheet), which yields a high side value of 50k ohms. Obviously adding more DS3231 RTC's to the line will change the largest allowable resistor that we should use (1 more drops it down to 33.3k, another one drops it to 25k, etc...).  It's important to note that each I2C device will have it's own capacitance so always look at the datasheet so you know what that value is.


Next, we'll use the same circuit, but this time let's switch from Standard mode to Fast mode (400kHz). As you can see is Figure 3Internal400kHz the rise time is very slow with respect to the clock frequency.  The frequency of the clock is measured at around 171kHz, which is significantly slower than the desired 400kHz. Also notice how the peak voltage only reaches 3.28V before switching to the second half of the duty cycle.  We're going to repeat the same test from above using the same resistors.  Before we begin let's take a look at the calculations for determining upper and lower pull-up resistor values.  The calculation for the lowest value pull-up resistor is the same as above, yielding 1.5k on the low side, however the maximum rise time for Fast mode is reduced from 1 microsecond to 300 nanoseconds. As you can see, using the formula and substituting the maximum bus capacitance of 400pF results in an upper limit resistance of 750 ohms which is actually lower than the lowest value resistor from the first calculation.  For this reason the maximum recommended bus capacitance is dropped down to about 200pF with a 5 volt system. So make sure you keep close watch on the total bus capacitance as you're building your circuit.  So lets install the resistors and see how they affect the signal quality (Figure 4).   Notice how the measured clock frequency doesn't approach 400kHz until we transition from 6.8k to 4.7k ohms.  You can also see how the signal takes on a good shape once we transition from 2.2k to 1.5k ohms.

Figure 4

























+11 # C Smith 2011-01-23 04:15
Thankyou very much for this information, very informative and well written.
+2 # Fabio Varesano 2011-01-29 18:13
Great article.. Thanks for sharing! What oscilloscope are you using?
+2 # Wayne Truchsess 2011-01-29 18:32
Thanks. It's an Atten Instruments model ADS1102C
+4 # darshit 2011-03-23 04:16
nice explanation with result.

this is right practice for understanding as well as design.

good informative.


keep it up.
+6 # Paulo de Almeida 2011-04-15 17:05
EXCELLENT article !!!

+3 # Srinivas Katepalli 2011-05-04 06:22
Its very very useful article.
It helps a lot to he designers and embedded developers

Thanks & regards
+3 # teson 2011-05-25 09:27
Very informative, thanks for the article!
+2 # rope 2011-06-09 07:46
You saved my day!
Thank you for your work!
+1 # Wayne Truchsess 2011-06-09 12:07
Glad I could help.
+1 # darshit 2011-06-10 04:26

what are you doing now?

just want to know if you don't mind.

thanks again for knowledge sharing.
+1 # Wayne Truchsess 2011-06-10 19:50
Most of my time has been dedicated to my GPS shield, ever since Hackaday did a little write up it's become pretty popular.
+3 # yuvraj 2011-09-09 04:08
very much informative. Thanks a lot.
# Bhushan Joshi 2011-09-10 01:53
Thanks Wayne,
It is very much easy to understand.. :-)

Thanks a bunch!!
+1 # jon 2011-09-26 22:33
this is a really great anaylsis: helpful, informative. Job well DONE. Thanks.
+2 # Jefferson 2011-12-01 05:37
Nice One Wayne, Thanks. Keep it up. :-)
+1 # sabir 2012-01-12 06:57
Nice Article, very helpful.
Varying pull up resistor does it effect fall time of the bus?? It will be great if you can show fall time variations also.
# PhilipFreidin 2014-03-14 02:22
While the fall time is affected by the value of the pull up resistor, the effect will be quite small, assuming reasonable values for the pullup resistor. The logic low driver inside the chip typically has an impedance of 20 to 30 ohms. Combined with the pullup resistor, it forms a voltage divider that ultimately will set the final logic low voltage.

With only a capacitive load and 5V power and output driver impedance of 25 ohms, here are the final low levels:

No pullup: 0V
20K pullup: 6.24 mV
4.7K pullup: 16.46 mV
1.5K pullup: 81.97 mV

If we set the fall time end point to when the signal drops below 0.5V, and total capacitance to 200 pF, then we get fall times of:

No pullup: 92.10 ns
20K pullup: 92.55 ns
4.7K pullup: 93.35 ns
1.5K pullup: 97.74 ns

Basically, the pullup resistor takes some of the current that could be used for discharging the capacitance. The lower the pullup resistor value, the more current flows through it when the clock driver is trying to pull the signal low, and less current remains to discharge the capacitance of the chip input/output capacitances, and any capacitance of the interconnect.

These numbers don't quite match the scope measurements above, probably because we don't know the actual total capacitance, the output impedance, or what the measurement points are that the scope uses to calculate fall time.
+1 # sabir 2012-01-12 06:59
Nice Article, it will be great if you can explain how fall time varies by varying pull up resistor.
+1 # lutfi 2012-04-14 04:53
nice article, keep it up..
i become understand about what is pull up resistor effect..
+1 # Mike Schreuder 2012-06-30 17:24
Very informative article, thx a lot. It helped a lot in understanding I2C hardware issues! Thx, Mike
+1 # Sky Lee 2012-07-02 01:54
Appreciate your hard work to create this informative article.
+1 # shivaraj kodibail 2012-07-24 10:00
Its really gives creative idea and good understanding.t hanx
+1 # Venus 2012-08-06 07:57
Very well doubts are clarified after reading your article...
# ranjithkumar 2012-09-04 13:58
Very informative articles. thanks a lot....
# Sam 2012-09-21 23:40
So this means,

if I have a Sensor that supports 400khz i2c, I should take 2,2k resistors and then its also no problem to run at slower 100khz bus speed with them ?
STM32 MCU @ 3,3V VDD.
And I would take 100ohms as series resistor.

Is that ok ?

I calculated my RP minimum is 967ohms ~ 1k.

Is it better to with 1,5k then ?
# Lou 2013-01-17 16:07
Interesting stuff but I am quite new to I2C. Can you please answer:
1) What version of the Wire library are you using?
2) What code was being run to generate the continuous clock (SCL)?
3) How does one "vary the speed" as you say?
# Krishna 2013-01-22 05:11
Wonderful stuff Mr.Wayne Truchsess.Peopl e having less knowledge on electrical signals and rise time etc., also can easily understand this.
# Usman 2013-01-29 23:20
Sir, God bless you for this wonderful article, congrats
# Arun 2013-05-06 16:39
Could you explain why the SCL frequency increases with increased R ?
I was expecting that the rise time, obviously, will increase, but that should not affect the Clock HIGH & LOW Periods
+1 # Wayne Truchsess 2013-05-07 00:22
Quoting Arun:
Could you explain why the SCL frequency increases with increased R ?
I was expecting that the rise time, obviously, will increase, but that should not affect the Clock HIGH & LOW Periods

Actually the frequency decreases with an increase in R. It typically affects the clock high period. Remember, if you have a 50% duty cycle and your resistance is too high, it will take longer for the circuitry to reach the defined HIGH state before it can switch to go LOW again. Since the duty cycle on the LOW side is not compensating for increased rise time you will see a net overall decrease in frequency.
# Arun 2013-05-07 21:01
Thanks for your reply, Wayne.
But I still have one doubt.

Ideally, the logic which drives the SCL Open-Drain/OC pads need to do only the following:
1. Let the line charge to VDD through Pull-up for a fixed amount of time- the HIGH period
2. After this fixed HIGH period is elapsed, enable the drive-down transistor for a fixed amount of time- the LOW period
-Repeat this 'n' times for n SCL cycles

According to my above assumptions, the HIGH Period & hence, Positive duty cycle should remain same for whatever pull-up usde.
The only change to be observed is the voltage to which the SCL line is charged at the end of the HIGH Period will decrease as we go on increasing the pull-up (as rise time/RC time constant increases).

From your explanation, it seems more like whatever logic that drives the SCL pads is sensing the voltage on the line OR in short, there is some kind of feedback to the logic as regards to the line voltage.

i.e, during the HIGH period, it (the logic) continuously senses the SCL line
And, only when it senses a voltage greater than some threshold, it ENABLES the Drive-down section of the pad.

What do you think is happening ?
# Wayne Truchsess 2013-05-08 03:16
Your assumptions are correct for points 1 and 2. The key thing to remember is how long it takes to reach a logic HIGH. If you look at an ideal cycle at 100kHz, each duty cycle is 5us. Let's say your pullup resistor is too large and the RC time constant results in a rise time of 6us, you've now effectively changed the frequency to about 90kHz.
# PhilipFreidin 2014-03-14 02:35
Unfortunately your initial assumptions are not correct for an I2C controller that supports multimaster. The ATMega chips have such controllers. Your third paragraph is closer to the way things are.

To support the I2C multimaster specification, the SCL driver does need to sense the clock line that it is driving. It does not start its internal clock high timer until it sees the clock line in logic high state. At 100 KHz the timer runs for 10 uS and at 400KHz it runs for 2.5 uS. Once the high duration is met (for the specified clock frequency), the signal then can go low. (see my other message about fall time). With lower pullup resistors, the signal gets to logic high faster, and so the total clock runs faster.
# Brian 2013-05-08 17:47
So, is there a voltage comparator inside the I2C controller to check if the voltage has reached logic HIGH?
# PhilipFreidin 2014-03-14 02:36
Yes, see my other response
+1 # Jonh 2013-06-27 12:21
AVR IS !!!!
# Suwang Jang 2013-08-28 08:43
Wow great explanation!
It was very helpful.
Thank you~
# Guest 2014-01-15 23:12
The shark fin graph looks cooler, I'll use between 33k and 47k. Thanks for the article.
# CktMaker 2016-01-27 19:06
Excellent article. I do have a few questions.
1. Why is the 4.7k trace better than the 1.5k trace? The 1.5k trace looks a better square wave.
2. When calculating max R pull-up for Fast Mode (400kHz), why do you substitute the max bus capacitance of 400pF instead of using your combined bus capacitance of 20pF as you did in the calculations for 100kHz?
Thanks in advance!


Go to top