Hi! Hope you're enjoying this blog. I have a new home at www.goldsborough.me. Be sure to also check by there for new posts <3

Sunday, October 6, 2013

Arduino and Multiplexing

So you have, say, 7 or more potentiometers but your Arduino only has 6 analog inputs. Now what? Well, you're screwed .. or not? Welcome to multiplexing. A multiplexer, or simply mux, is a small electronic device that converts multiple analog or digital signals into a binary sequence and then sends this value to only one, common, pin.

There are a couple of different multiplexers around, some are better for digital signals, some for analog, some for input (potentiometers), some for output (leds), nevertheless, the principle is the same for all of these. I will be using the M74HC4051B1 (no I did not headbang my keyboard).

Firstly, if you do not understand binary, have a look at this explanation. Next, let me explain what a mux actually does. Let's assume you have an 8 channel multiplexer, meaning you can hook up 8 different analog signals to your multiplexer. Instead of having to read each signal individually, we can send a number, in binary, to the multiplexer over 3 digital pins (3 bit binary number, depending on the high/low state of these three pins), then, the multiplexer will redirect the signals it gets from the potentiometer we want to the common pin, where we can finally read it.

Say we want to read channel 5 of our mux, given three digital pins p1, p2, p3. We would set p1 high, p2 low and p3 high, so the mux would read HIGH, LOW, HIGH - or 101, which is 5 in binary. Then it will direct the signal from channel 5 to our common analog pin.

 Here the schematic of a mux:


y = individual channels
z = common output/input pin
E = enable (connected to ground)
Vee = negative voltage (connected to ground)
Gnd = Ground 0V
s0, s1 and s2 = digital pins that send the bits


I will be using only two potentiometers, just to keep it simple. Connect it up, Scotty!

How to connect the mux:



You see, the analog output pins are connected to channel 5 and 7 (y5 and y7 in the above schem.), these are then replaced by the single output from the mux (cyan cable), connected to the Arduino's A0 analog input pin, and three digital pins for the three bits.

Here is what it looked like when I did it with only one pot:



Right. Assuming you connected everything properly, let's move on to the code. It is partly taken from an Arduino playground post, although modified quite a bit.


int r0 = 0;      
int r1 = 0;  // the three digital pins for the bits     
int r2 = 0;         

int  bin [] = {000, 1, 10, 11, 100, 101, 110, 111};//list of binary values

void setup(){

  pinMode(2, OUTPUT);    // r0
  pinMode(3, OUTPUT);    // r1
  pinMode(4, OUTPUT);    // r2

  Serial.begin(9600); // fire up the serial 
}

 
void loop () {
  
 for (int count=0; count < 8; count++) { //loop through each channel, checking for a signal
   
   int row = bin[count]; //channel 5 = 5th element in the bin list -> 101 etc. 
   
   r0 = bitRead(row,0); //bitRead() -> parameter 1 = binary sequence, parameter 2 = which bit to read, starting from the right most bit
   r1 = bitRead(row,1); //channel 7 = 111, 1 = 2nd bit 
   r2 = bitRead(row,2); // third bit

   digitalWrite(2, r0); // send the bits to the digital pins 
   digitalWrite(3, r1);
   digitalWrite(4, r2);
      
   Serial.print(count);
   Serial.print(" ==== ");
   Serial.println(analogRead(0)); // after sending the binary sequence, the mux determines which channel to read from and sends it to this analog input

   delay (1000); // time to read the values
   
 }

 } 


I hope the comments help you figuring out what does what. Once you upload your code, open the serial monitor. You'll notice that despite only connecting 2 (or how many connected) signals to the mux, the other channels are spewing out arbitrary values. This is because they are not connected to anything and thus float. Nevertheless, the values for the channels you connected should change depending on the state of your potentiometer.

I hope I cleared things up a bit. I wrote this tutorial because I had quite a hard time pulling together the information from the various sources there are online when I first used multiplexers. It's not so difficult once you grasp the concept of the three bits being sent over the three digital pins to let the analog pin know which channel to read from, and what the different pins do. If you do have any problems, or I made a mistake somewhere, or you disagree with some of my explanations (I'm only learning this stuff myself), feel free to comment.

3 comments :

  1. Hey, thanks for the tutorial! This is super helpful. Could you please clarify a bit more on why the other channels are spewing out arbitrary values when they are not connected to anything? I'm testing this with two accelerometers and the values does not seem to be changing, do you have any advice?

    ReplyDelete
  2. Hi friend,
    can you help me to wright programm of taking mean of 4 pot values??

    ReplyDelete
  3. For everyone seeing this guide today - the code does not work correctly! The bin array has to be
    int bin [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    The command bitRead reads the number in its binary form. So a number like 1000 doesn't represent 8. It's read as 1111101000.

    ReplyDelete