74LS138 Mux with two potentiometers (AD5206)

Question about Potentiometers and Arduino ...

Hi,

I am using an Arduino Duemilanove with a MuxShield to design a device that measures the intensity of 9 lasers using 9 IC photodiodes:

photoDiodes: (http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=296-23090-5-ND)

Mux Shield: (Mux Shield | Mayhew Labs)

I am also using potentiometers (AD5206) to control the intensity of the lasers ... Since the AD5206 can only control up to 6 lasers at a time, I need to use a 3-to-8 line decoder or multiplexer to toggle between the two potentiometers.

I am able to use just a single potentiometer (directly connected with the Mux Shield without using a decoder) and operate 6 lasers however when I try to use the decoder and have two potentiometers work at the same time I am having difficulties. I am not quite sure if it is the programming or the just the wiring of the decoder but I am unable to sort it out ... The code I am trying to use for the two potentiometers with the decoder is as follows:

#define CONTROL0 5 //MUX control pin 0 (S3 is connected to Arduino pin 2)
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

#define DATAOUT 9 //MOSI
#define SPICLOCK 8 //sck
#define DATAIN 12 //MISO - not used, but part of builtin SPI

#define AONE 13 //73LS138 - A0
#define ATWO 11 //73LS138 - A1
#define SLAVESELECT 10 //73LS138 - A2
#define E3 6

//byte pot=0;
byte data_counter=0;
byte resistance=0;

int pause = 500; // The higher the number, the slower the timing.
int mux2array[8];
int num[8];
float calc[8];

float SCALE = 4.8828125; // Conversion from 0-1023 to 0-5V
int ptime = 0;

char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}

void setup()
{
byte i;
byte clr;

pinMode(CONTROL0, OUTPUT); // Set MUX control pins to output
pinMode(CONTROL1, OUTPUT);
pinMode(CONTROL2, OUTPUT);
pinMode(CONTROL3, OUTPUT);

pinMode(14, OUTPUT);
pinMode(15, INPUT);
pinMode(16, OUTPUT); // Turn on output to digital pins 14 & 16 (MUX 1 & 2) and turn off the other multiplexer data pin

pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);

pinMode(SLAVESELECT,OUTPUT);
pinMode(AONE, OUTPUT);
pinMode(ATWO, OUTPUT);

pinMode(E3, OUTPUT);
// digitalWrite(SLAVESELECT,HIGH); //disable device

// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 (fastest)

SPCR = (1<<SPE)|(1<<MSTR);
clr=SPSR;
clr=SPDR;
delay(10);

for (i=0;i<6;i++)
{
write_pot1(i,255);
write_pot2(i,255);
}
Serial.begin(9600);
Serial.println();
Serial.print("TURBIDITY MEASUREMENTS");
Serial.println();
Serial.println();
Serial.print("Time (s)\t1 - 6.50 (mV)\tTime (s)\t2 - 5.10(mV)\tTime (s)\t3 - 3.70(mV)\tTime (s)\t4 - 2.20 (mV)\tTime (s)\t5 - 0.80 (mV)\tTime (s)\t6 - 6.00 (mV)\tTime (s)\t7 - 4.50 (mV)\tTime (s)\t8 - 3.00 (mV)\tTime (s)\t9 - 1.50 (mV)");
Serial.println();
}

byte write_pot1(int pot1, int value1)
{
digitalWrite(AONE, LOW);
digitalWrite(ATWO, LOW);
digitalWrite(SLAVESELECT,LOW); //2 byte opcode
spi_transfer(pot1);
spi_transfer(value1);
digitalWrite(AONE, HIGH);
digitalWrite(ATWO,HIGH);
digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
}

byte write_pot2(int pot2, int value2)
{
digitalWrite(AONE, HIGH);
digitalWrite(ATWO, LOW);
digitalWrite(SLAVESELECT,LOW); //2 byte opcode
spi_transfer(pot2);
spi_transfer(value2);
digitalWrite(AONE, HIGH);
digitalWrite(ATWO,HIGH);
digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
}

byte record_data(int a)
{
digitalWrite(CONTROL0, (a&15)>>3); //S3
digitalWrite(CONTROL1, (a&7)>>2); //S2
digitalWrite(CONTROL2, (a&3)>>1); //S1
digitalWrite(CONTROL3, (a&1)); //S0

delay(pause);
mux2array[a] = analogRead(1);
calc[a] = mux2array[a]*SCALE;
num[a] = (int)calc[a];
Serial.print(ptime);
ptime = ptime + 1;
Serial.print("\t");
Serial.print(num[a]);
Serial.print("\t");
delay(pause);
}

void loop()
{
write_pot1(0, 0);
record_data(data_counter);
write_pot1(0, 255);
data_counter++;

write_pot1(1, 0);
record_data(data_counter);
write_pot1(1, 255);
data_counter++;

write_pot1(2, 0);
record_data(data_counter);
write_pot1(2, 255);
data_counter++;

write_pot1(3, 0);
record_data(data_counter);
write_pot1(3, 255);
data_counter++;

write_pot1(4, 0);
record_data(data_counter);
write_pot1(4, 255);
data_counter++;

write_pot1(5, 0);
record_data(data_counter);
write_pot1(5, 255);
data_counter++;

write_pot2(1, 0);
record_data(data_counter);
write_pot2(1, 255);
data_counter++;

write_pot2(2, 0);
record_data(data_counter);
write_pot2(2, 255);
data_counter++;

write_pot2(3, 0);
record_data(data_counter);
write_pot2(3, 255);
data_counter++;

data_counter=0;
Serial.println();
}

If someone could kindly help me with this problem, that would be wonderful ... Thanks for your help!

Varun

Do you have some kind of "for" loop allergy?

When posting code, can you please use the "#" button on the editor's toolbar? (just next to the printer symbol)

I am having difficulties

You haven't explained what these might be.

Hi AWOL,

Thanks for the reply and sorry for the inconvenience. The reason I did not use "for" loops (in void loop) is because I wanted to change the intensity of each individual laser depending on the calibration of my system. I know they are all set to "0" and "255" but eventually the zeros will be different values.

Sorry for not putting "#", I am new to the board and I did not know this. Regarding the difficulties:

When I use this program with my setup, I only see the first two lasers on each potentiometer light up and then stay on forever. According the program, I should see the lasers alternate (turn on and off). Therefore, when I use the decoder to select the first potentiometer ... the lasers that are connected to the first potentiometers should start blinking in sequence from 1-6. The decoder should then switch to the second potentiometer and similarly lasers connected to the second potentiometer should start alternating. I hope I am a little better in explaining this time.

I will attach the code for you one more time:

#define CONTROL0 5                                         //MUX control pin 0 (S3 is connected to Arduino pin 2)
#define CONTROL1 4
#define CONTROL2 3
#define CONTROL3 2

#define DATAOUT 9                                         //MOSI
#define SPICLOCK 8                                        //sck
#define DATAIN 12                                         //MISO - not used, but part of builtin SPI

#define AONE 13                                           //73LS138 - A0
#define ATWO 11                                           //73LS138 - A1
#define SLAVESELECT 10                                    //73LS138 - A2
#define E3 6

//byte pot=0;
byte data_counter=0;
byte resistance=0;

int pause = 500;                                           // The higher the number, the slower the timing.
int mux2array[8];
int num[8];
float calc[8];

float SCALE = 4.8828125;                                   // Conversion from 0-1023 to 0-5V
int ptime = 0;

char spi_transfer(volatile char data)
{
  SPDR = data;                                             // Start the transmission
  while (!(SPSR & (1<<SPIF)))                              // Wait the end of the transmission
  {
  };
  return SPDR;                                             // return the received byte
}

void setup()
{
  byte i;
  byte clr;
  
  pinMode(CONTROL0, OUTPUT);                               // Set MUX control pins to output
  pinMode(CONTROL1, OUTPUT);
  pinMode(CONTROL2, OUTPUT);
  pinMode(CONTROL3, OUTPUT);
  
  pinMode(14, OUTPUT); 
  pinMode(15, INPUT);
  pinMode(16, OUTPUT);                                    // Turn on output to digital pins 14 & 16 (MUX 1 & 2) and turn off the other multiplexer data pin

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);

  pinMode(SLAVESELECT,OUTPUT);
  pinMode(AONE, OUTPUT);
  pinMode(ATWO, OUTPUT);
  
  pinMode(E3, OUTPUT);
//  digitalWrite(SLAVESELECT,HIGH);                         //disable device
  
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 (fastest)
  
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  
  for (i=0;i<6;i++)
  {
    write_pot1(i,255);
    write_pot2(i,255);
  }
  Serial.begin(9600);
  Serial.println();
  Serial.print("TURBIDITY MEASUREMENTS");
  Serial.println();
  Serial.println();
  Serial.print("Time (s)\t1 - 6.50 (mV)\tTime (s)\t2 - 5.10(mV)\tTime (s)\t3 - 3.70(mV)\tTime (s)\t4 - 2.20 (mV)\tTime (s)\t5 - 0.80 (mV)\tTime (s)\t6 - 6.00 (mV)\tTime (s)\t7 - 4.50 (mV)\tTime (s)\t8 - 3.00 (mV)\tTime (s)\t9 - 1.50 (mV)");
  Serial.println();
}
  
byte write_pot1(int pot1, int value1)
{
  digitalWrite(AONE, LOW);
  digitalWrite(ATWO, LOW);
  digitalWrite(SLAVESELECT,LOW);                           //2 byte opcode
  spi_transfer(pot1);
  spi_transfer(value1);
  digitalWrite(AONE, HIGH);
  digitalWrite(ATWO,HIGH);
  digitalWrite(SLAVESELECT,HIGH);                          //release chip, signal end transfer
}

byte write_pot2(int pot2, int value2)
{
  digitalWrite(AONE, HIGH);
  digitalWrite(ATWO, LOW);
  digitalWrite(SLAVESELECT,LOW);                           //2 byte opcode
  spi_transfer(pot2);
  spi_transfer(value2);
  digitalWrite(AONE, HIGH);
  digitalWrite(ATWO,HIGH);
  digitalWrite(SLAVESELECT,HIGH);                          //release chip, signal end transfer
}

byte record_data(int a)
{
  digitalWrite(CONTROL0, (a&15)>>3);                       //S3
  digitalWrite(CONTROL1, (a&7)>>2);                        //S2
  digitalWrite(CONTROL2, (a&3)>>1);                        //S1
  digitalWrite(CONTROL3, (a&1));                           //S0
  
  delay(pause);
  mux2array[a] = analogRead(1);
  calc[a] = mux2array[a]*SCALE;
  num[a] = (int)calc[a];
  Serial.print(ptime);
  ptime = ptime + 1;
  Serial.print("\t");
  Serial.print(num[a]);
  Serial.print("\t");  
  delay(pause);
}

void loop()
{ 
  write_pot1(0, 0);
  record_data(data_counter);
  write_pot1(0, 255);
  data_counter++;
  
  write_pot1(1, 0);
  record_data(data_counter);
  write_pot1(1, 255);
  data_counter++;
  
  write_pot1(2, 0);
  record_data(data_counter);
  write_pot1(2, 255);
  data_counter++;

  write_pot1(3, 0);
  record_data(data_counter);
  write_pot1(3, 255);
  data_counter++;

  write_pot1(4, 0);
  record_data(data_counter);
  write_pot1(4, 255);
  data_counter++;
  
  write_pot1(5, 0);
  record_data(data_counter);
  write_pot1(5, 255);
  data_counter++;

  write_pot2(1, 0);
  record_data(data_counter);
  write_pot2(1, 255);
  data_counter++;

  write_pot2(2, 0);
  record_data(data_counter);
  write_pot2(2, 255);
  data_counter++;

  write_pot2(3, 0);
  record_data(data_counter);
  write_pot2(3, 255);
  data_counter++;

  data_counter=0;
  Serial.println();
}

I hope this helps.

Thanks,
Varun

for (int i = 0; i < N_LASERS; ++i) {
  write_pot( pot [i], laser [i], calValue [i][0]);
  record_data(data_counter);
  write_pot( pot [i], laser [i], calValue [i][1]);
  data_counter++;
}

This way, you can vary the value of "N_LASERS" and get things to work, and your tables "pot", "laser" and "calValue" can all be defined in one place.

Can you post a schematic please. My concern is that a 74LS138 is a digital chip and I would not expect it to be used in this situation.

Hi Admins,

Actually, I figured it out. I am now using a "hex Inverter" to switch between the potentiometers. It does work because I only have two pots.

Thanks for your help

Varun

To switch between potentiometers that are analog pieces, you should use an analog multiplexer like 4051 for example.
Look here for an explanation Arduino Playground - 4051