00001 ## 00002 # 00003 # Class to calculate temperatures and voltages of thermocouples. The 00004 # basic equation is T = f(V) where T is temperature and V is voltage. The 00005 # approximating polynomials come from the Omega Temperature Catalog vol 26, 00006 # 1988, page T-12. 00007 # 00008 # The Tc class constructor takes a string that identifies the thermocouple. 00009 # Supported types are E, J, K, R, S, T. Type K is the default type. The 00010 # class methods are: 00011 # 00012 # mV_to_degF 00013 # mV_to_degC 00014 # degF_to_mV 00015 # degC_to_mV 00016 # 00017 # An exception will be raised if the input voltage or temperature is outside 00018 # of the allowed range. 00019 # 00020 # The method used is to calculate T give V by the polynomial approximation. 00021 # The inverse function (to calculate V given T) is gotten by using Newton's 00022 # method to invert the polynomial. 00023 # 00024 # If you call this module as a main module, it will run tests that validate 00025 # the output of the Tc class. 00026 # 00027 # Copyright (C) 2002 GDS Software 00028 # 00029 # This program is free software; you can redistribute it and/or 00030 # modify it under the terms of the GNU General Public License as 00031 # published by the Free Software Foundation; either version 2 of 00032 # the License, or (at your option) any later version. 00033 # 00034 # This program is distributed in the hope that it will be useful, 00035 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00036 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00037 # GNU General Public License for more details. 00038 # 00039 # You should have received a copy of the GNU General Public 00040 # License along with this program; if not, write to the Free 00041 # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00042 # MA 02111-1307 USA 00043 # 00044 # See http://www.gnu.org/licenses/licenses.html for more details. 00045 # 00046 00047 import sys, string 00048 __version__ = "$Id: tc.py,v 1.3 2002/08/21 12:41:49 donp Exp $" 00049 00050 00051 class Tc: 00052 # The following dictionary contains the coefficients of the polynomials 00053 # that convert EMF to temperature in degrees C. 00054 00055 # xx Check that the type K array is correct. In the C version, it had 00056 # xx only 9 terms, not 10. I made the last element (the x^9 term) 0. 00057 # xx Also check for type R. 00058 00059 coefficients = { 00060 "E" : [0.104967248, 17189.45282, -282639.0850, 12695339.5, -448703084.6, 1.10866e10, -1.76807e11, 1.71842e12, -9.19278e12, 2.06132e13], 00061 "J" : [-0.048868252, 19873.14503, -218614.5353, 11569199.78, -264917531.4, 2018441314.0, 0.0, 0.0, 0.0, 0.0], 00062 "K" : [0.226584602, 24152.10900, 67233.4248, 2210340.682, -860963914.9, 4.83506e10, -1.18452e12, 1.38690e13, -6.33708e13, 0.0], 00063 "R" : [0.263632917, 179075.491, -48840341.37, 1.90002e10, -4.82704e12, 7.62091e14, -7.20026e16, 3.71496e18, -8.03104e19, 0.0], 00064 "S" : [0.927763167, 169526.5150, -31568363.94, 8990730663.0, -1.63565e12, 1.88027e14, -1.37241e16, 6.17501e17, -1.56105e19, 1.69535e20], 00065 "T" : [0.100860910, 25727.94369, -767345.8295, 78025595.81, -9247486589.0, 6.97688e11, -2.66192e13, 3.94078e14, 0.0, 0.0] 00066 } 00067 00068 mV_limits = { 00069 "E" : [-5.237, 76.358], 00070 "J" : [0.0, 42.922], 00071 "K" : [0.0, 54.807], 00072 "R" : [0.0, 10.503], 00073 "S" : [0.0, 18.504], 00074 "T" : [-4.865, 20.869] 00075 } 00076 tc_error = -999.0 00077 00078 def __init__(self, tcType = "K", ignore_error = 0): 00079 self.coef = self.coefficients[tcType] 00080 self.limits = self.mV_limits[tcType] 00081 self.ignore_error = 0 00082 00083 def mV_to_degC(self, mV): 00084 if mV < self.limits[0] or mV > self.limits[1]: 00085 if self.ignore_error: 00086 raise `mV` + " out of limits" 00087 else: 00088 return self.tc_error 00089 return self.__v2c(mV/1000.) 00090 00091 def mV_to_degF(self, mV): 00092 return self.__c2f(self.mV_to_degC(mV)) 00093 00094 def degF_to_mV(self, mV): 00095 pass 00096 00097 def degC_to_mV(self, T): 00098 # Use Newton's method to find the root. 00099 raise "Not written" 00100 count = 0 00101 while 1: 00102 mV_new = mV_old - self.mV_to_degC(mV_old)/self.__deriv(mV_old) 00103 count = count + 1 00104 if (count > 100): 00105 raise "Too many iterations" 00106 if abs(mV_new - mV_old) < .001: 00107 pass 00108 00109 00110 def __v2c(self, v): 00111 # Evaluate the polynomial. Input is voltage in volts, output is 00112 # temperature in degrees C. 00113 a = self.coef 00114 return a[0]+v*(a[1]+v*(a[2]+v*(a[3]+v*(a[4]+v*(a[5]+v*(a[6]+v*(a[7] +v*(a[8]+v*a[9])))))))) 00115 00116 def __c2f(self, t): 00117 return 9.*t/5 + 32 00118 00119 ############################################################################## 00120 # Test the Tc class 00121 00122 if __name__ == "__main__": 00123 00124 error_cases = [ 00125 [-5.238e-3, "E"], 00126 [76.359e-3, "E"], 00127 [-1e-3, "J"], 00128 [42.923e-3, "J"], 00129 [-1e-3, "K"], 00130 [54.808e-3, "K"], 00131 [-1e-3, "R"], 00132 [10.504e-3, "R"], 00133 [-1e-3, "S"], 00134 [18.505e-3, "S"], 00135 [-4.866e-3, "T"], 00136 [20.870e-3, "T"], 00137 ] 00138 00139 # Polynomial error should be less than the following values in deg C 00140 tolerance = { 00141 "E" : 0.5, 00142 "J" : 0.1, 00143 "K" : 0.7, 00144 "R" : 0.5, 00145 "S" : 1.0, 00146 "T" : 0.5, 00147 } 00148 test_cases = { 00149 "E" : [ 00150 [0.0, 0.0], 00151 [6.317, 100.0], 00152 [13.419, 200.0], 00153 [21.033, 300.0], 00154 [28.943, 400.0], 00155 [36.999, 500.0], 00156 [45.085, 600.0], 00157 [53.110, 700.0], 00158 [61.022, 800.0], 00159 [68.783, 900.0], 00160 [76.357, 1000.0], 00161 ], 00162 "J" : [ 00163 [0.0, 0.0], 00164 [5.268, 100.0], 00165 [10.777, 200.0], 00166 [16.325, 300.0], 00167 [21.846, 400.0], 00168 [27.388, 500.0], 00169 [33.096, 600.0], 00170 [39.130, 700.0], 00171 [42.922, 760.0], 00172 ], 00173 "K" : [ 00174 [0.0, 0.0], 00175 [4.095, 100.0], 00176 [ 8.137, 200.0], 00177 [12.207, 300.0], 00178 [16.395, 400.0], 00179 [20.640, 500.0], 00180 [24.902, 600.0], 00181 [29.128, 700.0], 00182 [33.277, 800.0], 00183 [37.325, 900.0], 00184 [41.269, 1000.0], 00185 [45.108, 1100.0], 00186 [48.828, 1200.0], 00187 [52.398, 1300.0], 00188 ], 00189 "R" : [ 00190 [0.0, 0.0], 00191 [0.647, 100.0], 00192 [ 1.468, 200.0], 00193 [ 2.400, 300.0], 00194 [ 3.407, 400.0], 00195 [ 4.471, 500.0], 00196 [ 5.582, 600.0], 00197 [ 6.741, 700.0], 00198 [ 7.949, 800.0], 00199 [ 9.203, 900.0], 00200 [10.503, 1000.0], 00201 ], 00202 "S" : [ 00203 [0.0, 0.0], 00204 [0.645, 100.0], 00205 [ 1.440, 200.0], 00206 [ 2.323, 300.0], 00207 [ 3.260, 400.0], 00208 [ 4.234, 500.0], 00209 [ 5.237, 600.0], 00210 [ 6.274, 700.0], 00211 [ 7.345, 800.0], 00212 [ 8.448, 900.0], 00213 [ 9.585, 1000.0], 00214 [10.754, 1100.0], 00215 [11.947, 1200.0], 00216 [13.155, 1300.0], 00217 [14.368, 1400.0], 00218 [15.576, 1500.0], 00219 [16.771, 1600.0], 00220 [17.942, 1700.0], 00221 [18.503, 1750.0], 00222 ], 00223 "T" : [ 00224 [-4.864, -160.0], 00225 [-3.378, -100.0], 00226 [0.0, 0.0], 00227 [4.277, 100.0], 00228 [ 9.286, 200.0], 00229 [14.860, 300.0], 00230 [20.869, 400.0], 00231 ] 00232 } 00233 00234 # Test EMF to temperature conversion 00235 for tc_type in test_cases.keys(): 00236 tc = Tc(tcType = tc_type) 00237 cases = test_cases[tc_type] 00238 for case in cases: 00239 mV = case[0] 00240 degC_correct = case[1] 00241 degC = tc.mV_to_degC(mV) 00242 eps = degC - degC_correct 00243 if abs(eps) > tolerance[tc_type]: 00244 raise "Bad test case for type " + tc_type 00245 del tc 00246 00247 # Test the cases that should raise exceptions 00248 for case in error_cases: 00249 mV = case[0] 00250 tc_type = case[1] 00251 tc = Tc(tcType = tc_type) 00252 try: 00253 degC = tc.mV_to_degC(mV) 00254 raise "Didn't get exception" 00255 except: 00256 pass 00257 00258 #print "Tests finished" 00259 00260 ambient = [70, 75, 80, 85, 90, 95] 00261 tc = Tc() # Defaults to type K 00262 print " " * 10, "Ambient Temperature in deg F\n" 00263 print " mV\t", 00264 for amb in ambient: 00265 print "%5d\t" % amb, 00266 print 00267 for mv in xrange(100): 00268 mV = mv/10. 00269 degF = tc.mV_to_degF(mV) 00270 print "%.1f" % mV, 00271 for amb in ambient: 00272 print "\t%.0f" % (degF+amb), 00273 print 00274 00275 00276
© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved; If you reference this document or any part of this document you must use the citation verbatim (including the link) "© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved."
Notice: This source code contained in this document is NOT open source and is NOT being distributed as open source.
122,241 lines of code and growing...