Sat, 07 Nov 2015 13:23:07 +0100
Initial code from reprappro Marlin repository
0 | 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 | """Thermistor Value Lookup Table Generator | |
7 | ||
8 | 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 | |
10 | ||
11 | The main use is for Arduino programs that read data from the circuit board described here: | |
12 | http://make.rrrf.org/ts-1.0 | |
13 | ||
14 | Usage: python createTemperatureLookup.py [options] | |
15 | ||
16 | Options: | |
17 | -h, --help show this help | |
18 | --r0=... thermistor rating where # is the ohm rating of the thermistor at t0 (eg: 10K = 10000) | |
19 | --t0=... thermistor temp rating where # is the temperature in Celsuis to get r0 (from your datasheet) | |
20 | --beta=... thermistor beta rating. see http://reprap.org/bin/view/Main/MeasuringThermistorBeta | |
21 | --r1=... R1 rating where # is the ohm rating of R1 (eg: 10K = 10000) | |
22 | --r2=... R2 rating where # is the ohm rating of R2 (eg: 10K = 10000) | |
23 | --num-temps=... the number of temperature points to calculate (default: 20) | |
24 | --max-adc=... the max ADC reading to use. if you use R1, it limits the top value for the thermistor circuit, and thus the possible range of ADC values | |
25 | """ | |
26 | ||
27 | from math import * | |
28 | import sys | |
29 | import getopt | |
30 | ||
31 | class Thermistor: | |
32 | "Class to do the thermistor maths" | |
33 | def __init__(self, r0, t0, beta, r1, r2): | |
34 | self.r0 = r0 # stated resistance, e.g. 10K | |
35 | self.t0 = t0 + 273.15 # temperature at stated resistance, e.g. 25C | |
36 | self.beta = beta # stated beta, e.g. 3500 | |
37 | self.vadc = 5.0 # ADC reference | |
38 | self.vcc = 5.0 # supply voltage to potential divider | |
39 | self.k = r0 * exp(-beta / self.t0) # constant part of calculation | |
40 | ||
41 | if r1 > 0: | |
42 | self.vs = r1 * self.vcc / (r1 + r2) # effective bias voltage | |
43 | self.rs = r1 * r2 / (r1 + r2) # effective bias impedance | |
44 | else: | |
45 | self.vs = self.vcc # effective bias voltage | |
46 | self.rs = r2 # effective bias impedance | |
47 | ||
48 | def temp(self,adc): | |
49 | "Convert ADC reading into a temperature in Celcius" | |
50 | v = adc * self.vadc / 1024 # convert the 10 bit ADC value to a voltage | |
51 | r = self.rs * v / (self.vs - v) # resistance of thermistor | |
52 | return (self.beta / log(r / self.k)) - 273.15 # temperature | |
53 | ||
54 | def setting(self, t): | |
55 | "Convert a temperature into a ADC value" | |
56 | r = self.r0 * exp(self.beta * (1 / (t + 273.15) - 1 / self.t0)) # resistance of the thermistor | |
57 | v = self.vs * r / (self.rs + r) # the voltage at the potential divider | |
58 | return round(v / self.vadc * 1024) # the ADC reading | |
59 | ||
60 | def main(argv): | |
61 | ||
62 | r0 = 10000; | |
63 | t0 = 25; | |
64 | beta = 3947; | |
65 | r1 = 680; | |
66 | r2 = 1600; | |
67 | num_temps = int(20); | |
68 | ||
69 | try: | |
70 | opts, args = getopt.getopt(argv, "h", ["help", "r0=", "t0=", "beta=", "r1=", "r2="]) | |
71 | except getopt.GetoptError: | |
72 | usage() | |
73 | sys.exit(2) | |
74 | ||
75 | for opt, arg in opts: | |
76 | if opt in ("-h", "--help"): | |
77 | usage() | |
78 | sys.exit() | |
79 | elif opt == "--r0": | |
80 | r0 = int(arg) | |
81 | elif opt == "--t0": | |
82 | t0 = int(arg) | |
83 | elif opt == "--beta": | |
84 | beta = int(arg) | |
85 | elif opt == "--r1": | |
86 | r1 = int(arg) | |
87 | elif opt == "--r2": | |
88 | r2 = int(arg) | |
89 | ||
90 | if r1: | |
91 | max_adc = int(1023 * r1 / (r1 + r2)); | |
92 | else: | |
93 | max_adc = 1023 | |
94 | increment = int(max_adc/(num_temps-1)); | |
95 | ||
96 | t = Thermistor(r0, t0, beta, r1, r2) | |
97 | ||
98 | adcs = range(1, max_adc, increment); | |
99 | # adcs = [1, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 110, 130, 150, 190, 220, 250, 300] | |
100 | first = 1 | |
101 | ||
102 | print "// Thermistor lookup table for RepRap Temperature Sensor Boards (http://make.rrrf.org/ts)" | |
103 | print "// Made with createTemperatureLookup.py (http://svn.reprap.org/trunk/reprap/firmware/Arduino/utilities/createTemperatureLookup.py)" | |
104 | print "// ./createTemperatureLookup.py --r0=%s --t0=%s --r1=%s --r2=%s --beta=%s --max-adc=%s" % (r0, t0, r1, r2, beta, max_adc) | |
105 | print "// r0: %s" % (r0) | |
106 | print "// t0: %s" % (t0) | |
107 | print "// r1: %s" % (r1) | |
108 | print "// r2: %s" % (r2) | |
109 | print "// beta: %s" % (beta) | |
110 | print "// max adc: %s" % (max_adc) | |
111 | print "#define NUMTEMPS %s" % (len(adcs)) | |
112 | print "short temptable[NUMTEMPS][2] = {" | |
113 | ||
114 | counter = 0 | |
115 | for adc in adcs: | |
116 | counter = counter +1 | |
117 | if counter == len(adcs): | |
118 | print " {%s, %s}" % (adc, int(t.temp(adc))) | |
119 | else: | |
120 | print " {%s, %s}," % (adc, int(t.temp(adc))) | |
121 | print "};" | |
122 | ||
123 | def usage(): | |
124 | print __doc__ | |
125 | ||
126 | if __name__ == "__main__": | |
127 | main(sys.argv[1:]) |