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.

ADS1118EVM: Way to get accurate value in both modes

Part Number: ADS1118EVM
Other Parts Discussed in Thread: ADS1118

Hi Everyone,

I am working on an application, where I am interfacing ADS1118 EVM with EK-TM4C1294Xl.
Following is my configuraion
1) SPI2 module selected
    SSI TX - PD1
    SSI RX - PD0
    SSI FSS - PD2
    SSI CLK - PD3

I believe SSI interface is working fine.
2) Config register values sent
    a) ADC mode :  0xBD0B
    b) Temperature sensor mode : 0x8D1B
3) Converaion register got
    a) ADC mode : 0x106
    b) Temperature sensor mode : 0xBE8
4) After calculation:
    a) ADC mode: 2mV : Hot junction of thermocouple dipped in hot water of temperature 66-degree celsius. Measured by thermal gun.
        Formula used:
        Didn't perform reverse of 2's complement. Bipolar value selected (2^15).
        Voltage(mV) = (256 * conv_reg[0]) / 32768
    b) Temperature sensor mode: 23-degree celsius : Thermal gun measurement 26/27-degree celsius.
        Formula used:
        Right shift to obtain 14 bit value.
        Considering +/-0.03125 for final value.

I am not sure, whether I am getting correct values. Please guide me in right direction and let me know, If I am missing out any steps. My code is attached.

spi_final.c
//
//This program is used for interfacing ADS1118 temperature sensor to TM4C1294NCPDT microcontroller.
//TM4C1294NCPDT microcontroller provides Quad Synchronous Serial Interface(SSI).
//
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "uartstdio.h"

#define NUM_SSI_DATA 2

//
//UART0 is configured to get debug logs.
//
void InitConsole(void)
{
//
// Enable GPIO port A which is used for UART0 pins.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

//
// Configure the pin muxing for UART0 functions on port A0 and A1.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);

//
// Enable UART0 to configure the clock.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

//
// Using the internal 16MHz oscillator as the UART clock source.
//
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

//
// Select the alternate (UART) function for these pins.
//
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

//
// Initialize the UART for console I/O.
//
UARTStdioConfig(0, 115200, 16000000);
}

int main(void)
{
uint32_t ui32SysClock;
uint16_t config_reg[NUM_SSI_DATA];
uint16_t conv_reg[NUM_SSI_DATA];
uint16_t dummy;
uint16_t temp;
int index;
int i = 1;
uint16_t raw_data = 0;
uint16_t bit_test;

config_reg[0] = 0xbd0b;
config_reg[1] = 0x8d1b;

//
//Sets clock source for SSI module.
//
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_OSC), 25000000);

//
// Sets the serial console to use for displaying messages.
//
InitConsole();

//
// Display the setup on the console.
//
UARTprintf("SSI ->\n");
UARTprintf(" Mode: SPI with Polarity 0 and Phase 1\n");
UARTprintf(" Data: 16-bit\n\n");


SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);


SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

GPIOPinConfigure(GPIO_PD3_SSI2CLK);
GPIOPinConfigure(GPIO_PD2_SSI2FSS);
GPIOPinConfigure(GPIO_PD0_SSI2XDAT1);
GPIOPinConfigure(GPIO_PD1_SSI2XDAT0);

GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0);

SSIConfigSetExpClk(SSI2_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_1,
SSI_MODE_MASTER, 2000000, 16);

SSIEnable(SSI2_BASE);

for(index = 0; index < NUM_SSI_DATA; index++){
    while(SSIDataGetNonBlocking(SSI2_BASE, &conv_reg[index]))
    {
    }
}

SSIDataPut(SSI2_BASE, config_reg[0]);
UARTprintf("ADC_MODE config register sent\n\n");
while(SSIBusy(SSI2_BASE))
{
}

while(1){

SysCtlDelay(5750000);

if (i == 1) {
SSIDataGet(SSI2_BASE, &dummy);
UARTprintf("dummy data received\n");
i--;
}
SSIDataPut(SSI2_BASE, config_reg[1]);
UARTprintf("TEMP_MODE config register is sent\n\n");

SSIDataGet(SSI2_BASE, &conv_reg[0]);
UARTprintf("ADC_MODE data received is %x\n\n",conv_reg[0]);

//conv_reg[0] = ~(conv_reg[0] - 1);
temp = (256 * conv_reg[0]) / 32768;
UARTprintf("Thermocouple voltage difference value is %dmV\n\n", temp);

while(SSIBusy(SSI2_BASE))
{
}

SysCtlDelay(5750000);

SSIDataPut(SSI2_BASE, config_reg[0]);
UARTprintf("ADC_MODE configured\n");

SSIDataGet(SSI2_BASE, &conv_reg[1]);
UARTprintf("TEMP_MODE data received is %x\n\n",conv_reg[1]);

raw_data = conv_reg[1];
UARTprintf("raw data received as integer is %x\n", raw_data);
raw_data = raw_data >> 2;
UARTprintf("raw data received as integer is %x\n", raw_data);

bit_test = raw_data;

if((bit_test & 0x2000) == 1){
raw_data = raw_data - 0x01;
raw_data = ~(raw_data);
temp = (raw_data * (-0.03125));
UARTprintf("value in celsius is %d\n", temp);
} else {
temp = (raw_data * 0.03125);
UARTprintf("value in celsius is %d\n", temp);
}

}
}

  • Nischita,



    Based on your inputs and the settings, the values look ok to me.

    For the ADC mode, it looks like you are measuring from AIN2 to AIN3, with a data rate of 128SPS, and a FSR of ±0.256V. You're using single shot conversion mode, which I think is the best way to use this device.

    For the ADC data, you get a result of 0x106. This is 262d. To convert this to voltage. You use (262/2^15)*0.256. This gives a result of 2.05mV, which is close to the 2mV that you expect.

    For the temperature data, you get a result of 0xBE8. Because this is left justified, you right shift this two places to get 0x2FA. This is 762. Converting this value to temperature, you would use 762*0.03125. This result is 23.8125°C.

    So both results come close to your expected results.



    Joseph Wu
  • Hi Joseph,

    Thanks for explanation. I would like to know one more thing, that with 66-degree celsius of hot water temperature and 26-degree celsius as internal temperature resulting with 2mV as output from ADS1118 ADC mode is okay? Is it correct?

  • Nischita,

    A 2mV value seems close depending on the type of thermocouple, but there's definitely a potential for some error in the measurement.

    There is a TI guide to basic thermocouple measurements that you can use to learn about them. It'll give some information about thermocouples and how you can connect them to ADCs to get measurements. You can find a link below:

    Joseph Wu

  • Thanks, will go through this.