Microcontrollers · #13 of 52

5 V vs 3.3 V Logic + Level Shifting

Input Limits, Thresholds, Dividers, Buffers, and Bidirectional Buses

An Arduino Uno R3 development board.
A board can look friendly and still speak a different voltage language. Many Arduino-era modules assume 5 V logic. · SparkFun Electronics, CC BY 2.0

The robot hand team grabs a cheap sensor breakout from the drawer. It has four pins, the example code is everywhere, and the product page says "Arduino compatible." The temptation is to plug it into the ESP32 and move on.

That phrase is not an electrical guarantee. Arduino compatibility often means a 5 V world. ESP32-class GPIO lives in a 3.3 V world. A signal can be a perfectly valid logic high for one chip and a damaging over-voltage for the next chip.

Level shifting is not a ceremonial adapter board. It is the discipline of asking what voltage appears at the receiving pin, whether that voltage is a valid logic state, and whether it stays inside the absolute maximum ratings.

By the end, you can

  1. Separate supply voltage, logic-high voltage, input threshold and absolute maximum rating
  2. Explain why a 5 V output can damage a 3.3 V GPIO even when the signal is just a digital high
  3. Choose a one-way divider or buffer for 5 V to 3.3 V inputs
  4. Recognize when a 3.3 V output may not satisfy a 5 V input's high threshold
  5. Choose bidirectional translation for open-drain buses and push-pull translators for driven buses
  6. Use a repeatable pre-connection checklist before mixing boards and modules

Logic is analog before it is digital

A GPIO input does not receive the word "high." It receives a voltage. Inside the chip, input circuitry compares that voltage against thresholds. Below the low threshold it is read as zero. Above the high threshold it is read as one. Between those thresholds the chip is not promising a clean interpretation.

A voltage bar showing low, undefined, high and damage-risk regions for a 3.3 V input.
Digital decisions sit on analog voltage limits. The danger zone is not a logic state, it is stress on the pin. · TooFoo original SVG

For an ESP32-style 3.3 V GPIO, a useful mental model is:

  1. Near 0 V is a low.
  2. Around 3.3 V is a high.
  3. Around 5 V is not a better high. It is outside the pin's safe input range.
A NodeMCU ESP8266 development board photographed over a pinout sheet.
Wi-Fi microcontroller boards in this family are normally 3.3 V logic devices, even when a USB connector or regulator lets the board be powered from 5 V. · Vowstar, CC BY-SA 4.0

This is the first trap: power input voltage and GPIO voltage are not the same question. A board may accept 5 V on a VIN or USB pin because it has a regulator. The microcontroller pins may still tolerate only 3.3 V logic.

A module is powered from 5 V and its output pin drives directly into an ESP32 GPIO. What is the correct question?

5 V into 3.3 V: reduce the voltage

The easiest case is a one-way signal from a 5 V device into a 3.3 V input. A resistor divider can be enough when the signal is slow and the receiver input current is tiny.

An HC-SR04 ultrasonic distance sensor module.
The HC-SR04 is a classic bench example: common, useful, and often powered from 5 V with an echo output that must be checked before it touches a 3.3 V pin. · SparkFun, CC BY 2.0

The divider is the same circuit from Lesson #3. Put a top resistor between the 5 V output and the ESP32 input. Put a bottom resistor from the ESP32 input to ground. The pin sees the divided voltage:

Vpin=VinRbottomRtop+RbottomV_\text{pin}=V_\text{in}\frac{R_\text{bottom}}{R_\text{top}+R_\text{bottom}}

For a 5 V input, 10 kOhm on top and 20 kOhm on bottom gives:

Vpin=5 V2010+203.33 VV_\text{pin}=5\ \text{V}\frac{20}{10+20}\approx 3.33\ \text{V}
A two-resistor divider reducing a 5 V signal to about 3.33 V at an ESP32 input.
A divider is cheap and understandable. It is also one-way, resistive and edge-speed limited. · TooFoo original SVG
pin: 3.33 V current: 0.167 mA verdict: high

Try these moves:

  1. Start at 5 V, 10 kOhm top and 20 kOhm bottom. The pin lands near 3.33 V.
  2. Lower the top resistor to 1 kOhm and leave the bottom high. The pin can become unsafe.
  3. Raise both resistors very high. The DC voltage still looks right, but the node becomes easier to disturb and slower with capacitance.
  4. Lower the input voltage to 3.3 V. A divider may no longer be needed for safety.
Practice 1 warm-up

A 5 V sensor output goes through a 10 kOhm top resistor and a 20 kOhm bottom resistor to ground. Estimate the voltage at the ESP32 input and say whether it is below a 3.6 V absolute maximum.

Show worked solution

The input is 5 * 20 / (10 + 20), about 3.33 V. That is below 3.6 V, so the DC level is inside the absolute maximum. You would still check edge speed, input leakage and whether the signal only travels one way.

3.3 V into 5 V: check the receiving threshold

The reverse direction is subtler. A 3.3 V output does not damage a 5 V input. The question is whether the 5 V input recognizes 3.3 V as high.

A close-up of a WS2812B RGB LED strip.
Addressable LEDs are a common case where a 3.3 V data signal may be marginal when the LEDs are powered from 5 V. · SparkFun Electronics, CC BY 2.0

Some 5 V logic families accept a 3.3 V high easily. Others require a high threshold closer to a fraction of the 5 V supply. The right answer is in the receiving device's datasheet as VIH, the minimum input-high voltage.

A CMOS logic integrated circuit in a DIP package.
Logic family matters. CMOS, TTL-compatible inputs and modern translator ICs can have different high and low thresholds. · Mister rf, CC BY-SA 4.0

If VIH is 2.0 V, a 3.3 V output is a clear high. If VIH is 0.7 times a 5 V supply, the required high is 3.5 V and a 3.3 V output has no margin. In that case you use a buffer, a translator IC, or run the receiving device at a compatible voltage if the datasheet allows it.

A 5 V device says its input-high threshold is 0.7 times VCC. With VCC = 5 V, is a 3.3 V GPIO output guaranteed high?

Bidirectional lines need a different trick

I2C is the perfect warning against oversimplified level shifting. SDA and SCL are not ordinary push-pull outputs. Devices pull the line low and release it high through pull-up resistors. Either side may need to pull low.

A simplified MOSFET level shifter between a 3.3 V open-drain bus and a 5 V open-drain bus.
For open-drain buses, a MOSFET-style bidirectional shifter lets each side keep its own safe high voltage while either side can pull the line low. · TooFoo original SVG

That circuit is good for slow, open-drain buses such as many I2C connections. It is not a universal magic block. A fast push-pull SPI clock, a UART TX line, a camera bus or an LED data stream may need a unidirectional buffer, a direction-controlled transceiver or a translator designed for that edge rate and drive style.

Back side of an HC-SR04 ultrasonic distance sensor module.
A module's pins hide its internal circuit. You have to know which pins are inputs, outputs, open-drain, push-pull, analog or power before choosing the translator. · Suyash Dwivedi, CC BY-SA 4.0

For a mixed-voltage board, the choice is a table you apply every time:

  1. Same voltage on both sides: direct connection may be fine.
  2. 5 V output to 3.3 V input: divider or unidirectional buffer.
  3. 3.3 V output to 5 V input: check VIH; use a buffer if margin is weak.
  4. Open-drain bidirectional bus: MOSFET or I2C translator with pull-ups to each rail.
  5. Push-pull bidirectional bus: direction-controlled translator or a part designed for auto-direction at the needed speed.
  6. Analog signal: do not use a digital level shifter. Scale and protect it as an analog input.
Top and bottom views of Raspberry Pi Pico boards.
3.3 V microcontroller boards are everywhere now. The safest habit is to assume pins are not 5 V tolerant until the datasheet proves otherwise. · Ogidya, CC BY-SA 4.0

Measure before the expensive mistake

The bench workflow is simple and worth doing even when the circuit looks obvious.

  1. Identify every rail: 5 V, 3.3 V, battery, motor, sensor.
  2. Identify every signal direction: output, input, bidirectional, open-drain or analog.
  3. Read the receiving input limits: VIL, VIH and absolute maximum.
  4. Choose the translator based on direction and edge speed.
  5. Power the module without the microcontroller connected and measure the signal's idle voltage.
  6. Connect through the translator and measure the receiving pin.
  7. Only then run firmware.
Practice 2 core

You have an ESP32 reading the echo pin of a 5 V HC-SR04-style ultrasonic sensor, and also driving a 5 V addressable LED strip. Pick the likely translation method for each signal.

Show worked solution

The echo pin is a one-way 5 V output into a 3.3 V input, so a divider or unidirectional buffer can be appropriate if the timing still has margin. The LED data line is a one-way 3.3 V output into a 5 V input, so check the LED input-high threshold. If 3.3 V has weak margin, use a fast unidirectional buffer or logic translator powered for the target input level.

Many chips have ESD/protection structures from pins to rails. If you drive a pin above the rail, those structures can conduct current into the chip. Sometimes a circuit seems to work because the pin clamps through protection silicon. That is not safe operation. Limit injection current only when the datasheet explicitly allows it, and do not build a product around accidental clamp behavior.

Key takeaways

  • A digital input still receives an analog voltage. Valid logic and electrical safety are separate questions.
  • A 5 V high can damage a 3.3 V GPIO. Powering a board from USB or VIN does not make its pins 5 V tolerant.
  • A resistor divider is useful for slow one-way 5 V outputs into 3.3 V inputs, but it is not a universal translator.
  • A 3.3 V output into a 5 V input is usually safe but may not meet the receiving input-high threshold.
  • Open-drain bidirectional buses need translators that let each side pull low and return high to its own rail.
  • The pre-connection checklist is rail, direction, threshold, absolute maximum, translator, measurement, firmware.

Level shifting is the difference between "it plugged in" and "it is electrically allowed." The board does not know that the wire came from a sensor, an Arduino example, or a quick prototype. It only sees voltage and current. Train yourself to ask what the receiving pin sees before the wire touches the header, and mixed-voltage systems become routine rather than risky.

full glossary →