learning the ropes

things I made at ITP and after: sketches, prototypes, and other documentation

Wednesday, February 28, 2007

Chip Select on AD5206

Ai-Chen and I did a bit of rewiring on the Secret Tree circuit board. One of the problems we had last week was that all of the ground wires for the LEDs on the trees were connected to two PCB terminals. I didn’t purchase enough terminal at RadioShack so that every pair could have a ground of its own. This not only made things messy, but it also made the connections suspect.

Updated Circuit 002

The other major discovery I made which explained much of the circuit’s random (unintended) behavior was that the two AD5206 chips interfered with one another. I plugged a single LED into each of the twelve outputs (across the two chips) and found that a simple test program didn’t operate properly when both chips were running. As soon as I disconnected the three data lines (CLK, SDI, and CS) from the second chip, the first chip would work properly. I wondered if there might be some sort of “floating” condition when the two chips were used together. Since CLK and SDI were shared, I hypothesized that CS was likely the culprate. To test this, I added 10K pull-down resistors on the chip selects of both chips. It worked! The test program dimmed the lights in the proper sequence rather than skipping around randomly on the third and fourth outputs.

posted by Michael at 10:02 pm  

8 Comments »

  1. Hello,

    I have a similar question regarding the AD5206. I am trying to use two AD5206s as well. I am having trouble coordinating the two. Is there a way of turning the first pot on (while the second one is turned off) and light up the LEDs associated to the first pot and then switch to the second pot? I tried using a 74LS138 decoder but it did not work.

    Please let me know if this is possible or any other solution you might have. BTW, I am using these pots with Arduino ..

    Comment by Varun — July 12, 2010 @ 10:43 am

  2. Yes. The CS (chip-select) line on the AD5206… By using the 10K pull-down resistors as I suggested in the post, you will be enabling both chips. If you want to operate the AD5206 chips in sequence, you will need to use two digital outputs from the Arduino to control the chip selects (I think you could also get away with just a single output from the Arduino if you use a “hex inverter” chip to get the “logical” opposite of the Arduino output.

    Drive high the output of the Arduino that corresponds to the chip you want to enable (and simultaneously drive low the other output to disable the second AD5206).

    All of that said, I would stay away from the AD5206 as a solution for dimming LEDs. A bit of time has passed since I wrote the post you found — and while the AD5206 does approximate the effect of dimming the LEDs by changing the voltage that is going to them, using pulsewidth modulation (PWM) is a lower-power and more reliable way to dim LEDs. There are SPI-based chips which do this (though I don’t have any particular suggestions).

    Comment by Michael — July 12, 2010 @ 11:34 am

  3. Thank you for the help Michael,

    I just wanted to ask a quick question regarding arduino. If I am not mistaken, I believe pin 10 is the only CS. So, are you suggesting to use this one CS and relay it to two potentiometer CSs?

    Also, how do I use the 10k pull-down resistor accommodating the CS as well. If you could provide a few lines of code that would make me understand a bit better.

    I am sorry my background is not electrical (chemical engineering), hence the very basic questions.

    Thanks for your help.

    Varun

    Comment by Varun — July 12, 2010 @ 12:13 pm

  4. Varun,

    I’m a little confused where you are getting that pin 10 on Arduino is CS… The mapping between Arduino and the Atmega168 family ( http://arduino.cc/en/Hacking/PinMapping168 ) — and forgive me if you are using a newer Arduion — doesn’t show an CS pin on the Arduino. You can use any digital output pin (or pins).

    Also note that chip-select is “negative” — that’s what the horizontal bar over the name of the signal name indicates. To enable the chip, you pull the CS line low. To disable it, you drive the CS line high.

    Here’s a simple example:


    int CS_A = 2; // Chip select for AD5206 - A is connected to digital pin 2
    int CS_B = 3; // Chip select for AD5206 - B is connected to digital pin 2

    void setup()
    {
    pinMode(CS_A, OUTPUT); // sets the digital pin as output
    pinMode(CS_B, OUTPUT); // sets the digital pin as output
    }

    void loop()
    {
    digitalWrite(CS_A, LOW); // enable first AD5206
    digitalWrite(CS_B, HIGH); // disable second AD5206

    /* write code here that sets the levels on the first AD5206

    */

    digitalWrite(CS_A, HIGH); // disable first AD5206
    digitalWrite(CS_B, LOW); // enable second AD5206

    /* write code here that sets the levels on the first AD5206

    */
    }

    You asked how the CS would work with a pull-down resistor…

    Schematic including Arduino with 2 AD5206 chips

    When you use pull-down resistors, they serve to prevent an input (in this case, the CS on the AD5206) from floating. As I began writing this, however, I realized that for your application, where different Arduino outputs are connected to the chip selects on two different AD5206 chips, the pull-downs are probably unnecessary. In my case, they were necessary because I had the two chips ganged together in a weird way. If you see weird things happening, though… like very simple test code (turning channels of the AD5206 on and off) works sometimes and othertimes does not, you might have an issue that requires pull-down resistors.

    Comment by Michael — July 12, 2010 @ 12:51 pm

  5. Hi Michael,

    Thanks for your response. I tried what you suggested, however it did not switch between the AD5206 chips. Something really funny is happening:

    I connected the two CS for the AD5206 into Arduino pins 10 and 9 respectively. However, only the first potentiometer is working. Even after switching the CS for the first AD chip for the second one, it only works for the first potentiometer. I am attaching my code for you. Part of this code comes from the following website:

    #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 11 //MOSI
    #define DATAIN 12 //MISO – not used, but part of builtin SPI
    #define SPICLOCK 13 //sck
    #define SLAVESELECT 10 //ss

    #define DATAOUT1 8 //MOSI
    #define SPICLOCK1 7 //sck
    #define SLAVESELECT1 9 //ss

    byte pot=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(DATAOUT1, OUTPUT);
    pinMode(SPICLOCK1,OUTPUT);
    pinMode(SLAVESELECT1,OUTPUT);

    digitalWrite(SLAVESELECT,HIGH); //disable device
    digitalWrite(SLAVESELECT1,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>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_pot(pot, 0);
    record_data(pot);
    write_pot(pot, 255);
    pot++;

    if(pot==6)
    {
    pot=0;
    write_pot1(0, 0);
    record_data(pot);
    write_pot1(0, 255);

    write_pot1(1, 0);
    record_data(pot);
    write_pot1(1, 255);

    write_pot1(2, 0);
    record_data(pot);
    write_pot1(2, 255);

    // pot++;
    Serial.println();
    }
    }

    Also, I am using a muxshield to increase the I/Os:

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

    Thanks once again for your help.

    Comment by Varun — July 12, 2010 @ 2:22 pm

  6. Sorry, forgot to mention the website:

    http://www.arduino.cc/en/Tutorial/SPIDigitalPot

    Comment by Varun — July 12, 2010 @ 2:30 pm

  7. A few thoughts:

    Is your write_pot() function the same as the function implemented at the Arduino AD5206 tutorial? ( http://www.arduino.cc/en/Tutorial/SPIDigitalPot )

    (same question for the write_pot1() function, which I’m assuming you modified to utilize the SLAVESELECT1 constant).

    What is the record_data() function?

    Have you verified that the two AD5206 chips work without your multiplexer shield?

    Have you tried putting a delay in your loop between the SPI writes? Even just a small delay (10-20ms) might make a difference.

    Do you have a schematic? and are you sure your wiring is not at fault?

    Here is what I would try first:
    1. Take the mux-shield _and_ the AD5206 chips out… Verify that the logic you’re expecting to occur at outputs 9 and 10 on the Arduino is actually happening by driving LEDs with them directly (might want a 220-ohm current-limiting resistor there just in case… If you put a delay(1000) in your program between the write_pot() functions… you should see the two LEDs you’ve added toggling on and off. If you don’t see this, you’ve got a code problem.

    If that’s working right, try each AD5206 connected to the Arduino _by itself_. Basically, you want to try to separate your system into easy to test pieces.

    Comment by Michael — July 12, 2010 @ 2:58 pm

  8. Hi Michael,

    Thanks for the advice. I actually tried using the “hex inverter” as you earlier suggested and it worked beautifully since I only have two potentiometers.

    Thanks for your help!

    Varun

    Comment by Varun — July 13, 2010 @ 11:15 am

RSS feed for comments on this post. TrackBack URI

Leave a comment

Powered by WordPress