Wednesday, September 26, 2007

Multiplexy

The aim of this post is to address a query by the user "Boli" (see the comments page of the post "Arduino MIDI out example"). This a little demonstration of how to read up to 16 analog devices into the Arduino via 2 4051 multiplexers using 2 analog input pins and 3 digital output pins (plus RX and TX pins for serial transmission).

It should be noted that i have breadboarded and tested this method.

Obviously, this is a "barebones" example - if one was to actually implement this, a good idea might be to at least incorporate some sort of request byte from the host computer for each packet of 16 bytes received from the Arduino.

In other words, the patch must be started and then the Arduino must be reset (along with the zl group object) in order to really circumvent the issue of which byte corresponds to channel 1 of the first multiplexer.

But hey, this is just a quick little demo, yeah? Additional features can be easily added to this example without too much strain.


Hardware
The following connections should be made:

4051 (1)
  • pins 6, 7, 8 to GND
  • pin 16 to 5V
  • pin 3 to Arduino analog input pin 0
  • pin 11 to Arduino digital pin 2
  • pin 10 to Arduino digital pin 3
  • pin 9 to Arduino digital pin 4
  • analog sensors 1- 8 (eg. pots, LDRs, etc etc) to pins 13, 14, 15, 12, 1, 5, 2, 4
4051 (2)
  • pins 6, 7, 8 to GND
  • pin 16 to 5V
  • pin 3 to Arduino analog input pin 1
  • pin 11 to Arduino digital pin 2
  • pin 10 to Arduino digital pin 3
  • pin 9 to Arduino digital pin 4
  • analog sensors 9 - 16 (eg. pots, LDRs, etc etc) to pins 13, 14, 15, 12, 1, 5, 2, 4

Arduino Sketch:
byte data;

void setup() {

Serial.begin(57600);
DDRD = B00011110;

}

void loop() {
for(int i = 0; i < 16; i++) {

PORTD = (i % 8) << 2;

data = (analogRead(i / 8)) / 4;

Serial.print(data);
}
delay(5);

}


Max/MSP Patch:
Here you can see a most basic patch to receive the data.


Breadboard Picture:
Here you can see a breadboard example. Note that I have only connected one pot, because i only had one pot on hand at the time of writing this. But the idea remains the same.


7 comments:

J.Job said...

Instead of using a request byte you could format your data and use the 'match' Max object. For example if you programmed Arduino to send MIDI CC messages every time the value of a pot changed then you could use 'match 176 nn nn' and which would always grab a correct 3 byte message starting with the status byte.

To then use that data for MIDI you could then run it through 'zl filter 176' and then to 'midiformat' and finally 'midiout'.

Sebastian Tomczak said...

yes of course.

in fact, you could simply format all your data as MIDI and then use MIDI parse, which might be an easier way to do this.

AndresC said...

Hi Sebastian!
I´m a musician from Argentina, and I´m starting up with arduino and Max. I´m trying to reproduce you example. It works fine with 50k pots. Now I´m trying to replace the pots with ldr and all the readings in max went crazy. I appreciate any help.
Excuse my poor english and thank´s

Sebastian Tomczak said...

Hi Andres,
Thanks so much for your comment, i really appreciate it.

i am assuming you have used a resistor as the second half to balance out each LDR as a voltage divider?

cheers!

Patch said...

Hey Sebastian,

I seem to have hit a brick wall with my project atm. I will be eventually creating a 4 track 8 beats drum machine using LDRs. The idea will be that the user can place a box over the LDR or infact block the LED to the LDR with their body and it triggers certain drum samples. Anyway...
I'm a newcomer to the arduino and i've had a decent shot at your example. The main problem im having is that I need Max/MSP to read the idividual pins (they can be triggers for samples) on the mux, but everytime the arduino is reset the position of the pins has changed in Max.
How can I get this to do what i want...i'm pretty knackered now so if I've made a mess of this question just give us a heads up haha.

Cheers man,
Patch

lewis edwards said...

hi seb,

been having a good gander at your arduino knock-arounds, which are very very nice.
just one question though to pick your brain on.
i have bee trying to pick my own brain and other peoples, but just seems to run into a wall.

i want to do 16 channels per analog input, ending up with 80 pots, leaving 1 analog input left and also space on the other 4051's with space to put in more pots, if need be.

do you have, or know of any code to help get this done?

many thanks

lewis

niroa said...

Really helpful data, thank you for the post.