8 pots to 1 out using a 4051

Hi I've got a 4051 and 8 pots working and outputting numbers that i want to see in the serial monitor, but i don't know how to send the data into max/msp i think i need to get max to send a letter to arduino telling it to read the pots buut am getting confused with other peoples examples online because the code i have adapted is slightly different. here's what I got so far:

// adapted from post on this forum - more analog inputs

int MuxPin1=2;

int MuxPin2=3;

int MuxPin3=4;

int AnaInPin1=4;




//Declare variables

int MuxVal1 = 0; 

int MuxVal2 = 0; 

int MuxVal3 = 0; 

int BinVal = 0; 

int N = 0; 



//BinPat is used for figuring out the High / Low (1/0) values of the MUX control pins

int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};

//The PotValues array is used for storing the 16 vlues read from the potentiometers

int PotValues [] = {0,0,0,0,0,0,0,0};



void setup()

{ 

  //Initialize digital pins and serial communication speed

  pinMode(MuxPin1, OUTPUT);

  pinMode(MuxPin2, OUTPUT);

  pinMode(MuxPin3, OUTPUT); 

  beginSerial(19200);

} 





void loop() {

  readPotValues();

  sendPotValues();

  delay (10);

}



void readPotValues()

{

for (N=0; N<=7; N++) 

    {

      BinVal = BinPat[N];      

      MuxVal1 = BinVal & 0x01;

      MuxVal2 = (BinVal>>1) & 0x01;

      MuxVal3 = (BinVal>>2) & 0x01;

      digitalWrite(MuxPin1, MuxVal1);

      digitalWrite(MuxPin2, MuxVal2);

      digitalWrite(MuxPin3, MuxVal3);

      PotValues[N]=analogRead(AnaInPin1);

    }  

}

    

void sendPotValues()



{

for (N=0; N<=6; N++) 

    {

      Serial.print(PotValues[N]);

      Serial.print(',');

    }  

    Serial.println(PotValues[7]); 

}

any help would be greatly appreciated 
cheers and happy new year

I think yo are using the code i wrote for my multiplexing stuff. Cool :slight_smile:

I know absolutely nothing about MAX, so i can probably not help with details.

But i can explain the way i send data. I use the pot values in a VB.net program. VB.net has a smart function for splitting a string with a delimiter into an array of its individual substrings. Thats why i send alle the values (except the last) followd by a "," and then the last value without the ",". The last value is send with serial.println.

This way my VB.net program recieves one long string of comma seperated values, which i can very easyli split into the individual elements in an array.

Unless MAX has some string handeling functions like the ones i use in VB, you would probably need to send the data to MAX in a way that is more suitable for MAX to recieve. I think there's an example in the palyground sending data to MAX.

HI thanks for the code, I just deleted a bit so it will work with 8 and so i can understand what is going on thank you for putting the code online. In max I can read the serial port, but i am having trouble how to unpack 8 different sensor values through 1 analog read pin, I think i might have to put an identifier for each sensor i.e a = 1023, b = 0 and so on and then get max to split it back, do you how i might do this?

this dude has done what i would like to do but i don't want to copy him because I don't think i will understand what is going on properly.

If anyone has any suggestions it would be really helpful.

Cheers

What he is doing on the Arduino side is (in "our terms") just reading one pot value and sending it out the serial port at once.

And he is also waiting for MAX to send an "L" before he sends the pot values over. This is probably to allow MAX to handle the 8 values before it is flooded with data.

So the modified code for doing that would be (untested - not close to my Arduino stuff right now).

int MuxPin1=2;
int MuxPin2=3;
int MuxPin3=4;
int AnaInPin1=4;

//Declare variables
int MuxVal1 = 0;
int MuxVal2 = 0;
int MuxVal3 = 0;
int BinVal = 0;
int N = 0;
byte data_send = 0;
byte data_in = 0;

//BinPat is used for figuring out the High / Low (1/0) values of the MUX control pins

int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};

void setup()

{

//Initialize digital pins and serial communication speed

pinMode(MuxPin1, OUTPUT);

pinMode(MuxPin2, OUTPUT);

pinMode(MuxPin3, OUTPUT);

beginSerial(19200);

}

void loop() {

if(Serial.available() > 0) {
data_in = Serial.read();
if(data_in == 76) {
readPotValues();
}
}

delay (10);

}

void readPotValues()

{

for (N=0; N<=7; N++)

{
BinVal = BinPat[N];
MuxVal1 = BinVal & 0x01;
MuxVal2 = (BinVal>>1) & 0x01;
MuxVal3 = (BinVal>>2) & 0x01;
digitalWrite(MuxPin1, MuxVal1);
digitalWrite(MuxPin2, MuxVal2);
digitalWrite(MuxPin3, MuxVal3);
data_send=analogRead(AnaInPin1) / 4;
Serial.print(data_send);
}
Serial.flush();

}

This would require MAX to handle 8 raw bytes from the serial port.

As you can see, the sendPotValues() function and the potValues array is no longer required, as the 8 potvalues are send as soon as they are read.

EDIT:

The delay(10); call is probably not needed anymore.

thank you very much this works perfectly i'm going to try to adapt it to work with 16 now. Nice one, happy 2009!

I'm getting stuck on using 16 pots, what do i need with the second analog read pin if i want to use two multiplexers and data_send?

below is what i think is wrong

void readPotValues()
{
for (N=0; N<=7; N++) 
    {
      BinVal = BinPat[N];      
      MuxVal1 = BinVal & 0x01;
      MuxVal2 = (BinVal>>1) & 0x01;
      MuxVal3 = (BinVal>>2) & 0x01;
      digitalWrite(MuxPin1, MuxVal1);
      digitalWrite(MuxPin2, MuxVal2);
      digitalWrite(MuxPin3, MuxVal3);
      PotValues[N]=analogRead(AnaInPin1) / 4 ; // this doesn't need to be here
      PotValues[N + 8]=analogRead(AnaInPin2) / 4; // how do i send this?
      data_send=analogRead(AnaInPin1) / 4; 
      Serial.print(data_send);         
    }  
  Serial.flush();
}

thankyou

Then i would go back to my original code, just with two changes, the check for the "L" value send from MAX, and sending the values to max without the ",".

like this:

int MuxPin1=2;
int MuxPin2=3;
int MuxPin3=4;
int AnaInPin1=4;
int AnaInPin2=5;

//Declare variables
int MuxVal1 = 0;
int MuxVal2 = 0;
int MuxVal3 = 0;
int BinVal = 0;
int N = 0;
byte data_in=0;

//BinPat is used for figuring out the High / Low (1/0) values of the MUX control pins
int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};
//The PotValues array is used for storing the 16 vlues read from the potentiometers
int PotValues [] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void setup()
{
//Initialize digital pins and serial communication speed
pinMode(MuxPin1, OUTPUT);
pinMode(MuxPin2, OUTPUT);
pinMode(MuxPin3, OUTPUT);
beginSerial(19200);
}

void loop()
{
if(Serial.available() > 0)
{
data_in = Serial.read();
if(data_in == 76)
{
readPotValues();
sendPotValues();
}
}

}

void readPotValues()
{
for (N=0; N<=7; N++)
{
BinVal = BinPat[N];
MuxVal1 = BinVal & 0x01;
MuxVal2 = (BinVal>>1) & 0x01;
MuxVal3 = (BinVal>>2) & 0x01;
digitalWrite(MuxPin1, MuxVal1);
digitalWrite(MuxPin2, MuxVal2);
digitalWrite(MuxPin3, MuxVal3);
PotValues[N]=analogRead(AnaInPin1) / 4 ;
PotValues[N + 8]=analogRead(AnaInPin2) / 4;
}
}

void sendPotValues()

{
for (N=0; N<=15; N++)
{
Serial.print(PotValues[N]);
}
}

Again this is untested

Hope it works :slight_smile:

The code is fine, and works reading the data from 16 pots into the serial monitor with no comma so that is fine, but i need to do the data send bit with N+8 for analog pin 2, how do i send AnaInPin2's data as well?

data_send=analogRead(AnaInPin1) / 4;
Serial.print(data_send);
}
Serial.flush();

cheers

}

but i need to do the data send bit with N+8 for analog pin 2

It's not clear to me what you are asking here. As I read it you are sending the result of analogue in pin 2 because it was gathered with

PotValues[N + 8]=analogRead(AnaInPin2) / 4;

in a loop that went from 0 to 7
and sent with

Serial.print(PotValues[N]);

in a loop that goes from 0 to 15

So automatically the first 8 come from input 1 and the second 8 from input 2

Am I missing something?

I am using data send to get my data into max it works fine for 8:

int MuxPin1=2;
int MuxPin2=3;
int MuxPin3=4;
int AnaInPin1=4;

//Declare variables
int MuxVal1 = 0;
int MuxVal2 = 0;
int MuxVal3 = 0;
int BinVal = 0;
int N = 0;
byte data_send = 0;
byte data_in = 0;


//BinPat is used for figuring out the High / Low (1/0) values of the MUX control pins

int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};


void setup()

{

 //Initialize digital pins and serial communication speed

 pinMode(MuxPin1, OUTPUT);

 pinMode(MuxPin2, OUTPUT);

 pinMode(MuxPin3, OUTPUT);

 beginSerial(19200);

}


void loop() {


if(Serial.available() > 0) { 
     data_in = Serial.read(); 
     if(data_in == 76) {
           readPotValues();
           }
}

  delay (10);

}


void readPotValues()

{

for (N=0; N<=7; N++)

   {
     BinVal = BinPat[N];
     MuxVal1 = BinVal & 0x01;
     MuxVal2 = (BinVal>>1) & 0x01;
     MuxVal3 = (BinVal>>2) & 0x01;
     digitalWrite(MuxPin1, MuxVal1);
     digitalWrite(MuxPin2, MuxVal2);
     digitalWrite(MuxPin3, MuxVal3);
     data_send=analogRead(AnaInPin1) / 4;
     Serial.print(data_send);
   }
     Serial.flush();

}

but now i have hooked up two 4051's i am having trouble in what to write in the data_send bit i think i should go something like

data_send=analogRead(AnaInPin1) / 4;

// and analogRead(AnaInPin2) / 4; this is the bit i am unsure about how to send

    Serial.print(data_send);
  }
    Serial.flush();

}

Just use the code from my previous post, it takes care of all 16 pots, both reading and sending.

this is what i've been trying to do but it still doesn't work

int MuxPin1=2;
int MuxPin2=3;
int MuxPin3=4;
int AnaInPin1=4;
int AnaInPin2=5;

//Declare variables
int MuxVal1 = 0; 
int MuxVal2 = 0; 
int MuxVal3 = 0; 
int BinVal = 0; 
int N = 0; 
byte data_in=0;
byte data_send=0;

//BinPat is used for figuring out the High / Low (1/0) values of the MUX control pins
int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};
//The PotValues array is used for storing the 16 vlues read from the potentiometers
int PotValues [] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void setup()
{ 
 //Initialize digital pins and serial communication speed
 pinMode(MuxPin1, OUTPUT);
 pinMode(MuxPin2, OUTPUT);
 pinMode(MuxPin3, OUTPUT); 
 beginSerial(19200);
} 


void loop()
{
     if(Serial.available() > 0) 
     { 
               data_in = Serial.read(); 
               if(data_in == 76) 
           {
                           readPotValues();
                           sendPotValues();
                     }
}

}


void readPotValues()
{
for (N=0; N<=14; N++) 
   {
     BinVal = BinPat[N];      
     MuxVal1 = BinVal & 0x01;
     MuxVal2 = (BinVal>>1) & 0x01;
     MuxVal3 = (BinVal>>2) & 0x01;
     digitalWrite(MuxPin1, MuxVal1);
     digitalWrite(MuxPin2, MuxVal2);
     digitalWrite(MuxPin3, MuxVal3);
     PotValues[N]=analogRead(AnaInPin1) / 4 ;
     PotValues[N+8]=analogRead(AnaInPin2) / 4;  
   }  
}
   void sendPotValues()
   {
     for (N=0; N<=15; N++)
     {
       data_send = (PotValues[N]);
       Serial.print(data_send);
     }
     Serial.flush();
   }

mikmo sadly it doesn't i need to use the data_send bit i think and that is what is left from the code you posted

This isn't the code MikMo posted there are errors in it.
You have
void readPotValues()
{
for (N=0; N<=14; N++)

It should be:-
void readPotValues()
{
for (N=0; N<=7; N++)

you are right i changed that stupidly, but still when i do it with 7 in that place when i unpack the data in max all the boxes stay at 48, i don't think i have anything hooked up wrong, but there might be an error in my methodology. sorry about this

OK so you are not getting the values you expect. Now this is the interesting bit of embedded systems, the debugging.

If it were me I would start by changing the lines:-
PotValues[N]=analogRead(AnaInPin1) / 4 ;
PotValues[N+8]=analogRead(AnaInPin2) / 4;

to

PotValues[N]=N;
PotValues[N+8]=N+8;

Then you know what values are being sent.
Then get a terminal session going and see what comes back from that. You might want to add a Serial.println(); at the end of the loop to give each batch of 16 on a different line, you may also want to add temporally some spaces as well in the printing.

Then if that works as expected see if max unpacks it as you expect.

If all that works you are down to chasing hardware errors.

say if i did change that were would analogRead go?

int MuxPin1=2;
int MuxPin2=3;
int MuxPin3=4;
int AnaInPin1=4;
int AnaInPin2=5;

//Declare variables
int MuxVal1 = 0; 
int MuxVal2 = 0; 
int MuxVal3 = 0; 
int BinVal = 0; 
int N = 0; 
byte data_in=0;
byte data_send=0;

//BinPat is used for figuring out the High / Low (1/0) values of the MUX control pins
int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};
//The PotValues array is used for storing the 16 vlues read from the potentiometers
int PotValues [] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void setup()
{ 
 //Initialize digital pins and serial communication speed
 pinMode(MuxPin1, OUTPUT);
 pinMode(MuxPin2, OUTPUT);
 pinMode(MuxPin3, OUTPUT); 
 beginSerial(19200);
} 


void loop()
{
     if(Serial.available() > 0) 
     { 
               data_in = Serial.read(); 
               if(data_in == 76) 
           {
                           readPotValues();
                           sendPotValues();
                     }
}

}


void readPotValues()
{
for (N=0; N<=14; N++) 
   {
     BinVal = BinPat[N];      
     MuxVal1 = BinVal & 0x01;
     MuxVal2 = (BinVal>>1) & 0x01;
     MuxVal3 = (BinVal>>2) & 0x01;
     digitalWrite(MuxPin1, MuxVal1);
     digitalWrite(MuxPin2, MuxVal2);
     digitalWrite(MuxPin3, MuxVal3);
     PotValues[N]=N;
     PotValues[N+8]=N+8;  
   }  
}
   void sendPotValues()
   {
     for (N=0; N<=15; N++)
     {
       data_send = (PotValues[N]);
       Serial.print(data_send);
     }
     Serial.flush();
   }

You wouldn't have it at all. It's just a test to try and narrow down what is going wrong. Because you know what you are putting into the PotValues[] array you can filter out if the problem is before the analogue read or after it.
Once you have found this out you put them back in and delete the temporary ones.

quick question,

why use:

int BinPat [] = {000, 1, 10, 11, 100, 101, 110, 111};

and therefore BinVal in the loop:

for (N=0; N<=7; N++) {
     BinVal = BinPat[N];
     MuxVal1 = BinVal & 0x01;
     MuxVal2 = (BinVal>>1) & 0x01;
     MuxVal3 = (BinVal>>2) & 0x01;

surely BinVal can just be replaced by N, since MuxVals are just 1 bit in length (after & 0x01)...

hope that makes sense

b9