I needed extra analog inputs for an arduino project and it seems a multiplexer was the way to go.. It took a little while to sift through a heap of information on using a multiplexer with the arduino, and in the end I grabbed some 4051 ICs from Jaycar..
The 4051 allows you to choose between 8 analog inputs, reading them from just on arduino analog pin. (It can also be used in reverse, adding 8 analog outputs, but I am only interested in extra inputs for the moment)
** To hook it up to the arduio make the following connections: (the arduino pins are relatively arbitrary, though they are the ones used in the example code)
pin 3 : an arduino analog pin – eg: ANALOG IN PIN 0
pin 6,7 & 8 : all go to the arduino’s ground (Gnd)
pin 9 (s0): to arduino digital pin 10
pin 10 (s1): to arduino digital pin 9
pin 11 (s2): to arduino digital pin 8
pin 16 : to arduino +5V
** The rest of the pins on the 4051 (8 of them) are for the anolog inputs, as follows:
pin 1 : anolog input 4
pin 2 : anolog input 6
pin 4 : anolog input 7
pin 5 : anolog input 5
pin 12 : anolog input 3
pin 13 : anolog input 0
pin 14 : anolog input 1
pin 15 : anolog input 2
.
** Now in the arduino code you select which of the 8 analog inputs to read through arduino pin 1 but setting s0 , s1 and s2 to either low or high.
** S0 = 1 , S1 = 2 and s2 = 4
** so to read from analog input 0 (4051 pin 13) you would set s0,s1&s2 to low (0 + 0 + 0)
** to read from analog input 1 (4051 pin 14) you would set s0 to high and s1&s2 to low (1+0+0)
**and so on…
input 2 (pin 15): L,H,L (0+2+0)
input 3 (pin 12): H,H,L (1+2+0)
input 4 (pin 1): L,L,H (0+0+4)
input 5(pin 5): H,L,H (1+0+4)
input 6 (pin 2): L,H,H (0+2+4)
input 7 (pin 4): H,H,H (1+2+4)
** so while there is some fancy code around to read all of the inputs one after another in a for loop (see http://www.arduino.cc/playground/Learning/4051 it was this code that I found most confusing in understanding how the 4051 worked)
** all you really need to do is set the three arduino digital outputs to the correct setting for the analog input you want to read, then do an analogRead of pin 0
for example:
void setup() { //4051 digital control pins pinMode(8, OUTPUT); // s0 pinMode(9, OUTPUT); // s1 pinMode(10, OUTPUT); // s2 Serial.begin(9600); } void loop() { //Read Value of 4051 analog-in 0 by setting the values of s0,s1 and s2 digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(10, LOW); delay(10); //not sure if this delay is strictly necessary int readInZero = analogRead(0); // read the input pin Serial.print(readInZero); //use the result //repeat to read other pins (in this case analog in 2) digitalWrite(8, LOW); digitalWrite(9, HIGH); digitalWrite(10, LOW); delay(10); int readInTwo= analogRead(0); Serial.print(readInTwo); //etc. for the other 6 4051 analog inputs }
I have a question . With the multiplexed code above can I read any and all of the eight inputs. Let stay I have piezo sensors (8 on each multiplexer) would the code bet able to accept input from any of the piezos i hit. Or do I have manually select the pin I want to read? I see the code has some can of loop function is this scan all the pins and ready to read and of the inputs active? I and new to the arduino world and appreciate any advice you can offer.
Thank you in advance
Hi,
The loop function “void loop()” is where the guts of any arduino code goes. It simply loops through its instructions continually while the arduino is powered up.
So what you need to do is hook up all 8 piezos using the input pins of the multiplexer, then in the loop function read each of these pins in turn. (by setting s0, s1 & s2 to high or low according to what pin you are up to reading)
You cannot, in reality, read all of the 8 pins at once, you need to run through them in turn, but you do it fast enough that it makes no real difference to the user.
basically what you will be doing to the code above is adding 6 more code segments like the following but changing the LOW and HIGHS and also changing the variable name for each to make it unique (ie: readInTwo). This will switch through the inputs reading them in turn. If it seems laggy i would try removing or shortening the delay
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
delay(10);
int readInTwo= analogRead(0); //change this variable name to be unique for each pin
//do some stuff with the value you just got
hope this helps
andrew
Took me all night but here’s my understanding; special thanks to Andrew Burrell
Edited cy Caesar Passee
MUx A edited by pitchoilcan at geemail dot com
void setup()
{
//4051 digital control pins
pinMode
(8, OUTPUT); // s0
pinMode
(9, OUTPUT); // s1
pinMode
(10, OUTPUT); // s2
Serial.
begin(9600);
}
void loop()
{
//Read Value of 4051 analog-in 0 by setting the values of s0,s1 and s2
digitalWrite
(8, LOW);
digitalWrite
(9, LOW);
digitalWrite
(10, LOW);
delay
(10); //not sure if this delay is strictly necessary
int readInZero = analogRead(0); // read the input pin
Serial.print(readInZero); //use the result
//
digitalWrite
(8, LOW);
digitalWrite
(9, HIGH);
digitalWrite
(10, LOW);
delay
(10);
int readInTwo= analogRead(0);
Serial.print(readInTwo);
//
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
delay(10);
int readInFour= analogRead(0);
Serial.print(readInFour);
digitalWrite(8, High);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
delay(10);
int readInSix= analogRead(0);
Serial.print(readInSix);
//
digitalWrite(8, HiGH);
digitalWrite(9, HIGH);
digitalWrite(10, HiGH);
delay(10);
int readInSeven= analogRead(0);
Serial.print(readInSeven);
//
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
delay(10);
int readInFive= analogRead(0);
Serial.print(readInFive);
//
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delay(10);
int readInThree= analogRead(0);
Serial.print(readInThree);
//
digitalWrite(8, HIGH);
digitalWrite(9, Low;
digitalWrite(10, HIGH);
delay(10);
int readInOne= analogRead(0);
Serial.print(readInOne);
hi..
There were some syntax errors in your code, but the following, assuming your hardware is wired up correctly, should work for you to read all 8 analog inputs of the 4051 from analog pin 0 on the arduino. If you wanted to read from 3 4051s then you just need to repeat the process in the loop, but using two other analog pins on the arduino..
void setup()
{
//4051 digital control pins
pinMode(8, OUTPUT); // s0
pinMode(9, OUTPUT); // s1
pinMode(10, OUTPUT); // s2
Serial.begin(9600);
}
void loop()
{
//Read Value of 4051 analog-in 0 by setting the values of s0,s1 and s2
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
delay(10); //not sure if this delay is strictly necessary
int readInZero = analogRead(0); // read the arduino input pin the 4051 is using
Serial.println(readInZero); //use the result
//Read Value of 4051 analog-in 1 by setting the values of s0,s1 and s2
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
delay(10); //not sure if this delay is strictly necessary
int readInOne = analogRead(0); // read the arduino analog input pin
Serial.println(readInOne); //use the result
//Read Value of 4051 analog-in 2 by setting the values of s0,s1 and s2
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
delay(10);
int readInTwo= analogRead(0);
Serial.println(readInTwo); //use the result
//Read Value of 4051 analog-in 3 by setting the values of s0,s1 and s2
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
delay(10);
int readInThree= analogRead(0);
Serial.println(readInThree); //use the result
//Read Value of 4051 analog-in 4 by setting the values of s0,s1 and s2
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
delay(10);
int readInFour= analogRead(0);
Serial.println(readInFour); //use the result
//Read Value of 4051 analog-in 5 by setting the values of s0,s1 and s2
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
delay(10);
int readInFive= analogRead(0);
Serial.println(readInFive); //use the result
//Read Value of 4051 analog-in 6 by setting the values of s0,s1 and s2
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delay(10);
int readInSix= analogRead(0);
Serial.println(readInSix); //use the result
//Read Value of 4051 analog-in 7 by setting the values of s0,s1 and s2
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
delay(10);
int readInSeven= analogRead(0);
Serial.println(readInSeven); //use the result
}
Hi,
I was wondering if this setup means that it would not be possible for arduino to read the input of 2 analog pins on the multiplexer at the same time.
For example, if I connect 2 potentiometers to 2 pins of the multiplexer and turn them at the same time,would arduino successfully read both or that is not possible?
Thanks in advance,
Constantine.
It is not literally possible to read more than one of the multiplexer’s pins at once, but the loop happens so fast that you can turn the two (or more) pots at once and it will read them in turn but fast enough to act like they are all being read at once. (if it is still not quite fast enough look at removing or shortening the delay(10) in each of the ‘read’ code blocks in the sketch.)
hope this helps, a
I have a requirement for 10 analog input for photocells. Any ideas on this?
What additionalo IC to use for this?
Thanks,
Dave
Hi Dave,
Sorry I missed your question back on September. For more than 8 analogue inputs, there are two solutions I can think of. One would be to use two multiplexer ICs on 2 separate arduino pins, or more simply if you really only need 10 inputs, run 8 through the multiplexer and the last two through 2 standard arduino analogue inputs.
a
Hi Andrew, I build a controller with 32 pots connected to 4 multiplexers. I was wondering if you know how to properly transform these signals into a MIDI message. At the moment I can see all the pot values on the serial monitor, so I know they are properly connected. When I try to connect my controller through a midi device and into a DAW such as ableton or renoise, it responds as if I am turning every single knob at once without having touched them.
If you could give me some advice that would be amazing. Thanks!
const int Apin = 2;
const int Bpin = 3;
const int Cpin = 4;
const int trigPin = 5;
const int echoPin = 6;
byte potVal;
byte lastVal[32]; // store the latest value here if it’s different
byte MIDIBuf[3];
unsigned long duration;
int controllerNumber = 0;
#define CONTROLLER_CHANGE_STATUS 0xB0
void sendMIDI(int ctlNum, int value);
void setup(void)
{
digitalWrite(trigPin, LOW);
pinMode(Apin, OUTPUT);
pinMode(Bpin, OUTPUT);
pinMode(Cpin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(trigPin, OUTPUT);
Serial.begin(9600); // MIDI
}
void loop()
{
controllerNumber = 0;
digitalWrite(trigPin, HIGH); // start trig pulse
delay(1);//for (int i = 0; i < 20; ++i);
digitalWrite(trigPin, LOW); // end trig pulse
duration = pulseIn(echoPin, HIGH); // read width of echo pulse
MIDIBuf[0] = CONTROLLER_CHANGE_STATUS;
MIDIBuf[1] = controllerNumber;
MIDIBuf[2] = duration;
Serial.write(MIDIBuf, 3);
for (int i = 0 ; i < 8; ++i)
{
digitalWrite(Apin, (i & 1));
digitalWrite(Bpin, (i & 2));
digitalWrite(Cpin, (i & 4));
for (int analogPin = 0; analogPin >3)&0x7F; // force 7-bit
controllerNumber++;
if (lastVal[controllerNumber] != potVal)
Serial.println(analogRead(0));
delay(100);
{ // only send if changed
lastVal[controllerNumber] = potVal;
MIDIBuf[0] = CONTROLLER_CHANGE_STATUS;
MIDIBuf[1] = controllerNumber;
MIDIBuf[2] = potVal;
Serial.write(MIDIBuf, 3);
}
}
}
}