Files
brewpi/components/sensor/tempSensor_max31865.py
T
jensandClaude Sonnet 4.6 ac8de9da55 Add sensor variance config and smooth heat-rate estimate
[Sensor] - replace TempSensorSim's hardcoded k_noise with configurable
temp_offset/variance, accept **kwargs on Max31865 too so both sensors
share a constructor signature usable from TempSensorFactory.create()
[Temp Controller] - low-pass filter the backward-difference heat-rate
estimate (alpha=0.1) in both temp_controller.py and
temp_controller_smith.py instead of using the raw, noisy derivative
[Pot] - drop kn from demo_pot.py's params, matching the unused-field
removal already made to pot.py itself

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:47:24 +02:00

129 lines
2.3 KiB
Python
Executable File

#!/usr/bin/env python3
import time
from components import ATemperatureSensor, TemperatureSensorException
import spidev
class TempSensor_max31865(ATemperatureSensor):
def name(self):
return "Max31865"
def __init__(self, temp_offset=0, **kwargs):
ATemperatureSensor.__init__(self)
# Open SPI bus
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.max_speed_hz = 50000
self.spi.mode = 0b01
self.temp_offset = temp_offset
self.write_reg(0x00, 0xA3)
def read_reg(self, addr):
reg = self.spi.xfer([addr, 0xFF])
return reg[1]
def write_reg(self, addr, data):
self.spi.xfer([addr+0x80, data])
def read_digits(self):
for i in range(0, 10):
reg = self.read_reg(0x00)
if (0x20 & reg) == 0:
break
time.sleep(0.01)
digits = 0
msb = self.read_reg(0x01)
lsb = self.read_reg(0x02)
self.write_reg(0x00, 0xA3)
if lsb & 0x01 == 0x00:
digits = (256*msb + lsb) >> 1
else:
raise TemperatureSensorException("Could not read sensor!")
return digits
def temperature(self):
digits = self.read_digits()
return self.temp_offset + self.to_temperature(digits)
@staticmethod
def to_temperature(digits):
T = 0
R = __class__.calc_R(430, digits)
T = __class__.vanDusen_temp(R)
return T
@staticmethod
def calc_R(Rref, digits):
k = float(digits) / 32768
R = k*Rref
return R
@staticmethod
def vanDusen_temp(Rmeas):
RLut, TLut = __class__.vanDusenLut(100, -150, +500, 1.0)
# Find candidate
i = 0
for R in RLut:
if R > Rmeas:
break
i += 1
# Linear interpolation
R0 = RLut[i-1]
R1 = RLut[i]
T0 = TLut[i-1]
T1 = TLut[i]
dR = R1 - R0
dT = T1 - T0
k = (Rmeas-R0)/dR
T = T0 + dT*k
return T
@staticmethod
def vanDusenLut (R0, Tmin, Tmax, dT):
a = +3.90830e-03
b = -5.77500e-07
c = -4.18301e-12
Rv = []
Tv = []
T = Tmin
while T <= Tmax:
R = R0*(1 + a*T + b*T**2)
if T < 0.0:
R += R0*c*(T - 100)*T**3
Rv.append(R)
Tv.append(T)
T += dT
return Rv, Tv
# Main
if __name__ == '__main__':
sensor = TempSensor_max31865()
for k in range (0, 100):
for i in range (0, 8):
print("Reg[0x{}]: 0x{:02X}".format(i, sensor.read_reg(i)))
digits = sensor.read_digits()
print("Digits = {:04X}".format(digits))
print("Temperature = {:0.2f} °C".format(TempSensor_max31865.to_temperature(digits)))
time.sleep(0.5)
print("End of program")