• 通过热敏电阻计算温度(三)---Marlin实现分析


    文章目录


    通过热敏电阻计算温度(三)—Marlin实现分析

    marlin固件温度的计算方法采用的是Steinhart-Hart方程计算的方式。首先通过python生成温度查表数据,单片机端可以直接使用查表的方式计算温度数据。

    温度查表数据:
    OVERSAMPLENR 的值为16,数组中的第一个值为ADC采样值的16倍。因为实际计算中的ADC值是采样16次的和

    //专为stm32生成的温度查表
    //在此有一点需要注意,这里的数值类型不能再用short类型了,若还用short类型会报一系列警告信息,
    //同时要注意修改analog2temp(int raw, uint8_t e)函数,将与温度查表相关的类型short改为int类型
    const int temptable_1[][2]  = { 
    	{  (91 * OVERSAMPLENR ),  300 }, 
    	{  (98 * OVERSAMPLENR ),  295 }, 
    	{  (105 * OVERSAMPLENR ),  290 }, 
    	{  (112 * OVERSAMPLENR ),  285 }, 
    	{  (120 * OVERSAMPLENR ),  280 }, 
    	{  (129 * OVERSAMPLENR ),  275 }, 
    	{  (139 * OVERSAMPLENR ),  270 }, 
    	{  (150 * OVERSAMPLENR ),  265 }, 
    	{  (161 * OVERSAMPLENR ),  260 }, 
    	{  (174 * OVERSAMPLENR ),  255 }, 
    	{  (188 * OVERSAMPLENR ),  250 }, 
    	{  (203 * OVERSAMPLENR ),  245 }, 
    	{  (220 * OVERSAMPLENR ),  240 }, 
    	{  (239 * OVERSAMPLENR ),  235 }, 
    	{  (259 * OVERSAMPLENR ),  230 }, 
    	{  (281 * OVERSAMPLENR ),  225 }, 
    	{  (306 * OVERSAMPLENR ),  220 }, 
    	{  (332 * OVERSAMPLENR ),  215 }, 
    	{  (362 * OVERSAMPLENR ),  210 }, 
    	{  (395 * OVERSAMPLENR ),  205 }, 
    	{  (431 * OVERSAMPLENR ),  200 }, 
    	{  (471 * OVERSAMPLENR ),  195 }, 
    	{  (515 * OVERSAMPLENR ),  190 }, 
    	{  (563 * OVERSAMPLENR ),  185 }, 
    	{  (616 * OVERSAMPLENR ),  180 }, 
    	{  (674 * OVERSAMPLENR ),  175 }, 
    	{  (739 * OVERSAMPLENR ),  170 }, 
    	{  (809 * OVERSAMPLENR ),  165 }, 
    	{  (886 * OVERSAMPLENR ),  160 }, 
    	{  (969 * OVERSAMPLENR ),  155 }, 
    	{  (1060 * OVERSAMPLENR ),  150 }, 
    	{  (1159 * OVERSAMPLENR ),  145 }, 
    	{  (1265 * OVERSAMPLENR ),  140 }, 
    	{  (1379 * OVERSAMPLENR ),  135 }, 
    	{  (1501 * OVERSAMPLENR ),  130 }, 
    	{  (1630 * OVERSAMPLENR ),  125 }, 
    	{  (1765 * OVERSAMPLENR ),  120 }, 
    	{  (1906 * OVERSAMPLENR ),  115 }, 
    	{  (2052 * OVERSAMPLENR ),  110 }, 
    	{  (2202 * OVERSAMPLENR ),  105 }, 
    	{  (2353 * OVERSAMPLENR ),  100 }, 
    	{  (2504 * OVERSAMPLENR ),   95 }, 
    	{  (2654 * OVERSAMPLENR ),   90 }, 
    	{  (2800 * OVERSAMPLENR ),   85 }, 
    	{  (2942 * OVERSAMPLENR ),   80 }, 
    	{  (3076 * OVERSAMPLENR ),   75 }, 
    	{  (3203 * OVERSAMPLENR ),   70 }, 
    	{  (3321 * OVERSAMPLENR ),   65 }, 
    	{  (3429 * OVERSAMPLENR ),   60 }, 
    	{  (3527 * OVERSAMPLENR ),   55 }, 
    	{  (3615 * OVERSAMPLENR ),   50 }, 
    	{  (3692 * OVERSAMPLENR ),   45 }, 
    	{  (3760 * OVERSAMPLENR ),   40 }, 
    	{  (3819 * OVERSAMPLENR ),   35 }, 
    	{  (3869 * OVERSAMPLENR ),   30 }, 
    	{  (3912 * OVERSAMPLENR ),   25 }, 
    	{  (3948 * OVERSAMPLENR ),   20 }, 
    	{  (3978 * OVERSAMPLENR ),   15 }, 
    	{  (4002 * OVERSAMPLENR ),   10 }, 
    	{  (4022 * OVERSAMPLENR ),    5 }, 
    	{  (4039 * OVERSAMPLENR ),    0 },
     };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    根据温度查表数据将ADC采样值转换为温度数据的函数

    // Derived from RepRap FiveD extruder::getTemperature()
    // For hot end temperature measurement.//热端温度测量
    static float analog2temp(int raw, uint8_t e) {  //将温度的adc值转换为对应的温度值
    	uint8_t i;
      if(e >= EXTRUDERS) {
    		SERIAL_ERROR_START;
    		printf("%d",e);
    		printf(" - Invalid extruder number !");
    		printf("\n");
    		kill();
      } 
    
      if(heater_ttbl_map[e] != NULL) {
        float celsius = 0;
        int (*tt)[][2] = (int (*)[][2])(heater_ttbl_map[e]);
    
        for ( i=1; i<heater_ttbllen_map[e]; i++) {  //通过查表利用内差的方式估计挤出头目前的温度   
          if ((*tt)[i][0] > raw) {
            celsius = (*tt)[i-1][1] + 
              (raw - (*tt)[i-1][0]) * 
              (float)((*tt)[i][1] - (*tt)[i-1][1]) /
              (float)((*tt)[i][0] - (*tt)[i-1][0]);
            break;
          }
        }
    
        // Overflow: Set to last value in the table
        if (i == heater_ttbllen_map[e]) celsius = (*tt)[i-1][1];
    
        return celsius; //热敏电阻测量的数据生成的温度值
      }
      return 0;
      //return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET; //热电偶测得的数据计算温度值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    生成温度查表数据的python程序

    #!/usr/bin/python
    """Thermistor Value Lookup Table Generator
    
    Generates lookup to temperature values for use in a microcontroller in C format based on:
    http://en.wikipedia.org/wiki/Steinhart-Hart_equation
    
    The main use is for Arduino programs that read data from the circuit board described here:
    http://reprap.org/wiki/Temperature_Sensor_v2.0
    
    Usage: python createTemperatureLookup.py [options]
    
    Options:
      -h, --help        show this help
      --rp=...          pull-up resistor
      --t1=ttt:rrr      low temperature temperature:resistance point (around 25 degC)
      --t2=ttt:rrr      middle temperature temperature:resistance point (around 150 degC)
      --t3=ttt:rrr      high temperature temperature:resistance point (around 250 degC)
      --num-temps=...   the number of temperature points to calculate (default: 36)
    """
    
    from math import *
    import sys
    import getopt
    
    "Constants"
    ZERO   = 273.15                             # zero point of Kelvin scale
    VADC   = 3.3                                  # ADC voltage
    VCC    = 3.3                                  # supply voltage
    ARES   = pow(2,12)                          # 10 Bit ADC resolution
    VSTEP  = VADC / ARES                        # ADC voltage resolution
    TMIN   = 0                                  # lowest temperature in table
    TMAX   = 300                                # highest temperature in table
    
    class Thermistor:
        "Class to do the thermistor maths"
        def __init__(self, rp, t1, r1, t2, r2, t3, r3):
            l1 = log(r1)
            l2 = log(r2)
            l3 = log(r3)
            y1 = 1.0 / (t1 + ZERO)              # adjust scale
            y2 = 1.0 / (t2 + ZERO)
            y3 = 1.0 / (t3 + ZERO)
            x = (y2 - y1) / (l2 - l1)
            y = (y3 - y1) / (l3 - l1)
            c = (y - x) / ((l3 - l2) * (l1 + l2 + l3))
            b = x - c * (l1**2 + l2**2 + l1*l2)
            a = y1 - (b + l1**2 *c)*l1
    
            if c < 0:
                print "//"
                print "// WARNING: negative coefficient 'c'! Something may be wrong with the measurements! //"
                print "//"
                c = -c
            self.c1 = a                         # Steinhart-Hart coefficients
            self.c2 = b
            self.c3 = c
            self.rp = rp                        # pull-up resistance
    
        def resol(self, adc):
            "Convert ADC reading into a resolution"
            res = self.temp(adc)-self.temp(adc+1)
            return res
    
        def voltage(self, adc):
            "Convert ADC reading into a Voltage"
            return adc * VSTEP                     # convert the 10 bit ADC value to a voltage
    
        def resist(self, adc):
            "Convert ADC reading into a resistance in Ohms"
            r = self.rp * self.voltage(adc) / (VCC - self.voltage(adc)) # resistance of thermistor
            return r
    
        def temp(self, adc):
            "Convert ADC reading into a temperature in Celcius"
            l = log(self.resist(adc))
            Tinv = self.c1 + self.c2*l + self.c3* l**3 # inverse temperature
            return (1/Tinv) - ZERO              # temperature
    
        def adc(self, temp):
            "Convert temperature into a ADC reading"
            x = (self.c1 - (1.0 / (temp+ZERO))) / (2*self.c3)
            y = sqrt((self.c2 / (3*self.c3))**3 + x**2)
            r = exp((y-x)**(1.0/3) - (y+x)**(1.0/3))
            return (r / (self.rp + r)) * ARES
    
    def main(argv):
        "Default values"
        t1 = 25                                 # low temperature in Kelvin (25 degC)
        r1 = 100000                             # resistance at low temperature (10 kOhm)
        t2 = 150                                # middle temperature in Kelvin (150 degC)
        r2 = 1641.9                             # resistance at middle temperature (1.6 KOhm)
        t3 = 250                                # high temperature in Kelvin (250 degC)
        r3 = 226.15                             # resistance at high temperature (226.15 Ohm)
        rp = 4700;                              # pull-up resistor (4.7 kOhm)
        num_temps = 61;                         # number of entries for look-up table
    
        try:
            opts, args = getopt.getopt(argv, "h", ["help", "rp=", "t1=", "t2=", "t3=", "num-temps="])
        except getopt.GetoptError as err:
            print  str(err)
            usage()
            sys.exit(2)
    
        for opt, arg in opts:
            if opt in ("-h", "--help"):
                usage()
                sys.exit()
            elif opt == "--rp":
                rp = int(arg)
            elif opt == "--t1":
                arg =  arg.split(':')
                t1 = float(arg[0])
                r1 = float(arg[1])
            elif opt == "--t2":
                arg =  arg.split(':')
                t2 = float(arg[0])
                r2 = float(arg[1])
            elif opt == "--t3":
                arg =  arg.split(':')
                t3 = float(arg[0])
                r3 = float(arg[1])
            elif opt == "--num-temps":
                num_temps = int(arg)
    
        t = Thermistor(rp, t1, r1, t2, r2, t3, r3)
        increment = int((ARES-1)/(num_temps-1));
        step = (TMIN-TMAX) / (num_temps-1)
        low_bound = t.temp(ARES-1);
        up_bound = t.temp(1);
        min_temp = int(TMIN if TMIN > low_bound else low_bound)
        max_temp = int(TMAX if TMAX < up_bound else up_bound)
        temps = range(max_temp, TMIN+step, step);
    
        print "// Thermistor lookup table for Marlin"
        print "// ./createTemperatureLookupMarlin.py --rp=%s --t1=%s:%s --t2=%s:%s --t3=%s:%s --num-temps=%s" % (rp, t1, r1, t2, r2, t3, r3, num_temps)
        print "// Steinhart-Hart Coefficients: a=%.15g, b=%.15g, c=%.15g " % (t.c1, t.c2, t.c3)
        print "// Theoretical limits of termistor: %.2f to %.2f degC" % (low_bound, up_bound)
        print
        print "#define NUMTEMPS %s" % (len(temps))
        print "const long temptable[NUMTEMPS][2] = {"
    
        for temp in temps:
            adc = t.adc(temp)
            print "    {  (%d * OVERSAMPLENR ), %4s }%s // v=%s r=%s res=%s degC/count" % ((adc+0.5) , temp , \
                            ',' if temp != temps[-1] else ' ', \
                            t.voltage(adc), \
                            t.resist( adc), \
                            t.resol(  adc) \
                       )
        print "};"
    
    def usage():
        print __doc__
    
    if __name__ == "__main__":
        main(sys.argv[1:])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
  • 相关阅读:
    拿什么拯救你?这暴热的天气!只能用python分析做个可视化康康
    GBase 8s CLOSE 语句
    pg 模拟主库down机之pg_kaboom
    ris转换bib
    monkeyrunner录制脚本和回放
    MySQL 日期函数大全(更新中.....)
    shell脚本变量
    k8s之deployment应用
    C++学习日记:关于我决定开始学习C++的那些事
    【Game Of AutoTest】2、游戏自动化测试的技术选型
  • 原文地址:https://blog.csdn.net/xiaoyuanwuhui/article/details/134010821