qwt950 发表于 2010-5-7 20:08:13

关于二分法 与分段线性化查表法 ,欢迎探讨 这个表用在K型热电偶温度测量上

1,、二分法
举个例子:
我的理解 顺序表(2、5、7、10、14、15、18、 23 、35、 41 、 52)
找出12的位置
查4次,先和中间数15比,比15小
在和前半段中间数7比:比7大
只剩俩数了,和10比:比10大,
和14比:比14小
2、线性分段
公式为    Y=2T+ n   (n=0 、1 、2 、3 、 4.......54)
这个公式是用AD值算温度的Y为AD值,T温度
列出每个分段的
n   Y
0 2~43
1  44~70
2  71~91
3  92~110
4  111~129
比如   Y= 94
查的过程:1、 和中间数71比:比71大 2、 和后半段中间数91比:比91大
那么在表 3 中
则n=3    T=(94-3)/2=45.5    按分度表计算这是对的

我将K型分度放大250倍,用10位ADREF=5V ,分成1024份
-----------------------------------------
T    K      K*250      AD=y
-----------------------------------------
1    0.039          9.75      2
2    0.079   19.75             4.0448
3    0.119   29         6.0928
4    0.158   39.75      8.1408
5    0.198   49.5       10.1376
6    0.238             59.5      12.1856
7    0.277             69.25   14.1824
8    0.317             79.25             16.2304
9    0.357             89.25             18.2784
10   0.397             99.25             20.3264
11   0.437          109.25             22.3744
12   0.477          119.25             24.4224
13   0.517          129.25             26.4704
14   0.557          139.25      28.5184
15   0.597          149.25      30.5664
16   0.637          159.25             32.6144
17   0.677          169.25      34.6624
18   0.718          179.5       36.7616
19   0.758          189.5       38.8096
20   0.798          199.5       40.8576
21   0.838          209.5       42
21.5                     43
N=0    Y=2T+0
-------------------------------------
21.5                     44
22   0.879          219.75      45
23   0.919          229.75      47.0528
24   0.96          240         49.152
25   1          250         51.2
26   1.041          260.25      53.2992
27   1.081          270.25      55.3472
28   1.122          280.5       57.4464
29   1.163          290.75             59.5456
30   1.203   300.75             61.5936
31   1.244             311      63.6928
32   1.285          321.25      65.792
33   1.326          331.5       67.8912
34   1.366   341.5       69.9
34.5                     70
N=1Y=2T+1
---------------------------------------
34.5                     71
35   1.407          351.75      72.03
36   1.448          362         74.1376
37   1.489          372.25             76.2368
38   1.53          382.5       78.336
39   1.571      392.75   80.4352
40   1.612      403      82.5344
41   1.653      413.25   84.6336
42   1.694      423.5              86.7328
43   1.735      433.75   88.832
44   1.776      444              90.9
44.5                     91
N=2   Y=2T+2
-----------------------------------------
44.5                     92
45   1.817      454.25   93.03
46   1.858      464.5              95.1296
47   1.899      474.75   97.2288
48   1.941      485.25   99.3792
49   1.982      495.5      101.4784
50   2.023      505.75   103.5776
51   2.064      516      105.6768
52   2.106      526.5             107.8272
53   2.147      536.75   109.9
53.5                     110
N=3   Y=2T+3
----------------------------------------
53.5                     111
54   2.188       547       112.0256

这个表加工过将段与段 连续起来,计算只做整数部分!


看了不不少做热电偶 线性化的期刊文献,似乎没看见这样做的,但我觉得可以

有做过类似的东西的欢迎指导!

ywl0409 发表于 2010-5-7 21:12:15

个人认为二分法比较容易编程.特别是对应于热电耦的查表.
而且,查表的结果可能还要线性化插值,最后得出一个对应的温度值.

qwt950 发表于 2010-5-7 21:30:44

回复【1楼】ywl0409 老黄牛
-----------------------------------------------------------------------

恩是这样的,我的做法是直接求得温度,并且能够完全与热电偶分度表对应上,并不需要插值的计算

qwt950 发表于 2010-5-7 21:39:40

void check(int *a ,int l ,int h, int value)
{      
   int mid;   
   mid=(h+l)/2;   
   if(l<=h)   
{         
    if(value>a)         
{               
   l=mid+1;   
   check(a,l,h,value);      
   }            
else if(value<a)      
   {               
   h=mid-1;               
   check(a,l,h,value);      
   }      
   else if(value==a)      
    {               
   printf("Find\n");      
   exit(0) ;         
    }         
printf("Not Find\n");   
      exit(0);   
    }
}
   int main(int argc, char* argv[])
{   
int a={2,44,71,92,111};
    int low,high;   
    int n;      
    low=2;
    high=111;   
    printf("输入要查找的ad值:\n");   
    scanf("%d",&n);      
   check(a,low,high,n);   
    //high=sizeof(a)/sizeof(int);         
return 0;
}
二分法

mcu_lover 发表于 2010-5-7 21:46:53

学习。

qwt950 发表于 2010-5-8 09:27:06

别沉下去哦

eworker 发表于 2010-5-8 09:58:17

学习

ywl0409 发表于 2010-5-8 10:04:47

我觉得最后总要插值的,要不然就需要去分析靠近哪个值.

分度表只是给出两个对应的温度点的电压值,比如1度对应39.9uV,0度对应0V.
那么,如果当你的测量电压是20.7uV的时候,就需要去插值计算,或者根据你的要求,去靠近1度或者0度了.

qwt950 发表于 2010-5-8 11:41:52

LS可能理解的不很明确,AD值从0~ 1023   都能转成相应的温度值的。AD值取整,温度能精确到0.5℃对于一般的系统是够用的了

ywl0409 发表于 2010-5-8 11:56:51

那还是根据你AD转换来的电压精度来换算的.

按照你的做法,就是如果电压值落在了两个相邻的数据之间,那就是0.5度了.
我估计,要想正好获得和分度表中的数据一样的电压值是不太容易的.总有可能会有偏差.这还是和你的AD转换精度有关.
比如,你在1度的时候,采集到的电压值不会正好是39.9uV,那么就会得到0.5度或者1.5度的输出了.

可以这样理解吗?

qwt950 发表于 2010-5-8 12:56:03

回复【9楼】ywl0409 老黄牛
我估计,要想正好获得和分度表中的数据一样的电压值是不太容易的.总有可能会有偏差
-----------------------------------------------------------------------

恩 是这样,最开始我就是这样认为的,后来发现 AD值的整数部分与温度值的线性真的很好,才想出这样的办法,精度好坏那要看AD的了,至于插值我老感觉很麻烦

qwt950 发表于 2010-5-8 13:06:47

回复【9楼】ywl0409 老黄牛
-----------------------------------------------------------------------

很感谢对这个帖子的关注,和对这个问题的意见,我现在在做一个M16恒温焊台,传感器是K偶,补偿用18B20,1602显示。硬件部分焊接完了
程序部分 就差这个查表程序了
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_552369.jpg
(原文件名:截图00.jpg)


多提意见

zzy9903 发表于 2010-5-8 14:23:19

K型热电偶?是不是T12系列的一体头?

ywl0409 发表于 2010-5-8 15:24:18

嗯,你的用途是在测量烙铁温度上.
那么,也许你的最高温度设在500度的话,那么你的1LSB就对应0.5度,那是不需要插值来计算的.
而且,这里计算出来的0.5度也根本不需要考虑进去的.

qwt950 发表于 2010-5-8 15:53:30

回复【13楼】ywl0409 老黄牛
-----------------------------------------------------------------------
是这样的。要真能达到0.5的精度就挺好的了


回复【12楼】zzy9903 9903
-----------------------------------------------------------------------

烙铁头是国产A1322 一体;它的是K热电偶的

zzy9903 发表于 2010-5-8 16:09:33

看到了,貌似这个A1322与T12都差不多,都是用的K型热电偶,不过一个是分体另一个是一体,我也想做一个焊台,无奈水平不济,目前正在收集资料与学习中,上面的电路图太小了,看不清,能否给个大图学习一下?谢谢

qwt950 发表于 2010-5-8 16:33:34

回复【15楼】zzy9903 9903
-----------------------------------------------------------------------
图画的不咋地,随手画画有的地方有错误没来得及改、、 争取月内做好后 电路代码全部公开

zzy9903 发表于 2010-5-8 16:58:36

奥,好的,期待楼主的大作

yjcsoft 发表于 2010-5-9 00:46:48

楼主的QQ多少,我想和你一起讨论

qwt950 发表于 2010-5-9 09:15:11

一、
const unsigned char a=;   //用每个线性分段开头的数建的表1
const unsigned char b=;   //用每个线性分段尾数的数建的表2
for (i=0;i<5;i++)
{
uchar t,ad;
ad=get_ad();
    if(a<=ad)
      if(ad<=b)
      {
    t=( ad - i ) / 2;
      }
}

二、

const unsigned charTEMP_AD={2,44,71,92,111 }//用每个线性分段开头的数建的表


for (i=0;i<5;i++)
{
ad=get_ad();    // 取得AD值
if(TEMP_AD<=ad)
   if(ad<TEMP_AD)
t=( ad - i ) / 2;
break;
}
我的意图:将AD值取出,如果这个值在某一范围内,那么它在这个分段上,这个分段函数(AD=2t+n)的n就是这个范围所对应的指针(i)。
   得到i值,因为我要用这个 i 值 进行计算。

   t=( AD值 - i ) / 2; 是我要计算的公式

我写了两段两种想法,不知对不对    请帮看下那种合理有错误请纠正,我qq93307969

yjcsoft 发表于 2010-5-9 11:36:04

加你QQ了,没有回音

jack_yu 发表于 2010-5-9 11:50:01

mark!

qwt950 发表于 2010-5-9 12:06:48

我现在出来办点事,下午回来加你

qwt950 发表于 2010-5-9 17:50:29

归来 了,谁在帮看看19L这么写怎么样?并没用二分法,是查每一分段的第一个数,后带入线性公式计算,条件什么的在1L

qwt950 发表于 2010-5-10 11:30:06

#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
unsigned charTEMP_AD=
{ 0, 44, 71, 92,111,130,147,162,179,196,
215,234,253,278,305,342,383,430,467,498,
523,546,567,586,605,624,641,658,673,690,
705,720,735,748,763,778,791,806,819,832,
845,858,873,886,897,910,923,936,947,960,
973,984,997,1010,1021};//用每个线性分段开头的数建的表
void main(void)
{
while(1)
{
uchar i;
    for (i=0;i<56;i++)   
       {   
uint ad,t;
ad=ADC_convert();    // 取得AD值
if(ad>=TEMP_AD)
      {
       if(ad<TEMP_AD)
      {
                t=(ad-i-1)/2;
break;
      }
          }
    }
}
}

takashiki 发表于 2010-5-10 17:25:21

我写的软件,数据拟合,然后直接查表就可以了,省去了二分查表的麻烦。

数据拟合功能就是为了干这个用的!

软件在我的资料中自己找,代码写下:

unsigned char Tables = {
        0u,//(0.000, 0.054)
        0u,//(16.238, 0.228)
        1u,//(32.476, 0.567)
        1u,//(48.714, 1.057)
        2u,//(64.952, 1.683)
        2u,//(81.190, 2.422)
        3u,//(97.429, 3.254)
        4u,//(113.667, 4.154)
        5u,//(129.905, 5.100)
        6u,//(146.143, 6.069)
        7u,//(162.381, 7.043)
        8u,//(178.619, 8.003)
        9u,//(194.857, 8.934)
        10u,//(211.095, 9.824)
        11u,//(227.333, 10.665)
        11u,//(243.571, 11.449)
        12u,//(259.810, 12.174)
        13u,//(276.048, 12.839)
        13u,//(292.286, 13.445)
        14u,//(308.524, 13.997)
        14u,//(324.762, 14.500)
        15u,//(341.000, 14.961)
        15u,//(357.238, 15.389)
        16u,//(373.476, 15.793)
        16u,//(389.714, 16.183)
        17u,//(405.952, 16.568)
        17u,//(422.190, 16.960)
        17u,//(438.429, 17.366)
        18u,//(454.667, 17.796)
        18u,//(470.905, 18.257)
        19u,//(487.143, 18.757)
        19u,//(503.381, 19.301)
        20u,//(519.619, 19.894)
        21u,//(535.857, 20.537)
        21u,//(552.095, 21.234)
        22u,//(568.333, 21.984)
        23u,//(584.571, 22.786)
        24u,//(600.810, 23.639)
        25u,//(617.048, 24.539)
        25u,//(633.286, 25.483)
        26u,//(649.524, 26.466)
        27u,//(665.762, 27.483)
        29u,//(682.000, 28.530)
        30u,//(698.238, 29.601)
        31u,//(714.476, 30.693)
        32u,//(730.714, 31.801)
        33u,//(746.952, 32.922)
        34u,//(763.190, 34.054)
        35u,//(779.429, 35.196)
        36u,//(795.667, 36.348)
        38u,//(811.905, 37.510)
        39u,//(828.143, 38.685)
        40u,//(844.381, 39.876)
        41u,//(860.619, 41.087)
        42u,//(876.857, 42.320)
        44u,//(893.095, 43.579)
        45u,//(909.333, 44.866)
        46u,//(925.571, 46.180)
        48u,//(941.810, 47.518)
        49u,//(958.048, 48.870)
        50u,//(974.286, 50.223)
        52u,//(990.524, 51.552)
        53u,//(1006.762, 52.824)
        54u,//(1023.000, 53.992)
};

计算:
inline unsigned char GetValue(unsigned int ADC){    //ADC是你的采样值
   return Tables[(unsigned char)(ADC>>4)];
}

使用AVR和GCC编译器的话,将上述东西分配到Flash中,并用pgm_read_uchar,这里不具体分析了。

qwt950 发表于 2010-5-21 18:58:18

回复【24楼】qwt950
-----------------------------------------------------------------------

对于K偶这段代码在实际的系统当中测试通过,完全能将检测的AD值与温度值吻合起来!!
相对于600*2个数的顺序查表 节省了大量存贮空间,同样节省了查表的时间!

这种方法用的不是二分法与题目相违、、

Soul.art 发表于 2010-6-27 13:04:04

我用proteus仿真了 lz的这个算法,很是准确,非常棒~~

有一事不明,望LZ赐教AD=y,y值是如何得来,不应该是直接对应AD值吧?

qwt950 发表于 2010-6-27 19:39:11

回复【27楼】Soul.art 单片猪
-----------------------------------------------------------------------

是AD采集的值0--1024,计算得到的是带有小数的 我只取的整数部分

qwt950 发表于 2010-6-27 19:51:25

毕业了,今天再次来到这里,有些伤感心酸!在这里我学到了很多!

qwt950 发表于 2010-6-27 19:54:53

24L 这段代码的由来很巧合,是将热点偶信号放大250倍后,将电压值转化为AD值,才能使 AD值与温度值满足这样的关系!

qwt950 发表于 2010-6-27 20:01:27

我做的设计已经算是基本完成,实物做出来了可以恒温,但输出不是数字PID的,一大遗憾啊明天传上来

qwt950 发表于 2010-6-28 08:35:46

点击此处下载 ourdev_564376HBTIOH.rar(文件大小:2.49M) (原文件名:设计.rar)硬件电路设计
点击此处下载 ourdev_564377DPA7FB.rar(文件大小:288K) (原文件名:恒温控制程序.rar)
                  输出本应该用PID的可最终没能实现,用开关量进行控制,有继续做的把这里改善一下!

rube 发表于 2010-7-7 17:36:11

楼主的设计很好,在学校里就有这个水平相当不错了!
谢谢你的资料

wuqi716 发表于 2010-7-9 15:51:58

好贴

aspenlin 发表于 2010-8-7 08:18:21

mark

angle11 发表于 2010-9-23 14:53:49

学习

chenli_365 发表于 2010-11-20 22:13:17

谢谢你的无私奉献

wzhenhua 发表于 2010-12-6 17:54:32

mark

xuejianhua1986 发表于 2010-12-6 19:47:45

mark

xgy1009 发表于 2011-4-28 09:05:45

楼主你好,请问你有没有做过更高精度的温度测量,你做过的最高测温精度能达到多少?

xgy1009 发表于 2011-4-28 09:07:17

楼主,希望能加你QQ,向你请教几个问题。我的QQ:993698637

zhuangchao123 发表于 2011-6-19 17:10:12

学习啦不错的东西

zhenting1005 发表于 2011-7-2 13:21:39

那我用的是AD7135,89C51处理,1602显示,程序怎么弄啊,我实在弄不来,LZ帮帮忙把

zhenting1005 发表于 2011-7-2 13:28:17

希望LZ帮帮忙,QQ:51071930

tongyf 发表于 2011-7-7 13:01:51

好资料

jacky2011 发表于 2011-11-21 09:26:36

记号

dingliming 发表于 2012-2-10 05:44:57

很好

zhuangchao123 发表于 2012-2-10 09:57:35

很值得研究一下

asma 发表于 2012-2-15 23:34:29

mark

wwwjjjwww 发表于 2012-2-16 00:21:43

直接用公式计算,我做过温度变送器,公式计算最准准确。温度变送器的要求比你这个高多了。

smtgg 发表于 2012-3-4 21:41:09

mark

mcujack 发表于 2012-7-3 11:30:20

标记以后学习

jhxmzx 发表于 2013-4-20 09:36:35

楼主资料弄的很详细,学习了

yaonen 发表于 2016-7-13 23:51:30

标记以后学习
页: [1]
查看完整版本: 关于二分法 与分段线性化查表法 ,欢迎探讨 这个表用在K型热电偶温度测量上