Sixteen analog inputs on one pin with a CD74HC4067
Intermediate
Or see every lesson.
- 455parts on the bench
- 43boards running now
- 1.00xreal time, on every board
An Uno has six analog inputs. A CD74HC4067 multiplexer turns one of them into sixteen. It is sixteen electronic switches with one common pin, and four address lines pick which switch is closed, so the Arduino reads one channel at a time, very quickly, and gets them all. It is how MIDI controllers read a row of knobs.
The circuit above is an Uno with a CD74HC4067 reading three potentiometers on channels 0, 5 and 15, all through A0. Turn a knob and its number changes in the serial monitor. A second circuit further down does the same with the smaller 74HC4051, which has eight channels.
What you need
- An Arduino Uno
- A CD74HC4067 breakout board
- Three 10k potentiometers
- A half-size breadboard and jumper wires
Wiring
| Part and pin | Goes to | Note |
|---|---|---|
| Mux S0, S1, S2, S3 | Pins 2, 3, 4, 5 | The channel address, S0 the lowest bit |
| Mux COM (SIG) | A0 | The one analog pin |
| Mux EN | GND | Active low: tied low, the chip is on |
| Mux VCC and GND | 5 V and GND | |
| Pot wipers | Channels 0, 5 and 15 | Outer legs across 5 V and GND |
A switch, picked by number
Put a number from 0 to 15 on the four address lines, in binary, and that channel is joined to COM. Channel 5 is 0101: S0 high, S1 low, S2 high, S3 low. Every other channel is cut off. Because it is a real switch and not a buffer, it works both ways: the same chip can read sixteen sensors or send one signal out to sixteen places in turn.
The switch has about 70 ohms of resistance when it is closed. That is tiny next to a 10k potentiometer, so the reading is the same as wiring the pot straight to A0.
The sketch, step by step
readChannel() writes each bit of the channel number to its address pin, waits 50 microseconds for the switch and the ADC’s input to settle, and calls analogRead(A0). loop() reads channels 0, 5 and 15 and prints them on one line, three times a second.
All three knobs start in the middle, so the first lines say "ch0 512 ch5 512 ch15 512". Turn the knob on channel 0 all the way down and the one on channel 15 all the way up, and the line becomes "ch0 0 ch5 512 ch15 1023".
const uint8_t ADDRESS[4] = {2, 3, 4, 5};
const uint8_t CHANNELS[3] = {0, 5, 15};
int readChannel(uint8_t channel) {
for (uint8_t bit = 0; bit < 4; bit++) {
digitalWrite(ADDRESS[bit], (channel >> bit) & 1 ? HIGH : LOW);
}
delayMicroseconds(50);
return analogRead(A0);
}
void setup() {
Serial.begin(9600);
for (uint8_t bit = 0; bit < 4; bit++) pinMode(ADDRESS[bit], OUTPUT);
Serial.println("Mux knobs: channels 0, 5 and 15");
}
void loop() {
for (uint8_t i = 0; i < 3; i++) {
Serial.print("ch");
Serial.print(CHANNELS[i]);
Serial.print(" ");
Serial.print(readChannel(CHANNELS[i]));
Serial.print(i < 2 ? " " : "\n");
}
delay(300);
}The eight-channel 74HC4051
The 74HC4051, also sold as the CD4051, is the same idea with eight channels and three address lines. Its common pin is called Z and its channels Y0 to Y7, and it has two extra pins to tie off: E, the enable, to ground, and VEE, the negative supply, to ground on an Arduino. The second circuit reads three knobs on Y0, Y1 and Y2 through A0, with S0 to S2 on pins 2 to 4, and prints "Y0 512 Y1 512 Y2 512" until you turn one.
Pick the 4051 when eight inputs are enough and you want a chip that sits straight on a breadboard; pick the 4067 breakout for sixteen.
Using a library
The CD74HC4067 library by waspinator does the bit-setting for you. CD74HC4067 mux(2, 3, 4, 5) names the four address pins, and mux.channel(5) selects a channel; then you call analogRead() on the common pin yourself. Mokxi includes it. Writing the four digitalWrite() calls yourself, as this sketch does, is just as quick and shows what the chip is doing.
Common mistakes
EN left floating. EN is active low. Tie it to ground. Wire it to 5 V in this circuit and every switch opens: A0 is left with nothing on it, so all three readings wander at random instead of following the knobs.
A loose address wire. An address line that is not a clean high or low opens every switch too. Pull the S3 wire here and every channel reads a wandering number that has nothing to do with its knob.
Reading straight after changing the address. Give the switch and the ADC a few microseconds, as the 50 microsecond wait does.
Getting the bit order backward. S0 is the lowest bit. Wire S0 to S3 the other way around and channel 1 reads channel 8.
Forgetting VEE on the 74HC4051. Tie it to ground for signals between 0 and 5 V.
Questions
How do I read 16 analog inputs on an Arduino Uno?
Use a CD74HC4067: four digital pins for the address, the common pin to one analog input, and EN to ground. Set the address, wait a few microseconds, and analogRead() the common pin, once per channel.
What is the difference between the 74HC4051 and the CD74HC4067?
The 74HC4051 has eight channels and three address lines; the CD74HC4067 has sixteen channels and four. Both are analog switches that pass signals either way.
Can a multiplexer be used for outputs?
Yes. The channel is a switch, so a signal on the common pin goes out to whichever channel is selected. Only one channel is connected at a time, so outputs are lit one after another rather than all at once.
Does a multiplexer slow down analogRead()?
Barely. Setting four pins and waiting 50 microseconds adds well under a tenth of a millisecond to each reading, so all sixteen channels still read hundreds of times a second.
Keep going
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.