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.

ADS124S08: Converter stop to work properly

Part Number: ADS124S08

We are developing a signal transmitter with ADS124S08 and PIC32MX. Microcontroller is isolated form ADS124S08 via optocouplers (you can see that in attached file).

We are using internal reference and clock and input signals are single ended.

During testing we observed that converter stops to work properly and send zero as result. This situation persists until power is recycled (switched off and on). Not even a hardware reset makes the converter work properly.

Please, could you help me with this issue?

Thank you.

DImas Ramalho

dimas.ramalho@microsad.com.br

TH300.pdf

  • Hi Dimas,

    Usually this situation can happen if one of the Absolute Maximum Ratings is exceeded due to a transient or unexpected voltage.  Most likely the transient current is flowing through the ESD structure of the ADS124S08 and through the input pin of the ADC through the input filter resistor and then through a diode to ground.  The maximum current through the pin is 10mA.  The filter resistor is most likely not large enough in value to limit the current sufficiently.  I would suggest increasing the value of the filter resistors to see if that is an improvement.

    To be of more help I would need to know the conditions of the test where this is seen, and the specific device configuration (register settings) used.

    I did notice that in your schematic you are missing the required 330nF cap from AVDD to AVSS.

    Best regards,

    Bob B

  • Hi Bob,

    I´ll put 330 nF cap between AVDD and AVSS.
    Test condition is made with Thermocouple Type K and we have a contactor on and off with a cycle of 10 s making some noise.
    In the attached file you will find ADS_Int () that is called one time from the main initialising part and AnalogInputManager () that is called each 80 ms. This function reads channel 0 (room temperature for cold junction compensation from a TC1047) and channel 5 (TC-Type K).
    Best regards,
    Dimas Ramalho.
    AD_DS.c
    #include <xc.h>
    #include "tipos.h"
    #include "geral.h"
    #include "prot.h"
    #include "AD_DS.h"
    #include "par_def.h"
    
    extern SINT TabVar[];
    
    BYTE AIM_St;            // Estado atual do gerenciador das entradas anal�gicas
    BYTE ADS_Chn;           // Canal do AD
    BYTE ADS_Gain;          // Ganho do AD
    BYTE St_GPIO;           // Status dos pinos de I/O
    
    // Tabela com as leituras do AD 
    WORD Inp_Read[3];       // [0] - Leitura do AD para temperatura ambiente
                            // [1] - Leitura do AD para entrada local
                            // [2] - Leitura do AD para entrada remota
    
    struct T_ADC ADC;       // Status e resposta do AD     
    char ADS_TimerId;
    volatile BYTE Teste1;
    
    // -----------------------------------------------------------------------------
    // TMOD = TCLK * 16 E TCLK = 1 / 4.096 * 10E+6
    // -----------------------------------------------------------------------------
    void ADS_Init (void)
    {
        Timer4_Dly (ADS_RST_TMP);
        
        AIM_St = 0;
        
    //    SPI1_Config (SPI_CW_ADS);
    //    
    //    ADS_CS = ADS_CS_ON;
    //    
    //    SPI1_ByteMove (WREG + GPIODAT);
    //    SPI1_ByteMove (0x01);           // N�mero de bytes - 1.    
    //
    //    // -------------------------------------------------------------------------
    //    // GPIODAT[7:4] -> DIR[3:0] ; GPIODAT[3:0] -> DAT[3:0]
    //    //
    //    // DIR - BIT : 0 - sa�da
    //    //             1 - Entrada
    //    //
    //    // DAT - BIT : 0 - Sa�da em n�vel baixo
    //    //             1 - sa�da em n�vel alto
    //    //
    //    // Fonte de corrente desligada e burn-out ligado
    //    // -------------------------------------------------------------------------
    //    SPI1_ByteMove (0x0E);
    //
    //    // -------------------------------------------------------------------------
    //    // GPIOCON[7:4] -> N.U.     ; GPIOCON[0:3] -> CON[0:3] bit = 0 Anal�gica 
    //    // BIT : 0 - Anal�gica
    //    //       1 - Digital
    //    // -------------------------------------------------------------------------
    //    SPI1_ByteMove (0x0F);
    //    
    //    ADS_CS = ADS_CS_OFF;
    //    
    //    Timer4_Dly (ADS_CS_DLY);
        
        ADC_DOut ();
        
        ADS_CS = ADS_CS_ON;
     
        // Endere�o do primeiro registrador a ser escrito
        SPI1_ByteMove (WREG + INPMUX);
        
        // N�mero de bytes a serem enviados menos 1.
        SPI1_ByteMove (0x03);
        
        // Entrada positiva do A/D: Canal 0 (Temperatura ambiente);
        // Entrada negativa do A/D: Comum anal�gico
        SPI1_ByteMove (0x0C);
        
        // Tempo de atraso para in�cio da convers�o: 256 * Tmod (1 ms);
        // PGA habilitada;
        // Ganho unit�rio
        SPI1_ByteMove (0x68);
    
        // Global Chop habilitado;
        // Clock interno (4,096MHz);
        // Mode cont�nuo de convers�o;
        // Filtro de baixa lat�ncia
        // 60 SPS
        SPI1_ByteMove (0x96);  
        
        // Monitoramento da refer�ncia desabilitado;
        // Bypass do buffer positivo de refer�ncia interna desabilitado;
        // Bypass do buffer negativo de refer�ncia interna desabilitado;
        // Refer�ncia interna de 2,5;
        // Refer�ncia interna desliga em modo power down
        SPI1_ByteMove (0x39); 
        
        ADS_CS = ADS_CS_OFF;
        
        Timer4_Dly (ADS_CS_DLY);
        
        ADS_CS = ADS_CS_ON;
        
        SPI1_ByteMove (WREG + SYS);
        
        // Ajuste para 1 o n�mero de registradores a serem escritos 
        SPI1_ByteMove (0x00);
        // 8 amostragens para calibra��o do ganho e do offset do sistema;
        // Habilita o envio do status pr� posto ao resultado da convers�o
        SPI1_ByteMove (0x11);
            
        ADS_CS = ADS_CS_OFF;
        
        Timer4_Dly (ADS_CS_DLY);
        
        ADS_CS = ADS_CS_ON;
        
        SPI1_ByteMove (START);          // Inicia a convers�o
      
        ADS_CS = ADS_CS_OFF;
        
        Timer4_Dly (ADS_CS_DLY);
        
    //    ADS_CS = ADS_CS_ON;
    //    
    //    SPI1_ByteMove (RREG + GPIODAT);
    //    SPI1_ByteMove (0x00);                   // N�mero de bytes - 1.
    //    St_GPIO = SPI1_ByteMove (0) & 0x08;     // Envia o status junto com o resul-
    //                                            // tado da convers�o.     
    //    ADS_CS = ADS_CS_OFF;   
    //    
    //    JP1 = (St_GPIO >> 3) & 1;
    //    
    //    Timer4_Dly (ADS_CS_DLY);
    }
    
    BYTE ADS_Status (void)
    {
        BYTE Status;
        
    //    SPI1_Config (SPI_CW_ADS);    
        
        Timer4_Dly (ADS_CS_DLY);
        ADS_CS = ADS_CS_ON;
        
        SPI1_ByteMove (RREG+STATUS);
        SPI1_ByteMove (0);
        Status = SPI1_ByteMove (0);
        
        ADS_CS = ADS_CS_OFF;
    
        return (Status);
    }
        
    //void Le_GPIO (void)
    //{
    //    ADS_CS = ADS_CS_ON;
    //    
    //    SPI1_ByteMove (RREG + GPIODAT);
    //    SPI1_ByteMove (0x00);                   // N�mero de bytes - 1.
    //    St_GPIO = SPI1_ByteMove (0) & 0x07;     // Envia o status junto com o resul-
    //                                            // tado da convers�o.     
    //    ADS_CS = ADS_CS_OFF;   
    //    
    //    JP3 = St_GPIO & 1;
    //    JP2 = (St_GPIO >> 1) & 1;
    //    JP1 = (St_GPIO >> 2) & 1;   
    //    
    //    Inp_Read[1] = 0x8bcd;
    //}
    
    void ADS_Reset (void)
    {
        BYTE NTmr;
        
        SPI1_Config (SPI_CW_ADS);
        
        ADS_CS = ADS_CS_ON;
        
        SPI1_ByteMove (RESET);
    
        ADS_CS = ADS_CS_OFF;
        
        NTmr = LTimer_Alloc ();
        
        LTimer_On (2, NTmr);
        
        while (LTimer_St (NTmr));
    }
    
    void ADS_Read (void)
    {
        Timer4_Dly (ADS_CS_DLY);
        
        SPI1_Config (SPI_CW_ADS);
        
        ADS_CS = ADS_CS_ON;
        
        SPI1_ByteMove (RDATA);              // Envia o comando para ler o resultado
                                            // da convers�o    
        ADC.St = SPI1_ByteMove (0x00);      // L� o status   
        ADC.Res[2] = SPI1_ByteMove (0x00);  // L� o LSB da MSW
        ADC.Res[1] = SPI1_ByteMove (0x00);  // L� o MSB da LSW
        ADC.Res[0] = SPI1_ByteMove (0x00);  // L� o LSB da LSW
        
        ADS_CS = ADS_CS_OFF;       
    }
    
    void ADS_SelfCal (void)
    {
        SPI1_Config (SPI_CW_ADS);
        
        ADS_CS = ADS_CS_ON;
        
        SPI1_ByteMove (SFOCAL);             // Envia o comando de calibra��o do
                                            // offset
        ADS_CS = ADS_CS_OFF;        
    }
    
    // -----------------------------------------------------------------------------
    // Esta fun��o gerencia a aquisi��o dos sinais anal�gicos: temperatura ambiente
    // e entrada de sinal. Ela � chamada a partir de DoEvents a cada 80 ms.
    // -----------------------------------------------------------------------------
    void AnalogInputManager (void)
    {  
        switch (AIM_St)
        {
            // Temperatura ambiente
            case 0:
                ADS_Read ();
                Inp_Read[0] = 256 * ADC.Res[2] + ADC.Res[1];
                
                Timer4_Dly (ADS_CS_DLY);
                
                // Seleciona a entrada e o ganho do AD conforme INP1
                SelInpGain (); 
                
                Timer4_Dly (ADS_CS_DLY);     
                
    //            // Ligue a fonte de corrente se o tipo de sensor for RTD
    //            
    //            if (TabVar[INP1] == RTD)
    //               CtrlFonteCorrente (FC_ON);
    //            else
    //               CtrlFonteCorrente (FC_OFF);
    
                AIM_St = 1;
                break;
                
            // Entrada local 
            case 1:
                ADS_Read ();
                Inp_Read[1] = 256 * ADC.Res[2] + ADC.Res[1];
                
                Timer4_Dly (ADS_CS_DLY);
                
                AjInpGain (CH_TA, G1); 
                
                AIM_St = 0;
                break;           
        }
    }
    
    // -----------------------------------------------------------------------------
    // Esta fun��o ajusta o canal e o ganho a serem usados pelo AD para a leitura da
    // entrada local selecionada em INP1.
    // -----------------------------------------------------------------------------
    void SelInpGain (void)
    {
        switch (TabVar[INP1])
        {
            case RTD:
                AjInpGain (CH_RTD, G32);
                break;
                
            case MA1:
            case MA2:
                AjInpGain (CH_MA, G32);
                break;
                
            case VT1:
            case VT2:
                AjInpGain (CH_5V, G32);
                break;
                
            case VT3:
                AjInpGain (CH_10V, G32);
                break;
                
            default:
                AjInpGain (CH_MV, G32); 
        }
    }
    
    // -----------------------------------------------------------------------------
    // Seleciona a entrada e o ganho desejado no ADS124S08. InpNum � o canal deseja-
    // do (0 a 7) Gain � o ganho desejado (de 0 (G=1) a 7 (G=128)).
    // -----------------------------------------------------------------------------
    void AjInpGain (BYTE InpNum, BYTE Gain)
    { 
        // Configure a porta SPI para acesso ao ADS124S08.
        SPI1_Config (SPI_CW_ADS);             
        // Ative o chip select.
        ADS_CS = ADS_CS_ON;                        
        // Envie comando para escrita no INPMUX
        SPI1_ByteMove (WREG + INPMUX); 
        // Ajuste n�mero de registradores para 2
        SPI1_ByteMove (1);
        // Ajuste o canal desejado do ADS (entrada +). A entrada negativa � AINCOM.
        SPI1_ByteMove (InpNum + 0x0C);
        // Ajuste LTimer_Dly de 1 ms (DLY_256), ligue o PGA e o ganho desejado.
        SPI1_ByteMove (DLY_256 + PGA_ON + Gain); 
        // Desative o chip select     
        ADS_CS = ADS_CS_OFF; 
    }
    
    // -----------------------------------------------------------------------------
    // Fun��o para controle da fonte de corrente. O par�metro Estado liga a fonte de
    // corrente se for TRUE e desliga se for FALSE. A fonte de corrente deve ser li-
    // gada apenas quando o sensor utilizado for PT-100.
    // -----------------------------------------------------------------------------
    void CtrlFonteCorrente (BYTE Estado)
    {
        // Configure a porta SPI para acesso ao ADS124S08.
        SPI1_Config (SPI_CW_ADS);            
        
        // Ative o chip select.                                    
        ADS_CS = ADS_CS_ON;                        
        
        // Envie o comando de escrita no GPIODAT
        SPI1_ByteMove (WREG + GPIODAT);      
        
        // Ajuste o n�mero de bytes para 2.
        SPI1_ByteMove (1);
        
        // Ajuste GPIO3 com o n�vel desejado
        SPI1_ByteMove (0x70 | (8 * Estado));
        
        // Ajuste o registrador GPIOCON (todos os pinos configurador para digitais)
        SPI1_ByteMove (0x0F);    
        
        // Desative o chip select
        ADS_CS = ADS_CS_OFF;                             
    }
    
    // -----------------------------------------------------------------------------
    // ADC_DOut controla as sa�das digitais do ADS124S08E. 
    //
    // GPIO3 : Upscale burnout protection (1 - ON; 0 - OFF) 
    // GPIO2 : Downscale burnout protection (1 - OFF; 0 - ON)
    // GPIO1 : Dreno de corrente para RTD (1 - OFF; 0 - ON)
    // GPIO0 : Fonte de corrente para RTD (1 - ON; 0 - OFF)
    //
    // GPIO0 e GPIO1�s�o controladas pelo par�metro INP1, assim, sempre que INP1 �
    // alterado esta fun��o deve ser executada.
    //
    // INP1 == RTD : GPIO1 = 1 e GPIO0 = 0
    //      != RTD : GPIO1 = 0 e GPIO0 = 1
    //
    // GPIO3 e GPIO2 s�o controladas pelo par�metro BURN_P (Burnout Protection). 
    //
    // BURN_P : 0 - GPIO3 = 0 e GPIO2 = 1 : OFF
    //          1 - GPIO3 = 1 e GPIO2 = 1 : Upscale
    //          2 - GPIO3 = 0 e GPIO2 = 0 : Downscale
    //
    // A prote��o contra burnout deve permanecer desligada se o sensor for RTD. 
    // -----------------------------------------------------------------------------
    void ADC_DOut (void)
    {
        BYTE Dado;
        
        if (TabVar[INP1] == RTD)
            Dado = 9;
        else
        {
            switch (TabVar[BURN_P])
            {
                case 0:
                    Dado = 10;
                    break;
    
                case 1:
                    Dado = 2;
                    break;
                    
                case 2:
                    Dado = 14;
            }
        }
        
        // Configure a porta SPI para acesso ao ADS124S08.
        SPI1_Config (SPI_CW_ADS);            
        
        // Ative o chip select.                                    
        ADS_CS = ADS_CS_ON;                        
        
        // Envie o comando de escrita no GPIODAT
        SPI1_ByteMove (WREG + GPIODAT);      
        
        // Ajuste o n�mero de bytes para 2.
        SPI1_ByteMove (1);
        
        // Ajuste os pinos de sa�da (GPIO3 : GPIO0)
        SPI1_ByteMove (Dado);
        
        // Ajuste o registrador GPIOCON (todos os pinos configurados para digitais)
        SPI1_ByteMove (0x0F);    
        
        // Desative o chip select
        ADS_CS = ADS_CS_OFF; 
        
        Timer4_Dly (ADS_CS_DLY);
    }
  • Hi Dimas,

    I would focus on the contactor. Large transients often occur when the contactor is energized and deenergized.  The TC will have wiring that will pick up these transients similar to an antenna.  I would connect a scope to the various analog inputs to look for these transients and if the absolute maximum ratings for the ADC are violated. 

    I would also observe the analog ground to see if there is any significant ground bounce.  This may be an indicator of poor grounding or board layout issues.

    Best regards,

    Bob B