Cleaner code for 17 mux on a mega to read 256 analog signals

I have 16 cd74hc4067 multiplexors, conected on an arduino mega and each common pin of them goes through a 17th cd74hc4067 that connects to the mega as well. ofcourse i have used all available pins on the board to do so ( digital and analoge ) i only have A15 left unconnected. A0 will read all of them.

so i am using this code :slightly_smiling_face:

/*
 * Controlling and looping through a CD74HC4067's channel outputs
 *
 *
 * Connect the four control pins to any unused digital or analog pins.
 * This example uses digital pins 
 *0, 1, 2, and 3 for mux1.
 *4, 5, 6 and 7 for mux2.
 *8, 9, 10 and 11 for mux3.
 *...............................................
 *52, 53, A1 and A2 for mux14.
 *A3, A4, A5 and A6 for mux15.
 *A7, A8, A9 and A10 for mux16.
 *A11, A12, A13 and A14 for mux17.
* Connect the common pin to any other available pin. This is the pin that will be
 * shared between the 16 channels of the CD74HC4067. The 16 channels will inherit the
 * capabilities of the common pin. For example, if it's connected to an analog pin,
 * you will be able to use analogRead on each of the 16 channels.
 *
*/

#include <CD74HC4067.h>

               // s0 s1 s2 s3
CD74HC4067 mux1(0, 1, 2, 3);  // create a new CD74HC4067 object with its four control pins
CD74HC4067 mux2(4, 5, 6, 7);  // create a new CD74HC4067 object with its four control pins
CD74HC4067 mux3(8, 9, 10, 11);  // create a new CD74HC4067 object with its four control pins
.......................................................................................................................................................................
CD74HC4067 mux14(52, 53, A1, A2);  // create a new CD74HC4067 object with its four control pins
CD74HC4067 mux15(A3, A4, A5, A6);  // create a new CD74HC4067 object with its four control pins
CD74HC4067 mux16(A7, A8, A9, A10);  // create a new CD74HC4067 object with its four control pins
CD74HC4067 mux17(A11, A12, A13, A14);  // create a new CD74HC4067 object with its four control pins

const int g_common_pin = A0; // select a pin to share with the 16 channels of the CD74HC4067

void setup()
{
    pinMode(g_common_pin, INPUT); // set the initial mode of the common pin.
	                               // This can be changed in loop() for for each channel.
}

void loop()
{
 for (int x =0; x < 16; x++){
    for (int i = 0; i < 16; i++) {
        mux(x).channel(i);
        mux17.channel(x);
        analogRead(g_common_pin);
    }
}
}

will this mux(x).channel(i); work ? while the mux1 … mux17
any suggestion to a cleaner code for my project ?

You seem to use a lot of pins for addressing the parts.
I would drive the address lines in parallel to the 16 devices, and then use the enable line to select which one is feeding into A0 and delete the 17th entirely.
That drops you from 64 lines down to 4 address lines + 16 enable lines = 20 and frees up 44 pins.


setup() is missing pinMode statements to set the address pins to OUTPUT.

Then have your loop within a loop, with an array for the pins used

byte enablePin[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,};

Have 4 pins from a port as the address lines, say PORTL, D49 to D46, PORTL:0 to PORTL:3.
And an array to store the data, int analogArray[256]

for (enable = 0; enable <16 enable = enable+1){
digitalWrite (enablePin[enable], LOW);  // to the enable pin of the 4067s
  for (addressLines = 0; addressLines <16; addressLines = addressLines+1){
  PORTL = addressLines; // to Add0 to Add3 of the 4067s  
  analogArray[PORTL +(enable * 16)] = analogRead(0); // 0 to 15 +0, 0 to 15 + 16, 0 to 15 +32, etc.
  analogArray[PORTL +(enable * 16)] = analogRead(0); // read twice so the data can settle
   } 
digitalWrite (enablePin[enable], HIGH); 
}

so that could be done with an UNO ? If i used the analog in as digital ports, i have the ports needed. Right ?

Well,
Uno has 20 IO, and you need 21.
'1284P board with 32 IO would do it. Also 16K of SRAM for storing the captured data.
I offer a couple of boards, or you can gin up your own with an FTDI Basis for USB/Serial, 4 0.1uF caps, two 22pF caps, 16 or 20 MHz crystal, and 10K resistor.
Add Mightycore to your IDE

Board examples, more are on my website www.crossroadsfencing.com

Well, of course you could do it with a UNO anyway because your 17th 74HC4067 already selects which of the other multiplexers you use, so all the others can be permanently enabled.

That’s four address pins for all the first line selectors, another four for the second line selector, and the analog input pin. Totals nine, not 21!

What you do with all that data is another matter. :grin:

Also depends what going thru 2 muxes does to the signal.

Probably of much less concern than having the analog signal connected to the commons of all 16 multiplexers! :crazy_face:

The “on” resistance of the 74HC4067 is 60 Ohms - pretty negligible compared to the ADC input impedance. Shunt capacitance of the wiring may be more of a concern.

OP seems to use a Mega, with 16 A/D inputs, so no need to use a 17th multiplexer.
Just connect the outputs of the 16 74HC4067 to 16 different analogue input.
Then you only need to change the addresses with 4 lines (no enable).
Leo…

With all the free up pins by driving the 4067s in parallel, that would be another possibility.

I’m seeing higher, 120 ohm as the lowest Maximum resistance, with 60 being a typical resistance at 25C (have to read the datasheet to see that).
Wiring capacitance might be more concern as you indicated; there’s also additional input capacitance of each device the signal sees.
I haven’t tried running analog signals thru 2 devices and then into an '328P or 2560.

I was of course, taking the “typical” value. :sunglasses: Far better than the “original” CD4067.

Again, I was abbreviating.

No problem. I think we experienced folks know those things, but perhaps not the newer posters. Good to point out the benefits/flaws of different approaches for them.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.