- Published on
LED Resistor Calculations Done Right: Why Every Color Needs a Different Value, and the E24 Series
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction — Exactly What Happens When You Plug an LED Straight Into 5V
- An LED Is a Diode, Not a Resistor
- Forward Voltage Differs by Color
- Calculating the Resistor Value — At 5V and at 3.3V
- Why Round Up — The E24 Series and Standard Resistor Values
- Power Dissipated in the Resistor, and Its Rating
- Multiple LEDs — Why One Shared Resistor in Parallel Is a Bad Idea
- When a Pin Can't Handle It — Transistors and Driver ICs
- Conclusion — The Calculation Always Starts With Headroom Voltage
Introduction — Exactly What Happens When You Plug an LED Straight Into 5V
The sentence "an LED needs a resistor" is everywhere. But an explanation of why you need one, why it's 220 ohms, and whether a blue LED also gets 220 ohms, is much harder to find. You just end up copying a schematic that says 220 ohms.
That's where the trouble starts. A circuit that worked fine with 220 ohms on a 5V Arduino gets dim when you move it to a 3.3V Raspberry Pi. Swap in a blue LED instead of a red one and it doesn't light at all. Since you were only copying, you have no idea what needs to change.
This post's goal is to get you to the point where you can calculate where the number 220 came from. Then it doesn't matter whether the supply changes or the color changes — you can just work out the value yourself.
First, let's look precisely at what happens with no resistor at all. Connect a single red LED directly between 5V and GND, and 5V lands across the LED. When this LED is operating normally, the voltage across it is about 2.0V. That leaves 3.0V. This 3.0V lands across the LED's own tiny internal resistive component, whose value is roughly 10 ohms.
Current = 3.0V / 10 ohm = 0.3A = 300mA
300mA. This LED is built to handle 20mA. That's 15 times over. The LED chip itself is roughly 0.3mm on a side, and the power dissipated inside it is:
P = 5V × 0.3A = 1.5W
1.5W. A semiconductor sliver smaller than a matchhead is taking 1.5W. The junction temperature shoots up to hundreds of degrees almost instantly, and either the gold wire bonding the chip to the leads melts, or the junction itself is damaged. This is the physical reality behind "it flashed bright for a second and went dark." Unlike software, there's no undoing it.
An LED Is a Diode, Not a Resistor
To understand why this happens, you need to know that an LED is a fundamentally different kind of component from a resistor.
In a resistor, voltage and current are proportional. Apply 5V and five times as much flows as at 1V. Graph it, and it's a straight line.
An LED is a diode, and a diode's current increases exponentially with voltage. This relationship is called the Shockley diode equation, but for practical purposes what matters is not the equation itself but the outcome it produces.
Measure a typical 5mm red LED and you get roughly these values:
| Voltage applied | Current flowing | Compared to previous step |
|---|---|---|
| 1.7V | ~0.5mA | baseline |
| 1.8V | ~2mA | 4x |
| 1.9V | ~6mA | 3x |
| 2.0V | ~20mA | 3.3x |
| 2.1V | ~60mA | 3x |
| 2.2V | ~150mA | 2.5x |
Bump the voltage by just 0.1V — 5 percent — and the current triples. That's the nature of an exponential.
Two conclusions come out of this table.
First, directly specifying a voltage for an LED is close to impossible. To hit a target current of 20mA you'd need to nail the voltage at exactly 2.00V, but at just 2.05V the current is nearly double. Supply tolerance, temperature swings, and part-to-part variation are all on this same order of magnitude. Trying to control an LED through voltage doesn't work from the outset.
Second — and more dangerous — an LED cannot protect itself. As temperature rises, forward voltage drops by about 2mV per degree Celsius. So the hotter it gets, the more current flows at the same voltage. More current means it gets hotter still. Nothing puts the brakes on this feedback loop.
So the fix is to flip your approach. Instead of trying to specify voltage, specify current. The simplest, most reliable component for setting current is a series resistor. Because a resistor is a linear component where voltage and current stay proportional, if current tries to rise, the voltage across the resistor grows, which shrinks the voltage available to the LED, which pulls the current back down. A resistor is a current-limiting device and a negative-feedback device at the same time.
Forward Voltage Differs by Color
For an LED to emit light, the voltage needs to exceed the semiconductor's bandgap energy, and that energy is exactly what determines the color of light that comes out. Shorter-wavelength light — blue — demands more energy, so its forward voltage is higher. Color and voltage aren't independent; they're two faces of the same physical quantity.
Here are the representative values used in practice. Individual parts vary, so use the datasheet if you have one, but these values are generally safe to calculate from when you don't.
| Color | Typical forward voltage | Actual spread | Semiconductor material |
|---|---|---|---|
| Red | 2.0V | 1.8–2.2V | AlGaAs, GaAsP |
| Yellow | 2.1V | 2.0–2.4V | AlGaInP |
| Yellow-green (older style) | 2.2V | 2.0–2.4V | GaP |
| Pure green (high brightness) | 3.2V | 2.9–3.6V | InGaN |
| Blue | 3.2V | 2.9–3.6V | InGaN |
| White | 3.2V | 2.9–3.6V | InGaN + phosphor |
| Infrared (IR) | 1.3V | 1.2–1.5V | GaAs |
There's one boundary here that matters most in practice. Green LEDs actually come in two kinds. The old-style yellow-green ones are 2.2V, while the bright pure-green ones sold today are the same InGaN material as blue, so they're 3.2V. They look similar enough that using the same value for both throws your result way off. When in doubt, the fastest fix is to measure it directly with a multimeter's diode-test function — the value it shows is that LED's forward voltage.
And laying the number 3.2V next to a 3.3V board immediately shows you where the problem lies. We'll confirm this with a calculation in the next section.
Calculating the Resistor Value — At 5V and at 3.3V
The formula is just the previous post's Ohm's law again. Divide the voltage across the resistor by your target current.
Resistor = (Supply voltage - LED forward voltage) / Target current
Let's call the numerator the headroom voltage. The LED takes its own share, which is the forward voltage, and whatever's left over is the resistor's share.
What should the target current be? A typical 5mm LED's maximum rating is 20mA. Designing right at the maximum rating leaves zero margin, so aiming for around 15mA in practice is the safer choice. The brightness difference is barely perceptible to the eye. This blog's wiring validator tool also suggests resistor values based on a 15mA target.
5V Supply, Red LED
Headroom voltage = 5V - 2.0V = 3.0V
Resistor = 3.0V / 0.015A = 200 ohm
That comes out to exactly 200 ohms — a value that's right there on the standard-value list we'll cover next.
Calculating for 20mA instead gives:
Resistor = 3.0V / 0.02A = 150 ohm
150 ohms is also a standard value. And the commonly used 220 ohms sits somewhere generously above this range. Using 220 ohms, the actual current is:
Current = 3.0V / 220 ohm = 0.0136A = 13.6mA
13.6mA. Plenty bright, and very safe. That's why beginner kits are packed with 220-ohm resistors — it's not a wrong value, it's a value tilted toward safety.
3.3V Supply, Red LED
Headroom voltage = 3.3V - 2.0V = 1.3V
Resistor = 1.3V / 0.015A = 86.7 ohm
86.7 ohms — nothing like the 200 ohms from the 5V case. That's because the headroom voltage dropped from 3.0V to 1.3V. The supply voltage dropped 34 percent, but the resistor value dropped 57 percent. This non-linearity is exactly why "the same circuit got dim when I moved it to a Raspberry Pi." If you keep using the 200 ohms calculated for 5V,
Current = 1.3V / 200 ohm = 0.0065A = 6.5mA
only 6.5mA flows — less than half the target. The resistor isn't wrong; the supply changed, so it needs to be recalculated.
3.3V Supply, Blue LED — A Case Where the Calculation Doesn't Hold Up
Headroom voltage = 3.3V - 3.2V = 0.1V
Resistor = 0.1V / 0.015A = 6.67 ohm
A number comes out, but this circuit shouldn't be used. The reason is that the headroom voltage is only 0.1V.
We already noted that individual forward-voltage variation runs from 2.9V to 3.6V. If this particular LED happens to be 3.4V, the headroom voltage goes negative and it won't light at all. If it happens to be 3.0V, the headroom voltage becomes 0.3V and the current triples. Even a small sag in the 3.3V rail down to 3.25V would cut the brightness in half. In other words, this circuit is completely at the mercy of part variation and supply fluctuation.
The fix is one of three options: drive the LED off the 5V rail and only control the signal at 3.3V, use a different color with a lower forward voltage, or use a constant-current driver that actively holds the current steady. The rule of thumb is that once the headroom voltage drops below 20 percent of the supply voltage, it's time to reconsider handling this with a single resistor.
Summary of the Calculated Results
| Supply | Color | Forward voltage | Headroom voltage | Value calculated for 15mA | Standard value to pick | Actual current |
|---|---|---|---|---|---|---|
| 5V | Red | 2.0V | 3.0V | 200 ohm | 200 ohm | 15.0mA |
| 5V | Yellow | 2.1V | 2.9V | 193.3 ohm | 200 ohm | 14.5mA |
| 5V | Yellow-green | 2.2V | 2.8V | 186.7 ohm | 200 ohm | 14.0mA |
| 5V | Blue / White | 3.2V | 1.8V | 120 ohm | 120 ohm | 15.0mA |
| 3.3V | Red | 2.0V | 1.3V | 86.7 ohm | 91 ohm | 14.3mA |
| 3.3V | Yellow | 2.1V | 1.2V | 80.0 ohm | 82 ohm | 14.6mA |
| 3.3V | Yellow-green | 2.2V | 1.1V | 73.3 ohm | 75 ohm | 14.7mA |
| 3.3V | Blue / White | 3.2V | 0.1V | 6.67 ohm | not suitable | unstable |
The last two columns of this table are the other half of this article. We need to look at why the calculated value and the value you can actually buy differ, and why you always round toward the larger one.
Why Round Up — The E24 Series and Standard Resistor Values
Nobody sells an 86.7-ohm resistor. Resistors aren't manufactured in arbitrary values — only the values on a fixed list are ever produced. That list is called the E series.
The E24 series divides a single decade into 24 steps, made up of the following values and their multiples by 10, 100, and 1000:
1.0 1.1 1.2 1.3 1.5 1.6 1.8 2.0 2.2 2.4 2.7 3.0
3.3 3.6 3.9 4.3 4.7 5.1 5.6 6.2 6.8 7.5 8.2 9.1
So the values that actually exist are things like 82 ohm, 91 ohm, 100 ohm, 110 ohm — and 86.7 ohm isn't among them.
The reasoning behind this spacing is interesting. Adjacent values are spaced roughly 1.1x apart, i.e. about 10 percent. And the standard tolerance on an E24 resistor is 5 percent. In other words, it's a geometric progression engineered so that each value's error band neither overlaps its neighbors' nor leaves gaps between them. The tighter E96 series matches parts with 1 percent tolerance. Dividing evenly on a logarithmic scale is the same idea used for audio volume steps or image-resize increments.
Now here's the key question. When a calculated value isn't on the list, do you round up or down?
You must round up. The reason is that a larger resistor means less current. Round 86.7 ohm down to 82 ohm and:
Current = 1.3V / 82 ohm = 0.0159A = 15.9mA
15.9mA flows, more than the target. Round up to 91 ohm instead and:
Current = 1.3V / 91 ohm = 0.0143A = 14.3mA
14.3mA, less than the target. The brightness difference isn't noticeable, and the current lands on the safe side.
This principle becomes decisively important right at the pin current limit. A Raspberry Pi GPIO pin's allowed current is 16mA. Use 82 ohms and you get 15.9mA — sitting right at the limit with only 0.1mA to spare. Add part-to-part variation on top of that — say the LED's forward voltage happens to be 1.9V, giving a headroom voltage of 1.4V:
Current = 1.4V / 82 ohm = 0.0171A = 17.1mA
and you're over the limit. With 91 ohms instead, under the same conditions, you get 15.4mA — still inside the limit. That one step of rounding up is what creates the margin.
If you've already wired something up and want to quickly check whether this math holds, drop your board, part, and resistor value into this site's circuit wiring validator. It follows the same rule, picking the value above on the E24 series, and tells you whether the current your chosen resistor actually produces exceeds the pin's limit.
Power Dissipated in the Resistor, and Its Rating
The resistor dumps exactly the headroom voltage's worth as heat. Working out how much lets you know what resistor you actually need to buy.
5V, red LED, 200 ohms:
Voltage across the resistor = 3.0V
Current flowing = 15mA
Power dissipated = 3.0V × 0.015A = 0.045W = 45mW
45mW. Even the common 1/4W (250mW) resistor is only running at 18 percent of its rating, so there's plenty of headroom.
3.3V, red LED, 91 ohms:
Power dissipated = 1.3V × 0.0143A = 0.0186W = 18.6mW
Even less. This is why 3.3V circuits come out ahead on heat.
So does that mean an LED resistor can always be 1/4W? No — once the supply voltage climbs, the story changes. Say you're driving a single red LED at 20mA on a 12V lighting circuit:
Headroom voltage = 12V - 2.0V = 10.0V
Resistor = 10.0V / 0.02A = 500 ohm → E24 standard value 510 ohm
Power dissipated = 10.0V × 0.02A = 0.2W = 200mW
200mW. That fills 80 percent of a 1/4W resistor's 250mW rating. Since the earlier guideline was to stay under half the rating, it's correct to use a 1/2W resistor here.
And this calculation changes how you'd design the 12V circuit altogether. Dumping 10V as heat in a resistor means wasting 83 percent of the power you're supplying. That's why at 12V you string LEDs together in series to shrink the headroom voltage. Put five red LEDs in series:
Total LED voltage = 2.0V × 5 = 10.0V
Headroom voltage = 12V - 10.0V = 2.0V
Resistor = 2.0V / 0.02A = 100 ohm
Power dissipated = 2.0V × 0.02A = 0.04W = 40mW
Lighting five LEDs at the same 20mA, and the resistor loss is a fifth of what it was. Since current is shared in a series connection, all five light up at exactly the same brightness. This is why series is the first thing to consider when dealing with multiple LEDs.
Multiple LEDs — Why One Shared Resistor in Parallel Is a Bad Idea
If series is good, what about parallel? You'll often see a schematic with three LEDs side by side sharing a single resistor. It looks attractive because it uses fewer parts. But you should never wire it this way.
The reason is the exponential curve we saw earlier. Three LEDs wired in parallel are forced to have the same voltage across all of them. But the forward voltages of three LEDs are never actually equal — even parts from the same bag can differ by around 0.05V.
Let's confirm with numbers. On 5V with a single 150-ohm resistor and three parallel LEDs whose forward voltages happen to be 1.95V, 2.00V, and 2.05V:
All three LEDs' terminal voltage must be equal, and it settles somewhere close to the lowest one, 1.95V. The voltage across the resistor is then:
5V - 1.95V = 3.05V
Total current = 3.05V / 150 ohm = 0.0203A = 20.3mA
That total 20.3mA gets split three ways, and going back to the exponential table, the current at 1.95V runs roughly a third of what it is at 2.00V. Put the other way around, the LED with the lowest forward voltage hogs the current. Measure it in practice and you get roughly this split:
| LED | Forward voltage | Actual current flowing | Share |
|---|---|---|---|
| A | 1.95V | ~15mA | 74 percent |
| B | 2.00V | ~4mA | 20 percent |
| C | 2.05V | ~1mA | 5 percent |
The three light up at noticeably different brightness. That alone is a failure, but there's something worse still to come.
A, which hogged the current, gets the hottest. As temperature rises, forward voltage drops about 2mV per degree. If A's temperature climbs 25 degrees, its forward voltage drops another 0.05V, and then A grabs even more of the current. It gets hotter, its voltage drops further, and it grabs even more current. This is thermal runaway. Eventually A dies first, and once A dies, all of the remaining current piles onto B, putting B at risk too.
The correct wiring gives each LED its own resistor. Three separate resistors independently set the current in each branch, so even with part-to-part variation, the currents don't spread apart nearly as much. With a resistor present, the moment A tries to take more current, the voltage across A's own resistor grows and automatically applies the brakes. Saving one resistor at the cost of losing an LED is a bad trade no matter how you look at it.
When a Pin Can't Handle It — Transistors and Driver ICs
As the LED count grows, you hit a different wall than the resistor calculation: the limit on how much current a pin can supply.
This limit has two layers: a per-pin limit, and a combined total limit across every pin. You have to respect both.
| Board | Logic voltage | Per-pin limit | Total GPIO limit | How many 15mA LEDs |
|---|---|---|---|---|
| Arduino Uno R3 | 5V | 20mA (absolute max 40mA) | 200mA | 13 |
| Raspberry Pi 40-pin | 3.3V | 16mA | 50mA | 3 |
| ESP32 DevKit v1 | 3.3V | 12mA | 120mA | 10 (with per-LED target lowered to 12mA) |
The last column is the count computed purely from the total limit. Because the ESP32's per-pin limit is 12mA, you have to lower each LED's target current to 12mA, and then the total of 120mA gets split ten ways. Whichever limit — per-pin or total — gets hit first is the real ceiling.
Look at the Raspberry Pi numbers again. 16mA per pin is plenty for a single LED, but the overall total is 50mA. Light four 15mA LEDs and you're already over at 60mA. There are 40 pins, but only three LEDs.
The total limit exists for a physical reason. Each pin's output transistor connects to a shared power trace inside the chip, and that trace, along with the chip's bond wires and package leads, has to withstand the combined current together. Even if every individual pin is within spec, exceeding the total overheats that shared path. And the resistance of that internal power trace causes a voltage drop, destabilizing other circuitry elsewhere on the same chip.
Once you're past the limit, you have to abandon driving the LEDs directly from a pin. You have three options.
Switching with a Transistor
The pin only supplies a signal; the current comes straight from the power rail instead. Use a logic-level MOSFET or a small-signal transistor as the switch.
If you use a BJT, you need to calculate the base resistor. Say you're switching eight LEDs at 15mA each, 120mA total. To drive a small-signal transistor like the 2N3904 into saturation, use a generously conservative current gain estimate of around 10.
Base current needed = 120mA / 10 = 12mA
Base resistor = (5V - 0.7V) / 0.012A = 358 ohm
Picking the E24 value below that, 330 ohms:
Actual base current = (5V - 0.7V) / 330 ohm = 0.013A = 13mA
13mA, within the 20mA pin limit. Note that the base resistor rounds down, the opposite of the LED resistor. If base current is insufficient, the transistor doesn't fully turn on, so it dissipates power in itself and gets hot. The goal is different, so the rounding direction is different too.
The 0.7V is the base-emitter voltage drop — a characteristic value of the silicon junction, and it needs to be subtracted to get the voltage actually landing on the resistor.
Using a Driver IC
A driver array like the ULN2803 packs eight channels of Darlington transistors into a single chip. Each channel handles up to 500mA, and the input only draws about 1mA from a microcontroller pin. Pair it with a 74HC595 shift register and three pins can control eight or sixteen outputs.
The direction matters here. The ULN2803 is sink-only — its output pins only pull current down to GND, they never push it out. So the LED's anode has to connect to the power rail, and the cathode connects to the driver output. Wire it the source way instead, and no amount of code fixing will make it light up.
Moving to a Dedicated LED Driver
Once you're dealing with dozens of LEDs or more, or need to control brightness individually, a constant-current driver is the answer. Parts like the WS2812B, which build a driver right into each LED, are the classic example — and here the nature of the current calculation changes. A single WS2812B pixel running all three colors at full brightness draws 60mA. For a strip of 30 pixels:
60mA × 30 = 1800mA = 1.8A
1.8A. An Arduino's 5V rail limit is 450mA, so pulling the power straight from the board is off the table entirely. A separate power supply is required, and this leads into the article on motors and inductive loads.
PWM Is Not a Way to Reduce Current
If the goal is dimming, use PWM instead of increasing the resistor. But PWM doesn't reduce the current during the moments the LED is on — it only changes the on/off ratio to adjust the average brightness.
// Smoothly ramps the LED brightness up and down.
// The resistor is still 200 ohms, and the current during the "on" instant is still 15mA.
// PWM only changes the fraction of time the LED spends on.
const int LED_PIN = 9; // A PWM-capable pin on the Uno
const int STEP_DELAY_MS = 8;
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// Duty from 0 to 255. 255 means constantly on.
for (int duty = 0; duty <= 255; duty++) {
analogWrite(LED_PIN, duty);
delay(STEP_DELAY_MS);
}
for (int duty = 255; duty >= 0; duty--) {
analogWrite(LED_PIN, duty);
delay(STEP_DELAY_MS);
}
}
When budgeting pin current, you have to use the peak instantaneous current, not the PWM duty cycle. Don't calculate 7.5mA just because the duty is 50 percent. During the instant it's on, the full 15mA flows exactly as before, and that instantaneous value is what the pin's output transistor has to withstand.
Conclusion — The Calculation Always Starts With Headroom Voltage
There's really just one line to remember from LED resistor calculations: subtract the LED's forward voltage from the supply voltage, and divide the remainder by the current you want.
That single line keeps working no matter what the supply voltage or the color is. Instead of memorizing 220 ohms, remember this subtraction and division.
And it's worth building a habit of checking one more thing every time you look at the result of that subtraction — the headroom voltage: is this value too small relative to the supply voltage? As in the case of a blue LED on 3.3V, where only 0.1V of headroom is left, no matter how precisely you calculate the resistor value, the circuit stays fully exposed to part variation and supply fluctuation. Headroom voltage is both an ingredient in the calculation and a gauge of how robust the design actually is.
Next time, we move to the input side: the phenomenon of a button connected to a pin producing values that change however they please — floating inputs and pull-up resistors.