| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #include "stm32l1xx_hal.h"
- #include "app/thermo/NTCtsensor.h"
- #include "core/csect.h"
- #include "core/config.h"
- #include "core/config_pins.h"
- #include "drivers/adc/adc.h"
- #include "app/nfm/nfm_base.h"
- #include "math.h"
- // THERMO_SENSOR_KEEP_INITIALIZED
- // Do not turn off (=1) the sensor periferal driver btw measures
- #define NTC_THERMO_SENSOR_KEEP_INITIALIZED 1
- // THERMO_SENSOR_AVG_WINDOW
- // Digital exp-filter window size
- #define NTC_THERMO_SENSOR_AVG_WINDOW 8
- // THERMO_SENSOR_INTERVAL
- // Temperature measuring interval, ms
- #define NTC_DETECTION_HIGH_LEVEL 3970 // (3.2v) Value that indicates existance of sensor on line
- #define NTC_DETECTION_LOW_LEVEL 15 // (0.012v) Value that indicates existance of sensor on line
- #define NTC_THERMO_SENSOR_INTERVAL CONFIG_NTC_TSENSOR_INTERVAL
- #define NTC_LOW_RESISTANCE 1e3
- #define NTC_HIGH_RESISTANCE 35e4
- #define NTC_DEFAULT_TEMP_COEFF 3988
- static tNTCSensorTemp vNtcThermoSensor_AVGTemp = THERMO_SENSOR_INVALID_TEMP_VALUE;
- static size_t vNtcThermoSensor_AVGPoints = 0;
- static uint32_t vNtcThermoSensor_LastTick = 0;
- static uint32_t vNtcThermoSensor_Interval = NTC_THERMO_SENSOR_INTERVAL;
- static bool vNtcThermoSensor_bInitialized = false;
- static bool NtcThermoSensor_Init();
- static void NtcThermoSensor_UpdateAVGTemp( tNTCSensorTemp new_value ) ;
- static void NtcThermoSensor_ResetAvgTemp();
- static bool NtcThermoSensor_Serve();
- static bool NtcThermoSensor_GetReady();
- static tNTCSensorTemp NtcThermoSensor_GetAvgTemp();
- static void NtcThermoSensor_SetInterval(size_t ms);
- static bool NtcThermoSensor_GetAdcValue( tNTCSensorTemp * temp );
- static void NtcUpdateCurrentTempCoeff(uint16_t temp_coeff);
- const sNtcThermoSensorHandle_t NtcThermoSensor = {
- .Init = NtcThermoSensor_Init,
- .GetReady = NtcThermoSensor_GetReady,
- .ResetTempAVG = NtcThermoSensor_ResetAvgTemp,
- .ServeSensor = NtcThermoSensor_Serve,
- .GetTempAVG = NtcThermoSensor_GetAvgTemp,
- .SetSensorInterval = NtcThermoSensor_SetInterval,
- .UpdateCurrentTempCoeff = NtcUpdateCurrentTempCoeff
- };
- static uint16_t B_coeff = 0;
- static bool NtcThermoSensor_Init()
- {
- GPIO_InitTypeDef GPIO_NTC = {0};
- GPIO_NTC.Pin = CONFIG_PIN__NTC_TSENS_PWR;
- GPIO_NTC.Mode = GPIO_MODE_ANALOG;
- GPIO_NTC.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(CONFIG_PORT__NTC_TSENS_PWR, &GPIO_NTC);
-
- if(!NFMClass->methods.tempCoefficient.getTempCoeff(&B_coeff))
- {
- B_coeff = NTC_DEFAULT_TEMP_COEFF;
- }
-
- return true;
- }
- static bool NtcThermoSensor_GetReady()
- {
- bool bReady = false;
- __DI__
- bReady = ( vNtcThermoSensor_AVGPoints > 0 )
- && ( vNtcThermoSensor_AVGTemp != THERMO_SENSOR_INVALID_TEMP_VALUE );
- __EI__
- return bReady;
- }
- static void NtcThermoSensor_SetInterval(uint32_t ms)
- {
- __DI__ vNtcThermoSensor_Interval = ms; __EI__
- }
- static void NtcThermoSensor_ResetAvgTemp()
- {
- DI();
- vNtcThermoSensor_AVGTemp = THERMO_SENSOR_INVALID_TEMP_VALUE;
- vNtcThermoSensor_AVGPoints = 0;
- EI();
- }
- static tNTCSensorTemp NtcThermoSensor_GetAvgTemp()
- {
- tNTCSensorTemp value;
- __DI__ value = vNtcThermoSensor_AVGTemp; __EI__
- return value;
- }
- static int NtcThermoSensor_GetTempFromVoltage( tADCValue_t * adc_code )
- {
- uint16_t voltage = *adc_code * 3300 / 4095;
-
- float T1 = 298;
- double R1 = 10e3;
-
- double R2 = R1 * voltage / (3300 - voltage); // Resistance of NTC
- if(R2 <= NTC_LOW_RESISTANCE) R2 = NTC_LOW_RESISTANCE;
- if(R2 >= NTC_HIGH_RESISTANCE) R2 = NTC_HIGH_RESISTANCE;
- float b_value = ((log(R1)) - (log(R2))) / B_coeff;
- float temperature = (1 / ( (1 / T1) - b_value)) - 273;
- return (int)(temperature * 100); // in °C
- }
- static bool NtcThermoSensor_GetAdcValue( tNTCSensorTemp * temp )
- {
- tADCValue_t value;
- if(ADC1Handle.Start(CONFIG_ADC_CHANNEL_NTC_TSENS))
- {
- if(ADC1Handle.Measure(100, &value))
- {
- if(value <= NTC_DETECTION_HIGH_LEVEL && value >= NTC_DETECTION_LOW_LEVEL)
- {
- *temp = NtcThermoSensor_GetTempFromVoltage(&value); //Debug
- return true;
- }
- }
- }
- return false;
- }
- static void NtcUpdateCurrentTempCoeff(uint16_t temp_coeff)
- {
- B_coeff = temp_coeff;
- }
- static bool NtcThermoSensor_Serve()
- {
- bool bServe = false;
- __DI__ bServe = (HAL_GetTick() - vNtcThermoSensor_LastTick > vNtcThermoSensor_Interval); __EI__
- if( bServe )
- {
- if( !vNtcThermoSensor_bInitialized )
- {
- vNtcThermoSensor_bInitialized = NtcThermoSensor_Init();
- }
- if( vNtcThermoSensor_bInitialized )
- {
- tNTCSensorTemp temp_value;
- if( NtcThermoSensor_GetAdcValue( &temp_value ) )
- {
- NtcThermoSensor_UpdateAVGTemp( temp_value );
- }
- else
- {
- NtcThermoSensor_ResetAvgTemp();
- }
- }
- __DI__ vNtcThermoSensor_LastTick = HAL_GetTick(); __EI__
- }
- return bServe;
- }
- // ThermoSensor_UpdateAVGTemp
- // Performs averaging with exponential digital filter
- static void NtcThermoSensor_UpdateAVGTemp( tNTCSensorTemp new_value )
- {
- DI();
- if( (THERMO_SENSOR_INVALID_TEMP_VALUE) == vNtcThermoSensor_AVGTemp )
- {
- vNtcThermoSensor_AVGTemp = new_value;
- vNtcThermoSensor_AVGPoints = 1;
- }
- else
- {
- vNtcThermoSensor_AVGTemp = ( new_value + (tNTCSensorTemp)( vNtcThermoSensor_AVGTemp * vNtcThermoSensor_AVGPoints ) ) / (tNTCSensorTemp)( vNtcThermoSensor_AVGPoints + 1 );
- if( vNtcThermoSensor_AVGPoints < (NTC_THERMO_SENSOR_AVG_WINDOW) )
- vNtcThermoSensor_AVGPoints++;
-
- // Now @tmp is 16-bit value: [BBBBBBBBBB000000]
- // So, lets perform averaging:
- // n * AVG[i-1] + tmp
- // AVG[i] = -------------------
- // n+1
- // where
- // @AVG[i-1] is averaged temperature before operation,
- // @AVG[i] is averaged temperature after operation,
- // @n is the filter window size (=24),
- // @tmp is momentary measured temperature, [BBBBBBBBBB000000].
- //
- // So after averaging, bits 5..0 will be filled up.
- // Since the sensor has a 0.25*C accuracy, the @tmp should be divided
- // by 4 to get the value in degrees. But after averaging the whole accuracy
- // is changed due to the bits 5..0 are filled up. So, we need to divide
- // the value not 4, but 256 times to get value in degrees:
- // /4 - sensor accuracy
- // /64 - averaging accuracy (6 bits, 2^6=64)
- // So, 4*64 = /256 of degree.
- }
- EI();
-
- }
|