Cd4051 Multiplexer Tutorial Is Here!

would be so cool if someone could make a detailed guide on how to achieve this with oopsy and a json. i know there is stuff on here, but i just couldn’t figure it out. anyone here who can shed a new light. i really want to make a eurorack module with around 14 pots, 4 cv inputs and 2 cv outputs. so im in dire need of a multiplexer for those pots

What does your json and patch look like and the issue that you encountered?

Btw, we are thinking about making a blog post version of this tutorial, so I will see if we can fit in sections for Pure Data and Oopsy.

1 Like

This is what my json looks like right now and how i am trying to expand the pots from knob4 onwards using the code above used for oopsy. do you see any mistakes? this should work in theory right?

{
    "name":"hookedeman",
    "som": "seed",
    "defines": {
        "OOPSY_TARGET_HAS_OLED": 1,
        "OOPSY_HAS_ENCODER": 1
    },
    "max_apps": 8,
    "display": {
        "driver": "daisy::SSD130xI2c64x32Driver", 
        "dim": [64, 32]
    },
    "audio": {
    "channels": 2
},
"parents":
  "pot_mux": {
    "component": "CD4051",
    "mux_count": 8, // the number of pots connected
    "pin": {
      "adc": 28,  // the ADC input pin
      "sel0": 4, // The SEL0 digital output pin
      "sel1": 5, // The SEL1 digital output pin
      "sel2": 6  // The SEL2 digital output pin
    }
  },
"components": {
        "cv1": {
            "component": "AnalogControl",
            "pin": 18,
            "flip": true
        },
        "cv2": {
            "component": "AnalogControl",
            "pin": 19,
            "flip": true
        },
        "cv3": {
            "component": "AnalogControl",
            "pin": 20,
            "flip": true
        },
        "cv4": {
            "component": "AnalogControl",
            "pin": 21,
            "flip": true
        },
        "knob1": {
            "component": "AnalogControl",
            "pin": 16,
            "flip": true
        },
        "knob2": {
            "component": "AnalogControl",
            "pin": 15,
            "flip": true
        },
        "knob3": {
            "component": "AnalogControl",
            "pin": 17,
            "flip": true
        },
        "knob4": {
            "component": "CD4051AnalogControl",
            "index": 0, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob5": {
            "component": "CD4051AnalogControl",
            "index": 1, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob6": {
            "component": "CD4051AnalogControl",
            "index": 2, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob7": {
            "component": "CD4051AnalogControl",
            "index": 3, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob8": {
            "component": "CD4051AnalogControl",
            "index": 4, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob9": {
            "component": "CD4051AnalogControl",
            "index": 5, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob10": {
            "component": "CD4051AnalogControl",
            "index": 6, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "knob11": {
            "component": "CD4051AnalogControl",
            "index": 7, // which analog input pin on the CD4051 to read
            "parent": "pot_mux",
            "flip": true
        },
        "encoder": {
            "component": "Encoder",
            "pin": {"a":26, "b":25, "click":24 },
            "meta": [
                "menu_hold = ${name}.TimeHeldMs();",
                "menu_click = ${name}.FallingEdge();",
                "menu_rotate = ${name}.Increment();"
            ]
        },
        "sw1": {
            "component": "Switch",
            "pin": 9
        },
        "sw2": {
            "component": "Switch",
            "pin": 8
        },
        "led1": {
            "component": "Led",
            "pin": 7
        },
        "led2": {
            "component": "Led",
            "pin": 10
        },
        "led3": {
            "component": "Led",
            "pin": 0
        },
        "led4": {
            "component": "Led",
            "pin": 1
        },
        "led5": {
            "component": "Led",
            "pin": 2
        },
        "led6": {
            "component": "Led",
            "pin": 3
        },
        "cvout": {
            "component": "CVOuts"
          }
    },
    "aliases": {
        "gate": "gatein1",
        "gate1": "gatein1",
        "gate2": "gatein2",
        "encswitch": "encoder_rise",
        "enp": "encoder_press",
        "press": "encoder_press",
        "knob": "knob1",
        "ctrl": "knob1",
        "ctrl1": "knob1",
        "ctrl2": "knob2",
        "ctrl3": "knob3",
        "ctrl4": "knob4"
    }
}

Do note that json doesn’t officially support adding comments. It may depend on the parser if this works or not (most parsers do not like this).

I recently troubleshot this with another community member over here.

What led to the mux working with Oopsy there was connecting the mux to the Seed the same way as it is with the Field. Then, the Field template patch was compiled and flashed with Field as the selected board. This is so that we have as little variable as possible for troubleshooting. You’ll need to modify the gen~ patch a bit.

This is great! Thanks @Takumi_Ogata !!
(Sorry had accidentally put this into the wrong thread when I posted it.)

I’m using a TI CD74HC4067SM96 with 16 channels. I can query the first 8 channels the same way you describe.
I was digging through the forum but couldn’t find a 16 channel version. I guess I’d ‘just’ need to rewrite adc.h/.cpp to allow for 4 pins/16 channels? Or is there a simpler way? Anything to look out for?

Any help would be appreciated.

I think I figured it out. I attached the code that works for me… both for 8 and 16 channels.
Disclaimer: I wouldn’t fully trust myself with this if I didn’t have to. :slight_smile:

Maybe @Takumi_Ogata could have a quick look and advise if this could mess something else up that I’m not aware of.

adc.zip (6.2 KB)

2 Likes

I have a quick question. Can one set up a MUX to read digital inputs without having to set it up to read a voltage? I understand that you can use a MUX connected to an analog input to read switches that are set up like voltage dividers, but it would be simpler if you could just read them directly. Thanks the help!

Yes, you can, for instance, use a mux to read buttons, switches.

Excellent! I’ll have to give it a try in that case

Just for reference, what would the json file look like? ie. What would I read from the mux instead of “adc”?

I don’t use anything which uses the json file, I only use the libDaisy and DaisyDuino C++ stuff. So, I don’t know if the json2daisy code has anything explicitly for using a 4051 with switches.

BUT, if there is no direct json support for switches on a MUX, you can still just view a switch as a pot that only has two states - way up, and way down.

Thanks for the quick response. Yes, I’ve actually been just reading the switches as pots using a pullup resistor. I was just wondering if there was a better way to do it so I don’t have to solder a bunch of resistors to make a keyboard for a synth. Haha

Does it really need more than one pullup resistor?

I meant that there would be a pullup resistor for each button used as a key for a keyboard. Is that not necessary?

CD4051 is a bidirectional switch, I think one pullup on the Daisy side should work, easy for you to test it.

Excellent! I’ll give it a try