【RTD】二分法查找和分段线性插值算法在RTD中应用
文章目录
- 1 前言
- 2 二分法查找
- 2.1 复杂度
- 2.2 实现
- 3 分段线性插值
- 4 RTD实例
1 前言
处理器通过RTD采集电路(芯片)精确获得当前RTD电阻值后,再结合RTD与温度线性关系表,换算出当前环境温度。阻值与温度换算,通常是对“阻值—温度”进行查表匹配获得。因为,RTD“阻值—温度”在整个变化范围内不一定是标准线性关系,只在某一温度区间呈现线性或者接近线性。因此,首先将“阻值—温度”划分为一定数量的区间,然后通过“二分法查找算法”查找测量的阻值处于某一区间,再通过“线性插值法”计算出实际温度值。
相关文章:
【RTD】铂电阻测温原理与具体方法
【RTD】AD7793三线式铂电阻PT100/PT1000应用
【RTD】AD7793四线式铂电阻PT100/PT1000应用
【RTD】AD7793两线式铂电阻PT100/PT1000应用
【RTD】AD7793驱动程序
【RTD】二分法查找和分段线性插值算法在RTD中应用
2 二分法查找
二分法查找,或者成为折半法查找,是一种用于有序数组中查找特定元素的查找算法。二分法查找比较易于理解,查找步骤大致分为:
【1】将待查找数组分为两部分
【2】待查找值与数组中间值比较,确保待查找值处于哪一半部分
【3】将该半部分重复【1】【2】步骤,直至查找到目标值或者查找结束为止
2.1 复杂度
- 时间复杂度
【1】最坏情况查找最后一个元素(第一个元素),此时时间复杂度为T(n) = O(log2n)
【2】最理想情况首次查找中间元素即为目标值(奇数长度数组的正中间值,偶数长度数组的中间靠左的元素),此时时间复杂度为T(n) = O(1)
- 空间复杂度
S(n)=logn
2.2 实现
二分法查找算法,可以使用递归和非递归方式实现;递归方式对于查找长度比较长的数组需要更大的栈空间。
- 递归方式C语言实现
int binary_search(int *buf, uint32_t index_bottom, uint32_t index_top, int s_value)
{uint32_t index_mid = 0;if (index_bottom > index_top){return -1;}index_mid = index_bottom + (index_top-index_bottom)/2;if (buf[index_mid] == s_value) {return index_mid;}else if(buf[mid] > s_value){return binary_search(buf, index_bottom, index_mid-1, s_value);}else{return binary_search(buf, index_mid+1, index_top, s_value);}
}
- 非递归C语言实现
int binary_search(int *buf, uint32_t buf_size, int s_value)
{uint32_t index_bottom = 0;uint32_t index_top = buf_size-1;uint32_t index_mid = buf_size/2 - 1;while (index_top-index_bottom > 1){if (s_value < buf[index_mid]){index_top=index_mid; }else if(s_value>buf[index_mid]){index_bottom=index_mid; }else{return index_mid;}index_mid=(index_bottom+index_top)/2;}return -1;
}
3 分段线性插值
分段线性插值法,将目标样本点区间划分为多个区间[x,x+1],分别在每个区间上作一次线性方程,计算x点的插值时,只需用到左右的两个坐标点,计算量与坐标点个数n无关。
假设某一区间两个节点为(x1,y1)和(x2,y2),则该区间上的一次线性方程可以这样表示:
F1=x−x2x1−x2f(x1)+x−x1x2−x1f(x2)F1 = \frac{x-x2} {x1-x2} f(x1)+\frac{x-x1} {x2-x1}f(x2) F1=x1−x2x−x2f(x1)+x2−x1x−x1f(x2)
线性坐标图
以上图为例,利用方程式证明。
斜率:k=(y2−y1)(x2−x1)斜率:k = \frac{(y2-y1)} {(x2-x1)} 斜率:k=(x2−x1)(y2−y1)
线性方程:y−y1=k(x−x1)线性方程:y-y1 = k (x-x1) 线性方程:y−y1=k(x−x1)
y=(y2−y1)(x−x1)(x2−x1)+y1y = \frac{(y2-y1)(x-x1)} {(x2-x1)}+y1 y=(x2−x1)(y2−y1)(x−x1)+y1
y=x−x1x2−x1y2+(1+x−x1x1−x2)y1y = \frac{x-x1} {x2-x1}y2+(1+\frac{x-x1} {x1-x2})y1 y=x2−x1x−x1y2+(1+x1−x2x−x1)y1
y=x−x2x1−x2y1+x−x1x2−x1y2y = \frac{x-x2} {x1-x2} y1+\frac{x-x1} {x2-x1}y2 y=x1−x2x−x2y1+x2−x1x−x1y2
很显然,如果测量的RTD阻值刚好处于某一区间内,则需要使用插值法计算出当前温度值。
4 RTD实例
以PT00、PT1000为例,分别生成一个【-70℃ ~ +110℃】、【温度步进为0.5℃】的表(数组)。X轴表示阻值,y轴表示温度值,根据线性插值法,温度计算公式表示为:
y=[x−x2x1−x2y1+x−x1x2−x1y2]×s−hy = [\frac{x-x2} {x1-x2} y1+\frac{x-x1} {x2-x1}y2]\times {s}-h y=[x1−x2x−x2y1+x2−x1x−x1y2]×s−h
其中:
斜率 s = 0.5
初值 h = 70
const float PT100_CODE[361] =
{ /* -70 ~ + 110C */
72.335, 72.535, 72.735, 72.935, 73.134, 73.334, 73.534, 73.734, 73.934, 74.133,
74.333, 74.533, 74.732, 74.932, 75.131, 75.331, 75.53, 75.73, 75.929, 76.129,
76.328, 76.527, 76.726, 76.926, 77.125, 77.324, 77.523, 77.722, 77.921, 78.12,
78.319, 78.518, 78.717, 78.915, 79.114, 79.313, 79.512, 79.71, 79.909, 80.108,
80.306, 80.505, 80.703, 80.902, 81.1, 81.299, 81.497, 81.695, 81.894, 82.092,
82.29, 82.488, 82.687, 82.885, 83.083, 83.281, 83.479, 83.677, 83.875, 84.073,
84.271, 84.469, 84.666, 84.864, 85.062, 85.26, 85.457, 85.655, 85.853, 86.05,
86.248, 86.445, 86.643, 86.84, 87.038, 87.235, 87.432, 87.63, 87.827, 88.024,
88.222, 88.419, 88.616, 88.813, 89.01, 89.207, 89.404, 89.601, 89.798, 89.995,
90.192, 90.389, 90.586, 90.783, 90.98, 91.177, 91.373, 91.57, 91.767, 91.963,
92.16, 92.356, 92.553, 92.75, 92.946, 93.143, 93.339, 93.535, 93.732, 93.928,
94.124, 94.321, 94.517, 94.713, 94.909, 95.106, 95.302, 95.498, 95.694, 95.89,
96.086, 96.282, 96.478, 96.674, 96.87, 97.066, 97.261, 97.457, 97.653, 97.849,
98.044, 98.24, 98.436, 98.631, 98.827, 99.023, 99.218, 99.414, 99.609, 99.805,
100, 100.195, 100.391, 100.586, 100.781, 100.977, 101.172, 101.367, 101.562, 101.758,
101.953, 102.148, 102.343, 102.538, 102.733, 102.928, 103.123, 103.318, 103.513, 103.708,
103.903, 104.097, 104.292, 104.487, 104.682, 104.876, 105.071, 105.266, 105.46, 105.655,
105.849, 106.044, 106.238, 106.433, 106.627, 106.822, 107.016, 107.211, 107.405, 107.599,
107.794, 107.988, 108.182, 108.376, 108.57, 108.764, 108.959, 109.153, 109.347, 109.541,
109.735, 109.929, 110.123, 110.316, 110.51, 110.704, 110.898, 111.092, 111.286, 111.479,
111.673, 111.867, 112.06, 112.254, 112.447, 112.641, 112.835, 113.028, 113.221, 113.415,
113.608, 113.802, 113.995, 114.188, 114.382, 114.575, 114.768, 114.961, 115.155, 115.348,
115.541, 115.734, 115.927, 116.12, 116.313, 116.506, 116.699, 116.892, 117.085, 117.278,
117.47, 117.663, 117.856, 118.049, 118.241, 118.434, 118.627, 118.819, 119.012, 119.205,
119.397, 119.59, 119.782, 119.975, 120.167, 120.359, 120.552, 120.744, 120.936, 121.129,
121.321, 121.513, 121.705, 121.898, 122.09, 122.282, 122.474, 122.666, 122.858, 123.05,
123.242, 123.434, 123.626, 123.818, 124.009, 124.201, 124.393, 124.585, 124.777, 124.968,
125.16, 125.352, 125.543, 125.735, 125.926, 126.118, 126.309, 126.501, 126.692, 126.884,
127.075, 127.649, 127.458, 127.649, 127.84, 128.032, 128.223, 128.414, 128.605, 128.796,
128.987, 129.178, 129.37, 129.561, 129.752, 129.942, 130.133, 130.324, 130.515, 130.706,
130.897, 131.088, 131.278, 131.469, 131.66, 131.85, 132.041, 132.232, 132.422, 132.613,
132.803, 132.994, 133.184, 133.375, 133.565, 133.755, 133.946, 134.136, 134.326, 134.517,
134.707, 134.897, 135.087, 135.277, 135.468, 135.658, 135.848, 136.038, 136.228, 136.418,
136.608, 136.798, 136.987, 137.177, 137.367, 137.557, 137.747, 137.936, 138.126, 138.316,
138.506, 138.695, 138.885, 139.074, 139.264, 139.453, 139.643, 139.832, 140.022, 140.211,
140.4, 140.59, 140.779, 140.968, 141.158, 141.347, 141.536, 141.725, 141.914, 142.103,
142.293,
};const float PT1000_CODE[361] =
{/* -70 ~ + 110C */
723.345, 725.346, 727.346, 729.345, 731.344, 733.343, 735.341, 737.339, 739.337, 741.334,
743.331, 745.327, 747.324, 749.319, 751.315, 753.309, 755.304, 757.298, 759.292, 761.285,
763.278, 765.271, 767.263, 769.255, 771.247, 773.238, 775.229, 777.219, 779.21, 781.199,
783.189, 785.178, 787.166, 789.155, 791.143, 793.13, 795.117, 797.104, 799.091, 801.077,
803.063, 805.048, 807.033, 809.018, 811.003, 812.987, 814.97, 816.954, 818.937, 820.919,
822.902, 824.884, 826.865, 828.847, 830.828, 832.808, 834.789, 836.769, 838.748, 840.728,
842.707, 844.685, 846.663, 848.641, 850.619, 852.596, 854.573, 856.55, 858.526, 860.502,
862.478, 864.453, 866.428, 868.403, 870.377, 872.351, 874.325, 876.298, 878.271, 880.244,
882.217, 884.189, 886.16, 888.132, 890.103, 892.074, 894.044, 896.015, 897.985, 899.954,
901.923, 903.892, 905.861, 907.829, 909.797, 911.765, 913.732, 915.7, 917.666, 919.633,
921.599, 923.565, 925.53, 927.496, 929.461, 931.425, 933.39, 935.354, 937.317, 939.281,
941.244, 943.207, 945.169, 947.132, 949.093, 951.055, 953.016, 954.977, 956.938, 958.899,
960.859, 962.819, 964.778, 966.737, 968.696, 970.655, 972.613, 974.572, 976.529, 978.487,
980.444, 982.401, 984.358, 986.314, 988.27, 990.226, 992.181, 994.136, 996.091, 998.046,
1000, 1001.954, 1003.908, 1005.861, 1007.814, 1009.767, 1011.72, 1013.672, 1015.624, 1017.576,
1019.527, 1021.478, 1023.429, 1025.38, 1027.33, 1029.28, 1031.229, 1033.179, 1035.128, 1037.077,
1039.025, 1040.973, 1042.921, 1044.869, 1046.816, 1048.764, 1050.71, 1052.657, 1054.603, 1056.549,
1058.495, 1060.44, 1062.385, 1064.33, 1066.274, 1068.218, 1070.162, 1072.106, 1074.049, 1075.992,
1077.935, 1079.877, 1081.82, 1083.762, 1085.703, 1087.644, 1089.585, 1091.526, 1093.467, 1095.407,
1097.347, 1099.286, 1101.225, 1103.164, 1105.103, 1107.042, 1108.98, 1110.917, 1112.855, 1114.792,
1116.729, 1118.666, 1120.602, 1122.538, 1124.474, 1126.41, 1128.345, 1130.28, 1132.215, 1134.149,
1136.083, 1138.017, 1139.95, 1141.884, 1143.817, 1145.749, 1147.681, 1149.614, 1151.545, 1153.477,
1155.408, 1157.339, 1159.27, 1161.2, 1163.13, 1165.06, 1166.989, 1168.918, 1170.847, 1172.776,
1174.704, 1176.632, 1178.56, 1180.487, 1182.414, 1184.341, 1186.268, 1188.194, 1190.12, 1192.046,
1193.971, 1195.896, 1197.821, 1199.746, 1201.67, 1203.594, 1205.518, 1207.441, 1209.364, 1211.287,
1213.21, 1215.132, 1217.054, 1218.975, 1220.897, 1222.818, 1224.739, 1226.659, 1228.579, 1230.499,
1232.419, 1234.338, 1236.257, 1238.176, 1240.095, 1242.013, 1243.931, 1245.848, 1247.766, 1249.683,
1251.6, 1253.516, 1255.432, 1257.348, 1259.264, 1261.179, 1263.094, 1265.009, 1266.923, 1268.837,
1270.751,
};/* */
/*** @brief 二分法查找* @param buf:待查找数据表* @param buf_size:表格大小* @param s_value:查找目标值* @param out_data:返回值* @retval 匹配返回0,否则返回左值*/
int8_t binary_search(const float *buf, uint32_t buf_size, float s_value, uint32_t *out_data)
{uint32_t index_bottom = 0;uint32_t index_top = buf_size-1;uint32_t index_mid = buf_size/2 - 1;while (index_top-index_bottom > 1){if (s_value < buf[index_mid]){index_top=index_mid; }else if(s_value>buf[index_mid]){index_bottom=index_mid; }else{*out_data = index_mid; /* 恰好中值 */return 0x00;}index_mid=(index_bottom+index_top)/2;}*out_data = index_bottom; /* 处于区间内,返回左值 */return 0x01;
}/*** @brief 插值法阻值-温度换算* @param code:温度-阻值表* @param size:表格大小* @param resi:电阻阻值* @retval 实际温度值(℃)*/
float resi_temp_calc(const float *code, uint32_t size, float resi)
{int8_t ret = 0;uint32_t value = 0;float temp = 0.0f;float x1 = 0.0f;float x2 = 0.0f;float y1 = 0.0f;float y2 = 0.0f;ret = binary_search(&code[0], size, resi, &value);if (0x00 == ret){temp = value*0.5f-70;}else if(0x01 == ret){/* 插值法计算 */x1 = code[value];y1 = value;x2 = code[value+1];y2 = value+1;temp = (y1*(resi-x2)/(x1-x2) + y2*(resi-x1)/(x2-x1))*0.5f - 70;}else{/* tod: error */}return temp;
}#include <stdio.h>
#include <stdint.h>
int main(char argc, char **argv)
{float temp0 = 0.0f;float temp1 = 0.0f;temp0 = resi_temp_calc(&PT100_CODE[0], sizeof(PT100_CODE)/sizeof(float), 102);printf("PT100 temp=%.2fC\r\n", temp0);temp1 = resi_temp_calc(&PT1000_CODE[0], sizeof(PT1000_CODE)/sizeof(float), 1001.954);printf("PT1000 temp=%.2fC\r\n", temp1);return 0;
}
【RTD】二分法查找和分段线性插值算法在RTD中应用相关推荐
- matlab实现 分段线性插值算法 piecewise linear interpolation
我们先看<数值计算方法(丁丽娟)>这本书上关于分段线性插值的例题: 所以基本原理从例题中可以看懂 现在设计matlab脚本如下:输入inputn行2列的矩阵,代表已知的原始点,第一列为X值 ...
- 【二级java】 二分法查找
例题1 :对长度为n的线性表进行顺序查找,在最坏情况下所需要的比较次数为______. 解析: 如果线性表中的第一个元素就是被查找元素,则只需做一次比较就查找成功 查找次数为1 如果线形表中不存在该数 ...
- 二分法查找有序表中最接近的数值
二分查找(Binary Search): 二分查找又称折半查找,它是一种效率较高的查找方法. 二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构.不妨设有序表是递增有序 ...
- 基础算法之二分法查找
二分查找算法C 二分查找也属于顺序表查找范围,二分查找也称为折半查找.二分查找(有序)的时间复杂度为O(LogN). 二分查找的基本思想是, 在有序表中,取中间记录作为比较对象,若给定值与中间记录的关 ...
- 可自定义匹配规则查找控件_懂Excel轻松入门Python数据分析包pandas(二十八):二分法查找...
此系列文章收录在公众号中:数据大宇宙 > 数据处理 > E-pd 转发本文并私信我"python",即可获得Python资料以及更多系列文章(持续更新的) 经常听别人说 ...
- 重学数据结构——快速排序,二分法查找
每次提起快排,内心中都有点隐隐作痛. 当时腾讯的那个面试官让我写快排的前两遍排序结果,结果,我当时居然没写上来-- 这个,就是所谓的关键时刻掉链子吧,这么经典的快排都不会,真是丢死人了-- 今天在实验 ...
- 热敏电阻-温度换算算法(分段线性拟合法)
概要 在工业上,会有各种读取环境温度,或读取目标物体温度的需求,通常用到的方案有:传感器测温:热敏电阻测温等.本篇着重讲解使用热敏电阻测温的方法. 热敏电阻 何为热敏电阻?热敏电阻即为热电偶传感器,也 ...
- 查找算法(顺序查找、二分法查找、二叉树查找、hash查找)
查找功能是数据处理的一个基本功能.数据查找并不复杂,但是如何实现数据又快又好地查找呢?前人在实践中积累的一些方法,值得我们好好学些一下.我们假定查找的数据唯一存在,数组中没有重复的数据存在. (1)顺 ...
- 查找元素(线性表实训)
在线性表中查找特定元素是线性表的常用操作之一.要求补全函数search,实现在一个链表中搜索包含指定数据的结点.如果链表中有多个结点包含该数据,则返回第一个. 相关知识 由于链表结点都是动态内存分配得 ...
- 带有哨兵的顺序表查找和二分法查找(折半查找)(java)代码+说明
带有哨兵的顺序表查找和二分法查找(折半查找)(java)代码+说明 一:带有哨兵的顺序表查找 1.算法设计: ...
最新文章
- 【linux】Valgrind工具集详解(十四):Cachegrind(缓存和分支预测分析器)
- VMware Tools手动下载
- 学生电脑哪个牌子好_贺州腻子粉哪个牌子好
- 8-[多线程] 进程池线程池
- 修改服务器时间报错,修改服务器时间linux
- 让自己慢下来(2)-朋友们的回复
- 马云曾卖鲜花,柳传志卖冰箱!摆摊吧,程序员!
- 企业如何选择数据可视化工具
- MATLAB神经网络训练结果各参数解释
- Netty的并发编程实践5:不要依赖线程优先级
- 树莓派接入USB摄像头
- 点击发票填开就出现金税盘处于报税期,不能开票,怎么回事呢?
- UI设计师求职中常被问到的13个面试题及答案总结
- 学做 方玲玉 网络营销_网络营销实务教学课件作者方玲玉参考答案第08讲网络产品独特卖点提炼课件.ppt...
- 南阳oj 144 小柯的苦恼
- jQuery UI Dialog
- VSCode中值得推荐的常用的33个高效前端插件「效率篇」(二)
- R语言逻辑回归的预测概率怎么算
- Wex5 popOver组件的使用
- 小米手机升级后便签内容没了如何找回