2018-09-06 08:02 AM
Hi, Everyone.
I'm tring to make adc sensor works, to find a temperature.
I found AVG_Slope and V_25 in the datasheet:
AVG_Slope = 0.0046
V_25 = 1.46
And I used V_Ref = 3.0f and N_Bit = 4096f
This is My code (Only for adc_complete conversion)
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc->Instance == ADC1 ){
float value;
value = ((float)adc1_buff[3]/N_BIT)*V_REF;
oil_temp = (float)(((V_25 - value)/Avg_Slope)+25);
//oil_temp = value;
//printf("Dato 1 %d, Dato 2 %d, Dato 3 %d, Dato 4 %d", adc1_buff[0], adc1_buff[1], adc1_buff[2], oil_temp);
}
else if (hadc->Instance == ADC2 ){
float val;
float result;
HAL_GPIO_TogglePin(GPIOB, LD3_Pin);
result = HAL_ADC_GetValue(&hadc2);
val = ((float)result/N_BIT)*V_REF;
ntc = (float)(((V_25-val)/Avg_Slope)+25);
}
The problem is that resoult is crazy!
I found about 300° for 3.3 V in, so, surely, I'm doing some mistakes, but I can't find it.
Someone could me help to find them?
Many thanks!
2018-09-06 03:55 PM
I use this code:
void readProcessorTemperature(void) {
/*
Temperature sensor calibration value address
#define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2))
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8))
#define VDD_CALIB ((uint16_t) (330))
#define VDD_APPLI ((uint16_t) (300))
*/
// Temperature sensor calibration value address
#define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2)) // calibrated at 3.3V +-10mV @110C +/- 5C
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8)) // calibrated at 3.3V +-10mV @ 30C +/- 5C
#define VREFINT_CAL ((uint16_t*) ((uint32_t) 0x1FFFF7BA)) // calibrated at 3.3V +-10mV @ 30C +/- 5C
#define VDD_CALIB ((uint16_t) (3300))
#define VDD_APPLI ((uint16_t) (3295))
int32_t AveTemperatureADC = ADC_Channel_AVE[VTemp_Ad16]; // 16x over sampled, needs /16
double processorTemp; // the temperature in degree Celsius
processorTemp = (double) AveTemperatureADC / 16 - *TEMP30_CAL_ADDR; // /16 to remove the over sampling
processorTemp *= 110 - 30;
processorTemp /= ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;
processorTemp += 30;
processorTemperature = (int32_t)(processorTemp * 100);
// sprintf(string,"AveTemperatureADC %04X, ADC_CalibrationFactor %04X, *TEMP30_CAL_ADDR %04X, processorTemperature %.2f, processorTemp %.3f \n\r",AveTemperatureADC,ADC_CalibrationFactor,(int32_t) *TEMP30_CAL_ADDR,((float)processorTemperature/100),processorTemp);
// puts (string);
Vdda = (double)16 * 3.3 * *VREFINT_CAL; // remove the 16x over sampling without losing resolution
Vdda /= ADC_Channel_AVE[VRef_Ad17];
//char string[64];
setCursor1(0, 90);
sprintf(string, "processor Temperature %.1f ", ((float)processorTemperature) / 100);
puts1(string);
sprintf(string, "Vdda as %.3f \n\r", Vdda);
puts1(string);
}
2018-09-07 06:32 AM
Hi Tj, many thanks for your reply.
I've read your code, but I can't understand it properly.
For example: ADC_Channel_AVE function where is defined?
2018-09-07 03:09 PM
the Average is only 16 samples added up, hence /16 is required.
otherwise you can use the direct ADC result... without /16
2018-09-08 01:58 AM
Hi Tj, many thanks for your reply.
I generated the code using CubeMX, and I've modify it.
I've tried to use your code as follows:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc->Instance == ADC1 ){
oil_temp = (double)adc1_buff[3] - *TEMP30_CAL_ADDR;
oil_temp *= 110 - 30;
oil_temp /= ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;
oil_temp += 30;
oil_temp = (double)(oil_temp * 100);
}
where oil_temp is a double variabile that should contains a temperature in Celsius degree, and adc1_buff[3] is the input voltage that should be transformed in the temperature.
The problem is the temperature result is not right, I found about -7045..
Any suggestion?
Many thanks.
2018-09-08 05:37 AM
this calculation is for processor temperature. I never checked it on a stm32F303
I do not understand what you mean by Oil Temperature.
Do you have an Oil Temp sensor connected to an analog input ?
which temperature sensor is it ?
2018-09-08 05:49 AM
Hi Tj, many thanks for your reply.
At the moment there isn't a sensor connected to the pin, but there will be.
The exact sensor I don't know what will be, but probabily an NTC.
I've seen this formula on the user manual:
And I tried it (first post), but temperature out is very strange, so, I need only this formula works.
I will adapte the V_Ref in function the sensor that I will connected, without changing the code, o, at least, that's what I'd like to do.
2018-09-08 05:57 AM
2018-09-08 06:31 AM
Hi Tj, many thanks for your reply.
So, I use ADC conversion with DMA, so, I have adc1 with 4 channel, and one of these are the channel where I need to reed the oil temperature.
So, this is the code:
/*! Buffer created to storage ADC data by DMA N.B Every cycle, this buffer is overwritten*/
uint16_t adc1_buff[4];
double oil_temp;
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1_buff, 4 );
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc->Instance == ADC1 ){
oil_temp = (double)adc1_buff[3] - *TEMP30_CAL_ADDR;
oil_temp *= 110 - 30;
oil_temp /= ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;
oil_temp += 30;
oil_temp = (double)(oil_temp * 100);
}
I leave the part where I make start the timer, and where I include the adc file, to make code easly to read.
ADC start conversion is triggered by Tim2.
I only use ADC, the temperature I'd like read by the formula post above, but the result is very strange..
2018-09-08 07:20 AM
If you use an NTC temp sensor then the formula I gave you for processor temp is incorrect.
you will have to calculate your NTC ADC to Temperature Algorithm