Go Down

Topic: 74LS138 Mux with two potentiometers (AD5206) (Read 2005 times) previous topic - next topic

varun

Question about Potentiometers and Arduino ...

varun

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: (http://mayhewlabs.com/arduino-mux-shield)

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

AWOL

#2
Jul 08, 2010, 08:57 pm Last Edit: Jul 08, 2010, 08:58 pm by AWOL Reason: 1
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)

Quote
I am having difficulties

You haven't explained what these might be.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

varun

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:

Code: [Select]
#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

AWOL

Code: [Select]
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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Grumpy_Mike

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.

varun

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

fdufnews

#7
Jul 14, 2010, 12:39 am Last Edit: Jul 14, 2010, 12:41 am by fdufnews Reason: 1
To switch between potentiometers that are analog pieces, you should use an analog multiplexer like 4051 for example.
Look here for an explanation http://www.arduino.cc/playground/Learning/4051

Go Up