This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1241 timing

Other Parts Discussed in Thread: ADS1241

Hi, I am using the ADS1241 to read two thermcouples.

I am having some timing issues.  What I am doing is setting the mux to amplify between channels 4 and 5, then reading the output value, then I am changing the mux to read between channels 6 and 7 and then reading the output value.

First I wait until the DRDY bit goes low.  Then I wait 100 uS, then write to the MUX register.  Then wait another 100 uS.  Then I wait until DRDY bit goes high.  Then I wait until DRDY goes back low again. Then I have to wait 100 milliseconds or more before I read the RDATA register to get the output value.  If I don't wait 100 mS or more here, then it outputs the value of the wrong thermocouple.  And I am just looping over and over to keep reading both thermocouples all the time.  The problem is that 100 mS delay is pretty long and is messing up my keypad presses (keypad won't recognize button press during this 100 mS delay).

My question is, am I doing this right, is there a way to speed up that delay that seems to be required after a MUX change and before an RDATA read?

I have the data rate (DR) set to 15 Hz, by the way.

  • Signalflow,


    With the data rate at 15Hz, that means that the data will only come out every 66.7ms, so you're not going get that down an extra 33ms or so. That being said, you should be able to get that a little faster by telling the device to restart the read.

    Looking at the datasheet on page 10, on the second paragraph on the right side, the text talks about single-cycle settling. If you combine reading the device with writing the command to change the channel to the mux, you can get better results by giving more time to the digital filter to sample the correct mux input. The accuracy is shown in Figure 2 at the bottom of the page.

    If you can't write the data out that fast or don't want to have to worry about the sampling transitioning from one channel of the mux to the other, you can toggle the /DSYNC pin or send a DSYNC command. This will restart the digital filter so that it encorporates only the new channel sampling into the next data.

    Both methods should give you results close to sampling either channel close to 67 ms.


    Joseph Wu

  • Regarding your statement "if you combine reading the device with writing the command to change the channel to the mux, you can get better results by giving more time to the digital filter to sample the correct mux input."  I believe that is what I am currently doing, right?  Changing mux channel, waiting 100 mS and then reading value.

    For the DSYNC command, do I change the MUX first, then perform a DSYNC command and then have to wait 67 mS before do an RDATA command?

  • I tried changing mux, then waiting for DRDY bit to go HIGH the LOW again, then did a DSYNC command, and then immediately did an RDATA command.  In this case, it still reads only the 2nd thermocouple value read.  So it gives that 2nd thermocouple value for both channels that are read (basically gives bad data on the first thermocouple).

    Do I need to add a 67 mS delay between DSYNC command and RDATA?  But that would still give a 67 mS delay in my code where I couldn't poll key presses on a keypad.

    Or should I split the ADC read up in to two functions (MUX change, DRDY read, and DSYNC command), then perform some other actions (given the ADC time to update) and then perform an RDATA command?

    For example, right now I am doing

    Loop_start:

    Monitor switches();

    Update LCD();

    Read keypad();

    ADC read();

    Goto Loop_start;

    But should I change to something like the below in order to have some time between mux change and RDATA?

    Loop_start:

    ADC_MUX_AND_DRDY_AND_DSYNC();

    Monitor switches();

    Update LCD();

    Read keypad();

    ADC_RDATA();   //perform RDATA command

    Goto Loop_start;

  • Signalflow,


    With the data rate at 15 SPS, the ADC is sampling the input throughout that 67ms time period and you need the entire time for the conversion to complete. There's no sample and hold. Regardless of whatever you want to do, if your mux is not on the correct input for the entire 67ms, then you may get bad data.

    I'm not sure what you're doing in your interactions with your system, but I'd advise a this way of reading the device. For each attempt to read the inputs, start with a DSYNC shown below.

    DSYNC
    Wait for 67ms (or Wait for /DRDY to rise, its the same).
    Read Data.

    This would be for anytime you need a new data. As an example, if you want to change the MUX, change the MUX, issue the DSYNC, wait for the conversion to complete, then read the data.


    Joseph Wu

  • I am doing the following and still it is reading only the 2nd thermocouple, not the first.  Any idea what I am doing wrong?  Figure on pg. 10 says to wait until DRDY goes HIGH and then back to LOW before the conversion is complete, so that's what I am doing.

    ADC_read()

    {

    Write to MUX register

    DSYNC command

    Wait for DRDY to go high

    Wait for DRDY to go low

    read RDATA

    }

    //My main loop is as follows

    Main()

    {

    start_loop:

    ADC_read(channel1);

    ADC_read(channel2);

    goto start_loop;

    }

    Also, the paragraph on DSYNC is confusing as well (pg. 14) as it looks like after a DSYNC command is issued, the modulator is stuck in RESET until another SCLK is detected.  So to generate another SCLK, I created a dummy read of RDATA and then waited for DRDY to go HIGH and then back LOW before I did the real read of RDATA.  This still didn't fix the problem.

    When the DSYNC command is sent, the digital filter is reset
    on the edge of the last SCLK of the DSYNC command. The
    modulator is held in RESET until the next edge of SCLK is
    detected. Synchronization occurs on the next rising edge of
    the system clock after the first SCLK following the DSYNC
    command.

  • Signalflow,


    Let's try two changes. I can think of two things that might be affected, and one is something you brought up in your last post.

    So for each read, do this:

    Send RDATAC
    Set the Mux to the new value.
    Send DSYNC command
    Clock 8 SCLKs (using DIN=0 for a basic NOP)
    Wait for DRDY to fall
    Read out data
    Send SDATAC

    I've added a couple of things to the sequence and I'll explain why. I've started with the RDATAC to make sure the output register is always updated at the end of the conversion. If there had been an SDATAC at the beginning, the device stops updating data at the output register. Additionally, using the RDATA each time may be telling the device to update the data after the next DRDY pulse goes by, so you might be reading the conversion from the previous cycle. Second, I've added the 8 SCLKs to pull modulatore out of RESET. I'd forgotten that on this device, it requires another SCLK.

    It's possible that you don't need the RDATAC and SDATAC, as long as this is continually in this mode. Keeping the device in continuous read ensures that the data is updated into the output register after each conversion. Check this sequence out and see if your data comes out correct.


    Joseph Wu

  • There is no SDATAC command.  There is RDATA, RDATAC and STOPC.

    It seems like I should be able to do what I was doing with RDATA.

    Maybe this will shed some light on things.  Using the code below, if I heat up thermocouple 1, then no values are registered.  If I heat up thermocouple 2, then both thermocouples show the value for thermocouple 2.

    Then I commented out the line that says "Wait for DRDY to go high" so it only checks for when DRDY goes low.  The results in this case are that both thermocouples appear to be reading except the values are opposite (when I heat thermocouple 1, then the value for thermocouple 2 rises.  When i heat thermocouple 2, the value for thermocouple 1 rises so it is backwards).

    I'll try RDATAC but it seems like RDATA should work properly based on the datasheet.  I think the datasheet may be incorrect.

    ADC_read()

    {

    Write to MUX register

    DSYNC command

    Wait for DRDY to go high

    Wait for DRDY to go low

    read RDATA

    }

    //My main loop is as follows

    Main()

    {

    start_loop:

    ADC_read(channel1);

    ADC_read(channel2);

    goto start_loop;

    }

    I tried another variation where instead of waiting for DRDY to go HIGH and then back LOW

  • Based on figure 2 (pg. 10) it looks like I am supposed to wait until DRDY goes HIGH, and then back to LOW.  It's confusing.  On the left-most portion of the figure, DRDY goes low at the start of a new conversion, so if I just check when DRDY goes low, then it is already low, so I have been waiting for it to go HIGH and then back LOW again.

    Do I need to wait until it goes HIGH and then back down to LOW before doing RDATA?

  • I believe I figured it out.  When I was polling the DRDY bit of ACR register using a while loop I wasn't setting the DRDYbit=1 manually, so it may not have ever been going throug the loop to read the ACR register.

    It appears to be reading the correct inputs now that I added a DRDYbit=1 statement in front of the while loops.

    while (DRDYbit==1)

    {

    read ACR register;

    DRDYbit=(ACR>>7)&(0x01);

    }

  • Signalflow,

    Good to hear that you might have a solution.


    Just to clear two things up. 1. I wrote SDATAC earlier, and I meant to write STOPC. It's basically the same thing. In our newer parts, we call the command SDATAC (sorry about that). 2. I believe that after a DSYNC, the /DRDY automatically goes high. Since the DSYNC resets the digital filter, it indicates that by saying that the data is no longer ready to be read out.


    Hopefully, your solution works. If there are any other questions, let me know. If the question is new, start another thread and close this one up.

    Joseph Wu