Arduino + 4051 mux/demux + newb = HELL

All,
I am pretty lost here. I am trying to read a total of 32 analog inputs with the Arduino Decimella. I've got 5 4051 mux/demux and hoped to get 4 of them through the fifth one and down to one analog pin on my arduino.

I have seen Arduino Playground's 4051 tut and it seems to imply that 96 inputs could be used this way. I only need 32.

I am pretty sure I can get the wiring down, but the actual code eludes me. A LOT. I need help, and you guys seem pretty capable.

I am an absolute n00b, and need hand holding. :-/

Thoughts?

There is code included in the article. What specifically do you not understand?

The code presented in the article doesn't manage the hardware requirements stated - multiple mux through one mux - and only iterates through the extant inputs, numbering them.

I need to receive input from 32 pins, check the value of it and take action.

Let's face it, though. You aren't really interested in helping, otherwise you'd have done something other than troll my post. Really, what does pointing out code on a page I've talked of being confused by do? How is that helpful?

otherwise you'd have done something other than troll my post

I think you are being unfair here. It was pointed out that code was supplied and you were asked what you didn't understand.

Now it turns out that because it didn't do EXACTLY what you want it is no good. It sounds like this is some sort of assessment you have and you want someone else to do it for you. The code is there to show you the basic principals of how to talk to the multiplexer. Try and understand what it does, only then you will know what you need to do to make it do what you want.

Just stating your requirements and expecting some one to write the code is not how this board works. You will find this board is the most helpful one on the net if you ask the right questions.

Questions like:-
(post a bit of code) .... this code scans 96 channels, how can I restrict it to 32.

For 32 analog inputs you only need 4 4051's, that can be driven with 3 digital lines and 1 analog line for each of the 4051's. Theres no need to drive the 4 4051's throug a fifth 4051.

I made a system with 16 slide pots (two 4051's) this could be expanded to 4. It is based on the example from the playground with 2 4051's i basically just renamed some variables to have more meaningfull names (for me at least :slight_smile: ) and added some code to send the values out over the serial port. You can find it here:

http://mikmo.dk/misc/arduinomux.zip

Grumpy_Mike
I apologize if I have come off as unfair. I have been at this for a couple of days now and as a beginner have found the rift between not understanding and completely understanding to be pretty rough on this here Internet.

Go ahead and hit google - look for "arduino" and "4051". You get, consistently, 2 articles with actual code relevant to using the 4051. One of them is the playground and another is a gentleman pushing MIDI through the serial port and his code has comments by peers telling him how it is wrong.

There is a high price of entry, it seems, intellectually, to this hobby/artform. Just go to these very forums; there are a large number of people asking questions and getting, "why don't you just do x" and "you have to do the work yourself". This attitude doesn't engender any kind of support and, in fact, drives people away from the understanding.

Look, I've done work. I have messed with the code I've found, written my own from scratch and approached the problem from a ton of different angles. When I was finally out of options I came here, to the source, and read. I did a search for anything relevant and found 4 forum posts directly related to the 4051, 3 of which were unresolved and the final post resolved with someone changing direction. Only then did I post my own topic. And what happens? I get told that there is code I've seen a hundred times now there and asked what exactly I don't understand about it.

If I was unfair, perhaps it is because I didn't explain myself. Let me try here: I don't understand what the hell I am supposed to do to attain multiplexy. I have read the conceptual articles, the whitepapers - I understand multiplexy in theory and in physical practice. What I don't understand is how the arduino can talk directly to the 4051. I get that I am polling an analog pin, I get that the 4051 is sending values and I get that I make requests through the digital pins, but I have yet to see a code example where this is lain out with any sort of structure or comment.

I have stated clearly that I am new at this and am NOT looking for someone else to "do the work". I am absolutely looking for someone to say, "You know what? maybe I won't keep this secret gem to myself. Maybe I don't need to feel superior and it won't make me look any less impressive if I share."

MikMo
This is an excellent start. Thank you very much. I have reviewed it closely and believe that this may be the key to understanding just what the hell is going on.

The reason I wanted to concatenate 4 mux into one mux is because I have a need for more than the 2 analog pins that would be left after.

Thank you for this.

Hi skinnytie,

"You know what? maybe I won't keep this secret gem to myself. Maybe I don't need to feel superior and it won't make me look any less impressive if I share."

You might feel like that's what we think but nothing could be further from the truth. I have spent most of my life in education and I like sharing what I know. The problem is how to balance helping some one against doing it for them, which is no help at all. What you have to do is make a judgement and I am sorry if in your case the judgement was off.

Many, many, years ago (I was 21 then) I was on a stand at a show representing the Admiralty Underwater Weapons Establishment showing our work with active filters. I explained to one person how these filters sorted out the sound from sonar into different frequencies bands. After some time he asked "What is frequency", I had to stop short and change my tack. The very next visitor to the stand I said in my opening remark "you do know what frequency means", he looked daggers at me and said "I am professor of Electronics at Imperial Collage". Which goes to prove you can't get it right all the time.

I am not sure if you are still unsure about these things but:-

how the arduino can talk directly to the 4051

The 4051 has three digital input select lines these should be wired to digital pins on the Arduino and the pins set to be outputs. Then the combination of high and low levels on these pins determine which one of the 8 input pins (Y0 to Y7) is connected through to the Z pin. Connect this Z pin to an analogue input and use this to measure what ever is on the Y inputs.
If all the select lines are low then input Y0 is chosen. If then S0 is high (with S1 & S2 low) Y1 is chosen and so on in a binary fashion. That means S2 contributes 4 to the number on Y0, with S1 contributing 2 and S0 contributing 1.

I hope that clears some things up.

hello
i read several threads and the /learning/4051 thing and cant figure out what the deal is.

i got 16 analog sensors and 16 pwm-leds (one sensor for each led)

from what i understood i need 2 4051's for the input and 2 for the output.

but:
can someone tell me(send a link/ post a code with pictures and lots of comments) how to connect everything and how to write code that it fits for my setting?

im newbie in electric circuitry and programming.
a dont fully understand the symbols in the pix from the zip-file.
please help!
greets uisel.

i read several threads and the /learning/4051 thing and cant figure out what the deal is.

This is a sign that you need a simpler project... I'm not trying to be "mean". You need to build upon prior success or you have less of a chance to understand "what the deal is".

Please locate and read the CD4051 data sheet. Like maybe here: Texas Instruments 109150, DS datasheet pdf

It has bi-directional analog pins and a "common" pin. Think of it like a 7 position rotary switch. At any one time... one of the 0-7 pins is connected to "common" pin. You select it with a binary "input" to the 3 selector pins. Hopefully, this is not what is confusing you... if it is... you need to spend more time learning binary logic.

got 16 analog sensors and 16 pwm-leds (one sensor for each led)

What kind of sensors? PWM LEDS?

Let me see if I can understand...

So you want to cycle through 16 LEDs (note: one at a time... ) controlling brightness with PWM and also sense which LED is lit?

See... we can't help you understand... if it's not clear to us what you are doing.

(I am going to try this again, adobe acrobat stuck a update in on me and in the nag storm I clicked OK to reboot my computer... yea, anyway)

as pwillard stated a multiplexer is similar to a rotary switch, in the 4051 you have a 8:1 ratio, meaning 8 in/outs can be connected to another single in/out one at a time

I reference you to this image on Wikipedia

the 4051 is mostly refered to as a multiplexer, but it can perform both multiplexing and demultiplexing, and in what you described you would need both so its a good choice

now lets check out the data sheet (using Texas Instruments)

Go down to the second page and look at the pinout diagram for the 4051 (the others are variations in the family) on the right of the chip you will see I/O 0-3, on the left 4-7 (0-7 = 8, zero is a value) and one pin for common

Also on the right of the chip are 3 pins marked A, B, and C, these are your binary inputs, a combination of these three pins at a high (+V, 5 volts with most arduinos) or low (grounded) state selects which of the 8 I/O's are connected to the 1 common I/O

What is the combination??

Go down to page 4 of the datasheet, you will see a truth table, containing pins "inhibit" which you can ignore for now, and C, B, A

if C, B and A are all connected to ground (low) then we see that channel 0 is connected to the common pin

if C & B are low, but A is high (+V) then channel 1 is connected to the common pin

and so on until you reach 7

I think that's enough basic idea dump for now, but feel free to ask away

I don't think the first mux (note: I am going to use the term "mux" for "multiplexer" - its easier to write) is where he is stuck at - he's trying to connect up the other 4 mux's thru the singular mux.

What you're going to need to do is this; for what I am going to call the "primary" mux, you only need to hook up 2 of the 3 selector pins (because you are only going to hook up to that mux the other 4 mux's - and 2 ^ 2 = 4); so, the primary mux's output goes into the analog Arduino pin; this much I think (?) you understand. You also (?) I think understand that you need to connect up 2 digital pins to that first mux; in order to select one of the four first input lines, ok?

Now, for each of the four remaining mux's (which I will refer to as "secondary" as needed), in order to select one of the pins, you are going to need 3 digital lines on the Arduino, for a total of 12 lines. The Z output of each of these secondary mux's will go into one of the first four inputs of the "primary" mux; the selector pins pin of each secondary mux go to 3 other digital lines on the Arduino (for 12 other digital pins).

So - you have a total of 16 digital pins (2 pins for the primary mux, and 3 pins each for the 4 secondary mux's) involved, plus one analog input pin.

Do you see your problem, yet? You will...

All you have to do in order to select one of the analog lines from the mux's, is write code to:

  1. The analog input pin you want is on one of the secondary mux's, so for that mux, set its selector pins to the binary value for the input pin on the mux (decimal 0-7).

  2. On the primary mux, set its two selector lines to the value (decimal 0-3) for the secondary mux you are needing to measure.

  3. Read the value with analogRead().

  4. For another pin/sensor, repeat these steps as needed (in fact, stick your code into a function that decodes your number of 0-31 into the proper mux combo selection, so you can do "int x = myMuxAnalogRead(?);" to get the value, where "?" is an integer byte value of 0-31 decimal.

Here's your problem:

You need 16 digital i/o pins for this control on the Arduino (2 for the primary mux, and 12 for the secondary mux's); on the standard Arduino you have 14 digital i/o pins (0-13), and 6 analog input pins. The six analog pins can be used as digital pins, if pin numbers 14-19 are used with digitalWrite(). You need one analog pin.

So - lets say you -don't- forgo using the rx/tx pins (pins 0 and 1) for USB communication; that leaves 12 pins. Let's say you assign pins (2-3 for the primary mux selector pins. Now you need 12 more pins for the remaining mux's.

Let's say these pins are used:

  1. secondary mux #1 = pins 4-6
  2. secondary mux #2 = pins 7-9
  3. secondary mux #3 = pins 10-12
  4. secondary mux #4 = pins 13-15

Leaving you with pins 16-19 as analog input pins; one of which you need, leaving you with three remaining analog pins. If you forgo the use of rx/tx, you will get back two more analog input pins (but you won't have any USB serial communications).

You say you need those other analog pins, though - do you have enough given what I have said above? If not, your options are:

  1. Use an Arduino Mega - more digital i/o and analog pins; worries over, you don't even have to use the extra primary mux.

  2. Attempt to find an analog multiplexer chip (other than the 4051) which has more inputs - if you can find a 1 of 16, you will only need 4 lines per chip (8 total), plus your two for the 4051, leaving plenty of digital and analog inputs left over.

  3. The cheap, but more complex solution: Use a set of latching shift registers to control the 4051s - see here:

If it were me, I would look into option 2 - while it is bound to be more expensive for such a chip, it won't be something that breaks the bank, provided you can find one (check Mouser or Digikey, or maybe someone here knows of something off the top of their head).

[edit]
Check out this - the mpc506A:

Not exactly cheap, but it will do the job - something I also noticed, and which I don't know if the 4051 has (?) - on the inputs of the mpc506a, there are current limiting resistors built into the chip; you will probably have to take these into account in your readings of your sensors.
[/edit]

Option 3 should only be considered if you don't mind the extra complexity; you being a newbie, more complexity isn't what you want, though, which is why option 2 is best. Option 3 might be something to shoot for when you have more experience and/or less change to spare for larger mux's.

I hope this helps (and I hope I haven't made any mistakes; I probably did - so please help me if I did, Arduino fans!)...

:slight_smile:

You may be able to do what you want using your 5 muxes and 6 I/O pins. Use one mux to control the other four. Connect the four mux up such that their common output goes to the analog input pin. Connect the first 3 I/O pins to the three control pins on the four mux in a parallel alignment. Wire the the second three I/O pins to the three control mux control pins. On the control mux connect four of the input lines to the inhibit pins on the four other muxes, and tie the common output to ground. On the four other muxes make the inhibit pins high using very high resistance resistors. Now in a static condition the four main muxes are inhibited. Using the control mux via the second set of three I/O lines, uninhibit the desired mux by pulling the inhibit pin low to ground on the desired mux, and then select the input pin on the selected mux using the first three I/O pins (the three other mux will still be inhibited).

zoomkat:

Can you draw up and post a schematic diagram of what you are saying? I can kinda follow the logic, but it seems like there may be a grounding issue somewhere (gut feeling - as I said, I am not following the logic completely).

In some ways, I feel your idea can work; in others, it seems like there is a bug - but it is all "just a feeling".

If it is workable - then that's a great way to do it. If it isn't; then maybe there is a small point that has to be changed to make it work - I think it is worth seeing and pursuing, at least from an idea standpoint, as it would help others in the future to create these kind of circuits for such needs.

I would love to see a schematic and understand the idea better!

:slight_smile:

This is a different chip setup, but it may show part of what I'm thinking of. The left hand side shows the paralleling of the control inputs on the chips. In this the D pin is also in parallel with all the chips. The latch enable LE is individual for each chip. In this setup the desired pin select (A0-A2) is sent to all chips, and the hi/lo select (D) is sent to all chips. The LE pin on the desired chip is clocked hi/lo to latch the pin on the desired chip to the D value (hi or lo). In the mux in question four of the chips are wired in parallel with their inhibit pins held hi with a high value resistor connected to the inhibit pin. There is a wire connected between the resistor and the inhibit pin, that when grounded, will drop the voltage on the inhibit pin low enough to uninhibit the chip and allow it to function. These grounding wires are routed to the individual inputs on the fifth mux. The common output on the fifth mux is connected to ground. Now the fifth mux can control which of the four other chips inhibit pins are connected to ground, allowing the selected mux to individually function. If this works, then four additional muxes could be added for 64 individual inputs being controlled to a single analog pin on the board. In my tinkering with the 4051 the control pins shouldn't be allowed to float, so they need to be pulled lowhen not hi.
Edit: sorry about the big pix caused scrolling.

zoomkat: Your diagram may totally confuse the original poster; I had to pull the datasheet for the part shown to see that your circuit is for a multi-device serial in to parallel output digital shift register; he is asking about a analog parallel in, single analog out multiplexer system - they aren't quite the same.

Now, you noted that - I just don't want the OP to be too confused. I am also not saying that what you are proposing won't work, but you are doing a disservice to the OP by posting a completely unrelated circuit working in the wrong direction with the wrong kind of data (digital vs analog) - eeek! :slight_smile:

Can you show what you are thinking by using the 4051? What I am wondering is how you plan on tying the analog outputs together to bring them down to a single output (which was the purpose of his 5th control 4051) - I suppose you could try to use a simple analog mixer circuit of sorts (which would introduce even more impedance to the measurement); I am not sure you can tie the 4 4051s outputs together and lead them to a singular pin or not...?

Forgive me for chucking in my tuppence worth. I really doubt you can tie analogue signals together. To achieve a 32:1 mux with 8:1 mux chips implies you need the 5th one to mux the mux's - as it were.
The problem now is addressing this lot correctly using a minimum of digital lines. I believe this minimum is 7 lines, which break down as follows.
0-2 Addr lines to each of the 4 input mux
3-4 Addr for the 5th mux which accepts input from the 1st 4
5-6 4 inhibit lines, one for each of the 4 input mux. This bit is achieved via a 74hc139 2 - 4 line decoder.

This scheme will uniquely select 1 of the 32 analogue inputs and pass it to a single Arduino analogue input.

The bit about tying the unselected inputs to ground doesn't make much sense to me I'm afraid. If they are sources, where's the need?

when you do not have a signal (pin) connected to either high or low it acts as an antenna

SO!

Depending on the alignment of the sun vs static in the air + did joe just spark a pezo based ciggerette lighter is the pin high or low

yea the arduino doesnt know either ...

so you tie a weak (current speaking) connection to high or low (pull up or down) so when the other end is disconnected there is a definite HIGH or LOW definition on the pin, not "floating"

as far as the 7 lines, you seem right (I am a bit rusty on mux puzzles atm) but on the other hand you can use like a 74xx168 and reduce that to 2 wires (serial to 8bit parallel) and still have a signal left over

Its totally dependent on will, need and what works for U

They're analogue signals. The only one of interest is the selected one.
This is the only one the Arduino can "see". What the rest are up to is of no consequence.

Here is my 2 bits worth. You could eliminate the 595 and connect the7 address lines directly to the Arduino, but this both saves
io lines and allows the clock and data lines to operate other serial peripherals. You could also use a HC164 (has no latch)

The software just needs to select the active pin on the 4051 via the A,B & C lines, choose which of the 4051 you want, clock the pattern to the HC595, latch data to output then read the A/D pin on Arduino.

Hope this gets you going.

I too am working my way up the curve and there is absolutely no substitute for perseverance and attention to detail. (thanks guys. I remain chastened)