A multiplexer (MUX) is an electronic switch that routes one of several input signals to a single output line based on the binary state of its select pins. In a real circuit or installation, a MUX fundamentally changes your microcontroller's physical limits by allowing you to read 8, 16, or even 64 sensors using only a handful of GPIO or ADC pins, drastically reducing wiring harness complexity, PCB trace routing, and overall BOM cost.
Think of a MUX like a multi-position rotary switch on an old stereo receiver, but toggled electronically via digital logic levels instead of your thumb. Instead of manually turning a knob to select the CD player or the turntable, your microcontroller sends a binary code to the MUX's select pins, instantly connecting the desired input channel to the common output.
The Core Mechanics: How a MUX Routes Signals
Multiplexers are categorized by their channel count, usually expressed as a ratio like 8:1 or 16:1. The number of available channels is always a power of two ($2^n$), where $n$ is the number of digital select pins required to address them. For an 8-channel MUX, you need 3 select pins ($2^3 = 8$). For a 16-channel MUX, you need 4 select pins ($2^4 = 16$).
When you apply a binary word to the select pins, the internal MOSFET gates open and close to create a low-resistance path from the chosen input to the output. For example, on a standard 8-channel MUX, setting the select pins to S2=1, S1=0, S0=1 (binary 5) connects Input 5 directly to the Output pin, while Inputs 0-4 and 6-7 remain electrically isolated.
Numeric Example: Sizing a MUX for an ESP32 Sensor Array
Let's look at a concrete bench scenario. You are using an ESP32 DevKit v1 to read eight resistive soil moisture sensors. Because the ESP32 only has a limited number of usable ADC pins, you route all eight sensor signals through a TI CD4051B analog multiplexer into a single ADC pin.
The CD4051B is a classic analog MUX, but it has a critical specification you must calculate for: On-Resistance ($R_{ON}$). While an ideal switch has 0Ω resistance, the internal MOSFETs of the CD4051B introduce roughly 240Ω of resistance when powered at 5V. However, when powered at 3.3V (to match the ESP32's logic and ADC limits), that $R_{ON}$ spikes to approximately 400Ω.
Here is how that 400Ω alters your circuit math:
- Sensor Resistance (Wet Soil): 2,000Ω
- Pull-up Resistor: 10,000Ω (10kΩ)
- Ideal Voltage (No MUX): $V_{out} = 3.3V \times \frac{2000}{10000 + 2000} = 0.550V$
Now, insert the MUX between the sensor and ground. The MUX's 400Ω $R_{ON}$ adds in series with the sensor:
- Actual Lower Leg Resistance: 2,000Ω + 400Ω = 2,400Ω
- Actual Voltage (With MUX): $V_{out} = 3.3V \times \frac{2400}{10000 + 2400} = 0.638V$
That is an 88mV shift. If your firmware calibration expects 0.550V for 'fully saturated soil', the MUX's internal resistance will cause the ESP32 to read the soil as drier than it actually is. To fix this, you must either calibrate out the 400Ω offset in software, or use a MUX with a lower $R_{ON}$ (like the 74HC4067 at ~120Ω), or buffer the signal with an op-amp before it hits the ADC.
Where You Meet This in Practice
Multiplexers are ubiquitous in both hobbyist and industrial electronics. You will typically encounter them in three main scenarios:
- ADC Expansion: Reading dozens of analog sensors (thermistors, potentiometers, strain gauges) using a single high-resolution ADC pin via chips like the 16-channel 74HC4067.
- I2C Bus Isolation: The I2C protocol only allows one device per address. If you need to wire four identical OLED displays with the same hardcoded I2C address, you use an I2C multiplexer like the TCA9548A to route the SDA/SCL lines to one display at a time.
- Audio and Signal Routing: In guitar pedal switchers or modular synthesizers, analog MUXes route audio signals between different effect chains without introducing the digital clock noise that PWM or digital potentiometers might cause.
Real-World Scenario Walkthrough: The Ghost Reading Bug
Multiplexers introduce specific failure modes that don't exist in direct-wired circuits. Here is a walkthrough of a common debugging scenario on the bench.
- The Setup: You wire 16 capacitive soil moisture sensors to a 74HC4067 MUX, connected to an ESP32. You use 4 GPIOs for the select pins and 1 GPIO for the ADC input. You write a simple
forloop to cycle through the binary addresses and take an ESP32 ADC oneshot reading. - The Numbers: The loop runs as fast as the ESP32 can execute, toggling the select pins and immediately calling
analogRead()with zero delay. The sensors output between 1.2V (dry) and 2.8V (wet). - The Outcome: The serial monitor shows erratic data. Channel 5 reads the exact same moisture level as Channel 4. Channel 12 reads a ghost voltage of Channel 11. The readings seem to 'lag' by one step.
- What Went Wrong: This is a classic charge injection and RC settling bug. When the MUX switches channels, the internal parasitic capacitance of the MOSFETs and the ESP32's internal ADC sampling capacitor (roughly 10pF to 100pF depending on attenuation) need time to charge to the new channel's voltage. By reading the ADC in a tight loop with no delay, you are sampling the ADC capacitor before it has finished charging from the previous channel's voltage. The fix is to add a 2ms to 5ms
delay()after toggling the MUX select pins and before triggering the ADC conversion, allowing the RC circuit to settle.
What People Commonly Confuse With a MUX
Because they all deal with routing or expanding signals, MUXes are frequently confused with other logic ICs. Here is how to tell them apart:
| Component | Direction of Signal Flow | State Memory? | Primary Use Case |
|---|---|---|---|
| Multiplexer (MUX) | Many Inputs → One Output | No (Combinational) | Selecting one sensor/signal to read. |
| Demultiplexer (DEMUX) | One Input → Many Outputs | No (Combinational) | Routing a single signal to one of many destinations (e.g., address decoding). |
| Shift Register (e.g., 74HC595) | Serial In → Parallel Out | Yes (Sequential) | Expanding digital output pins to drive LEDs or relays. |
| I2C GPIO Expander (e.g., MCP23017) | Serial Bus ↔ Parallel I/O | Yes (Registers) | Adding independent, addressable digital I/O pins via I2C. |
Frequently Asked Questions
Can I use a digital MUX (like the 74HC157) to route analog sensor signals?
No. Digital multiplexers are designed to snap signals to strict logic thresholds (0V or VCC). If you feed a 1.5V analog signal into a digital MUX powered at 5V, it will likely interpret it as a logic LOW and output 0V, destroying your analog data. Always use an analog switch/MUX (like the CD4051B or 74HC4067) for continuous voltage signals.
Do I need pull-down resistors on the MUX select pins?
Yes, it is highly recommended. When a microcontroller like the ESP32 or Arduino boots up, its GPIO pins are in a high-impedance (floating) state for a few milliseconds before the firmware initializes them. During this boot window, floating select pins will cause the MUX to rapidly and randomly switch channels, potentially connecting a high-voltage input to your sensitive ADC pin. 10kΩ pull-down resistors on the select pins force the MUX to default to Channel 0 during boot.
Does a MUX consume a lot of power?
Static power consumption is negligible (usually in the microamp range for CMOS chips like the 74HC series). However, dynamic power consumption spikes during switching due to the brief 'shoot-through' current when internal MOSFETs transition. If you are switching channels at high frequencies (e.g., audio sampling rates), factor in the switching losses.






