-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMAX31855.py
More file actions
115 lines (108 loc) · 4.12 KB
/
MAX31855.py
File metadata and controls
115 lines (108 loc) · 4.12 KB
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
import math
import spidev
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 5000
def readInternalC():
"""Return internal temperature value in degrees celsius."""
v = _read32()
# Ignore bottom 4 bits of thermocouple data.
v >>= 4
# Grab bottom 11 bits as internal temperature data.
internal = v & 0x7FF
if v & 0x800:
# Negative value, take 2's compliment. Compute this with subtraction
# because python is a little odd about handling signed/unsigned.
internal -= 4096
# Scale by 0.0625 degrees C per bit and return value.
return internal * 0.0625
def readTempC():
"""Return the thermocouple temperature value in degrees celsius."""
v = _read32()
# Check for error reading value.
if v & 0x7:
return float('NaN')
# Check if signed bit is set.
if v & 0x80000000:
# Negative value, take 2's compliment. Compute this with subtraction
# because python is a little odd about handling signed/unsigned.
v >>= 18
v -= 16384
else:
# Positive value, just shift the bits to get the value.
v >>= 18
# Scale by 0.25 degrees C per bit and return value.
return v * 0.25
def readLinearizedTempC():
# MAX31855 thermocouple voltage reading in mV
thermocoupleVoltage = (readTempC() - readInternalC()) * 0.041276
# MAX31855 cold junction voltage reading in mV
coldJunctionTemperature = readInternalC()
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 thermocoupleVoltage < 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 thermocoupleVoltage < 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 thermocoupleVoltage < 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))
def _read32():
# Read 32 bits from the SPI bus.
raw = spi.readbytes(4)
if raw is None or len(raw) != 4:
raise RuntimeError('Did not read expected number of bytes from device!')
value = raw[0] << 24 | raw[1] << 16 | raw[2] << 8 | raw[3]
return value