Newer
Older
/*
* temperatureRegulation.c
*
* Created on: Apr 16, 2023
* Author: Flax
*
* Prefix : REG
*/
// ==============
// Local includes
// ==============
#include "temperatureRegulation.h"
// ===============
// Local constants
// ===============
#define cREGTempSPTMax (400U)
#define cREGTempSPTMin (50U)
#define cREGTempSPTDft (250U)
#define cREGTempSPTStbyDft (100U)
#define cREGPwmMax (65535)
#define cRegPIDProp (10)
#define cRegPIDInteg (10)
#define cRegPIDDeriv (10)
// Temperature measure transfer function parameters
// OPA gain : 681
// Input divider bridge gain : 100k / (100k + 5k6) = 0.946969
// On legacy Arduino code : gain = 0.39, offset = 23.9, resolution 10 bits
// Translated to 12 bits : 0.0975 ~= 100 / 1024
#define ADC_TO_TEMP_GAIN_NUM (100U)
#define ADC_TO_TEMP_GAIN_DEN (1024U)
#define ADC_TO_TEMP_OFFSET (24U)
#define cREGAdcErrorThres (4090U)
// ===============
// Local variables
// ===============
static bool RegOffState_B;
static bool RegStandbyState_B;
static bool RegErrorState_B;
static uint16_t RegTempSPT_U16;
static uint16_t RegTempMeas_U16[2U];
static uint16_t RegTempMeasBuffer_U16A[2U];
static int32_t RegPwmDyc_S32;
static uint32_t RegPwmDyc_U32;
static uint16_t RegTempDeg_U16;
// PID
static int32_t RegEpsilon_S32A[2U];
// ==========================
// Local functions prototypes
// ==========================
// ===========================
// Local functions definitions
// ===========================
// ============================
// Shared functions definitions
// ============================
void REGInit (void)
{
RegOffState_B = true;
RegStandbyState_B = false;
// TODO : load NVM values
RegTempSPT_U16 = cREGTempSPTDft;
RegTempSPTStby_U16 = cREGTempSPTStbyDft;
}
void REGStart (void)
{
mREDAdcEnable();
// mREGAdcStartConversion();
}
void REGStop (void)
{
}
void REGCyclicTask (void)
{
if (mREGAdcIsReady())
{
// Trigger conversion
mREGAdcStartConversion();
// Read ADC input
RegTempMeasBuffer_U16A[1] = mREGAdcReadValue();
if (RegTempMeasBuffer_U16A[1] >= cREGAdcErrorThres)
{
// Error
}
}
else
{
// ADC not ready
RegTempMeasBuffer_U16A[1] = 0xFFFF;
}
// Calculate average
RegTempMeasBuffer_U16A[0] += RegTempMeasBuffer_U16A[1];
RegTempMeasBuffer_U16A[0] = RegTempMeasBuffer_U16A[0] >> 1U;
RegTempMeas_U16[1] = RegTempMeas_U16[0]; // Memorise previous value
RegTempMeas_U16[0] = RegTempMeasBuffer_U16A[0];
// PID
RegEpsilon_S32A[1] = RegEpsilon_S32A[0]; // Memorise previous value
RegEpsilon_S32A[0] = RegTempSPT_U16 - RegTempMeas_U16[0];
RegPwmDyc_S32 = (RegEpsilon_S32A[0] * cRegPIDProp)
+ ((RegEpsilon_S32A[0] - RegEpsilon_S32A[1]) * cRegPIDDeriv)
+ (((RegEpsilon_S32A[0] + RegEpsilon_S32A[1]) >> 1U) * cRegPIDInteg);
// Only keep positive values
if (RegPwmDyc_S32 > 0)
{
RegPwmDyc_U32 = RegPwmDyc_S32;
}
else if (RegPwmDyc_S32 < (uint32_t)cREGPwmMax)
{
RegPwmDyc_U32 = (uint32_t)cREGPwmMax;
}
else
{
RegPwmDyc_U32 = 0U;
}
// Set PWM output duty cycle
mREGPwmSetCompareValue(RegPwmDyc_U32);
// Calculate physical temperature
// Transfer function
RegTempDeg_U16 = (uint16_t)(((((uint32_t)ADC_TO_TEMP_GAIN_NUM * (uint32_t)(RegTempMeas_U16[0])) / (uint32_t)ADC_TO_TEMP_GAIN_DEN) + (uint32_t)ADC_TO_TEMP_OFFSET) & (uint32_t)0x0000FFFF);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
bool REGIsError (void)
{
return RegErrorState_B;
}
bool REGIsStandby(void)
{
return RegStandbyState_B;
}
bool REGIsOff(void)
{
return RegOffState_B;
}
void REGErrorReset (void)
{
RegOffState_B = false;
}
void REGStandbySet(void)
{
RegStandbyState_B = true;
}
void REGStandbyReset(void)
{
RegStandbyState_B = false;
}
void REGOffSet(void)
{
RegOffState_B = true;
}
void REGOffReset(void)
{
RegOffState_B = false;
}
bool REGSPTSet (uint16_t temp_spt_u16)
{
bool ret_B = false;
if ((temp_spt_u16 <= (uint16_t)cREGTempSPTMax) && (temp_spt_u16 >= (uint16_t)cREGTempSPTMin))
{
RegTempSPT_U16 = temp_spt_u16;
ret_B = true;
}
return (ret_B);
}
uint16_t REGSPTGet (void)
{
return RegTempSPT_U16;
}
uint16_t REGTempGet (void)
{
bool REGSPTStbySet (uint16_t temp_spt_u16)
{
bool ret_B = false;
if ((temp_spt_u16 <= (uint16_t)cREGTempSPTMax) && (temp_spt_u16 >= (uint16_t)cREGTempSPTMin))
{
RegTempSPTStby_U16 = temp_spt_u16;
ret_B = true;
}
return (ret_B);
}
uint16_t REGSPTStbyGet (void)
{
return RegTempSPTStby_U16;
}