Cd4051 Multiplexer Tutorial Is Here!

I have seen community members getting a multiplexer to work Patch SM (here and also here with some modifications to libDaisy and etc), but we should offer a simple example code in the DaisyExamples when we get a chance in the future.

All CMOS chips must have a decoupling capacitor across the power pins.
This is even more needed when using a breadboard, and especially using high speed digital MCU along with CMOS on a breadboard.

If anyone couldn’t get this to work, try it again with a 100nF capacitor going from pin VDD to VSS.

Radiated-emissions-measurements

From the datasheet

Each VCC terminal should have a good bypass capacitor to prevent power disturbance. For devices with a single supply, a 0.1-μF bypass capacitor is recommended.

It is acceptable to parallel multiple bypass capacitors to reject different frequencies of noise. 0.1-μF and 1-μF capacitors are commonly used in parallel. The bypass capacitor should be installed as close to the power terminal as possible for best results.
CD4051 Datasheet

Hint: You can even pass audio through the cd405x chips if you use bipolar power, -5v,0v,5v is most common but anything under 20 volts is OK.

1 Like

Hey @Takumi_Ogata, this is really helpful. Was struggling to get this to work, but all makes sense now.

Is there a way to set the values of the mux pins, e.g. to set the state of 8 LEDs? Guessing there is a SetMux equivalent, but can’t seem to find anything in the documentation that references this.

Thanks again,
Luke

Not to hijack the thread but you might want to consider using a modern ADB5206 instead.
I just made a circuit with a 4051/4051 combo (filter pole switching) and i struggled with the logic level against the audio level that can pass through.
Also, after adding two TL074 just to boost daisy level of 3v3 to 10V switching level i spent 4 ICs and over 30 passives just to get that done .And it would draw an absurd amount of power…
The ADB5206/ADB52067 on the other hand switch at 3v3 and let up to 48V of signal level pass…they run totally cool and need anything but 3-4 gateout pins as well.

1 Like

Mux C++ code for Patch SM. I shared this on Discord but thought it should be here as well. I made the code a bit more readable. Credit to Takumi for original code. You do indeed need to stop the ADC at Init.

#include "daisy_patch_sm.h"
#include "daisy_seed.h"

using namespace daisy;
using namespace patch_sm;

/** Global Hardware access */
DaisyPatchSM hw;

int main(void)
{
    /** Initialize our hardware */
    hw.Init();
    hw.adc.Stop();

    /** Configure ADC channel */
    AdcChannelConfig adc_cfg;

    /** Set ADC to pin A2/ADC_9 for 8 inputs and digital pins to D1, D2, D3  */
    adc_cfg.InitMux(hw.GetPin(DaisyPatchSM::PinBank::A, 2), 8, 
    hw.GetPin(DaisyPatchSM::PinBank::D, 1), 
    hw.GetPin(DaisyPatchSM::PinBank::D, 2), 
    hw.GetPin(DaisyPatchSM::PinBank::D, 3)); 

    /** Initialize the ADC with our configuration */
    hw.adc.Init(&adc_cfg, 1);

    /** Start the ADC conversions in the background */
    hw.adc.Start();

    /** Startup the USB Serial port */
    hw.StartLog();

    while(1)
    {
        /** Print the values via Serial every 250ms 
         *  Values will be 0 when inputs are 0V, 65535 when inputs are 3v3 */
        System::Delay(250); 

        hw.Print("Input 1: %d", hw.adc.GetMux(0, 0));  hw.Print(" | ");
        hw.Print("Input 2: %d", hw.adc.GetMux(0, 1));  hw.Print(" | ");
        hw.Print("Input 3: %d", hw.adc.GetMux(0, 2));  hw.Print(" | ");
        hw.Print("Input 4: %d", hw.adc.GetMux(0, 3));  hw.Print(" | ");
        hw.Print("Input 5: %d", hw.adc.GetMux(0, 4));  hw.Print(" | ");
        hw.Print("Input 6: %d", hw.adc.GetMux(0, 5));  hw.Print(" | ");
        hw.Print("Input 7: %d", hw.adc.GetMux(0, 6));  hw.Print(" | ");
        hw.Print("Input 8: %d", hw.adc.GetMux(0, 7));  hw.PrintLine(" ")
    }
}
1 Like

Awesome! Thank you for sharing here as well :slight_smile:
Greatly appreciate your contribution to the community.

I wonder if this breaks the code that handles the CV inputs?

I’ll check. I have been wondering seeing as you mentioned CV inputs. Is it best practice to use ADC for potentiometers or CV or does it matter? Is there a particular use case for CV 5v vs ADC 3v3 for using analogue potentiometers? Of course, I understand the need for 5v control voltage input for pitch from a sequencer.

I see in the datasheet:
Potentiometer example:
CV_1 to CV_8
ADC_9 to ADC_12*
*When using ADC_9 to ADC_12, use +3V3 instead of +5V OUT

It depends on what you need. The CV inputs are a more precious resource, and bipolar isn’t needed for pots. But if you need more pots, and less CV inputs, the CV inputs are fine.

I’m thinking the MUX code is more appropriate for Seed, since Patch SM already has code which takes control of ADC and CV inputs. This doesn’t mean you can’t use a MUX with Patch SM, but it would need some code which doesn’t reconfigure the ADC 9-12 inputs.

As for the +3V3 adc limit, I told you that multiple times, and it’s in the STM32 datasheet. Of course, a real schematic would be nice.

That clears it up for me. Thanks. I think I will reserve 2 ADC channels for linear potentiometers for Envelope and VCA with Mux and use CV for exponential pots like filter and oscillator. But have yet to explore this and being able to use exponential Decay/ Sustain with linear Attack/Release (is this done digitally) and being able to switch between linear and exponential like the Intellijel Quadra. I may also explore using SPI with D8/9.

There is no need to use anything but linear pots, they can be processed digitally to get any curve you like.

Fantastic. I thought I’d need Expo for volume etc. :slight_smile: