You've got your I2C bus wired up, but the signals look terrible on the scope — slow rise times, rounded edges, maybe even communication failures. Nine times out of ten, the culprit is the pull-up resistor value. Too large and your rise times are glacial. Too small and you waste power and overload your I2C devices.
Let's work through the math so you can pick the right value every time.
Why I2C Needs Pull-Up Resistors
I2C uses open-drain (or open-collector) drivers. That means the bus lines — SDA and SCL — can only be pulled low actively. To get the lines back to a high state, you need pull-up resistors connected to your supply rail (VCC).
This is by design. Open-drain buses avoid bus contention — if two devices try to drive the bus at the same time, nobody gets damaged. But it means the pull-up resistors are responsible for every rising edge on the bus.
The resistor value determines how fast the bus capacitance charges back to VCC. Get this wrong, and your rise time violates the I2C spec, causing data corruption.
The I2C Specification: What You Need to Hit
The NXP I2C-bus specification (UM10204, Rev 7 — the current standard) defines maximum rise times for each mode:
| Mode | Max Clock | Max Rise Time (tr) |
|---|---|---|
| Standard Mode | 100 kHz | 1000 ns |
| Fast Mode | 400 kHz | 300 ns |
| Fast Mode Plus | 1 MHz | 120 ns |
| High Speed Mode | 3.4 MHz | 40 ns |
Rise time is measured from 0.3 × VCC to 0.7 × VCC.
There's also a minimum requirement — the pull-up can't sink too much current. The spec defines a minimum sink current of 3 mA for Standard/Fast Mode and 20 mA for Fast Mode Plus. This translates to a minimum resistor value.
The Pull-Up Resistor Formula
The rise time of an RC circuit charging through a resistor is:
tr = 0.8473 × Rp × Cb
Where:
- tr = rise time (seconds)
- Rp = pull-up resistance (ohms)
- Cb = total bus capacitance (farads)
- 0.8473 = ln(0.7/0.3), the constant for 30%-70% charging
Rearranging to solve for the maximum pull-up resistance:
Rp(max) = tr(max) / (0.8473 × Cb)
And the minimum resistance (from the current sink limit):
Rp(min) = (VCC - VOL(max)) / IOL(min)
Where VOL(max) is the maximum low-level output voltage (typically 0.4V) and IOL(min) is the minimum sink current.
A Real Example: Fast Mode at 400 kHz
Let's say you're designing an I2C bus with:
- VCC = 3.3V
- Mode = Fast Mode (400 kHz)
- Bus capacitance = 100 pF (typical for a short PCB trace with 2-3 devices)
- VOL(max) = 0.4V
- IOL(min) = 3 mA
Step 1: Calculate Rp(max)
Rp(max) = 300 ns / (0.8473 × 100 pF)
Rp(max) = 300e-9 / 84.73e-12
Rp(max) = 3,541Ω ≈ 3.5kΩ
Step 2: Calculate Rp(min)
Rp(min) = (3.3V - 0.4V) / 3 mA
Rp(min) = 2.9 / 0.003
Rp(min) = 967Ω ≈ 1kΩ
Step 3: Pick a standard value between min and max
Your pull-up resistor should be between 967Ω and 3,541Ω. A standard 2.2kΩ or 3.3kΩ resistor works well here. I'd go with 2.2kΩ — it gives you some margin on rise time while staying well above the minimum.
With 2.2kΩ:
tr = 0.8473 × 2200 × 100e-12 = 186 ns
That's comfortably under the 300 ns limit.
Bus Capacitance: The Hidden Variable
Bus capacitance is where things get tricky. You need to account for:
- Device pin capacitance — typically 5-10 pF per I2C pin (check your datasheets)
- PCB trace capacitance — roughly 0.5-2 pF/cm depending on your stackup
- Wire capacitance — if you're running off-board, this adds up fast
- Connector parasitics — another few pF per connector
For a typical on-board design with 3 devices and 10cm of trace:
Cb = (3 devices × 2 pins × 7 pF) + (10cm × 1.5 pF/cm)
Cb = 42 pF + 15 pF = 57 pF
That's manageable. But add a 1-meter cable to an external sensor, and you can easily hit 200-400 pF. At that point, your pull-up values get very tight, and you might need an active pull-up or an I2C bus extender like the PCA9600.
Pull-Up Resistor Reference Table
Here are typical pull-up values for common scenarios:
| Scenario | VCC | Devices | Bus Cap | Mode | Rp Value |
|---|---|---|---|---|---|
| Short PCB, 2-3 devices | 3.3V | 3 | ~50 pF | 400 kHz | 4.7kΩ |
| Short PCB, 4-6 devices | 3.3V | 5 | ~100 pF | 400 kHz | 2.2kΩ |
| Short PCB, many devices | 3.3V | 8 | ~150 pF | 400 kHz | 1.5kΩ |
| Long trace or cable | 3.3V | 3 | ~200 pF | 400 kHz | 1.2kΩ |
| Standard mode, relaxed | 5V | 3 | ~100 pF | 100 kHz | 10kΩ |
| Fast Mode Plus | 3.3V | 3 | ~100 pF | 1 MHz | 680Ω |
These are starting points. Always verify with the math for your specific design.
Power Consumption: The Other Constraint
Pull-up resistors draw current whenever the bus is held low. The static power dissipation per line:
P = VCC² / Rp
For a 3.3V bus with 2.2kΩ pull-ups on both SDA and SCL:
P = (3.3² / 2200) × 2 = 0.0099W ≈ 10 mW
That's negligible. But if you're running a battery-powered device and the bus is held low for extended periods (like a stuck device), that current adds up. For ultra-low-power designs, consider using higher values (10kΩ-47kΩ) if your bus timing allows it.
Some designs use MOSFET-based active pull-ups that provide strong pull-up during transitions and weak pull-up during idle. The PCA9600 and LTC4311 do this automatically.
Common Mistakes
Using 10kΩ everywhere. This works for Standard Mode at 100 kHz, but it's too high for Fast Mode. At 400 kHz with 100 pF bus capacitance:
tr = 0.8473 × 10,000 × 100e-12 = 847 ns
That's nearly triple the 300 ns limit. Your bus might work on the bench but fail at temperature extremes or with production variations.
Forgetting that both lines need pull-ups. SDA and SCL both need their own pull-up resistors. Not just SDA.
Mixed voltage buses without level shifters. If you have 3.3V and 5V devices on the same bus, you can't just tie the pull-ups to 5V. Use a bidirectional level shifter (like the PCA9306) or a voltage translator designed for I2C.
Too many devices on one bus. Each device adds pin capacitance. The I2C spec limits bus capacitance to 400 pF for Standard/Fast Mode. If you're approaching that limit, use an I2C multiplexer (TCA9548A) or bus repeater to split the bus into segments.
Design Checklist
Before finalizing your I2C pull-up values, verify:
- Rise time meets spec for your bus speed
- Rp is above the minimum (current sink limit)
- You've estimated total bus capacitance realistically
- Both SDA and SCL have pull-ups
- Power consumption is acceptable for your application
- You've checked device datasheets for any special pull-up requirements
Some I2C devices — particularly certain sensors and EEPROMs — have specific recommendations for pull-up values in their datasheets. Always check.
When to Use Something Stronger Than a Resistor
If your calculation gives you an Rp value below about 1kΩ, you're pushing the limits of passive pull-ups. Consider:
- Active pull-up ICs (PCA9600, LTC4311) — use a current source instead of a resistor
- I2C bus extenders (P82B715) — buffer the bus for long runs
- I2C multiplexers (TCA9548A) — split a heavily loaded bus into segments
These add cost and complexity, but they're the right solution when you have long cables, many devices, or high bus speeds.
Don't want to crunch these numbers by hand every time? The I2C Pull-Up Resistor Calculator handles the math for you. Enter your supply voltage, bus speed, and estimated capacitance, and it computes the valid pull-up range with margin. It follows the NXP I2C specification (UM10204) formulas directly — same math, fewer headaches.