heater: Add support for AD595 type sensors
Add support for sensor chips that produce a voltage that linearly scales with temperature. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
ff6a96665a
commit
f66b1ac450
|
@ -161,14 +161,18 @@ heater_pin: ar4
|
||||||
# setting may be used to limit the total power output (over extended
|
# setting may be used to limit the total power output (over extended
|
||||||
# periods) to the heater. The default is 1.0.
|
# periods) to the heater. The default is 1.0.
|
||||||
sensor_type: EPCOS 100K B57560G104F
|
sensor_type: EPCOS 100K B57560G104F
|
||||||
# Type of sensor - this may be "EPCOS 100K B57560G104F" or "ATC
|
# Type of sensor - this may be "EPCOS 100K B57560G104F", "ATC
|
||||||
# Semitec 104GT-2". This parameter must be provided.
|
# Semitec 104GT-2", or "AD595". This parameter must be provided.
|
||||||
sensor_pin: analog1
|
sensor_pin: analog1
|
||||||
# Analog input pin connected to thermistor. This parameter must be
|
# Analog input pin connected to the sensor. This parameter must be
|
||||||
# provided.
|
# provided.
|
||||||
#pullup_resistor: 4700
|
#pullup_resistor: 4700
|
||||||
# The resistance (in ohms) of the pullup attached to the
|
# The resistance (in ohms) of the pullup attached to the
|
||||||
|
# thermistor. This parameter is only valid when the sensor is a
|
||||||
# thermistor. The default is 4700 ohms.
|
# thermistor. The default is 4700 ohms.
|
||||||
|
#adc_voltage: 5.0
|
||||||
|
# The ADC comparison voltage. This parameter is only valid when the
|
||||||
|
# sensor is an AD595. The default is 5 volts.
|
||||||
control: pid
|
control: pid
|
||||||
# Control algorithm (either pid or watermark). This parameter must
|
# Control algorithm (either pid or watermark). This parameter must
|
||||||
# be provided.
|
# be provided.
|
||||||
|
|
|
@ -9,9 +9,13 @@ import math, logging, threading
|
||||||
Sensors = {
|
Sensors = {
|
||||||
# Common thermistors and their Steinhart-Hart coefficients
|
# Common thermistors and their Steinhart-Hart coefficients
|
||||||
"EPCOS 100K B57560G104F": (
|
"EPCOS 100K B57560G104F": (
|
||||||
|
"thermistor",
|
||||||
0.000722136308968056, 0.000216766566488498, 8.92935804531095e-08),
|
0.000722136308968056, 0.000216766566488498, 8.92935804531095e-08),
|
||||||
"ATC Semitec 104GT-2": (
|
"ATC Semitec 104GT-2": (
|
||||||
|
"thermistor",
|
||||||
0.000809651054275124, 0.000211636030735685, 7.07420883993973e-08),
|
0.000809651054275124, 0.000211636030735685, 7.07420883993973e-08),
|
||||||
|
# Linear style conversion chips and their gain/offset
|
||||||
|
"AD595": ("linear", 300.0 / 3.022, 0.),
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMPLE_TIME = 0.001
|
SAMPLE_TIME = 0.001
|
||||||
|
@ -30,8 +34,14 @@ class PrinterHeater:
|
||||||
error = error
|
error = error
|
||||||
def __init__(self, printer, config):
|
def __init__(self, printer, config):
|
||||||
self.name = config.section
|
self.name = config.section
|
||||||
self.sensor_c = config.getchoice('sensor_type', Sensors)
|
sensor_params = config.getchoice('sensor_type', Sensors)
|
||||||
self.pullup_r = config.getfloat('pullup_resistor', 4700.)
|
self.is_linear_sensor = (sensor_params[0] == 'linear')
|
||||||
|
if self.is_linear_sensor:
|
||||||
|
adc_voltage = config.getfloat('adc_voltage', 5.)
|
||||||
|
self.sensor_coef = sensor_params[1] * adc_voltage, sensor_params[2]
|
||||||
|
else:
|
||||||
|
pullup = config.getfloat('pullup_resistor', 4700.)
|
||||||
|
self.sensor_coef = sensor_params[1:] + (pullup,)
|
||||||
self.min_extrude_temp = config.getfloat('min_extrude_temp', 170.)
|
self.min_extrude_temp = config.getfloat('min_extrude_temp', 170.)
|
||||||
self.min_temp = config.getfloat('min_temp')
|
self.min_temp = config.getfloat('min_temp')
|
||||||
self.max_temp = config.getfloat('max_temp')
|
self.max_temp = config.getfloat('max_temp')
|
||||||
|
@ -80,21 +90,27 @@ class PrinterHeater:
|
||||||
self.mcu_pwm.set_pwm(pwm_time, value)
|
self.mcu_pwm.set_pwm(pwm_time, value)
|
||||||
# Temperature calculation
|
# Temperature calculation
|
||||||
def calc_temp(self, adc):
|
def calc_temp(self, adc):
|
||||||
r = self.pullup_r * adc / (1.0 - adc)
|
if self.is_linear_sensor:
|
||||||
|
gain, offset = self.sensor_coef
|
||||||
|
return adc * gain + offset
|
||||||
|
c1, c2, c3, pullup = self.sensor_coef
|
||||||
|
r = pullup * adc / (1.0 - adc)
|
||||||
ln_r = math.log(r)
|
ln_r = math.log(r)
|
||||||
c1, c2, c3 = self.sensor_c
|
|
||||||
temp_inv = c1 + c2*ln_r + c3*math.pow(ln_r, 3)
|
temp_inv = c1 + c2*ln_r + c3*math.pow(ln_r, 3)
|
||||||
return 1.0/temp_inv + KELVIN_TO_CELCIUS
|
return 1.0/temp_inv + KELVIN_TO_CELCIUS
|
||||||
def calc_adc(self, temp):
|
def calc_adc(self, temp):
|
||||||
if temp is None:
|
if temp is None:
|
||||||
return None
|
return None
|
||||||
c1, c2, c3 = self.sensor_c
|
if self.is_linear_sensor:
|
||||||
|
gain, offset = self.sensor_coef
|
||||||
|
return (temp - offset) / gain
|
||||||
|
c1, c2, c3, pullup = self.sensor_coef
|
||||||
temp -= KELVIN_TO_CELCIUS
|
temp -= KELVIN_TO_CELCIUS
|
||||||
temp_inv = 1./temp
|
temp_inv = 1./temp
|
||||||
y = (c1 - temp_inv) / (2*c3)
|
y = (c1 - temp_inv) / (2*c3)
|
||||||
x = math.sqrt(math.pow(c2 / (3.*c3), 3.) + math.pow(y, 2.))
|
x = math.sqrt(math.pow(c2 / (3.*c3), 3.) + math.pow(y, 2.))
|
||||||
r = math.exp(math.pow(x-y, 1./3.) - math.pow(x+y, 1./3.))
|
r = math.exp(math.pow(x-y, 1./3.) - math.pow(x+y, 1./3.))
|
||||||
return r / (self.pullup_r + r)
|
return r / (pullup + r)
|
||||||
def adc_callback(self, read_time, read_value):
|
def adc_callback(self, read_time, read_value):
|
||||||
temp = self.calc_temp(read_value)
|
temp = self.calc_temp(read_value)
|
||||||
with self.lock:
|
with self.lock:
|
||||||
|
|
Loading…
Reference in New Issue