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: Crashing

Part Number: ADS124S08

Hi Bob

We are still developing the transmitter with input for multiple types of sensors (TC, RTD, among others) and 4 to 20 mA output based on ADS124S08 and PIC32MX.

Although we did input the improvings you suggested we are still experiencing crashs from the ADS.

Basically, It works perfectly in the lab envoirment.

But, as we submit the device to a noise generated by a contactor switching (period of 5s and duty cycle of 50%) we observed after some time that the ADS124S08 stops to work properly and even a software restart doesn´t recover its normal working. Just after a power recycling ADS124S08 return to normal operation.

In the attached file you will find schematic diagram and software code (in C). This time we input in the diagram the power supply.

Hopefully you could help us to solve it.

Best Regards

Joao Luiz Froehlich
Development Engineer
TH300V4.pdf

5554.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[];
// ----------------------------- STATUS DO JUMPER ------------------------------
// STATUS DO Jumper: ON - Jumper inserido; OFF - Jumper removido
BYTE JP1;   // JP1 - Sa�da anal�gica presente

// -----------------------------------------------------------------------------

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[0:3] -> DAT[0:3]
    //
    // 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 (0x85);

    // -------------------------------------------------------------------------
    // 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);
    
    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;                             
}

  • Hi Joao,

    I don' see anything as an issue with the code.  EMI can be a concerning problem as this can enter the PCB in a couple of ways.  One is through the power supply and the other is external wiring connected to the analog inputs.  There is a lot going on within your schematic, so it is difficult for me to predict exactly what is happening but often times when the ADC just stops working there is an overstress condition taking place where the Absolute Maximum Ratings of the ADS124S08 are being exceeded.  This is generally where the input voltage exceeds the supply by more than 300mV and the current through the input pins exceeds 10mA.  It is important to note regardless of the input being measured any input that exceeds the Absolute Maximum Ratings can affect device operation.

    Poor PCB routing where large inductances due to narrow traces in the ground and power path can make the issues worse.  In the end, you need to determine how the EMI from the contactor is affecting your system.  After determining the source of how the EMI is causing the ADS124S08 to stop working you can then find a solution for resolving the transient.

    Best regards,

    Bob B