소스 검색

Merge pull request #1319 from stv0g/Development

Cleanup and refactoring of termistor LUT generator (fixes bug #1305)
Bo Herrmannsen 10 년 전
부모
커밋
5a5b95edbf
2개의 변경된 파일86개의 추가작업 그리고 86개의 파일을 삭제
  1. 0
    0
      Marlin/scripts/createSpeedLookupTable.py
  2. 86
    86
      Marlin/scripts/createTemperatureLookupMarlin.py

Marlin/scripts/create_speed_lookuptable.py → Marlin/scripts/createSpeedLookupTable.py 파일 보기


+ 86
- 86
Marlin/scripts/createTemperatureLookupMarlin.py 파일 보기

@@ -1,12 +1,8 @@
1 1
 #!/usr/bin/python
2
-#
3
-# Creates a C code lookup table for doing ADC to temperature conversion
4
-# on a microcontroller
5
-# based on: http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html
6 2
 """Thermistor Value Lookup Table Generator
7 3
 
8 4
 Generates lookup to temperature values for use in a microcontroller in C format based on: 
9
-http://hydraraptor.blogspot.com/2007/10/measuring-temperature-easy-way.html
5
+http://en.wikipedia.org/wiki/Steinhart-Hart_equation
10 6
 
11 7
 The main use is for Arduino programs that read data from the circuit board described here:
12 8
 http://make.rrrf.org/ts-1.0
@@ -16,85 +12,87 @@ Usage: python createTemperatureLookup.py [options]
16 12
 Options:
17 13
   -h, --help        show this help
18 14
   --rp=...          pull-up resistor
19
-  --t1=ttt:rrr      low temperature temperature:resistance point (around 25C)
20
-  --t2=ttt:rrr      middle temperature temperature:resistance point (around 150C)
21
-  --t3=ttt:rrr      high temperature temperature:resistance point (around 250C)
22
-  --num-temps=...   the number of temperature points to calculate (default: 20)
15
+  --t1=ttt:rrr      low temperature temperature:resistance point (around 25 degC)
16
+  --t2=ttt:rrr      middle temperature temperature:resistance point (around 150 degC)
17
+  --t3=ttt:rrr      high temperature temperature:resistance point (around 250 degC)
18
+  --num-temps=...   the number of temperature points to calculate (default: 36)
23 19
 """
24 20
 
25 21
 from math import *
26 22
 import sys
27 23
 import getopt
28 24
 
25
+"Constants"
26
+ZERO   = 273.15                             # zero point of Kelvin scale
27
+VADC   = 5                                  # ADC voltage
28
+VCC    = 5                                  # supply voltage
29
+ARES   = 2**10                              # 10 Bit ADC resolution
30
+VSTEP  = VADC / ARES                        # ADC voltage resolution
31
+TMIN   = 0                                  # lowest temperature in table
32
+TMAX   = 350                                # highest temperature in table
33
+
29 34
 class Thermistor:
30 35
     "Class to do the thermistor maths"
31 36
     def __init__(self, rp, t1, r1, t2, r2, t3, r3):
32
-        t1 = t1 + 273.15               # low temperature (25C)
33
-        r1 = r1                        # resistance at low temperature
34
-        t2 = t2 + 273.15               # middle temperature (150C)
35
-        r2 = r2                        # resistance at middle temperature
36
-        t3 = t3 + 273.15               # high temperature (250C)
37
-        r3 = r3                        # resistance at high temperature
38
-        self.rp = rp                   # pull-up resistance
39
-        self.vadc = 5.0                # ADC reference
40
-        self.vcc = 5.0                 # supply voltage to potential divider
41
-        a1 = log(r1)
42
-        a2 = log(r2)
43
-        a3 = log(r3)
44
-        z = a1 - a2
45
-        y = a1 - a3
46
-        x = 1/t1 - 1/t2
47
-        w = 1/t1 - 1/t3
48
-        v = pow(a1,3) - pow(a2,3)
49
-        u = pow(a1,3) - pow(a3,3)
50
-        c3 = (x-z*w/y)/(v-z*u/y)
51
-        c2 = (x-c3*v)/z
52
-        c1 = 1/t1-c3*pow(a1,3)-c2*a1
53
-        self.c1 = c1
54
-        self.c2 = c2
55
-        self.c3 = c3
56
-
57
-    def res(self,adc):
37
+        l1 = log(r1)
38
+        l2 = log(r2)
39
+        l3 = log(r3)
40
+        y1 = 1.0 / (t1 + ZERO)              # adjust scale
41
+        y2 = 1.0 / (t2 + ZERO)
42
+        y3 = 1.0 / (t3 + ZERO)
43
+        x = (y2 - y1) / (l2 - l1)
44
+        y = (y3 - y1) / (l3 - l1)
45
+        c = (y - x) / ((l3 - l2) * (l1 + l2 + l3))
46
+        b = x - c * (l1**2 + l2**2 + l1*l2)
47
+        a = y1 - (b + l1**2 *c)*l1
48
+        
49
+        if c < 0:
50
+            print "//////////////////////////////////////////////////////////////////////////////////////"
51
+            print "// WARNING: negative coefficient 'c'! Something may be wrong with the measurements! //"
52
+            print "//////////////////////////////////////////////////////////////////////////////////////"
53
+            c = -c
54
+        self.c1 = a                         # Steinhart-Hart coefficients
55
+        self.c2 = b
56
+        self.c3 = c
57
+        self.rp = rp                        # pull-up resistance
58
+
59
+    def resol(self, adc):
58 60
         "Convert ADC reading into a resolution"
59 61
         res = self.temp(adc)-self.temp(adc+1)
60 62
         return res
61 63
 
62
-    def v(self,adc):
64
+    def voltage(self, adc):
63 65
         "Convert ADC reading into a Voltage"
64
-        v = adc * self.vadc / (1024 )   # convert the 10 bit ADC value to a voltage
65
-        return v
66
+        return adc * VSTEP                     # convert the 10 bit ADC value to a voltage
66 67
 
67
-    def r(self,adc):
68
+    def resist(self, adc):
68 69
         "Convert ADC reading into a resistance in Ohms"
69
-        v = adc * self.vadc / (1024 )   # convert the 10 bit ADC value to a voltage
70
-        r = self.rp * v / (self.vcc - v)    # resistance of thermistor
70
+        r = self.rp * self.voltage(adc) / (VCC - self.voltage(adc)) # resistance of thermistor
71 71
         return r
72 72
 
73
-    def temp(self,adc):
73
+    def temp(self, adc):
74 74
         "Convert ADC reading into a temperature in Celcius"
75
-        v = adc * self.vadc / (1024 )   # convert the 10 bit ADC value to a voltage
76
-        r = self.rp * v / (self.vcc - v)    # resistance of thermistor
77
-        lnr = log(r)
78
-        Tinv = self.c1 + (self.c2*lnr) + (self.c3*pow(lnr,3))
79
-        return (1/Tinv) - 273.15        # temperature
75
+        l = log(self.resist(adc))
76
+        Tinv = self.c1 + self.c2*l + self.c3* l**3) # inverse temperature
77
+        return (1/Tinv) - ZERO              # temperature
80 78
 
81
-    def adc(self,temp):
79
+    def adc(self, temp):
82 80
         "Convert temperature into a ADC reading"
83
-        y = (self.c1 - (1/(temp+273.15))) / (2*self.c3)
84
-	x = sqrt(pow(self.c2 / (3*self.c3),3) + pow(y,2))
85
-        r = exp(pow(x-y,1.0/3) - pow(x+y,1.0/3)) # resistance of thermistor
86
-        return (r / (self.rp + r)) * (1024)
81
+        x = (self.c1 - (1.0 / (temp+ZERO))) / (2*self.c3)
82
+        y = sqrt((self.c2 / (3*self.c3)**3 + x**2)
83
+        r = exp((y-x)**(1.0/3) - (y+x)**(1.0/3))
84
+        return (r / (self.rp + r)) * ARES
87 85
 
88 86
 def main(argv):
89
-
90
-    rp = 4700;
91
-    t1 = 25;
92
-    r1 = 100000;
93
-    t2 = 150;
94
-    r2 = 1641.9;
95
-    t3 = 250;
96
-    r3 = 226.15;
97
-    num_temps = int(36);
87
+    "Default values"
88
+    t1 = 25                                 # low temperature in Kelvin (25 degC)
89
+    r1 = 100000                             # resistance at low temperature (10 kOhm)
90
+    t2 = 150                                # middle temperature in Kelvin (150 degC)
91
+    r2 = 1641.9                             # resistance at middle temperature (1.6 KOhm)
92
+    t3 = 250                                # high temperature in Kelvin (250 degC)
93
+    r3 = 226.15                             # resistance at high temperature (226.15 Ohm)
94
+    rp = 4700;                              # pull-up resistor (4.7 kOhm)
95
+    num_temps = 36;                         # number of entries for look-up table
98 96
     
99 97
     try:
100 98
         opts, args = getopt.getopt(argv, "h", ["help", "rp=", "t1=", "t2=", "t3=", "num-temps="])
@@ -102,7 +100,7 @@ def main(argv):
102 100
         print  str(err)
103 101
         usage()
104 102
         sys.exit(2)
105
-        
103
+
106 104
     for opt, arg in opts:
107 105
         if opt in ("-h", "--help"):
108 106
             usage()
@@ -111,44 +109,46 @@ def main(argv):
111 109
             rp = int(arg)
112 110
         elif opt == "--t1":
113 111
             arg =  arg.split(':')
114
-            t1 = float( arg[0])
115
-            r1 = float( arg[1])
112
+            t1 = float(arg[0])
113
+            r1 = float(arg[1])
116 114
         elif opt == "--t2":
117 115
             arg =  arg.split(':')
118
-            t2 = float( arg[0])
119
-            r2 = float( arg[1])
116
+            t2 = float(arg[0])
117
+            r2 = float(arg[1])
120 118
         elif opt == "--t3":
121 119
             arg =  arg.split(':')
122
-            t3 = float( arg[0])
123
-            r3 = float( arg[1])
120
+            t3 = float(arg[0])
121
+            r3 = float(arg[1])
124 122
         elif opt == "--num-temps":
125
-            num_temps =  int(arg)
123
+            num_temps = int(arg)
126 124
 
127
-    max_adc = (1024 ) - 1
128
-    min_temp = 0
129
-    max_temp = 350
130
-    increment = int(max_adc/(num_temps-1));
131
-            
132 125
     t = Thermistor(rp, t1, r1, t2, r2, t3, r3)
133
-    tmp = (min_temp - max_temp) / (num_temps-1)
134
-    print tmp
135
-    temps = range(max_temp, min_temp + tmp, tmp);
126
+    increment = int((ARES-1)/(num_temps-1));
127
+    step = (TMIN-TMAX) / (num_temps-1)
128
+    low_bound = t.temp(ARES-1);
129
+    up_bound = t.temp(1);
130
+    min_temp = int(TMIN if TMIN > low_bound else low_bound)
131
+    max_temp = int(TMAX if TMAX < up_bound else up_bound)
132
+    temps = range(max_temp, TMIN+step, step);
136 133
 
137 134
     print "// Thermistor lookup table for Marlin"
138 135
     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)
139
-    print "// Steinhart-Hart Coefficients: %.15g, %.15g,  %.15g " % (t.c1, t.c2, t.c3)
140
-    print "//#define NUMTEMPS %s" % (len(temps))
136
+    print "// Steinhart-Hart Coefficients: a=%.15g, b=%.15g, c=%.15g " % (t.c1, t.c2, t.c3)
137
+    print "// Theoretical limits of termistor: %.2f to %.2f degC" % (low_bound, up_bound)
138
+    print
139
+    print "#define NUMTEMPS %s" % (len(temps))
141 140
     print "const short temptable[NUMTEMPS][2] PROGMEM = {"
142 141
 
143
-    counter = 0
144 142
     for temp in temps:
145
-        counter = counter +1
146
-        if counter == len(temps):
147
-            print "   {(short)(%.2f*OVERSAMPLENR), %s}  // v=%s r=%s res=%s C/count" % ((t.adc(temp)), temp, t.v(t.adc(temp)), t.r(t.adc(temp)),t.res(t.adc(temp)))
148
-        else:
149
-            print "   {(short)(%.2f*OVERSAMPLENR), %s}, // v=%s r=%s res=%s C/count" % ((t.adc(temp)), temp, t.v(t.adc(temp)), t.r(t.adc(temp)),t.res(t.adc(temp)))
143
+        adc = t.adc(temp)
144
+        print "    { (short) (%7.2f * OVERSAMPLENR ), %4s }%s // v=%.3f\tr=%.3f\tres=%.3f degC/count" % (adc , temp, \
145
+                        ',' if temp != temps[-1] else ' ', \
146
+                        t.voltage(adc), \
147
+                        t.resist( adc), \
148
+                        t.resol(  adc) \
149
+                    )
150 150
     print "};"
151
-    
151
+
152 152
 def usage():
153 153
     print __doc__
154 154
 

Loading…
취소
저장