diff --git a/lib/max31855.py b/lib/max31855.py index 69334d2..0d76704 100644 --- a/lib/max31855.py +++ b/lib/max31855.py @@ -39,7 +39,8 @@ class MAX31855(object): '''Reads SPI bus and returns current value of thermocouple.''' self.read() self.checkErrors() - return getattr(self, "to_" + self.units)(self.data_to_tc_temperature()) + #return getattr(self, "to_" + self.units)(self.data_to_tc_temperature()) + return getattr(self, "to_" + self.units)(self.data_to_LinearizedTempC()) def get_rj(self): '''Reads SPI bus and returns current value of reference junction.''' @@ -135,6 +136,105 @@ class MAX31855(object): GPIO.setup(self.cs_pin, GPIO.IN) GPIO.setup(self.clock_pin, GPIO.IN) + def data_to_LinearizedTempC(self, data_32 = None): + '''Return the NIST-linearized thermocouple temperature value in degrees + celsius. See https://learn.adafruit.com/calibrating-sensors/maxim-31855-linearization for more infoo. + This code came from https://github.com/nightmechanic/FuzzypicoReflow/blob/master/lib/max31855.py +''' + if data_32 is None: + data_32 = self.data + # extract TC temp + # Check if signed bit is set. + if data_32 & 0x80000000: + # Negative value, take 2's compliment. Compute this with subtraction + # because python is a little odd about handling signed/unsigned. + data_32 >>= 18 + data_32 -= 16384 + else: + # Positive value, just shift the bits to get the value. + data_32 >>= 18 + # Scale by 0.25 degrees C per bit and return value. + TC_temp = data_32 * 0.25 + # Extract Internal Temp + data_32 = self.data + # Ignore bottom 4 bits of thermocouple data. + data_32 >>= 4 + # Grab bottom 11 bits as internal temperature data. + Internal_Temp= data_32 & 0x7FF + if data_32 & 0x800: + # Negative value, take 2's compliment. Compute this with subtraction + # because python is a little odd about handling signed/unsigned. + Internal_Temp -= 4096 + # Scale by 0.0625 degrees C per bit and return value. + Internal_Temp = Internal_Temp * 0.0625 + + # MAX31855 thermocouple voltage reading in mV + thermocoupleVoltage = (TC_temp - Internal_Temp) * 0.041276 + # MAX31855 cold junction voltage reading in mV + coldJunctionTemperature = Internal_Temp + coldJunctionVoltage = (-0.176004136860E-01 + + 0.389212049750E-01 * coldJunctionTemperature + + 0.185587700320E-04 * math.pow(coldJunctionTemperature, 2.0) + + -0.994575928740E-07 * math.pow(coldJunctionTemperature, 3.0) + + 0.318409457190E-09 * math.pow(coldJunctionTemperature, 4.0) + + -0.560728448890E-12 * math.pow(coldJunctionTemperature, 5.0) + + 0.560750590590E-15 * math.pow(coldJunctionTemperature, 6.0) + + -0.320207200030E-18 * math.pow(coldJunctionTemperature, 7.0) + + 0.971511471520E-22 * math.pow(coldJunctionTemperature, 8.0) + + -0.121047212750E-25 * math.pow(coldJunctionTemperature, 9.0) + + 0.118597600000E+00 * math.exp(-0.118343200000E-03 * math.pow((coldJunctionTemperature-0.126968600000E+03), 2.0))) + # cold junction voltage + thermocouple voltage + voltageSum = thermocoupleVoltage + coldJunctionVoltage + # calculate corrected temperature reading based on coefficients for 3 different ranges + # float b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10; + if voltageSum < 0: + b0 = 0.0000000E+00 + b1 = 2.5173462E+01 + b2 = -1.1662878E+00 + b3 = -1.0833638E+00 + b4 = -8.9773540E-01 + b5 = -3.7342377E-01 + b6 = -8.6632643E-02 + b7 = -1.0450598E-02 + b8 = -5.1920577E-04 + b9 = 0.0000000E+00 + elif voltageSum < 20.644: + b0 = 0.000000E+00 + b1 = 2.508355E+01 + b2 = 7.860106E-02 + b3 = -2.503131E-01 + b4 = 8.315270E-02 + b5 = -1.228034E-02 + b6 = 9.804036E-04 + b7 = -4.413030E-05 + b8 = 1.057734E-06 + b9 = -1.052755E-08 + elif voltageSum < 54.886: + b0 = -1.318058E+02 + b1 = 4.830222E+01 + b2 = -1.646031E+00 + b3 = 5.464731E-02 + b4 = -9.650715E-04 + b5 = 8.802193E-06 + b6 = -3.110810E-08 + b7 = 0.000000E+00 + b8 = 0.000000E+00 + b9 = 0.000000E+00 + else: + # TODO: handle error - out of range + return 0 + return (b0 + + b1 * voltageSum + + b2 * pow(voltageSum, 2.0) + + b3 * pow(voltageSum, 3.0) + + b4 * pow(voltageSum, 4.0) + + b5 * pow(voltageSum, 5.0) + + b6 * pow(voltageSum, 6.0) + + b7 * pow(voltageSum, 7.0) + + b8 * pow(voltageSum, 8.0) + + b9 * pow(voltageSum, 9.0)) + + class MAX31855Error(Exception): def __init__(self, value): self.value = value