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
#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; }