Overview
The purpose of this project was as a test to see if the 4051 mux would be usable in audio switching. I've been designing a programmable guitar pedal switcher and used this as a test project to see if there were any fatal issues with using them for this purpose. I also had some attiny85s around and hadn't found a project for them. Being able to use two pins to control the select lines of 3 muxes was a perfect use case.In a future iteration I'll try the 4052 mux, the only reason I didn't use one this time is because I didn't have any, and I have heaps of 4051s lying around.
Bill of Materials
- Attiny85
- 3 x 4051 Multiplexers
- 2 x Momentary buttons
- 4 x Leds
- 5 x Stereo sockets
- 1 x 7805 Voltage regulator
- 2 x 10uF electrolytic capacitors
- 3 x 1k resistors
Code
The code for this is pretty basic, and self explanatory, with the attiny only using 2 inputs and 2 outputs. Each of the buttons either increments or decrements the current channel. Since the switcher only has 4 channels, only the first 2 select lines are used, with the third select line tied to ground. All 3 4051s use the same select lines.Using enum classes in this context is a bit overkill, but I've been trying to use as much c++ stuff as possible recently to get more comfortable with it.
I take advantage of the fact that the leds are powered through the common line on the multiplexer to use only one current limiting resistor for all of the leds.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
4 Channel Stereo Audio Switcher | |
Multiplexer pins connected to 3 separate muxes | |
MUX 1 = Audio left | |
MUX 2 = Audio right | |
MUX 3 = Led display | |
*/ | |
#define NUM_CHANNELS 4 | |
/* Mux select pin indexes */ | |
enum class Select | |
{ | |
A = 0, | |
B = 1 | |
}; | |
/* Button pin define indexes */ | |
enum class BtnInd | |
{ | |
INCR = 0, | |
DECR = 1 | |
}; | |
/* Pin defines */ | |
const uint8_t MUX_PINS[2] = {3, 4}; | |
const uint8_t BUTTON_PINS[2] = {0, 2}; | |
/* Channel States */ | |
uint8_t current_channel = 0; | |
uint8_t prev_channel = 0; | |
void setup() | |
{ | |
for(uint8_t i = 0; i < 2; i++) | |
{ | |
pinMode(MUX_PINS[i], OUTPUT); | |
pinMode(BUTTON_PINS[i], INPUT); | |
} | |
} | |
void loop() | |
{ | |
read_buttons(); | |
if(prev_channel != current_channel) | |
{ | |
channel_set(); | |
} | |
} | |
/* Increment or decrement current channel */ | |
void read_buttons(void) | |
{ | |
if(digitalRead(BUTTON_PINS[(uint8_t)BtnInd::INCR]) == HIGH) | |
{ | |
prev_channel = current_channel; | |
if(current_channel < (NUM_CHANNELS - 1)) | |
{ | |
current_channel++; | |
} | |
delay(250); /* debounce */ | |
} | |
if(digitalRead(BUTTON_PINS[(uint8_t)BtnInd::DECR]) == HIGH) | |
{ | |
prev_channel = current_channel; | |
if(current_channel > 0) | |
{ | |
current_channel--; | |
} | |
delay(250); /* debounce */ | |
} | |
} | |
void channel_set(void) | |
{ | |
digitalWrite(MUX_PINS[(uint8_t)SELECT::A], (current_channel & (0x1 << 0))); | |
digitalWrite(MUX_PINS[(uint8_t)SELECT::B], (current_channel & (0x1 << 1))); | |
} |