Pt100 code using direct mathematical equation & Piecewise Linear Approximation

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. I have made to code to convert RTD resistance into temperature. It is attached. It used direct mathematical method. made using Analog device AN709.

 

2. Code is also measuring time in which conversion is done. Surprisingly for negative temperature values, it takes around 280us max & for positive temperature it takes around 144us max.  
Code is run on arduino Uno. 
I thought it would take much higher time as lots of floats are involved.

 

3. Just made some random resistance value at step of 0.29 to see how much range is covered. 

 

4. Any sample code in c for Piecewise Linear Approximation method?
In AN709, link point takes to different page.
I wanted to make code on array based also, as it will much less memory & less time.

5. Also in function  
static uint8_t pt100_res_to_temp(float res , float *r_tempc)

at starting i had checked for res parameter is negative, if its negative passed by error, system dont make incorrect calculations.
Now I want to check if res passed is NaN or not.
This is done so that all the correct/incorrect values checked should be tested in this function & function always return correct error codes & values.
Is this step correct to check if number is NaN

 

if(res != res)
{
}

 

Or some compilers may optimize it away?
if its incorrect what step should I use?

 

typedef float  float32_t;
#define f32_t  float32_t

#define RTD_NOM  (100.0f)

#define RTD_A    ((f32_t)3.9083e-3)
#define RTD_B    ((f32_t)-5.775e-7) 
#define RTD_C    ((f32_t)–4.183e–12)  /* not used */

#define RTD_Z1   (-RTD_A)
#define RTD_Z2   ((RTD_A * RTD_A) - (4.0f * RTD_B))
#define RTD_Z3   ((4.0f * RTD_B) / RTD_NOM)
#define RTD_Z4   (2.0f * RTD_B)

#define RTD_C0   ((f32_t)-242.02)
#define RTD_C1   ((f32_t)+2.2228)
#define RTD_C2   ((f32_t)+2.5859e-3)
#define RTD_C3   ((f32_t)-4.8260e-6)
#define RTD_C4   ((f32_t)-2.8183e-8)
#define RTD_C5   ((f32_t)+1.5243e-10)




void setup() 
{
    Serial.begin(250000);

}

void loop() 
{
    uint8_t err;
    uint32_t old_time, new_time;
    float resistance = 0.0f , tempc;
    uint16_t cnt; 
    
    for(cnt = 0U ; cnt < 1360U ; cnt++)
    {
        resistance = cnt * 0.29f;
        old_time = micros();
        err = pt100_res_to_temp(resistance , &tempc);
        new_time = micros();
    
        Serial.println();
        Serial.print("Sno: ");
        Serial.print(cnt);
        Serial.print(" ; ");
        Serial.print("Time(us): ");
        Serial.print(new_time - old_time);
        Serial.print(" ; ");
        Serial.print("Resistance: ");
        Serial.print(resistance , 8);
        Serial.print(" ; ");
        Serial.print("Temperature: ");
        Serial.print(tempc , 8); 
        Serial.print(" ; ");   
        Serial.print("Error: ");
        Serial.print(err);
    }

    while(1);

}


static uint8_t pt100_res_to_temp(float res , float *r_tempc)
{
    uint8_t out_of_range = 0U;
      
    float32_t temp;
    float32_t res_square;
    float32_t res_cube;
    float32_t res_quad;
    float32_t res_pent;

    if(res < 0.0f)
    {
        out_of_range = 1U;     /* resistance out of bound on lower side, cant be negative */
        temp = -999.999f;           
    }
    else
    {      
        temp = RTD_Z2 + (RTD_Z3 * res);
        if(temp < 0.0f)
        {
            out_of_range = 2U;     /* resistance out of bound on higher side */ 
            temp = +999.999f;
        }
        else
        {
            temp = ( RTD_Z1 + sqrt(temp) ) / RTD_Z4;
    
            if(temp < 0.0f)    /* if negative temp */ 
            {
                res_square =  res * res;
                res_cube   =  res_square * res;
                res_quad   =  res_cube   * res;
                res_pent   =  res_quad   * res;
    
                temp = +(RTD_C0)
                       +(RTD_C1 * res)
                       +(RTD_C2 * res_square)
                       +(RTD_C3 * res_cube)
                       +(RTD_C4 * res_quad)
                       +(RTD_C5 * res_pent);
            }          
        }
    }

    *r_tempc = temp;

    return out_of_range;
}

 

Last Edited: Sat. Aug 19, 2017 - 08:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

x != x
.
is surely logically impossible and can never be true in any language for any value?
.
In C <math.h> provides the isnan() function to test for NaN

Last Edited: Sat. Aug 19, 2017 - 03:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sure, x!=x is per definition correct for 1!. (Also it is valid 0!=: 1)

Sorry, I am only kidding.

 

If I have to solve the above mentioned task, I would at first look which temperature range is of interest. From absolute zero to liquid iron-- or only from -25°C to 100°C. Next I have to look which precision is necessary. Then I will select the apropriate method according to this border conditions. Always helpful is a visual, graphical representation of temperature vs. resistence of your measuring device.

a.) a simple lookup table from a calibration with a high precision thermometer. If neccessary with a lot of points when the curve a very non-linear.

b.) an approximation, at least for small ranges, e.g. make a linear regession (--> Excel, or manuell )

c.) with at least three well determined point a quadratic approximation (idea: three x,y-points yield three equations --> solving ax²+bx+c=y.. with four points an more you can go with x³ ....)

d.) maybe you can divide the whole range into some subranges where one of above mentioned methods help.

 

I avoid all floating-point computaions in my little projekts as far as possible. Sometime I simply multiply according to needed extend all value to gain handy integers.

I hope this helps you.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
x != x . is surely logically impossible and can never be true in any language for any value? . In C <math.h> provides the isnan() function to test for NaN

 

I think it's the other way around, all comparisons involving NANs return false. So, if x is a NAN, 

x == x;

is false.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0