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.

ADS1248 s/w management for RTD interface (PT1000)

Other Parts Discussed in Thread: ADS1248, LMP90079, ADS1247

Dear Sirs,

a few months ago you valuable Bob Benjamin gave me some hints for designing a 4x RTD (PT1000) interface using the ADS1248. Now the hardware is ready and our s/w engineers need some hel to make system firmware development faster. In order to avoid as possible - like we say - to "discover hot water".

The final schgematic of the interface is in the file (attached). 

I'm not asking for the code, but just for the correct sequence of actions to do: i.e.: registers to be programmed and suggested values, and suggestions to avoid critical issues, to make ADS1248 management (connected as from the image) almost instantly working in the best way.

The temperature reading process hasn't to be fast. 20 readings/second could be ok.

Any suggestion and contribution is welcome.

My best regards

Paolo Bozzola

  • Hi Paulo,

    The basic steps are as follows:

    • Power up the device
    • Set RESET high and wait the determined start up time as per datasheet
    • Set START high (required to read/write the registers)
    • Set the register configurations used
      • PGA
      • Data rate
      • Mux configuration
      • Turn on internal reference
      • Select reference to be used as REF1
      • Select IDAC current
      • Select IDAC routing
      • Issue a SELFOCAL
    • Wait for DRDY to transition from high to low
    • Read data and change mux channel and IDAC routing
    • Wait for DRDY to transition from high to low
    • Read data and change mux channel and IDAC routing
    • keep repeating.....

    The actual register selections will be determined by your design.

    Best regards,
    Bob B

  • Dear Bob,

    after some struggle the ADS1248 seems to work and next days we'll put it under deep testing. By the way, one good reason for initial problems was the SPI speed: we have used the same software used in out other product using Lmp90079) which run at 10Mhz; but then we discovered the ADS1248 can only accept up to 2Mhz.

    Once we have changed the SPI timings, all is working now and now it's a matter of trimming things.

    One last question: in my first post I attached the schematic of one bank of ADS1248 of our board. The system has two identical channels. They receive independent signals from the uP, except for the RESET (common for both), the SPI Clock,  and for the MOSI (which are common for both ADS1248).
    Quite strange, if we program both ADS1248, then they start converting, then both give the DRDY signal, when I activate only one Chip Select (e.g.: to ADS1248 #1) and I give the SPI commands to read only ADS1248 #1, we see the DRDY signal goes reset from ADS1248 #1, but also ADS1248 #2 resets its DRDY output!

    Why?

    The CS of the 2nd ADS1248 is high, so the 2nd ADS1248 should be insensitive to SPI commands coming in  from uP's MOSI (I told before: MOSI output from uP is common to both ADS1248, while MISO from each ADS1248 goes to different pins of the uP).

    Notice that we do programming actions in parallel for both, start them both, and conversion data seems correct, but we can't explain such DRDY reset from the ADS1248 which CS is inactive.
    This happens symmetrically: if we access converter #2, keeping CS1 inactive, then it is ADS1248 #1 which also resets its DRDY output as soon as something is transmitted on the MOSI wire by the uP.

    Any suggestion/explanation is welcome.

    Thanks!

    My best regards

    Paolo

  • Hi Paulo,

    The internal logic for the ADS1248 is rather complicated.  The logic for the resetting of DRDY is seperate from the SPI interface itself.  If you look at page 35 of the datasheet this is discussed in the CS section. At the end of the first paragraph of that section there is a statement "DRDY pin operation is independent of CS."  What you are seeing is the behavior of the device.  If this is problematic for you, read my response in this post:

    http://e2e.ti.com/support/data_converters/precision_data_converters/f/73/t/160153.aspx

    The above thread is for the ADS1247.  As the ADS1247 and ADS1248 are the same family of devices, the control application would apply to both devices.

    Best regards,

    Bob B

  • Dear Bob,

    sorry I did not focus on that post before, it seems it's 100% same as my situation.

    And we also are solving the issue by software: we do all things on 1st ADS1248 "forgetting" the 2nd one, then we do all things on 2nd ADS1248 "forgetting" the 1st one.

    Next PCB revision I will bring independent MOSI and SCLK to the converters.

    Thanks a lot for your valuable support.

    My best regards

    Paolo

  • Dear Bob,

    I am reopening this issue because we're about to start MP for the product where we use the ADS1248 and we are having speed problems.

    In other words, we cannot raise up the speed over 5SPS! 

    Here below is the sequence of operations we are using now. Just FYI see that for each reading of a conversion, we have to read and discard the first reading from the ADC, otherwise we get strange readings.

    I have tried a lot of different configurations, I have even thought of some mistake I made in the h/w design (attached too). The filters have 2.2 milli-second time constant, so I don't think this is the reason why it's impossible to run faster.

    Honestly speaking, the 5 SPS seems to work fine and it was pretty acceptable solution, until some inside customer's tech office wanted to have a faster reading. Now, in fact, due to all delays and retries, temperatures are updated about every 2~3 seconds; the new request is to have a refresh every 200 ms or faster.

    Thanks a lot for the help which surely you will give.

    I have attached the latest schematic of the ADS1248 interface for 4x RTD PT1000

    My best regards

    Paolo

    paolo.bozzzola@cjb.it 


    ACTUAL SEQUENCE OF OPERATIONS

    Startup & Initialization (just done once at the beginning)

    1         set signal RESET# active (low level)

    2         set SLCK clock not active (low level)

    3         set chip select CS# not active (high level)

    4         set START active (high level)

    5         wait 10 milliseconds

    6         release RESET# (set high level)

    7         Wait 2 milliseconds                              (t RHSC = 0.6 milliseconds,  our delay is affordable)

    8         write 0x28 into register 0x02 (MUX1)

    - Internal oscillator in use

    - Internal reference always on

    - REF1 input pair selected

    - Normal Operation (default)

    9         write 0x00 into register 0x03 (SYS0)

    - PGA Gain = 1

             - Output data rate = 5 SPS

    10     write 0x04 into register 0x0a (IDAC0)

    - DOUT/DRDY pin functions only as Data Out (however we use DRDY# on pin 25)

              - IMAG : Magnitude of the excitation current =  500 µA

    11     Send SYSOCAL command                                                                                            

    12     Wait 2000 milliseconds

    13     Write 0x07 into register 0x00  (MUX0)

    - Select AIN0 as positive input channel

    - Select AIN7 as negative input channel

    14     Write 0xf8 into register 0x0b (IDAC1)

    - Output pin of Excitation current source 1 - disabled

    - Output pin of Excitation current source 2 = IEXT1                                         

    15     Wait 100 milliseconds

    16     Wait conversion has been completed

    17     Read conversion result and discard it                     

    18     Wait 2 milliseconds                                                         

    Loop :

    (1st RTD)              

    1         (Initial activity to get conversion on AIN0):  Assert START Signal (high level)

    2         Write 0x07 into register 0x00  (MUX0)

    - Select AIN0 as positive input channel

    - Select AIN7 as negative input channel

    3         Write 0xf8 into register 0x0b (IDAC1)

    - Output pin of Excitation current source 1 – always disabled

    - Output pin of Excitation current source 2 – IEXT1 (pin 20 of ADS1248)                                  

    4         Wait 2 milliseconds

    5         Wait the conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)      

    6         Get data from chip and discard them                                     

    7         Wait 1 millisecond

    8         Wait another conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)

    9         Release START Signal (low level)

    10     Read Conversion (Relative to couple AIN0 – AIN7) and save the result

     

    (2nd RTD)

    11     (Initial activity to get conversion on AIN1):  Assert START Signal (high level)

    12     Write 0x0f to register 0x00  (MUX0)

    - Select AIN1 as positive input channel

    - Select AIN7 as negative input channel

    13     Write 0xf9 to register 0x0b (IDAC1)

    - Output pin of Excitation current source 1 – always disabled

    - Output pin of Excitation current source 2 – IEXT2 (pin 19 of ADS1248)                                                  

    14     Wait 2 milliseconds

    15     Wait the conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)

     

    16     Get data from chip and discard them                                     

    17     Wait 1 millisecond

    18     Wait another conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)

    19     Release START Signal (low level)

    20     Get Conversion (Relative to couple AIN1 – AIN7) and save the result

     

    (3rd  RTD)

    21     (Initial activity to get conversion on AIN2):  Assert START Signal (high level)

    22     Write 0x17 to register 0x00  (MUX0)

    - Select AIN2 as positive input channel

    - Select AIN7 as negative input channel

    23     Write 0xf4 to register 0x0b (IDAC1)

    - Output pin of Excitation current source 1 – always disabled

    - Output pin of Excitation current source 2 – AIN4 (pin 13 of ADS1248)                                   

    24     Wait 2 milliseconds

    25     Wait the conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)

    26     Get data from chip and discard them                                     

    27     Wait 1 millisecond

    28     Wait another conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)       

    29     Release START Signal (low level)

    30     Get Conversion (Relative to couple AIN2 – AIN7) an save the result

     

    (4th  RTD)

    31     (Initial activity to get conversion on AIN3):  Assert START Signal (high level)

    32     Write 0x1f to register 0x00  (MUX0)

    - Select AIN3 as positive input channel

    - Select AIN7 as negative input channel

    33     Write 0xf5 to register 0x0b (IDAC1)

    - Output pin of Excitation current source 1 – always disabled

    - Output pin of Excitation current source 2 – AIN5 (pin 14 of ADS1248)                                   

    34     Wait 2 milliseconds

    35     Wait the conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)

    36     Get data from chip and discard them                                     

    37     Wait 1 millisecond

    38     Wait another conversion has been completed, checking when DRDY# goes low (pin 25 of ADS1248)

    39     Release START Signal (low level)

    40     Get Conversion (Relative to couple AIN3 – AIN7) an save the result

    41     Go to loop

    RTD Interface ADS1248.pdf
  • Dear Bob,

    before you feel frightened by my previous help request, I want to update you with more recent actions made here.

    As you could see from the schematic attached in former post, basically my wiring folows your suggestions in an older post, and basically it's a 4-wire RTD circuitry. Really the 4 RTD's are 2-wire models, but the wires are very short (~50cm) so we can really consider the circuit like a 4-wire setup.

    Notice: the schematic has a mistake, where C96 was connected before R87. Here attached is the correct schematic.

    We use only one IDAC source and route it every step from IEXT1, IEXT2, AIN4 and AIN5. The RTS's are PT1000 so, with IDAC source @ 500uA, we have 845 milliVolt over the RRef, and in fact when it's 25ºC ambient temperature, and the RTD are almost 1100 Ohms, we have:  (32768/845)*550=21328=5350Hex. And when we run the whole system at the fantastic speed of..... 5 SPS we get very stable reading around this value.

    The problem is that we can't go faster.

    If we change to next speed step or higher, readings decrease to 3300Hex for all channels, stay stable but of course they are not the true temperature. Like the IDAC is not able to give enough current and we read a lover voltage drop over the RTD's.

    We have tried any of the following:

    a) preset the ADS1248 to work only between AIN0 and AIN7 (hence reading only RTD1) and then looping w/out any change in the MUX and IDAC routing registers.

    b) we have changed filter capacitors from 2.2uF to 100nF.

    c) we have changed gain and/or current intensity

    But as soon as we change the SPS higher than 5 SPS, we can't get any more the correct reading from the RTD, even if it's only one and no MUX routing.

    By the way, you see that the sequrence of actions shows that we have to make a reading and then discard it. Doing this (and running at 5 SPS) then we can get very precise RTD measurements; if we don't make this dummy reading, we can't get precise results.

    Before I begin to search for a poltergeist inside my board, would you kindly try to give me some help?

    If you need more info, don't hesitate to ask: I will immediately provide.

    Thanks a lot in advance.

    My best regards

    Paolo

    RTD Interface ADS1248(corrected).pdf
  • Paolo,


    At this point, I would concentrate on the reference and it's response time. If your reference is turned on and off, I would look at reducing C90 from 10uF to 1uF. It's unlikely that this is that large of a contributor, but it's something.

    Another thing I can see is the REFP1 and REFN1 inputs. The combination of C91 and R89 plus R91 makes a time constant that reaches into the milliseconds. With settling, you'd need maybe 10x that amount. By switching in different current paths, it might be briefly changing the reference value and requiring extra settling time. Start by reducing R89 and R91 to 1k and see if that helps.


    Joseph Wu

  • Dear All,

    for the benefit of people using ADS1248, we have found the hidden tricks to get perfect ADS1248 behavior.

    Our speed problems have been due to 2 things:

    1) the incorrect "position" of execution inside the program of the SYSOCAL command. 
    It must be done BEFORE any register initialization!

    2) excess RC filter value for the 4 inputs, where the 2.2uF has been now changed ionto 100nF. We have also changed C90 to 1uF. See attached schematic which reports new values.

    Here below there is the ultimate code:

    void thermoThread(void)

    {

            static embtime_t tmCold;

            static embtime_t tm;

            static u8 state = THERMOTHREAD_STATE_SETUP_START;

            static u8 sonda;

            u8 tmp;

            u32 val;

                  

            if (time_fired(tmCold)) {

                   tmCold = time_ms(100);         // cold joint temp read sometimes

                   temperatureBase = getTemperatureBase();

            }

           

            switch (state) {

            case THERMOTHREAD_STATE_SETUP_START:

                   state = THERMOTHREAD_STATE_SETUP_HARDWARE_SETUP;

                   break;

            case THERMOTHREAD_STATE_SETUP_HARDWARE_SETUP:

                   clrSpi1Clock();

                   assertReset(); //Put Chip in ResetMode (no operations)

                   releaseReset(); //Release Reset Pin (start chip)

     

                   releaseCs(0);

                   releaseCs(1);

                   assertStart(0); // start pin must be asserted from now!

                   assertStart(1); // start pin must be asserted from now!

                  

                   tm = time_ms(10);              // puls must last 4 ms min

                   state = THERMOTHREAD_STATE_SETUP_RESET_ADS;

                   break;

            case THERMOTHREAD_STATE_SETUP_RESET_ADS :

                   if (time_fired(tm)) {

                           spiAdcSendByte(0, ADS1248_CMD_RESET);

                           spiAdcSendByte(1, ADS1248_CMD_RESET);

     

                           tm = time_ms(5);               // post reset time (at least 0,6 ms but better longer)

                           state = THERMOTHREAD_STATE_SETUP_STOP_CONTINUOUS_MODE;

                   }

                   break;

            case THERMOTHREAD_STATE_SETUP_STOP_CONTINUOUS_MODE :

                   if ((getDRDYConversionComplete(0) == 0) || (getDRDYConversionComplete(1) == 0)) {

                           break;

                   }

                   AdcStopContinuousRead(0);

                   AdcStopContinuousRead(1);

                   tm = time_ms(100);

                   state = THERMOTHREAD_STATE_SETUP_OFFSET_CALIBRATION;

                   break;

            case THERMOTHREAD_STATE_SETUP_OFFSET_CALIBRATION:

                   if (time_fired(tm)) {

                           AdcSendSysOcal(0);

                           AdcSendSysOcal(1);

                           tm = time_ms(100);

                           state = THERMOTHREAD_STATE_SETUP_CONFIG_REGISTERS;

                   }

                   break;

            case THERMOTHREAD_STATE_SETUP_CONFIG_REGISTERS:              // set registers which stay the same along the whole conversion

                   if (time_fired(tm)) {

                           tmp = 0x28; // internal ref on, ref1 selected, normal op

                           AdcWriteReg(0, ADS1248_MUX1_REGISTER, &tmp, 1);

                           AdcWriteReg(1, ADS1248_MUX1_REGISTER, &tmp, 1);

                          

                           tmp = 0x03;                    // gain1 - 40 sps

                           AdcWriteReg(0, ADS1248_SYS0_REGISTER, &tmp, 1);

                           AdcWriteReg(1, ADS1248_SYS0_REGISTER, &tmp, 1);

                          

                           tmp = 0x04;            //500uA current source DRDY normal mode

                           AdcWriteReg(0, ADS1248_IDAC0_REGISTER, &tmp, 1);

                           AdcWriteReg(1, ADS1248_IDAC0_REGISTER, &tmp, 1);            

                          

                           tm = time_ms(500);

                           state = THERMOTHREAD_STATE_SETUP_FINALIZE;

                   }

                   break;

            case THERMOTHREAD_STATE_SETUP_FINALIZE:

                   if (time_fired(tm)) {

                           if ((getDRDYConversionComplete(0) == 0) || (getDRDYConversionComplete(1) == 0)) {

                                   break;

                           }

                           tm = time_ms(100); // wait 100mS before start loop readings

                           state = THERMOTHREAD_STATE_LOOP_START;

                   }

                   break;

                  

            // Continuous Reading Loop

            case THERMOTHREAD_STATE_LOOP_START:

                   if (time_fired(tm)) {

                           ConfigureMux(0, sonda);

                           ConfigureMux(1, sonda);

                           tm = time_ms(2);

                           state = THERMOTHREAD_STATE_LOOP_WAIT_DATA;

                   }

                   break;

            case THERMOTHREAD_STATE_LOOP_WAIT_DATA :

                   if ((getDRDYConversionComplete(0) == 0) || (getDRDYConversionComplete(1) == 0)) {

                           break;

                   }

                   state = THERMOTHREAD_STATE_LOOP_READ;

                   break;

            case THERMOTHREAD_STATE_LOOP_READ:

                   val = AdcReadConversion(0);

                   tcRawValues[0+sonda] = val >> 8;

                   val = AdcReadConversion(1);

                   tcRawValues[4+sonda] = val >> 8;

                  

                   if (++sonda == 4) {

                           sonda = 0;

                   }

                   state = THERMOTHREAD_STATE_LOOP_FINALIZE;

                   break;

            case THERMOTHREAD_STATE_LOOP_FINALIZE:

                   state = THERMOTHREAD_STATE_LOOP_START;

                   break;

            }

    }

     


    As you can see the thread is a state-machine.

    The code is quite readable.

    After... so many efforts, whoever needs some help can contact us!

    Paolo Bozzola

    paolo.bozzola@cjb.it 

    RTD Interface ADS1248(corrected-2).pdf
  • Paolo,


    Calibration should be done AFTER register initialization. The device should be set into the final configuration that you need before calibrating it to remove errors. If you imagine that the input PGA has an offset error, you want to set the PGA, and then calibrate out the offset error. If you run the calibration first and then set the PGA, your offset is probably no longer the same in a different gain.

    Incidentally, most people will not run a SYSOCAL. In a system offset calibration, you need to be able to short the inputs together outside the device and run the SYSOCAL. Often, people will configure the device they way they want and then run a SELFOCAL. In this case, a self offset calibration will tie the inputs together internally to the device and run the offset calibration. If you need an offset calibration, you may want to do it any time you change the gain or perhaps the data rate.

    Excess RC filter values can cause some delay in measurement. This not only applies for the analog inputs, but for the reference inputs as well. If you consider that the ADC compares the analog input to a reference value, both are similar in what they require for bandwidth and settling.


    Joseph Wu

  • Dear Joseph,

    I have edited this post right now after more testing this morning.

    For some Murphy's law issue, the s/f which you saw in previous message included the SYSOCAL command but truly the command code was for the SELFOCAL.
    Sorry.

    This is the updated programming sequence:


     

    void thermoThread(void)

    {

            static embtime_t tmCold;

            static embtime_t tm;

            static u8 state = THERMOTHREAD_STATE_SETUP_START;

            static u8 sensorIndex = 0;

            static u32 val_ads1 = 0;

            static u32 val_ads2 = 0;

            u8 tmp;

                  

            if (time_fired(tmCold)) {

                   tmCold = time_ms(100);

                   // Cold-Junction temperature updated every 100mS, not always

                   temperatureBase = getTemperatureBase();

            }

           

            switch (state) {

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_START:

                   // maybe we will do something here in the future...

                   state = THERMOTHREAD_STATE_SETUP_HARDWARE_SETUP;

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_HARDWARE_SETUP:

                  

                   clrSpi1Clock();

                   assertReset(); //Put Chip in ResetMode (no operations)

                   releaseReset(); //Release Reset Pin (start chip)

     

                   releaseCs(SPI_ADS1248_ONE);

                   releaseCs(SPI_ADS1248_TWO);

           

                   assertStart(SPI_ADS1248_ONE);  // start pin must be asserted during ADC configuration!

                   assertStart(SPI_ADS1248_TWO); // start pin must be asserted during ADC configuration!

                  

                   tm = time_ms(10);              // 4mS minimum

                   state = THERMOTHREAD_STATE_SETUP_RESET_ADS;

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_RESET_ADS :

                  

                   if (time_fired(tm)) {

                           spiAdcSendByte(SPI_ADS1248_ONE, ADS1248_CMD_RESET);

                           spiAdcSendByte(SPI_ADS1248_TWO, ADS1248_CMD_RESET);

     

                           tm = time_ms(5);               // post reset time (0,6mS minimum)

                           state = THERMOTHREAD_STATE_SETUP_STOP_CONTINUOUS_MODE;

                   }

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_STOP_CONTINUOUS_MODE :

                  

                   if ((getDRDYConversionComplete(0) == SPI_ADS1248_ONE) ||

                                   (getDRDYConversionComplete(1) == SPI_ADS1248_TWO)) {

                           break;

                   }

                   AdcStopContinuousRead(SPI_ADS1248_ONE);

                   AdcStopContinuousRead(SPI_ADS1248_TWO);

                   tm = time_ms(100);

                   state = THERMOTHREAD_STATE_SETUP_CONFIG_REGISTERS;

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_CONFIG_REGISTERS:

                  

                   if (time_fired(tm)) {

                           tmp = 0x28; // internal ref on, ref1 selected, normal operation

                           AdcWriteReg(SPI_ADS1248_ONE, ADS1248_MUX1_REGISTER, &tmp, 1);

                           AdcWriteReg(SPI_ADS1248_TWO, ADS1248_MUX1_REGISTER, &tmp, 1);

                          

                           tmp = 0x03;                    // GAIN=1  SPS=40

                           AdcWriteReg(SPI_ADS1248_ONE, ADS1248_SYS0_REGISTER, &tmp, 1);

                           AdcWriteReg(SPI_ADS1248_TWO, ADS1248_SYS0_REGISTER, &tmp, 1);

                          

                           tmp = 0x04;            //500uA current source DRDY normal mode

                           AdcWriteReg(SPI_ADS1248_ONE, ADS1248_IDAC0_REGISTER, &tmp, 1);

                           AdcWriteReg(SPI_ADS1248_TWO, ADS1248_IDAC0_REGISTER, &tmp, 1);           

                          

                           tm = time_ms(500);

                           state = THERMOTHREAD_STATE_SETUP_OFFSET_CALIBRATION;

                   }

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_OFFSET_CALIBRATION:

                  

                   if (time_fired(tm)) {

                           /* WE DO NOT WANT THE CALIBRATION

                           * system is powered without the first TC connected

                            * the calibration offset will cause wrong readings

                            * on all TC connected.

                            * we can't do it every reading because it takes

                           * about 400mS for 40 SPS

                           /*/

                           ConfigureMux0(SPI_ADS1248_ONE, sensorIndex);

                           ConfigureMux0(SPI_ADS1248_TWO, sensorIndex);

                           AdcSendSelfOcal(SPI_ADS1248_ONE);

                           AdcSendSelfOcal(SPI_ADS1248_TWO);

                           state = THERMOTHREAD_STATE_SETUP_WAIT_END_CALIBRATION;

                   }

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_WAIT_END_CALIBRATION:

     

                   // Wait the DRDY for the end calibration before start Read-Loop

                   if ((getDRDYConversionComplete(SPI_ADS1248_ONE) == 0) ||

                                   (getDRDYConversionComplete(SPI_ADS1248_TWO) == 0)) {

                           break;

                   }

                   state = THERMOTHREAD_STATE_SETUP_FINALIZE;

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_SETUP_FINALIZE:

           

                   tm = time_ms(10); // wait 10mS before start loop readings

                   state = THERMOTHREAD_STATE_LOOP_START;

                   break;

    //===================================================================================   

            // Continuous Reading-Loop states

            case THERMOTHREAD_STATE_LOOP_START:

                  

                   if (time_fired(tm)) {

                           ConfigureMux0(SPI_ADS1248_ONE, sensorIndex);

                           ConfigureMux0(SPI_ADS1248_TWO, sensorIndex);

                           assertStart(SPI_ADS1248_ONE);

                           assertStart(SPI_ADS1248_TWO);

                           state = THERMOTHREAD_STATE_LOOP_WAIT_DATA;

                   }

                   break;

    //===================================================================================

            case THERMOTHREAD_STATE_LOOP_WAIT_DATA :

                  

                   if ((getDRDYConversionComplete(SPI_ADS1248_ONE) == 0) ||

                                   (getDRDYConversionComplete(SPI_ADS1248_TWO) == 0)) {

                           break;

                   }

                   releaseStart(SPI_ADS1248_ONE);

                   releaseStart(SPI_ADS1248_TWO);

                   state = THERMOTHREAD_STATE_LOOP_READ;

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_LOOP_READ:

     

                   val_ads1 = AdcReadConversion(SPI_ADS1248_ONE);

                   val_ads2 = AdcReadConversion(SPI_ADS1248_TWO);

                   state = THERMOTHREAD_STATE_LOOP_FINALIZE;

                   break;

    //===================================================================================   

            case THERMOTHREAD_STATE_LOOP_FINALIZE:

                  

                   tcRawValues[0+sensorIndex] = val_ads1 >> 8;

                   tcRawValues[4+sensorIndex] = val_ads2 >> 8;

           

                   if (++sensorIndex == MAX_NUM_OF_SENSORS) {

                           sensorIndex = 0;

                   }

                   tm = time_ms(1); // wait 1mS before start a new reading

                   state = THERMOTHREAD_STATE_LOOP_START;

                   break;

            }

    }


    As you can see, we are performing the SELFOCAL (not SYSOCAL!) after register initialization, and still we get some "strange"result:

    a) we MUST call the ConfigureMux0 function to set the internal Mux (AIN0 and AIN7 for 1st RTD) before doing the SELFOCAL otherwise the SELFOCAL sets a totally wrong result

    b) IF the SELFOCAL is done (after setting the MUX0 for 1st RTD connected to AIN0 and AIN7) and RTD is missing or in short, SELFOCAL again gives unpredictable results on following readings

    So, it seems the SELFOCAL "is affected" by external connections, while the manual says that the PGA offset is computed after "internal" short of its inputs.

    So my questions are:

    ==> why SELFOCAL gives then wrong readings if RTD is not connected or has problems?

    ==> why SELFOCAL needs we set MUX0 ? If we do not do we always get wrong readings.

    ==> Is the short between PGA + and PGA - inputs done internally and automatically by the SELFOCAL or we need to  preset the MUX? Page 54 of the Manual clearly says "the device internally shorts the inputs". But it seems not

    ==> Or have we to set the MUX0 to "short" for example MUX_SP and MUX_SN together? (e.g.: both to AIN0)?

    These seems to be last unclear things.

    In a summary:

    Above code is running ok if the SELFOCAL is done after presetting 0x28 into MUX1,  0x03 into SYS0 and 0x04 into IDAC0 registers.

    Not only, but we must also set MUX0 before doin the SELFOCAL otherwise it does not work.

    Later today we will try other tests like setting PGA + and PGA- to same pin before sending the SELFOCAL, and see what happens.

    If we get more feedback I will ad a new post

    Many thanks in advance

    Paolo

  • Dear All,
    I see that a post I sent after Joseph Wu answer seems has gone lost.
    In that Post I was explaining that for some reason we were truly using the SELFOCAL correctly but who wrote the f/w used the SYSOCAL label.
    Sorry.
    Now the f/w works ok and we get perfect readings.
    But very slow SPS.
    Then I changed the capacitors values and finally we could run well at much faster SPS.
    If anybody needs the final schematics, I will be pleased to send a copy.

    Paolo Bozzola
  • Paolo,


    I'm glad you were able to get your system working. Let me know if you have any other questions.


    Joseph Wu
  • Thanks to you.

    My best regards

    Paolo