CD74HC4067 16-Channel Analog Multiplexer – Complete Guide

The CD74HC4067 16-channel analog multiplexer module solves the opposite problem of an I/O expander: instead of adding digital pins, it lets you read 16 analog signals through a single ADC pin. The module is based on the CD74HC4067 from Texas Instruments and is one of the cheapest and simplest ways to connect a whole array of sensors, potentiometers or buttons to a compact board like the ESP32-C6 SUPER MINI.

In this complete guide we cover:

  • What the CD74HC4067 is
  • Technical specifications
  • Pinout
  • Channel selection – truth table for all 16 channels
  • ESP32-C6 SUPER MINI wiring
  • How the multiplexer actually works
  • ESP-IDF example code
  • Using it as a demultiplexer (output mode)
  • CD74HC4067 vs 74HC4051 vs ADS1115 comparison
  • Practical engineering tips

What is the CD74HC4067?

The CD74HC4067 is a 16-channel analog multiplexer/demultiplexer. Think of it as a 16-position rotary switch controlled by 4 digital pins: the binary value on the select pins S0–S3 determines which of the 16 channels (C0–C15) is connected to the common signal pin (SIG).

Key properties:

  • 16 channels, selected with just 4 GPIO pins
  • Bidirectional — works as multiplexer (16→1) and demultiplexer (1→16)
  • Passes analog and digital signals
  • True analog switch: whatever voltage is on the channel appears on SIG
  • Break-before-make switching (channels never short together)
  • Enable pin (EN) to disconnect all channels

Because the chip is a passive switch, it doesn’t “convert” anything — your ESP32 ADC does the actual measurement. That keeps the module dirt cheap while giving you 16 analog inputs on a board that only has a handful of ADC pins.

Technical Specifications

ParameterValue
Channels16 (C0 – C15)
Select pins4 (S0 – S3)
Signal typeAnalog and digital, bidirectional
Supply voltage2V – 6V
Signal voltage range0V to VCC
ON-resistance≈ 70 Ω (typ. @ 4.5V), higher at 3.3V
Max channel current25 mA (absolute max — stay well below)
SwitchingBreak-before-make
Switch-on time< 1 µs
Standby current< 1 µA
Operating temperature-55°C to +125°C

⚠️ The signal voltage must stay between GND and VCC. Negative voltages or signals above the supply will damage the chip. When powered from 3.3V, never feed a 5V sensor signal into a channel.

Pinout

The common breakout board exposes the following pins:

PinDescription
VCCSupply (3.3V with ESP32)
GNDGround
SIGCommon signal pin (to ESP32 ADC)
S0Channel select bit 0 (LSB)
S1Channel select bit 1
S2Channel select bit 2
S3Channel select bit 3 (MSB)
ENEnable, active low — LOW = enabled
C0 – C15The 16 channel pins

Most breakout boards already pull EN to GND on the PCB, so the module is enabled by default. If you want to disable all channels (high-impedance state), drive EN HIGH from a GPIO.

Channel Selection – Truth Table

The channel is simply the binary value of S3·S2·S1·S0. This table covers all 16 channels and doubles as your reference during wiring and debugging:

ChannelS3S2S1S0Selected Pin
00000C0
10001C1
20010C2
30011C3
40100C4
50101C5
60110C6
70111C7
81000C8
91001C9
101010C10
111011C11
121100C12
131101C13
141110C14
151111C15

With EN = HIGH, no channel is connected regardless of S0–S3.

Connecting to the ESP32-C6 SUPER MINI

Six wires are all you need:

CD74HC4067 ModuleESP32-C6 SUPER MINIFunction
VCC3V3Power
GNDGNDGround
SIGGPIO2 (ADC1_CH2)Analog input
S0GPIO18Select bit 0
S1GPIO19Select bit 1
S2GPIO20Select bit 2
S3GPIO21Select bit 3
ENGND (or free GPIO)Enable

Notes:

  • On the ESP32-C6, the ADC (ADC1) is available on GPIO0 – GPIO6. SIG must go to one of these pins — GPIO2 is a safe choice on the SUPER MINI.
  • S0–S3 are plain digital outputs, so any free GPIO works. GPIO18–21 keeps the ADC pins free for other sensors.
  • Avoid GPIO8 (onboard RGB LED) and GPIO9 (BOOT button).

How It Works

Reading 16 sensors becomes a simple loop:

  1. Write the channel number (0–15) to S0–S3
  2. Wait a few microseconds for the switch to settle
  3. Read the ADC on SIG
  4. Repeat for the next channel

The switch itself settles in under a microsecond, but the RC combination of the ~70 Ω ON-resistance, your wiring and the ESP32 ADC sampling capacitor needs a short settling delay — especially with high-impedance sources. A 10–50 µs delay after switching is a safe rule of thumb.

ESP-IDF Example Code

The example below scans all 16 channels once per second and prints the raw ADC values and voltages:

c

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_log.h"
#include "rom/ets_sys.h"

#define MUX_S0        GPIO_NUM_18
#define MUX_S1        GPIO_NUM_19
#define MUX_S2        GPIO_NUM_20
#define MUX_S3        GPIO_NUM_21
#define MUX_SIG_ADC   ADC_CHANNEL_2   /* GPIO2 = ADC1_CH2 */

static const char *TAG = "CD74HC4067";
static adc_oneshot_unit_handle_t adc_handle;
static adc_cali_handle_t cali_handle;

static void mux_select(uint8_t channel)
{
    gpio_set_level(MUX_S0, (channel >> 0) & 1);
    gpio_set_level(MUX_S1, (channel >> 1) & 1);
    gpio_set_level(MUX_S2, (channel >> 2) & 1);
    gpio_set_level(MUX_S3, (channel >> 3) & 1);
    ets_delay_us(50);   /* settling time */
}

void app_main(void)
{
    /* Select pins as outputs */
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << MUX_S0) | (1ULL << MUX_S1) |
                        (1ULL << MUX_S2) | (1ULL << MUX_S3),
        .mode = GPIO_MODE_OUTPUT,
    };
    ESP_ERROR_CHECK(gpio_config(&io_conf));

    /* ADC oneshot unit */
    adc_oneshot_unit_init_cfg_t unit_cfg = {
        .unit_id = ADC_UNIT_1,
    };
    ESP_ERROR_CHECK(adc_oneshot_new_unit(&unit_cfg, &adc_handle));

    adc_oneshot_chan_cfg_t chan_cfg = {
        .atten = ADC_ATTEN_DB_12,        /* full 0 – 3.3V range */
        .bitwidth = ADC_BITWIDTH_12,
    };
    ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle, MUX_SIG_ADC, &chan_cfg));

    /* Calibration (curve fitting on ESP32-C6) */
    adc_cali_curve_fitting_config_t cali_cfg = {
        .unit_id = ADC_UNIT_1,
        .atten = ADC_ATTEN_DB_12,
        .bitwidth = ADC_BITWIDTH_12,
    };
    ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&cali_cfg, &cali_handle));

    while (1) {
        for (uint8_t ch = 0; ch < 16; ch++) {
            mux_select(ch);

            int raw, mv;
            ESP_ERROR_CHECK(adc_oneshot_read(adc_handle, MUX_SIG_ADC, &raw));
            ESP_ERROR_CHECK(adc_cali_raw_to_voltage(cali_handle, raw, &mv));

            ESP_LOGI(TAG, "C%-2d  raw: %4d  voltage: %4d mV", ch, raw, mv);
        }
        printf("\n");
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

No library, no protocol, no addresses — the CD74HC4067 is controlled with nothing more than four GPIO writes.

Prefer Arduino?

cpp

const int S0 = 18, S1 = 19, S2 = 20, S3 = 21;
const int SIG = 2;

void muxSelect(uint8_t ch) {
  digitalWrite(S0, ch & 1);
  digitalWrite(S1, (ch >> 1) & 1);
  digitalWrite(S2, (ch >> 2) & 1);
  digitalWrite(S3, (ch >> 3) & 1);
  delayMicroseconds(50);
}

void setup() {
  Serial.begin(115200);
  for (int p : {S0, S1, S2, S3}) pinMode(p, OUTPUT);
}

void loop() {
  for (uint8_t ch = 0; ch < 16; ch++) {
    muxSelect(ch);
    Serial.printf("C%d: %d\n", ch, analogRead(SIG));
  }
  delay(1000);
}

Using It as a Demultiplexer (Output Mode)

Because the switch is bidirectional, you can also drive the SIG pin and route that signal to one of the 16 channels — for example to fire 16 LEDs or trigger inputs one at a time.

Keep in mind:

  • Only one channel at a time is connected — this is time-multiplexing, not 16 simultaneous outputs
  • The ~70 Ω ON-resistance sits in series with your load
  • Stay far below the 25 mA absolute maximum channel current

For 16 real, simultaneous outputs, an MCP23017 I/O expander is the better tool — the two modules complement each other perfectly.

CD74HC4067 vs 74HC4051 vs ADS1115

FeatureCD74HC406774HC4051ADS1115
Channels1684
Interface4 GPIO + 1 ADC3 GPIO + 1 ADCI²C
ADC usedESP32 internal (12-bit)ESP32 internal (12-bit)Internal 16-bit
AccuracyESP32 ADC (moderate)ESP32 ADC (moderate)High (PGA, differential)
SpeedVery fast switchingVery fast switchingMax 860 SPS
BidirectionalYesYesNo (input only)
PriceVery lowVery lowHigher

When to Choose the CD74HC4067

  • Many analog sources (potentiometers, LDRs, moisture sensors)
  • Moderate accuracy is fine
  • Speed matters
  • Minimal cost per channel

When to Choose the ADS1115

  • High accuracy or small signals (load cells, precise voltages)
  • Differential measurements
  • You want to bypass the ESP32’s non-linear ADC entirely

Pro tip: combine them — an ADS1115 behind a CD74HC4067 gives you 16 channels of 16-bit precision.

Practical Engineering Tips

1. Give the Signal Time to Settle

Always wait 10–50 µs after changing S0–S3 before reading the ADC. With high-impedance sensors (> 100 kΩ), wait longer or add a small buffer (voltage follower op-amp).

2. Don’t Ignore the ON-Resistance

The ~70 Ω in series is irrelevant for an ADC measurement (high input impedance), but matters when sourcing current. Never use the mux for anything power-related.

3. Tie Unused Channels to GND

Floating channel pins can couple noise into your readings. Ground the channels you don’t use.

4. Discharge Ghost Voltages

The ADC sample capacitor retains charge from the previous channel. If you see readings “bleeding” from one channel into the next, read the ADC twice and discard the first sample.

5. Know the ESP32 ADC’s Limits

The ESP32-C6 ADC is non-linear near 0V and VCC. Use the ESP-IDF calibration API (as in the example) and avoid measuring signals in the extreme corners of the range when accuracy matters.

Conclusion

The CD74HC4067 16-channel analog multiplexer is the perfect companion for pin-limited boards like the ESP32-C6 SUPER MINI. For less than a euro it turns one ADC pin into sixteen.

It offers:

  • 16 analog or digital channels through 5 pins total
  • Bidirectional operation — mux and demux
  • No protocol, no library, no configuration
  • Near-zero power consumption
  • Seamless pairing with the MCP23017 for digital I/O

If your project has more sensors than pins, the CD74HC4067 should be the first module you reach for.

error: Content is protected !!
Scroll to Top