I made some progress in applying piecewise interpolation to approximate the nist curve.
Again, using Type B as an example.
General approach:
I would break down the entire curve into 64 points (63 pieces of linear lines), and within each line, 256 points are linearly interpolated, for a total of 16K points along the curve.
64 points are used as a compromise between accuracy and storage. Since we are using long types here, each curve takes about 64 * 4 byte = 250 bytes.
The reason to pick 256 points will be clear later on.
Data structure:
Roughly the same, but rather than storing coefficients, we now store data points:
typedef struct {
signed long uV_LOW; //low range of the input voltage, uv
signed long uV_HIGH; //high range of the input voltage, uv
signed long Cx1000[TC_POINTS]; //temperature points, in 0.001 Celsius
} TCCURVE_TYPEDEF;
Here is the curve for Type B:
/TC TYPE B curve
const TCCURVE_TYPEDEF TCB_curve ={
291, 13820, {
249916.0747, 323704.7308, 383399.8668, 435096.9286, 481439.2474, 523865.2027, 563318.3990, 600402.6075,
635512.0226, 669016.1792, 701160.7584, 732037.5081, 761835.4734, 790670.0534, 818641.4668, 845836.6596,
872331.0218, 898189.9269, 923470.1060, 948220.8699, 972485.1895, 996300.6468, 1019700.267, 1042713.24,
1065365.549, 1087680.500, 1109679.183, 1131380.850, 1152803.236, 1173962.825, 1194875.058, 1215554.514,
1236015.038, 1256269.853, 1276331.638, 1296212.593, 1315924.481, 1335478.664, 1354886.134, 1374157.53,
1393303.160, 1412333.021, 1431256.820, 1450084.002, 1468823.774, 1487485.140, 1506076.941, 1524607.89,
1543086.619, 1561521.724, 1579921.805, 1598295.511, 1616651.571, 1634998.822, 1653346.219, 1671702.834,
1690077.826, 1708480.392, 1726919.679, 1745404.660, 1763943.968, 1782545.676, 1801217.016, 1819964.035
}
};
The numbers are digitized using the NIST polynomial.
Breaking it down:
Each thermocouple output (uv) is taken to generate two numbers, i6 (6-bit type) to indicate which piece-wise section that uv value should be, and i256 (8-bit value) to indicate which point within that section we should interpolate to.
We do that with two macros:
//convert uv to index - 6bits:256bits. 6 bits of index and 256bits of interpolation
#define TCB_uv2index(uv) (((uv) - TCB_curve.uV_LOW) * ((TC_POINTS - 1) << 8) / (TCB_curve.uV_HIGH - TCB_curve.uV_LOW))
//256-point interpolation
#define TCB_itp(i6, i256) (((TCB_curve.Cx1000[i6+1] - TCB_curve.Cx1000[i6]) * i256) >> 8)
TCB_uv2index() generates a 6+8 bit value that contains i6 and i256.
TCB_itp() does the interpolation calculation.
Tie them together:
All of them is tied together with a function:
//convert uv to mC(=Cx1000)
signed long TCB_uv2c(signed long uv) {
unsigned char *i256 = &uv; //i256 points to uv - endian dependent
unsigned char *i6=i256+1; //i6 = piece-wise index, i256 = index within a piece
uv = TCB_uv2index(uv); //convert uv to 6+8bit index
return TCB_curve.Cx1000[*i6] + TCB_itp(*i6, *i256); //=piece-wise value + interpolation
}
*i6 and *i256 are two pointers that breaks down the 14-bit index (now contained in uv). This speeds up the execution considerably, at the expense of its endian-dependence.
Accuracy:
Here is the run for Type B over the entire temperature range.
uv = 291, TCB_uv2c(uv) = 249916, TCB9_mv2c(uv) = 249.9161
uv = 391, TCB_uv2c(uv) = 284215, TCB9_mv2c(uv) = 286.6775
uv = 491, TCB_uv2c(uv) = 318515, TCB9_mv2c(uv) = 319.1925
uv = 591, TCB_uv2c(uv) = 347255, TCB9_mv2c(uv) = 348.6309
uv = 691, TCB_uv2c(uv) = 375004, TCB9_mv2c(uv) = 375.7608
uv = 791, TCB_uv2c(uv) = 400362, TCB9_mv2c(uv) = 401.0867
uv = 891, TCB_uv2c(uv) = 424393, TCB9_mv2c(uv) = 424.9460
uv = 991, TCB_uv2c(uv) = 447043, TCB9_mv2c(uv) = 447.5751
uv = 1091, TCB_uv2c(uv) = 468586, TCB9_mv2c(uv) = 469.1500
uv = 1191, TCB_uv2c(uv) = 489393, TCB9_mv2c(uv) = 489.8108
uv = 1291, TCB_uv2c(uv) = 509281, TCB9_mv2c(uv) = 509.6737
uv = 1391, TCB_uv2c(uv) = 528642, TCB9_mv2c(uv) = 528.8361
uv = 1491, TCB_uv2c(uv) = 546981, TCB9_mv2c(uv) = 547.3782
uv = 1591, TCB_uv2c(uv) = 565201, TCB9_mv2c(uv) = 565.3645
uv = 1691, TCB_uv2c(uv) = 582439, TCB9_mv2c(uv) = 582.8455
uv = 1791, TCB_uv2c(uv) = 599822, TCB9_mv2c(uv) = 599.8616
uv = 1891, TCB_uv2c(uv) = 616174, TCB9_mv2c(uv) = 616.4483
uv = 1991, TCB_uv2c(uv) = 632494, TCB9_mv2c(uv) = 632.6412
uv = 2091, TCB_uv2c(uv) = 648206, TCB9_mv2c(uv) = 648.4791
uv = 2191, TCB_uv2c(uv) = 663911, TCB9_mv2c(uv) = 664.0013
uv = 2291, TCB_uv2c(uv) = 679061, TCB9_mv2c(uv) = 679.2353
uv = 2391, TCB_uv2c(uv) = 694002, TCB9_mv2c(uv) = 694.1690
uv = 2491, TCB_uv2c(uv) = 708638, TCB9_mv2c(uv) = 708.8216
uv = 2591, TCB_uv2c(uv) = 722991, TCB9_mv2c(uv) = 723.2098
uv = 2691, TCB_uv2c(uv) = 737274, TCB9_mv2c(uv) = 737.3565
uv = 2791, TCB_uv2c(uv) = 751126, TCB9_mv2c(uv) = 751.2740
uv = 2891, TCB_uv2c(uv) = 764876, TCB9_mv2c(uv) = 764.9744
uv = 2991, TCB_uv2c(uv) = 778279, TCB9_mv2c(uv) = 778.4685
uv = 3091, TCB_uv2c(uv) = 791653, TCB9_mv2c(uv) = 791.7668
uv = 3191, TCB_uv2c(uv) = 804764, TCB9_mv2c(uv) = 804.8789
uv = 3291, TCB_uv2c(uv) = 817766, TCB9_mv2c(uv) = 817.8138
uv = 3391, TCB_uv2c(uv) = 830432, TCB9_mv2c(uv) = 830.5800
uv = 3491, TCB_uv2c(uv) = 843074, TCB9_mv2c(uv) = 843.1854
uv = 3591, TCB_uv2c(uv) = 855461, TCB9_mv2c(uv) = 855.6376
uv = 3691, TCB_uv2c(uv) = 867880, TCB9_mv2c(uv) = 867.9433
uv = 3791, TCB_uv2c(uv) = 880007, TCB9_mv2c(uv) = 880.1091
uv = 3891, TCB_uv2c(uv) = 892027, TCB9_mv2c(uv) = 892.1411
uv = 3991, TCB_uv2c(uv) = 903916, TCB9_mv2c(uv) = 904.0449
uv = 4091, TCB_uv2c(uv) = 915767, TCB9_mv2c(uv) = 915.8260
uv = 4191, TCB_uv2c(uv) = 927433, TCB9_mv2c(uv) = 927.4892
uv = 4291, TCB_uv2c(uv) = 938938, TCB9_mv2c(uv) = 939.0393
uv = 4391, TCB_uv2c(uv) = 950400, TCB9_mv2c(uv) = 950.4807
uv = 4491, TCB_uv2c(uv) = 961679, TCB9_mv2c(uv) = 961.8175
uv = 4591, TCB_uv2c(uv) = 973043, TCB9_mv2c(uv) = 973.0535
uv = 4691, TCB_uv2c(uv) = 984113, TCB9_mv2c(uv) = 984.1925
uv = 4791, TCB_uv2c(uv) = 995183, TCB9_mv2c(uv) = 995.2378
uv = 4891, TCB_uv2c(uv) = 1006080, TCB9_mv2c(uv) = 1006.1926
uv = 4991, TCB_uv2c(uv) = 1016957, TCB9_mv2c(uv) = 1017.0602
uv = 5091, TCB_uv2c(uv) = 1027790, TCB9_mv2c(uv) = 1027.8432
uv = 5191, TCB_uv2c(uv) = 1038487, TCB9_mv2c(uv) = 1038.5445
uv = 5291, TCB_uv2c(uv) = 1049083, TCB9_mv2c(uv) = 1049.1666
uv = 5391, TCB_uv2c(uv) = 1059613, TCB9_mv2c(uv) = 1059.7120
uv = 5491, TCB_uv2c(uv) = 1070072, TCB9_mv2c(uv) = 1070.1831
uv = 5591, TCB_uv2c(uv) = 1080532, TCB9_mv2c(uv) = 1080.5821
uv = 5691, TCB_uv2c(uv) = 1090859, TCB9_mv2c(uv) = 1090.9112
uv = 5791, TCB_uv2c(uv) = 1101085, TCB9_mv2c(uv) = 1101.1723
uv = 5891, TCB_uv2c(uv) = 1111289, TCB9_mv2c(uv) = 1111.3674
uv = 5991, TCB_uv2c(uv) = 1121461, TCB9_mv2c(uv) = 1121.4985
uv = 6091, TCB_uv2c(uv) = 1131547, TCB9_mv2c(uv) = 1131.5673
uv = 6191, TCB_uv2c(uv) = 1141505, TCB9_mv2c(uv) = 1141.5756
uv = 6291, TCB_uv2c(uv) = 1151464, TCB9_mv2c(uv) = 1151.5251
uv = 6391, TCB_uv2c(uv) = 1161316, TCB9_mv2c(uv) = 1161.4173
uv = 6491, TCB_uv2c(uv) = 1171234, TCB9_mv2c(uv) = 1171.2541
uv = 6591, TCB_uv2c(uv) = 1180987, TCB9_mv2c(uv) = 1181.0367
uv = 6691, TCB_uv2c(uv) = 1190708, TCB9_mv2c(uv) = 1190.7668
uv = 6791, TCB_uv2c(uv) = 1200367, TCB9_mv2c(uv) = 1200.4459
uv = 6891, TCB_uv2c(uv) = 1209980, TCB9_mv2c(uv) = 1210.0753
uv = 6991, TCB_uv2c(uv) = 1219630, TCB9_mv2c(uv) = 1219.6564
uv = 7091, TCB_uv2c(uv) = 1229141, TCB9_mv2c(uv) = 1229.1907
uv = 7191, TCB_uv2c(uv) = 1238625, TCB9_mv2c(uv) = 1238.6794
uv = 7291, TCB_uv2c(uv) = 1248040, TCB9_mv2c(uv) = 1248.1239
uv = 7391, TCB_uv2c(uv) = 1257444, TCB9_mv2c(uv) = 1257.5254
uv = 7491, TCB_uv2c(uv) = 1266848, TCB9_mv2c(uv) = 1266.8853
uv = 7591, TCB_uv2c(uv) = 1276174, TCB9_mv2c(uv) = 1276.2047
uv = 7691, TCB_uv2c(uv) = 1285417, TCB9_mv2c(uv) = 1285.4849
uv = 7791, TCB_uv2c(uv) = 1294658, TCB9_mv2c(uv) = 1294.7271
uv = 7891, TCB_uv2c(uv) = 1303912, TCB9_mv2c(uv) = 1303.9324
uv = 7991, TCB_uv2c(uv) = 1313075, TCB9_mv2c(uv) = 1313.1020
uv = 8091, TCB_uv2c(uv) = 1322187, TCB9_mv2c(uv) = 1322.2371
uv = 8191, TCB_uv2c(uv) = 1331276, TCB9_mv2c(uv) = 1331.3388
uv = 8291, TCB_uv2c(uv) = 1340330, TCB9_mv2c(uv) = 1340.4082
uv = 8391, TCB_uv2c(uv) = 1349427, TCB9_mv2c(uv) = 1349.4463
uv = 8491, TCB_uv2c(uv) = 1358424, TCB9_mv2c(uv) = 1358.4543
uv = 8591, TCB_uv2c(uv) = 1367382, TCB9_mv2c(uv) = 1367.4333
uv = 8691, TCB_uv2c(uv) = 1376325, TCB9_mv2c(uv) = 1376.3842
uv = 8791, TCB_uv2c(uv) = 1385225, TCB9_mv2c(uv) = 1385.3080
uv = 8891, TCB_uv2c(uv) = 1394195, TCB9_mv2c(uv) = 1394.2059
uv = 8991, TCB_uv2c(uv) = 1403041, TCB9_mv2c(uv) = 1403.0788
uv = 9091, TCB_uv2c(uv) = 1411886, TCB9_mv2c(uv) = 1411.9277
uv = 9191, TCB_uv2c(uv) = 1420685, TCB9_mv2c(uv) = 1420.7535
uv = 9291, TCB_uv2c(uv) = 1429481, TCB9_mv2c(uv) = 1429.5572
uv = 9391, TCB_uv2c(uv) = 1438316, TCB9_mv2c(uv) = 1438.3398
uv = 9491, TCB_uv2c(uv) = 1447068, TCB9_mv2c(uv) = 1447.1023
uv = 9591, TCB_uv2c(uv) = 1455793, TCB9_mv2c(uv) = 1455.8454
uv = 9691, TCB_uv2c(uv) = 1464504, TCB9_mv2c(uv) = 1464.5702
uv = 9791, TCB_uv2c(uv) = 1473269, TCB9_mv2c(uv) = 1473.2776
uv = 9891, TCB_uv2c(uv) = 1481944, TCB9_mv2c(uv) = 1481.9684
uv = 9991, TCB_uv2c(uv) = 1490607, TCB9_mv2c(uv) = 1490.6436
uv = 10091, TCB_uv2c(uv) = 1499249, TCB9_mv2c(uv) = 1499.3041
uv = 10191, TCB_uv2c(uv) = 1507885, TCB9_mv2c(uv) = 1507.9506
uv = 10291, TCB_uv2c(uv) = 1516572, TCB9_mv2c(uv) = 1516.5841
uv = 10391, TCB_uv2c(uv) = 1525184, TCB9_mv2c(uv) = 1525.2055
uv = 10491, TCB_uv2c(uv) = 1533774, TCB9_mv2c(uv) = 1533.8157
uv = 10591, TCB_uv2c(uv) = 1542364, TCB9_mv2c(uv) = 1542.4154
uv = 10691, TCB_uv2c(uv) = 1550935, TCB9_mv2c(uv) = 1551.0057
uv = 10791, TCB_uv2c(uv) = 1559576, TCB9_mv2c(uv) = 1559.5872
uv = 10891, TCB_uv2c(uv) = 1568133, TCB9_mv2c(uv) = 1568.1610
uv = 10991, TCB_uv2c(uv) = 1576686, TCB9_mv2c(uv) = 1576.7278
uv = 11091, TCB_uv2c(uv) = 1585232, TCB9_mv2c(uv) = 1585.2886
uv = 11191, TCB_uv2c(uv) = 1593773, TCB9_mv2c(uv) = 1593.8443
uv = 11291, TCB_uv2c(uv) = 1602382, TCB9_mv2c(uv) = 1602.3956
uv = 11391, TCB_uv2c(uv) = 1610914, TCB9_mv2c(uv) = 1610.9435
uv = 11491, TCB_uv2c(uv) = 1619446, TCB9_mv2c(uv) = 1619.4890
uv = 11591, TCB_uv2c(uv) = 1627974, TCB9_mv2c(uv) = 1628.0328
uv = 11691, TCB_uv2c(uv) = 1636574, TCB9_mv2c(uv) = 1636.5759
uv = 11791, TCB_uv2c(uv) = 1645103, TCB9_mv2c(uv) = 1645.1192
uv = 11891, TCB_uv2c(uv) = 1653632, TCB9_mv2c(uv) = 1653.6636
uv = 11991, TCB_uv2c(uv) = 1662165, TCB9_mv2c(uv) = 1662.2101
uv = 12091, TCB_uv2c(uv) = 1670698, TCB9_mv2c(uv) = 1670.7595
uv = 12191, TCB_uv2c(uv) = 1679310, TCB9_mv2c(uv) = 1679.3127
uv = 12291, TCB_uv2c(uv) = 1687851, TCB9_mv2c(uv) = 1687.8708
uv = 12391, TCB_uv2c(uv) = 1696403, TCB9_mv2c(uv) = 1696.4347
uv = 12491, TCB_uv2c(uv) = 1704957, TCB9_mv2c(uv) = 1705.0052
uv = 12591, TCB_uv2c(uv) = 1713521, TCB9_mv2c(uv) = 1713.5833
uv = 12691, TCB_uv2c(uv) = 1722165, TCB9_mv2c(uv) = 1722.1699
uv = 12791, TCB_uv2c(uv) = 1730745, TCB9_mv2c(uv) = 1730.7659
uv = 12891, TCB_uv2c(uv) = 1739338, TCB9_mv2c(uv) = 1739.3723
uv = 12991, TCB_uv2c(uv) = 1747938, TCB9_mv2c(uv) = 1747.9898
uv = 13091, TCB_uv2c(uv) = 1756556, TCB9_mv2c(uv) = 1756.6193
uv = 13191, TCB_uv2c(uv) = 1765250, TCB9_mv2c(uv) = 1765.2618
uv = 13291, TCB_uv2c(uv) = 1773897, TCB9_mv2c(uv) = 1773.9179
uv = 13391, TCB_uv2c(uv) = 1782545, TCB9_mv2c(uv) = 1782.5884
uv = 13491, TCB_uv2c(uv) = 1791224, TCB9_mv2c(uv) = 1791.2740
uv = 13591, TCB_uv2c(uv) = 1799977, TCB9_mv2c(uv) = 1799.9754
uv = 13691, TCB_uv2c(uv) = 1808686, TCB9_mv2c(uv) = 1808.6932
uv = 13791, TCB_uv2c(uv) = 1817400, TCB9_mv2c(uv) = 1817.4278
Warning:
1) there is no boundary check.
2) endian-dependent.
When I get more time, I will get some sense of how it performs in terms of speed + storage vs. the other approaches.