Was writing code to convert thermocouple k type conversion formula for best accuracy. Goal is to use polynomial functions and not the table or other method, that I will write in next code. Currently accuracy is concern. Below is my code, any one found any issue in that?
Currently i have simulated only by putting different millivolt values & cold junction value as 0c. Any way it can be improved further for accuracy or any other error in code.
/*
1. Convert the cold-junction temperature (TCJ) to a voltage (VCJ)
2. Add the cold-junction voltage to the measured thermocouple voltage (VCJ + VTC)
3. Convert the summed cold-junction voltage and thermocouple voltage to the thermocouple temperature
(TTC)
*/
#define float32_t float
const float32_t ci_i0_below0 = 0.000000000000E+00;
const float32_t ci_i1_below0 = 0.394501280250E-01;
const float32_t ci_i2_below0 = 0.236223735980E-04;
const float32_t ci_i3_below0 = -0.328589067840E-06;
const float32_t ci_i4_below0 = -0.499048287770E-08;
const float32_t ci_i5_below0 = -0.675090591730E-10;
const float32_t ci_i6_below0 = -0.574103274280E-12;
const float32_t ci_i7_below0 = -0.310888728940E-14;
const float32_t ci_i8_below0 = -0.104516093650E-16;
const float32_t ci_i9_below0 = -0.198892668780E-19;
const float32_t ci_i10_below0 = -0.163226974860E-22;
const float32_t ci_i0_above0 = -0.176004136860E-01;
const float32_t ci_i1_above0 = 0.389212049750E-01;
const float32_t ci_i2_above0 = 0.185587700320E-04;
const float32_t ci_i3_above0 = -0.994575928740E-07;
const float32_t ci_i4_above0 = 0.318409457190E-09;
const float32_t ci_i5_above0 = -0.560728448890E-12;
const float32_t ci_i6_above0 = 0.560750590590E-15;
const float32_t ci_i7_above0 = -0.320207200030E-18;
const float32_t ci_i8_above0 = 0.971511471520E-22;
const float32_t ci_i9_above0 = -0.121047212750E-25;
const float32_t a0_above0 = 0.118597600000E+00;
const float32_t a1_above0 = -0.118343200000E-03;
const float32_t a2_above0 = 0.126968600000E+03;
const float32_t d0_i0 = 0.0000000E+00;
const float32_t d0_i1 = 2.5173462E+01;
const float32_t d0_i2 = -1.1662878E+00;
const float32_t d0_i3 = -1.0833638E+00;
const float32_t d0_i4 = -8.9773540E-01;
const float32_t d0_i5 = -3.7342377E-01;
const float32_t d0_i6 = -8.6632643E-02;
const float32_t d0_i7 = -1.0450598E-02;
const float32_t d0_i8 = -5.1920577E-04;
const float32_t d0_i9 = 0.0000000E+00;
const float32_t d1_i0 = 0.000000E+00;
const float32_t d1_i1 = 2.508355E+01;
const float32_t d1_i2 = 7.860106E-02;
const float32_t d1_i3 = -2.503131E-01;
const float32_t d1_i4 = 8.315270E-02;
const float32_t d1_i5 = -1.228034E-02;
const float32_t d1_i6 = 9.804036E-04;
const float32_t d1_i7 = -4.413030E-05;
const float32_t d1_i8 = 1.057734E-06;
const float32_t d1_i9 = -1.052755E-08;
const float32_t d2_i0 = -1.318058E+02;
const float32_t d2_i1 = 4.830222E+01;
const float32_t d2_i2 = -1.646031E+00;
const float32_t d2_i3 = 5.464731E-02;
const float32_t d2_i4 = -9.650715E-04;
const float32_t d2_i5 = 8.802193E-06;
const float32_t d2_i6 = -3.110810E-08;
const float32_t d2_i7 = 0.000000E+00;
const float32_t d2_i8 = 0.000000E+00;
const float32_t d2_i9 = 0.000000E+00;
void setup()
{
Serial.begin(9600);
}
void loop()
{
uint32_t err;
float32_t tempc;
err = thermocouple_tempc(54.819f, 0.0f , &tempc);
Serial.print(err);
Serial.print(" ");
Serial.println(tempc);
}
uint32_t thermocouple_tempc(float32_t vtc_mV , float32_t cj_tempc , float32_t *tc_tempc_return)
{
uint32_t err = 0U;
float32_t vcj_mV = 0.0f;
float32_t vsum = 0.0f;
float32_t tempc = 0.0f;
//////////////// STEP-A cold-junction temperature (TCJ) to a voltage (VCJ)
/* convert cj_temp into mv by below equation
*
* E = sum(i=0 to n) c_i t^i.
*
* The equation above 0 °C is of the form
* E = sum(i=0 to n) c_i t^i + a0 exp(a1 (t - a2)^2).
*
*/
if(cj_tempc < -270.0f)
{
err = 1U; //cold-junction undertemperatyre
}
else if((cj_tempc >= -270.0f) && (cj_tempc < 0.0f))
{
vcj_mV = ( ci_i0_below0 * pow(cj_tempc , 0U) )
+ ( ci_i1_below0 * pow(cj_tempc , 1U) )
+ ( ci_i2_below0 * pow(cj_tempc , 2U) )
+ ( ci_i3_below0 * pow(cj_tempc , 3U) )
+ ( ci_i4_below0 * pow(cj_tempc , 4U) )
+ ( ci_i5_below0 * pow(cj_tempc , 5U) )
+ ( ci_i6_below0 * pow(cj_tempc , 6U) )
+ ( ci_i7_below0 * pow(cj_tempc , 7U) )
+ ( ci_i8_below0 * pow(cj_tempc , 8U) )
+ ( ci_i9_below0 * pow(cj_tempc , 9U) )
+ ( ci_i10_below0 * pow(cj_tempc , 10U) );
}
else if((cj_tempc >= 0.0f) && (cj_tempc <= 1372.0f))
{
vcj_mV = ( ci_i0_above0 * pow(cj_tempc , 0U) )
+ ( ci_i1_above0 * pow(cj_tempc , 1U) )
+ ( ci_i2_above0 * pow(cj_tempc , 2U) )
+ ( ci_i3_above0 * pow(cj_tempc , 3U) )
+ ( ci_i4_above0 * pow(cj_tempc , 4U) )
+ ( ci_i5_above0 * pow(cj_tempc , 5U) )
+ ( ci_i6_above0 * pow(cj_tempc , 6U) )
+ ( ci_i7_above0 * pow(cj_tempc , 7U) )
+ ( ci_i8_above0 * pow(cj_tempc , 8U) )
+ ( ci_i9_above0 * pow(cj_tempc , 9U) )
+ ( a0_above0 * ( exp(a1_above0 * pow((cj_tempc - a2_above0), 2U) ) ) );
}
else if(cj_tempc > 1372.0f)
{
err = 2U; //cold-junction overtemperatyre
}
else
{
err = 3U; //NAN or unknown error
}
//////////////// STEP-B cold-junction voltage to the measured thermocouple voltage (VCJ + VTC)
if(0U == err)
{
vsum = vcj_mV + vtc_mV;
if(vsum < -5.891f)
{
err = 4U; //sum voltage falls below convertable range
}
else if((vsum >= -5.891f) && (vsum <= 54.886f))
{
//err = 0U; this is conevertiable range
}
else if(vsum > 54.886f)
{
err = 5U; //sum voltage above convertable range
}
else
{
err = 6U; //NAN or unknown error
}
}
//////////////// STEP-C vsum coversion to temperature
if(0U == err)
{
if(vsum < -5.891f)
{
err = 7U; //under-voltage for final ocnversion
}
else if((vsum >= -5.891f) && (vsum < 0.0f))
{
tempc = ( d0_i0 * pow(vsum , 0U) )
+ ( d0_i1 * pow(vsum , 1U) )
+ ( d0_i2 * pow(vsum , 2U) )
+ ( d0_i3 * pow(vsum , 3U) )
+ ( d0_i4 * pow(vsum , 4U) )
+ ( d0_i5 * pow(vsum , 5U) )
+ ( d0_i6 * pow(vsum , 6U) )
+ ( d0_i7 * pow(vsum , 7U) )
+ ( d0_i8 * pow(vsum , 8U) )
+ ( d0_i9 * pow(vsum , 9U) );
}
else if((vsum >= 0.0f) && (vsum < 20.644f))
{
tempc = ( d1_i0 * pow(vsum , 0U) )
+ ( d1_i1 * pow(vsum , 1U) )
+ ( d1_i2 * pow(vsum , 2U) )
+ ( d1_i3 * pow(vsum , 3U) )
+ ( d1_i4 * pow(vsum , 4U) )
+ ( d1_i5 * pow(vsum , 5U) )
+ ( d1_i6 * pow(vsum , 6U) )
+ ( d1_i7 * pow(vsum , 7U) )
+ ( d1_i8 * pow(vsum , 8U) )
+ ( d1_i9 * pow(vsum , 9U) );
}
else if((vsum >= 20.644f) && (vsum <= 54.886f))
{
tempc = ( d2_i0 * pow(vsum , 0U) )
+ ( d2_i1 * pow(vsum , 1U) )
+ ( d2_i2 * pow(vsum , 2U) )
+ ( d2_i3 * pow(vsum , 3U) )
+ ( d2_i4 * pow(vsum , 4U) )
+ ( d2_i5 * pow(vsum , 5U) )
+ ( d2_i6 * pow(vsum , 6U) )
+ ( d2_i7 * pow(vsum , 7U) )
+ ( d2_i8 * pow(vsum , 8U) )
+ ( d2_i9 * pow(vsum , 9U) );
}
else if(vsum > 54.886f)
{
err = 8U; //over-voltage for final ocnversion
}
else
{
err = 9U; //NAN or unknown error
}
}
if(0U == err)
{
if(tempc < -200.0f)
{
err = 10U; //final calcualtions result in under temperature
}
else if(tempc > 1372.0f)
{
err = 11U; //final calcualtions result in over temperature
}
else
{
*tc_tempc_return = tempc;
//err = 0U; //final calcualtions ok
}
}
return err;
}