About thermocouples

/* v2t Voltage to temperature calculation for type E, J, K, R, S, and T thermocouples. Copyright Jan Panteltje 2010 - always. Released under the GPL License. This program uses data from

formatting link

To compile this, type: gcc -Wall -o v2t v2t.c

*/

/* filename v2t.c */

#include #include

void print_usage() { fprintf(stderr, "Panteltje (c) v2t-01 thermocouple volatge to temperature calculator\n"); fprintf(stderr, "Usage: v2t type[E|J|K|R|S|T] voltage\n"); fprintf(stderr, "Example:\n\ v2t T -.00535\n"); } /* end function print_usage */

int main(int argc, char **argv) { double temperature; double x; double a0, a1, a2, a3, a4, a5, a6, a7, a8, a9;

if(argc != 3) { print_usage();

exit(1); }

/* get voltage */ x = atof(argv[2]);

switch(argv[1][0]) { case 'E': fprintf(stdout, "type E, nickel-10%% chromium(+) versus constantan(-)

-100°C to 1000°C ± 0.5°C 9th order\n"); a0 = 0.104967248; a1 = 17189.45282; a2 = -282639.0850; a3 = 12695339.5; a4 = -448703084.6; a5 = 1.10866E+10; a6 = 1.76807E+11; a7 = 1.71842E+12; a8 = -9.19278E+12; a9 = 2.06132E+13; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x

  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x) + (a9 * x * x
  • x * x * x * x * x * x * x) ; break; case 'J': fprintf(stdout, "type J Iron(+) versus cconstantan(-) 0°C to 760°C ±
0.1°C 5th order\n"); a0 = -0.048868252; a1 = 19873.14503; a2 = -218614.5353; a3 = 11569199.78; a4 = -264917531.4; a5 = 2018441314; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x); break; case 'K': fprintf(stdout, "type K nickel-10%% chromium(+) versus nickel-5%%(-) (aluminum silicon) 0°C to 1370°C ± 0.7°C 8th order\n"); a0 = 0.226584602; a1 = 24152.10900; a2 = 67233.4248; a3 = 2210340.682; a4 = -860963914.9; a5 = 4.83506E+10; a6 = -1.18452E+12; a7 = 1.38690E+13; a8 =-6.33708E+13; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x); break; case 'R': ; fprintf(stdout, "type R platinum-13%% rodium(+) versus platinum(-) 0°C to 1000°C ± 0.5°C 8th order\n"); a0 = 0.263632917; a1 = 179075.491; a2 = -48840341.37; a3 = 1.90002E+10; a4 = -4.82704E+12; a5 = 7.62091E+14; a6 = -7.20026E+16; a7 = 3.71496E+18; a8 = -8.03104E+19; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x); break; case 'S': fprintf(stdout, "type S platinum-10%% rodium(+) versus platinum(-) 0°C to 1750°C ± 1°C 9th order\n"); a0 = 0.927763167; a1 = 169526.5150; a2 = -31568363.94; // a3 = 8990730663; a3 = 899073066E1; a4 = -1.63565E+12; a5 = 1.88027E+14; a6 = -1.37241E+16; a7 = 6.17501E+17; a8 = -1.56105E+19; a9 = 1.69535E+20; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x) + (a9 * x * x
  • x * x * x * x * x * x * x) ; break; case 'T': fprintf(stdout, "type T thermocouple +/- .5 C accuracy copper(+) versus constantan(-) 160°C to 400°C ±0.5°C 7th order\n"); a0 = 0.100860910; a1 = 25727.94369; a2 = -767345.8295; a3 = 78025595.81; // a4 = -9247486589; a4 = -924748658E+1; a5 = 6.97688E+11; a6 = -2.66192E+13; a7 = 3.94078E+14; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) ; break; default: print_usage(); break; } /* end switch thermocouple type */

fprintf(stdout, "temperature=%.2f\n", temperature);

exit(0); } /* end function main */

Reply to
Jan Panteltje
Loading thread data ...

Why is t nonzero when v is zero?

John

Reply to
John Larkin

Because it's polynomial a curve fit.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

thermocouples.

formatting link

.. a polynomial curve fit, that should be..

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

thermocouples.

formatting link

But shouldn't it cross 0:0 ?

John

Reply to
John Larkin

thermocouples.

formatting link

Yes, but there's a finite number of terms in the polynomial so in general it won't give you the least-squares optimal fit by crossing

0,0.

If you force the error at one point (say 0V in) to zero, then the optimal coefficients will be a bit different and the overall error will be higher, in general.

Best regards, Spehro Pefhany

--
"it's the network..."                          "The Journey is the reward"
speff@interlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Reply to
Spehro Pefhany

On a sunny day (Sat, 18 Sep 2010 16:25:52 -0700) it happened John Larkin wrote in :

Voltage actually reverses for temperatures below zero.

formatting link
figure 3, page 5.

Reply to
Jan Panteltje

x * x) + (a4 * x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x= * x * x * x) + (a7 * x * x * x * x * x * x * x) ;

Is this a good way to implement a polynomial?

Reply to
C Egernet

x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7

  • x * x * x * x * x * x * x) ;

You can do something like

t = a(0) s = x

for i = 1 to 7

t = t + a(i) * s s = s * x

next

On successive iterations, s = x, x^2, x^3...

if I got that right without benefit of coffee.

You can rearrange it to avoid the useless last multiply, if it's worth it.

John

Reply to
John Larkin

x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7

  • x * x * x * x * x * x * x) ;

Yes:

formatting link

Cheers! Rich

Reply to
Rich Grise

  • x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) ;

No; count the stars.

John

Reply to
John Larkin

  • x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) ;

You need to do a little algebraic manipulation to see how it works. The given thing above needs (N^2 + N)/2 stars - the "Horner" method uses only N. Did you even look at the article?

Thanks, Rich

Reply to
Rich Grise

  • x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) ;

No, it's horrible. The obvious inefficiency doesn't matter much--how much CPU are you going to use computing this, say, 10 times per second? However, it's also horribly ill-conditioned numerically, both in the extraction of the polynomial coefficients and in evaluation.

Horner's rule helps the inefficiency but not the ill-conditioning, but a Chebyshev fit followed by Clenshaw's rule for evaluation is the right way to go. (Clenshaw's rule is a recurrence form that implicitly generates the Chebyshev polynomials as it computes the summation. It's really cute.)

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs
Principal
ElectroOptical Innovations
55 Orchard Rd
Briarcliff Manor NY 10510
845-480-2058

email: hobbs (atsign) electrooptical (period) net
http://electrooptical.net
Reply to
Phil Hobbs

rOn a sunny day (Mon, 20 Sep 2010 08:49:40 -0700) it happened John Larkin wrote in :

  • x * x * x * x ) + (a5 * x * x * x * x * x) +

It is irrelevant, as this is a command line program, and you will not notice the sysload, unless you type a lot faster. The alternative method is also described in the pdf the source referenced, so I am fully aware of that. This was easier to enter, for a fee I will type the other version. All that said, and regarding your comment about not zero at zero C, I have updated it to use the NIST tables for type T, now it IS zero at 0 C, and goes to -270 (for type T). But that is only because I need to go that low. But it is just typed in, and not tested very much, the f*cking tables were wrong, had to type it all in and fix it, so if you want better try this, If you find an error in it, let me know, I will fix it: PS this also displays Kelvin, and F.

/* v2t Voltage to temperature calculation for type E, J, K, R, S, and T thermocouples. Copyright Jan Panteltje 2010 - always. Released under the GPL License. This program uses data from

formatting link

To compile this, type: gcc -Wall -o v2t v2t.c -lm

*/

/* filename v2t.c */

#include #include #include

void print_usage() { fprintf(stderr, "Panteltje (c) v2t-0.2 thermocouple voltage to temperature calculator\n"); fprintf(stderr, "Usage: v2t type[E|J|K|R|S|T] voltage\n"); fprintf(stderr, "Example:\n\ v2t T -.00535\n"); } /* end function print_usage */

int main(int argc, char **argv) { int i; double temperature; double x; double a0, a1, a2, a3, a4, a5, a6, a7, a8, a9; /* Thermoelectric Voltage in Millivolts from Reference Tables N.I.S.T. Monograph

175 Revised to ITS-90 NIST */ double Type_T[]={ /* 0 -270 */

-6.258,-6.256,-6.255,-6.253,-6.251,-6.248,-6.245,-6.242,-6.239,-6.236, /* 10 -260 */

-6.232,-6.228,-6.223,-6.219,-6.214,-6.209,-6.204,-6.198,-6.193,-6.187, /* 20 -250 */

-6.180,-6.174,-6.167,-6.160,-6.153,-6.146,-6.138,-6.130,-6.122,-6.114, /* 30 -240 */

-6.105,-6.096,-6.087,-6.078,-6.068,-6.059,-6.049,-6.038,-6.028,-6.017, /* 40 -230 */

-6.007,-5.996,-5.985,-5.973,-5.962,-5.950,-5.938,-5.926,-5.914,-5.901, /* 50 -220 */

-5.888,-5.876,-5.863,-5.850,-5.836,-5.823,-5.809,-5.795,-5.782,-5.767, /* 60 -210 */

-5.753,-5.739,-5.724,-5.710,-5.695,-5.680,-5.665,-5.650,-5.634,-5.619, /* 70 -200 */

-5.603,-5.587,-5.571,-5.555,-5.539,-5.523,-5.506,-5.489,-5.473,-5.456, /* 80 -190 */

-5.439,-5.421,-5.404,-5.387,-5.369,-5.351,-5.334,-5.316,-5.297,-5.279, /* 90 -180 */

-5.261,-5.242,-5.224,-5.205,-5.186,-5.167,-5.148,-5.128,-5.109,-5.089, /* 100 -170 */

-5.070,-5.050,-5.030,-5.010,-4.989,-4.969,-4.949,-4.928,-4.907,-4.886, /* 110 -160 */

-4.865,-4.844,-4.823,-4.802,-4.780,-4.759,-4.737,-4.715,-4.693,-4.671, /* 120 -150 */

-4.648,-4.626,-4.604,-4.581,-4.558,-4.535,-4.512,-4.489,-4.466,-4.443, /* 130 -140 */

-4.419,-4.395,-4.372,-4.348,-4.324,-4.300,-4.275,-4.251,-4.226,-4.202, /* 140 -130 */

-4.177,-4.152,-4.127,-4.102,-4.077,-4.052,-4.026,-4.000,-3.975,-3.949, /* 150 -120 */

-3.923,-3.897,-3.871,-3.844,-3.818,-3.791,-3.765,-3.738,-3.711,-3.684, /* 160 -110 */

-3.657,-3.629,-3.602,-3.574,-3.547,-3.519,-3.491,-3.463,-3.435,-3.407, /* 170 100 */

-3.379,-3.350,-3.322,-3.293,-3.264,-3.235,-3.206,-3.177,-3.148,-3.118, /* 180 -90 */

-3.089,-3.059,-3.030,-3.000,-2.970,-2.940,-2.910,-2.879,-2.849,-2.818, /* 190 -80 */

-2.788,-2.757,-2.726,-2.695,-2.664,-2.633,-2.602,-2.571,-2.539,-2.507, /* 200 -70 */

-2.476,-2.444,-2.412,-2.380,-2.348,-2.316,-2.283,-2.251,-2.218,-2.186, /* 210 -60 */

-2.153,-2.120,-2.087,-2.054,-2.021,-1.987,-1.954,-1.920,-1.887,-1.853, /* 220 -50 */

-1.819,-1.785,-1.751,-1.717,-1.683,-1.648,-1.614,-1.579,-1.545,-1.510, /* 230 -40 */

-1.475,-1.440,-1.405,-1.370,-1.335,-1.299,-1.264,-1.228,-1.192,-1.157, /* 240 -30 */

-1.121,-1.085,-1.049,-1.013,-0.976,-0.940,-0.904,-0.867,-0.830,-0.794, /* 250 -20 */

-0.757,-0.720,-0.683,-0.646,-0.608,-0.571,-0.534,-0.496,-0.459,-0.421, /* 260 -10 */

-0.383,-0.345,-0.307,-0.269,-0.231,-0.193,-0.154,-0.116,-0.077,-0.039, /* 270 0 */ 0.000,0.039,0.078,0.117,0.156,0.195,0.234,0.273,0.312,0.352, /* 280 10 */ 0.391,0.431,0.470,0.510,0.549,0.589,0.629,0.669,0.709,0.749, /* 290 20 */ 0.790,0.830,0.870,0.911,0.951,0.992,1.033,1.074,1.114,1.155, /* 300 30 */ 1.196,1.238,1.279,1.320,1.362,1.403,1.445,1.486,1.528,1.570, /* 310 40 */ 1.612,1.654,1.696,1.738,1.780,1.823,1.865,1.908,1.950,1.993, /* 320 50 */ 2.036,2.079,2.122,2.165,2.208,2.251,2.294,2.338,2.381,2.425, /* 330 60 */ 2.468,2.512,2.556,2.600,2.643,2.687,2.732,2.776,2.820,2.864, /* 340 70 */ 2.909,2.953,2.998,3.043,3.087,3.132,3.177,3.222,3.267,3.312, /* 350 80 */ 3.358,3.403,3.448,3.494,3.539,3.585,3.631,3.677,3.722,3.768, /* 360 90 */ 3.814,3.860,3.907,3.953,3.999,4.046,4.092,4.138,4.185,4.232, /* 370 100 */ 4.279,4.325,4.372,4.419,4.466,4.513,4.561,4.608,4.655,4.702, /* 380 110 */ 4.750,4.798,4.845,4.893,4.941,4.988,5.036,5.084,5.132,5.180, /* 390 120 */ 5.228,5.277,5.325,5.373,5.422,5.470,5.519,5.567,5.616,5.665, /* 400 130 */ 5.714,5.763,5.812,5.861,5.910,5.959,6.008,6.057,6.107,6.156, /* 410 140 */ 6.206,6.255,6.305,6.355,6.404,6.454,6.504,6.554,6.604,6.654, /* 420 150 */ 6.704,6.754,6.805,6.855,6.905,6.956,7.006,7.057,7.107,7.158, /* 430 160 */ 7.209,7.260,7.310,7.361,7.412,7.463,7.515,7.566,7.617,7.668, /* 440 170 */ 7.720,7.771,7.823,7.874,7.926,7.977,8.029,8.081,8.133,8.185, /* 450 180 */ 8.237,8.289,8.341,8.393,8.445,8.497,8.550,8.602,8.654,8.707, /* 460 190 */ 8.759,8.812,8.865,8.917,8.970,9.023,9.076,9.129,9.182,9.235, /* 470 200 */ 9.288,9.341,9.395,9.448,9.501,9.555,9.608,9.662,9.715,9.769, /* 480 210 */ 9.822,9.876,9.930,9.984,10.038,10.092,10.146,10.200,10.254,10.308, /* 490 220 */

10.362,10.417,10.471,10.525,10.580,10.634,10.689,10.743,10.798,10.853, /* 500 230 */ 10.907,10.962,11.017,11.072,11.127,11.182,11.237,11.292,11.347,11.403, /* 510 240 */ 11.458,11.513,11.569,11.624,11.680,11.735,11.791,11.846,11.902,11.958, /* 520 250 */ 12.013,12.069,12.125,12.181,12.237,12.293,12.349,12.405,12.461,12.518, /* 530 260 */ 12.574,12.630,12.687,12.743,12.799,12.856,12.912,12.969,13.026,13.082, /* 540 270 */ 13.139,13.196,13.253,13.310,13.366,13.423,13.480,13.537,13.595,13.652, /* 550 280 */ 13.709,13.766,13.823,13.881,13.938,13.995,14.053,14.110,14.168,14.226, /* 560 290 */ 14.283,14.341,14.399,14.456,14.514,14.572,14.630,14.688,14.746,14.804, /* 570 300 */ 14.862,14.920,14.978,15.036,15.095,15.153,15.211,15.270,15.328,15.386, /* 580 310 */ 15.445,15.503,15.562,15.621,15.679,15.738,15.797,15.856,15.914,15.973, /* 590 320 */ 16.032,16.091,16.150,16.209,16.268,16.327,16.387,16.446,16.505,16.564, /* 600 330 */ 16.624,16.683,16.742,16.802,16.861,16.921,16.980,17.040,17.100,17.159, /* 610 340 */ 17.219,17.279,17.339,17.399,17.458,17.518,17.578,17.638,17.698,17.759, /* 620 350 */ 17.819,17.879,17.939,17.999,18.060,18.120,18.180,18.241,18.301,18.362, /* 630 360 */ 18.422,18.483,18.543,18.604,18.665,18.725,18.786,18.847,18.908,18.969, /* 640 370 */ 19.030,19.091,19.152,19.213,19.274,19.335,19.396,19.457,19.518,19.579, /* 650 380 */ 19.641,19.702,19.763,19.825,19.886,19.947,20.009,20.070,20.132,20.193, /* 660 390 */ 20.255,20.317,20.378,20.440,20.502,20.563,20.625,20.687,20.748,20.810, };

if(argc != 3) { print_usage();

exit(1); }

/* get voltage */ x = atof(argv[2]);

/* get thermocouple type */ switch(argv[1][0]) { case 'E': fprintf(stdout, "type E, nickel-10%% chromium(+) versus constantan(-)

-100°C to 1000°C ± 0.5°C 9th order\n"); a0 = 0.104967248; a1 = 17189.45282; a2 = -282639.0850; a3 = 12695339.5; a4 = -448703084.6; a5 = 1.10866E+10; a6 = 1.76807E+11; a7 = 1.71842E+12; a8 = -9.19278E+12; a9 = 2.06132E+13; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x

  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x) + (a9 * x * x
  • x * x * x * x * x * x * x) ; break; case 'J': fprintf(stdout, "type J Iron(+) versus cconstantan(-) 0°C to 760°C ±
0.1°C 5th order\n"); a0 = -0.048868252; a1 = 19873.14503; a2 = -218614.5353; a3 = 11569199.78; a4 = -264917531.4; a5 = 2018441314; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x); break; case 'K': fprintf(stdout, "type K nickel-10%% chromium(+) versus nickel-5%%(-) (aluminum silicon) 0°C to 1370°C ± 0.7°C 8th order\n"); a0 = 0.226584602; a1 = 24152.10900; a2 = 67233.4248; a3 = 2210340.682; a4 = -860963914.9; a5 = 4.83506E+10; a6 = -1.18452E+12; a7 = 1.38690E+13; a8 = -6.33708E+13; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x); break; case 'R': fprintf(stdout, "type R platinum-13%% rodium(+) versus platinum(-) 0°C to 1000°C ± 0.5°C 8th order\n"); a0 = 0.263632917; a1 = 179075.491; a2 = -48840341.37; a3 = 1.90002E+10; a4 = -4.82704E+12; a5 = 7.62091E+14; a6 = -7.20026E+16; a7 = 3.71496E+18; a8 = -8.03104E+19; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x); break; case 'S': fprintf(stdout, "type S platinum-10%% rodium(+) versus platinum(-) 0°C to 1750°C ± 1°C 9th order\n"); a0 = 0.927763167; a1 = 169526.5150; a2 = -31568363.94; a3 = 899073066.3E1; a4 = -1.63565E+12; a5 = 1.88027E+14; a6 = -1.37241E+16; a7 = 6.17501E+17; a8 = -1.56105E+19; a9 = 1.69535E+20; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) + (a8 * x * x * x * x * x * x * x * x) + (a9 * x * x
  • x * x * x * x * x * x * x) ; break; case 'T': #ifdef OLD_CODE fprintf(stdout, "type T thermocouple +/- .5 C accuracy copper(+) versus constantan(-) 160°C to 400°C ±0.5°C 7th order\n"); a0 = 0.100860910; a1 = 25727.94369; a2 = -767345.8295; a3 = 78025595.81; a4 = -924748658.9E+1; a5 = 6.97688E+11; a6 = -2.66192E+13; a7 = 3.94078E+14; temperature = a0 + (a1 * x) + (a2 * x * x) + (a3 * x * x * x) + (a4 * x
  • x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) ; #endif // OLD_CODE

fprintf(stdout, "type T thermocouple +/- 1 C accuracy copper(+) versus constantan(-) -270°C to 399°C ±1°C\n");

/* range check */ if(x < -.006258) { fprintf(stderr, "value < -.006258, temperature < 270 °C, out of range, aborting.\n");

exit(1); }

/* due to inaccuray in math this will limit to .0281 */ if(x > .020872) { fprintf(stderr, "value > 20.872, temperature > 399 °C, out of range, aborting.\n"); exit(1); }

/* used as flag for if no match */ temperature = 1000.0;

/* go trough the table until a match is found */ for(i = 0; i < 670; i++) { if( Type_T[i] >= (x * 1000.0) ) { temperature = i - 270;

/* test if closer to current position than previous, select the closest */ if(i > 0) { double da, db;

da = Type_T[i ] - (x * 1000.0); db = Type_T[i - 1] - (x * 1000.0);

if(fabs(da) > fabs(db) ) { temperature -= 1; } }

break; } }

/* test if not found it table */ if(temperature == 1000.0) { fprintf(stderr, "value > 20.872, temperature > 399 °C, out of range, aborting.\n");

exit(1); } break; default: print_usage(); exit(1); break; } /* end switch thermocouple type */

/* display to user in C, K, and F */ fprintf(stdout, "temperature is %.2f °K %.2f °C %.2f °F\n", temperature +

273.15, temperature, (temperature * 9.0/5.0) + 32.0);

exit(0); } /* end function main */

Reply to
Jan Panteltje

x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7

  • x * x * x * x * x * x * x) ;

About the worst, as others have said.

When there is no problem with data storage space, I think cubic splines are a better way to go than polynomials. Thermocouples are almost linear, so the matrix has a very high condition number (and it gets worse as you add terms to try to increase the accuracy). That means that the intermediate calculations have to be done to a much higher number of bits accuracy than the required end results.

Reply to
Spehro Pefhany

Wow. You must have been watching too much of xxx stuff. Stick with piecewise linear interpolation.

VLV

Reply to
Vladimir Vassilevsky

  • x * x * x * x ) + (a5 * x * x * x * x * x) + (a6 * x * x * x * x * x * x) + (a7 * x * x * x * x * x * x * x) ;

Agreed. (I seem to recall minimax helping in balancing inexact constants and inexact FP calculations, too.) But what really surprised me also in just reading the code shown above is that the obvious basic algebra simplification wasn't done, either, which also may improve how it works with inexact FP.

= a0+x*(a1+x*(a2+x*(a3+x*(a4+x*(a5+x*(a6+x*a7))))));

Jon

Reply to
Jon Kirwan

I think one could successfully argue that Jan's original form is a little more obvious to the casual observer (...although I think he'd use pow() ) and that it's reasonable to expect the optimizer to make the simplification you've written there. Isn't it Knuth or someone with the quote about pre-mature optimization being the root of many bugs?

Optimizers are great tools -- they tend to catch a lot of bugs in code, and in most cases do a better job optimizing than humans would have the time/patience to do anyway. (Granted, humans still need to pick good algorithsm -- no optimizer can turn a bubble sort into a quicksort.)

---Joel

Reply to
Joel Koltner

I don't recall Knuth saying that, and I read every chapter of all three of his early 1970's books. But you are making a wrong point. What I wrote isn't a 'pre-mature' optimization. It's the last step, not the first. It's just fine to concentrate on getting things right, first. _Then_ it is also fine to make adjustments, afterwards. Which is all I was thinking here.

Know of any that will perform the indicated transform? I'd like to try this out, right away!

Jon

Reply to
Jon Kirwan

rOn a sunny day (Mon, 20 Sep 2010 08:49:40 -0700) it happened John Larkin wrote in :

PS Somebody here mentioned 'thermocouples are almost linear'. I dunno who it was, and google search does not even find this thread. But thermocouples are extremely non-linear the more you get to absolute zero. Here is an example, close to -270 C: With the NIST tables: grml: ~ # ./v2t T -0.006258 type T thermocouple +/- 1 C accuracy copper(+) versus constantan(-) -270°C to

399°C ±1°C temperature is 3.15 °K -270.00 °C -454.00 °F

With the polinomial method: grml: ~ # v2t T -0.006258 type T thermocouple +/- .5 C accuracy copper(+) versus constantan(-) 160°C to

400°C ±0.5°C 7th order temperature is 40.45 °K -232.70 °C -386.87 °F As you see the error is > 37 degrees K.

For a bit higher temeprature: With the NIST tables: grml: ~ # v2t T -0.004865 type T thermocouple +/- .5 C accuracy copper(+) versus constantan(-) 160°C to

400°C ±0.5°C 7th order temperature is 113.48 °K -159.67 °C -255.41 °F

With the polinomial method: grml: ~ # ./v2t T -0.004865 type T thermocouple +/- 1 C accuracy copper(+) versus constantan(-) -270°C to

399°C ±1°C temperature is 113.15 °K -160.00 °C -256.00 °F

Now, at -160 C, the difference is only a fration of a degree C.

So thermocuples are so non-linear that the polinomial method is no longer usable below about -160 C, as the (old) program indicates.

That is why I am using the NIST tables for those low temperatures.

Reply to
Jan Panteltje

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.