Go Down

Topic: Mux Shield Analog In/Digital Out (Read 1 time) previous topic - next topic

etk1

Aug 02, 2011, 11:38 am Last Edit: Aug 02, 2011, 09:32 pm by etk1 Reason: 1
I'm trying to use a Mux Shield in a way that it would have M0 and M1 sending analog in data over serial, and having M2 print digital data received via serial.

I'm trying to get both to work simultaneously in MaxMSP, and am wondering if it is even possible to both send and received different streams of serial data at the same time; although I had figured that if should be doing that as long as I'm not using a write function in the Arduino code.  Here's my sketch so far as I've written it. Sorry if its a tad messy.

Thanks in advance!

http://mayhewlabs.com/products/arduino-mux-shield

Code: [Select]

//Attempting mux0 and mux1 analog in, and mux2 digital out
#define CONTROL0 5    
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

int maxData;

int mux0array[16];
int mux1array[16];

int A;
int B;
int C;
int D;

void setup()
{
 
 Serial.begin(28800);

 pinMode(CONTROL0, OUTPUT);
 pinMode(CONTROL1, OUTPUT);
 pinMode(CONTROL2, OUTPUT);
 pinMode(CONTROL3, OUTPUT);
}
 

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

   digitalWrite(CONTROL0, (i&15)>>3);
   digitalWrite(CONTROL1, (i&7)>>2);  
   digitalWrite(CONTROL2, (i&3)>>1);  
   digitalWrite(CONTROL3, (i&1));    
   
   mux0array[i] = analogRead(0);
   Serial.print("mux0array: ");
   for (int i=0; i<16; i++)
 {
   Serial.print(mux0array[i]);
   Serial.print("-");
 }
   Serial.println();
 }
 
for (int i=0; i<16; i++)
 {
   digitalWrite(CONTROL0, (i&15)>>3);
   digitalWrite(CONTROL1, (i&7)>>2);  
   digitalWrite(CONTROL2, (i&3)>>1);  
   digitalWrite(CONTROL3, (i&1));    
   mux1array[i] = analogRead(1);
   
   Serial.print("mux1array: ");
   for (int i=0; i<16; i++)
 {
   Serial.print(mux1array[i]);
   Serial.print("-");
 }
   Serial.println();
}
 
 
 {  
 pinMode(16, OUTPUT);
 }
  while(Serial.available() > 0) {
     maxData = Serial.read();
   }
    if (maxData == 0)
   {
   A = 2;
   B = 2;
   C = 2;
   D = 2;
   }
   if (maxData == 1)
   {
   A = 0;
   B = 0;
   C = 0;
   D = 0;
   }
   if (maxData == 3)
   {
   A = 1;
   B = 0;
   C = 0;
   D = 0;
   }
    if (maxData == 5)
   {
   A = 0;
   B = 1;
   C = 0;
   D = 0;
   }
   if (maxData == 7)
   {
   A = 1;
   B = 1;
   C = 0;
   D = 0;
   }
   
 {
   digitalWrite(16, HIGH);
 }
 for (int i=0; i<16; i++)
   digitalWrite(CONTROL0, (D)); //S3
   digitalWrite(CONTROL1, (C)); //S2
   digitalWrite(CONTROL2, (B)); //S1
   digitalWrite(CONTROL3, (A)); //S0
}


 
 

 

     
   

Grumpy_Mike

#1
Aug 02, 2011, 01:16 pm Last Edit: Aug 02, 2011, 09:56 pm by Grumpy_Mike Reason: 1

Also please supply a link to the shield you have so that we can see what it is supposed to do.

You can send and receive serial information at the same time.


Grumpy_Mike

Thanks for making the changes.

Not sure what the digital stuff is doing at the end but the way you had the analogue input bit going outputted all 16 values in the array every time you read in one value.
This will result in lots of printed output and once every 16 times it will be right.

Try this modification:-
Code: [Select]
//Attempting mux0 and mux1 analog in, and mux2 digital out
#define CONTROL0 5   
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

int maxData;

int mux0array[16];
int mux1array[16];

int A;
int B;
int C;
int D;

void setup()
{
 
  Serial.begin(28800);

  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
}
 

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

    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2); 
    digitalWrite(CONTROL2, (i&3)>>1); 
    digitalWrite(CONTROL3, (i&1));     
   
    mux0array[i] = analogRead(0);
  }
  // now print out the array
      Serial.print("mux0array: ");
    for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }
    Serial.println();

 
for (int i=0; i<16; i++)
  {
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2); 
    digitalWrite(CONTROL2, (i&3)>>1); 
    digitalWrite(CONTROL3, (i&1));     
    mux1array[i] = analogRead(1);
}
    Serial.print("mux1array: ");
    for (int i=0; i<16; i++)
  {
    Serial.print(mux1array[i]);
    Serial.print("-");
  }
    Serial.println();
 
   
  pinMode(16, OUTPUT);
   while(Serial.available() > 0) {
      maxData = Serial.read();
    }
     if (maxData == 0)
    {
    A = 2;
    B = 2;
    C = 2;
    D = 2;
    }
    if (maxData == 1)
    {
    A = 0;
    B = 0;
    C = 0;
    D = 0;
    }
    if (maxData == 3)
    {
    A = 1;
    B = 0;
    C = 0;
    D = 0;
    }
     if (maxData == 5)
    {
    A = 0;
    B = 1;
    C = 0;
    D = 0;
    }
    if (maxData == 7)
    {
    A = 1;
    B = 1;
    C = 0;
    D = 0;
    }
   
  {
    digitalWrite(16, HIGH);
  }
  for (int i=0; i<16; i++)
    digitalWrite(CONTROL0, (D)); //S3
    digitalWrite(CONTROL1, (C)); //S2
    digitalWrite(CONTROL2, (B)); //S1
    digitalWrite(CONTROL3, (A)); //S0
}

etk1

Alright, thank you, that seems to be a bit more clean.  The digital stuff at the end was trying to output received serial data (from MaxMSP) out of the third multiplexer.  I had it working on its own perfectly okay (ill post the code) and the problem I was running into was getting both the 2 mux arrays analog in's whilst sending the 3rd mux digital out.

The maxData (four zero's) was being tested by if statements to produce a single led HIGH on my command from incoming Serial data

Truth table for the mux chips found here:

http://focus.ti.com/lit/ds/symlink/cd74hc4067.pdf

Code: [Select]



//Give convenient names to the control pins
#define CONTROL0 5   
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

int maxData;

int A;
int B;
int C;
int D;

void setup()
{
 
  Serial.begin(28800);
  //Set MUX control pins to output
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
}
 

void loop()
{
 
  pinMode(16, OUTPUT);
{
    while(Serial.available() > 0) {
      maxData = Serial.read();
    }
     if (maxData == 0)
    {
    A = 2;
    B = 2;
    C = 2;
    D = 2;
    }
    if (maxData == 1)
    {
    A = 0;
    B = 0;
    C = 0;
    D = 0;
    }
    if (maxData == 3)
    {
    A = 1;
    B = 0;
    C = 0;
    D = 0;
    }
     if (maxData == 5)
    {
    A = 0;
    B = 1;
    C = 0;
    D = 0;
    }
    if (maxData == 7)
    {
    A = 1;
    B = 1;
    C = 0;
    D = 0;
    }
   
  {
    digitalWrite(16, HIGH);
  }

    digitalWrite(CONTROL0, (D)); //S3
    digitalWrite(CONTROL1, (C)); //S2
    digitalWrite(CONTROL2, (B)); //S1
    digitalWrite(CONTROL3, (A)); //S0
}
}
     
   



Grumpy_Mike

OK try this. I have changed the logic so that if there is data it empties the buffer and then uses the last received readings to set the outputs. The way you had it was that the outputs were being set every time through the loop whether new data was received or not.

Code: [Select]
//Attempting mux0 and mux1 analog in, and mux2 digital out
#define CONTROL0 5   
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

int maxData;

int mux0array[16];
int mux1array[16];

int A=0;
int B=0;
int C=0;
int D=0;

void setup()
{
 
  Serial.begin(28800);

  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
}
 

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

    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2); 
    digitalWrite(CONTROL2, (i&3)>>1); 
    digitalWrite(CONTROL3, (i&1));     
   
    mux0array[i] = analogRead(0);
  }
  // now print out the array
      Serial.print("mux0array: ");
    for (int i=0; i<16; i++)
  {
    Serial.print(mux0array[i]);
    Serial.print("-");
  }
    Serial.println();

 
for (int i=0; i<16; i++)
  {
    digitalWrite(CONTROL0, (i&15)>>3);
    digitalWrite(CONTROL1, (i&7)>>2); 
    digitalWrite(CONTROL2, (i&3)>>1); 
    digitalWrite(CONTROL3, (i&1));     
    mux1array[i] = analogRead(1);
}
    Serial.print("mux1array: ");
    for (int i=0; i<16; i++)
  {
    Serial.print(mux1array[i]);
    Serial.print("-");
  }
    Serial.println();
 
   
  pinMode(16, OUTPUT);
  if(Serial.available() > 0) {
       while(Serial.available() > 0) {
       maxData = Serial.read();
        }
     if (maxData == 0)
    {
    A = 2;
    B = 2;
    C = 2;
    D = 2;
    }
    if (maxData == 1)
    {
    A = 0;
    B = 0;
    C = 0;
    D = 0;
    }
    if (maxData == 3)
    {
    A = 1;
    B = 0;
    C = 0;
    D = 0;
    }
     if (maxData == 5)
    {
    A = 0;
    B = 1;
    C = 0;
    D = 0;
    }
    if (maxData == 7)
    {
    A = 1;
    B = 1;
    C = 0;
    D = 0;
    } 
    digitalWrite(16, HIGH);
    for (int i=0; i<16; i++)
    digitalWrite(CONTROL0, (D)); //S3
    digitalWrite(CONTROL1, (C)); //S2
    digitalWrite(CONTROL2, (B)); //S1
    digitalWrite(CONTROL3, (A)); //S0
}
}

etk1

Thanks for the code.  I'm still having issues with it working together... In fact, twisting a potentiometer hooked into one of the analog muliplexers is actually causing the led's to blink at different intensities.  I'm wondering if this has something to do with the way the shield is constructed, as the analog in's all read in a voltage even is something is not connected to them, and it will vary depending on the voltage coming through an in with something connected to it.  But thanks for all your help though so far Grumpy Mike!

Grumpy_Mike

#7
Aug 03, 2011, 07:19 am Last Edit: Aug 03, 2011, 07:24 am by Grumpy_Mike Reason: 1
Quote
as the analog in's all read in a voltage even is something is not connected to them, and it will vary depending on the voltage coming through an in with something connected to it.


No that is normal and is to do with the sample an hold capacitor on the input of the A/D converter. It is the same on the internal multiplexer of the arduino.

Is this bit right?
Code: [Select]
if (maxData == 0)
   {
   A = 2;
   B = 2;
   C = 2;
   D = 2;
   }

all the other things set these variables to 1 or 0.

Also this line:-
   digitalWrite(16, HIGH);
This pin is never set to anything else so what is it supposed to do?

Finnola7John

I am new to this so can anybody help me in supplying a link to the shield?

Grumpy_Mike

Look in the first post for the link.

etk1

In the truth table having no pins HIGH was labeled as sending S0, S1, S2, and S3 all x, which then would have to be defined in the arduino code, so I thought I'd just put anything that wasn't a 1 or a 0.  Would there be a better way? 

As far as the [digital write 16, HIGH] chuck of code, it was just turning on the correct digital out pin to then receive the maxData.  Do you think this could be the thing causing the irrational behavior?

Thanks again-

Grumpy_Mike

When something is marked x it means don't care, it has to be a 0 or a 1 but it has no effect on the outcome what ever. You can't set an output pin to a 2 it makes no sense, we are talking about logic levels here.

As to pin 16, if it is always an output and always high then it is better to put that bit of code in the setup(), however as it doesn't change I would not expect it to give rise to any odd behavior.

Hi all,
I am bran new to Arduino having just migrated from PIC Micro-controllers.
I have a UNO and was planning on building a project that displays different patterns using LED's
I got myself the MUX shield to increase the number of outputs.
I was rather hoping I could also control not only how many LED'S switch on or off but also the brightness.
I now realise that this shield can only be configured for analog input and not output even though the chip it is based on (CD74HC4067) is capable of analog output.
I am considering modifying the shield by simply connecting the UNO's PWM outputs to the COM lines on the MUX board.
The value on these outputs can then be switched to the appropriate outputs.

I have hit a major wall!
It appears that the MUX shield can only switch one output at a time i.e. I can't switch several LED's on at the same time.
The only way i see this possible is if the code runs fast it appears that several LED's are on at the same time.
Maybe it is the way i am writing my code?

I have the code below, each channel works but in the loop it doesn't, can anybody help please?

// has anybody else noticed these look backwards backwards?
//#define CONTROL0 5    // D5
//#define CONTROL1 4    // D4 - S2
//#define CONTROL2 3    // D3 - S1
//#define CONTROL3 2    // D2 - S0

// modified from example code
#define CONTROL0 2  // D2 - S0
#define CONTROL1 3  // D3 - S1
#define CONTROL2 4  // D4 - S2
#define CONTROL3 5  // D5 - S3

void setup(){
  //Set MUX control pins to output
  // these are the adressing control pins and expect a binary value 0000 to 1111 to select one of 16 channels
  pinMode(CONTROL0, OUTPUT);
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
}

void loop (){
  // turn on M0
  pinMode(14, OUTPUT); //COM1
  pinMode(15, INPUT);  //COM2
  pinMode(16, INPUT);  //COM3
 
  // output pattern 1
  pattern01();
  delay(500);
  all_off();
  pattern02();
  delay(500);
  all_off();
}

void all_off() {
//This for loop is used to turn off all leds on M0
  for (int i=0; i<16; i++)
  {
    digitalWrite(CONTROL0, (i&15)>>3); //S3
    digitalWrite(CONTROL1, (i&7)>>2);  //S2
    digitalWrite(CONTROL2, (i&3)>>1);  //S1
    digitalWrite(CONTROL3, (i&1));     //S0
    digitalWrite(14, LOW);
  }

}

// output this led pattern 1010
// see CD74HC4067 truth table for info
// remember all OFF = channel 0
void pattern01() {
    // set output to on
    digitalWrite(14, HIGH);
    // select MUX channel / output 0 - LED 1
    digitalWrite(CONTROL0, LOW);
    digitalWrite(CONTROL1, LOW);
    digitalWrite(CONTROL2, LOW);
    digitalWrite(CONTROL3, LOW);
    // select MUX channel / output 2 - LED 3
    digitalWrite(CONTROL0, LOW);
    digitalWrite(CONTROL1, HIGH);
    digitalWrite(CONTROL2, LOW);
    digitalWrite(CONTROL3, LOW);
}

// output this led pattern 0101
void pattern02() {
    // set output to on
    digitalWrite(14, HIGH);
    // select channel / output 1 - LED 2
    digitalWrite(CONTROL0, HIGH);
    digitalWrite(CONTROL1, LOW);
    digitalWrite(CONTROL2, LOW);
    digitalWrite(CONTROL3, LOW);
    // select channel / output 3 - LED 4
    digitalWrite(CONTROL0, HIGH);
    digitalWrite(CONTROL1, HIGH);
    digitalWrite(CONTROL2, LOW);
    digitalWrite(CONTROL3, LOW);
}

Go Up