Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

ADS124S08: Read ADC From ADS124S08

Part Number: ADS124S08

Tool/software:

Hi

I'ım using STM32 microcontroller and ADS124S08 with thermopile and NTC.

In particular, I can connect the thermopile and read the correct mV value. If I need to explain in detail, when I hold a flashlight to the thermopile, I read the same values from both the multimeter and the value displayed with mvValue. But when I disassemble the thermopile and read it when it is empty, it tends to drop down from 1249... mV. This is exactly what is shown in the video.

A second point is that when I connect the thermopile and cover it with my hand or cover it with something black, I get the same value of 1249... and this value remains constant. This is the situation in the photo.

Note: In both the video and the photo, the temperature sensor (NTC) is not connected.

My documents related to software and hardware are attached. Is there anything wrong? How can I overcome this problem?

2185.ADS124S08.h

2185.ADS124S08.c
/*
 * Aut EArsanaci
 * ADS124S08.c
 *
 */

#include "ADS124S08.h"
#include "main.h"
#include <math.h>

extern SPI_HandleTypeDef hspi1;
extern struct ads124s08 adcValue;
extern struct irradiance irradiance;

// Initializes device for use in the ADS124S08
int8_t initDevice(void)
{
	//Default register settings
	// Reset Device
	HAL_GPIO_WritePin(GPIOA, CS_Pin, RESET);
	HAL_SPI_Transmit(&hspi1, (uint8_t *)RESET_OPCODE_MASK, 1, 100);
	HAL_GPIO_WritePin(GPIOA, CS_Pin, SET);

	//Write Ref Voltage
	uint8_t write_refvolt[3] = {0};
	write_refvolt[0] = 0x45;
	write_refvolt[1] = 0x00;
	write_refvolt[2] = 0x3A;
	assertStart();
	HAL_GPIO_WritePin(GPIOA, CS_Pin, RESET);
	HAL_SPI_Transmit(&hspi1, write_refvolt, 3, 250);
	HAL_GPIO_WritePin(GPIOA, CS_Pin, SET);
	deassertStart();

	return (1);
}

// Sets the GPIO hardware START pin HIGH

void assertStart()
{
	HAL_GPIO_WritePin(GPIOA, START_Pin, SET);
}

// Sets the GPIO hardware START pin LOW

void deassertStart()
{
	HAL_GPIO_WritePin(GPIOA, START_Pin, RESET);
}

// For start the device you need read data one time
void startDevice(void)
{
	readDataThermopile(&adcValue);
}


void set_gain(uint8_t gain_data)
{
	uint8_t write_gain[3] = {0};
	write_gain[0] = 0x43;
	write_gain[1] = 0x00;
	write_gain[2] = gain_data;
	assertStart();
	HAL_GPIO_WritePin(GPIOA, CS_Pin, RESET);
	HAL_SPI_Transmit(&hspi1, write_gain, 3, 250);
	HAL_GPIO_WritePin(GPIOA, CS_Pin, SET);
	deassertStart();
}

void change_inmux(uint8_t channel)
{
	uint8_t write_mux[3] = {0};
	write_mux[0] = 0x42;
	write_mux[1] = 0x00;
	write_mux[2] = channel;
	assertStart();
	HAL_GPIO_WritePin(GPIOA, CS_Pin, RESET);
	HAL_SPI_Transmit(&hspi1, write_mux, 3, 250);
	HAL_GPIO_WritePin(GPIOA, CS_Pin, SET);
	deassertStart();
	HAL_Delay(1);
}

void start_conversion()
{
	//Start Conversion Mode
	uint8_t start[1]= {0x08};
	HAL_GPIO_WritePin(GPIOA, CS_Pin, RESET);
	HAL_SPI_Transmit(&hspi1, start, 1, 250);
	HAL_GPIO_WritePin(GPIOA, CS_Pin, SET);
	HAL_Delay(1);
}

void readData(uint8_t *data)
{
	uint8_t rdata[1]= {0x12};
	assertStart();
	HAL_GPIO_WritePin(GPIOA, CS_Pin, RESET);
	HAL_SPI_Transmit(&hspi1, rdata, 1, 250);
	HAL_SPI_Receive(&hspi1, data, 3, 250);
	HAL_GPIO_WritePin(GPIOA, CS_Pin, SET);
	deassertStart();
}

void readDataThermopile(struct ads124s08 *adcValue)
{
	static double mvValue = 0;

	set_gain(0x0A);
	change_inmux(0x01);
	start_conversion();

	//Read Data Mux AIN0-AIN1
	uint8_t rdata_data[3] = {0};
	readData(rdata_data);

	volatile int32_t value = (rdata_data[0] << 16) | (rdata_data[1] << 8) | rdata_data[2];

	if(value > 0)
	{
		mvValue = ((value * 0.625 / 0x7FFFFF)*1000);
		adcValue->mvValue = mvValue;
		adcValue -> irr_adc = value;
	}

}

void readDataNtc(struct ads124s08 *adcValue)
{
	double ntcValue = 0;
	double ntcOhm = 0;
	static double temperature = 0;

	uint8_t rdata_data[3] = {0};

	set_gain(0x08);
	change_inmux(0x23);
	start_conversion();

	readData(rdata_data);
	volatile int32_t value = (rdata_data[0] << 16) | (rdata_data[1] << 8) | rdata_data[2];

	if(value != 0)
	{
		ntcValue = value * 2.5/ 0x7FFFFF;
		ntcOhm = (5e+7 * (2.5 - ntcValue)) / (25e+3 - (15e+3 * (2.5 - ntcValue)));
		temperature = (1 /(1.123431435e-3 + (2.349138236e-4 * log(ntcOhm)) +
				(0.8546607990e-7 * pow(log(ntcOhm),3))))- 273.15;
		adcValue->temperature = temperature;
	}

}

void calculateIrradiance(struct ads124s08 *adcValue, struct irradiance *irradiance)
{
		irradiance->compIrradiance = adcValue->mvValue / adcValue->sensivity;
}

//void run_irradiance(struct irradiance *irradiance)
//{
//	calculateIrradiance(&(irradiance->ads124s08), &irradiance);
//}

  • Hi Emre ARSANACI,

    If your inputs are floating when the thermopile is disconnected, then that input will be undefined. It looks like in your system you have one pin (AIN1) biased to mid-supply, while the other pin (AIN0) is floating. So it makes sense you are getting a nonzero value with the thermopile removed

    If you want to get a known input when the thermopile is disconnected, you will need to bias both pins through weak pull-up/pull-down resistors. This might inject some small current into the thermopile measurement, but this is usually the way that thermocouples are biased.

    -Bryan

  • Hi Bryan,

    Thanks for reply. I am aware of what you said about the value I saw when I removed the thermopile, but I have the following problem. When I cover the thermopile with a black cloth or with my hand, I see the same floating values. Or when I leave it outside at night, I see floating values again when there is no light in the environment. What are your thoughts on this subject?

  • Hi Emre ARSANACI,

    What is the point of covering the thermopile with a cloth or having no light in the environment? It is my understanding that a thermopile is several thermocouples in series and is therefore measuring temperature

    What values are you reading when you do this? Can you provide the raw ADC readings in hex, as well as the measured voltage at the input (using a 6.5 digit DMM or better)?

    -Bryan

  • Under the sun, it outputs mV due to the temperature difference. The reason I cover it is that I want it to show 0. When I put my hand, the mV value comes because I create a temperature difference again. For example, I read this value such as 2mV with a multimeter. But I read floating value through the ADS integration.

    Unfortunately, I cannot take measurements with an oscilloscope. When I take a measurement with a DMM, I get data like in the video below. 

    irradc is the value that I read from the ADS124S08 integration. irradc is the value that I read from the ADS124S08 integration. It is also available in the software file above.  Unfortunately I don't have a better DMM available. Sometimes the value I read on the DMM can be -0.1 mV. 

     

  • Hi Emre ARSANACI,

    The ADS124S08 has a binary two's complement coding scheme, this might be the issue

    In your video, you show an "average" code of about 300 when the sensor is uncovered, and this corresponds to a voltage of 0.1mV on your DMM (this is unfortunately not the correct tool to use for these types of measurements). A code value of 300 corresponds to a voltage of 22uV assuming you are using the ADC's internal 2.5V voltage reference and a gain of 4.

    Then you show an average code of 16776626 when the sensor is covered, which reads 0V or -0.1mV on your DMM. Since the ADC uses a bipolar coding scheme, this large value is actually a very small negative value (Code - 2^24 = -590). This corresponds to a voltage of -44uV, not 1.249V.

    I don't know what the expected range of output signals from your sensor should be, but this seems reasonable given that there is likely a negligible temperature difference between covered and uncovered

    -Bryan