mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-08-10 07:15:10 -06:00
ds18b20: new module for 1-wire temperature sensor (#3462)
Initial commit of code to support 1-wire (Dallas) sensors such as the DS18B20. Requires Linux kernel drivers to create a file in /sysfs which is read by this module, and temperature typically returned to a temperature_fan. Signed-off-by: Alan Lord <alanslists@gmail.com> Signed-off-by: Josh Headapohl <joshhead@gmail.com>
This commit is contained in:
parent
19397a0a2b
commit
7d4df65920
5 changed files with 372 additions and 2 deletions
77
klippy/extras/ds18b20.py
Normal file
77
klippy/extras/ds18b20.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# Support for 1-wire based temperature sensors
|
||||
#
|
||||
# Copyright (C) 2020 Alan Lord <alanslists@gmail.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import logging
|
||||
import mcu
|
||||
|
||||
DS18_REPORT_TIME = 3.0
|
||||
# Temperature can be sampled at any time but conversion time is ~750ms, so
|
||||
# setting the time too low will not make the reports come faster.
|
||||
DS18_MIN_REPORT_TIME = 1.0
|
||||
|
||||
class DS18B20:
|
||||
def __init__(self, config):
|
||||
self.printer = config.get_printer()
|
||||
self.name = config.get_name().split()[-1]
|
||||
self.sensor_id = config.get("serial_no")
|
||||
self.temp = self.min_temp = self.max_temp = 0.0
|
||||
self._report_clock = 0
|
||||
self.report_time = config.getfloat(
|
||||
'ds18_report_time',
|
||||
DS18_REPORT_TIME,
|
||||
minval=DS18_MIN_REPORT_TIME
|
||||
)
|
||||
self._mcu = mcu.get_printer_mcu(self.printer, config.get('sensor_mcu'))
|
||||
self.oid = self._mcu.create_oid()
|
||||
self._mcu.register_response(self._handle_ds18b20_response,
|
||||
"ds18b20_result", self.oid)
|
||||
self._mcu.register_config_callback(self._build_config)
|
||||
|
||||
def _build_config(self):
|
||||
self._mcu.add_config_cmd("config_ds18b20 oid=%d serial=%s" % (self.oid,
|
||||
self.sensor_id.encode("hex")))
|
||||
|
||||
clock = self._mcu.get_query_slot(self.oid)
|
||||
self._report_clock = self._mcu.seconds_to_clock(self.report_time)
|
||||
self._mcu.add_config_cmd("query_ds18b20 oid=%d clock=%u rest_ticks=%u"
|
||||
" min_value=%d max_value=%d" % (
|
||||
self.oid, clock, self._report_clock,
|
||||
self.min_temp * 1000, self.max_temp * 1000), is_init=True)
|
||||
|
||||
def _handle_ds18b20_response(self, params):
|
||||
temp = params['value'] / 1000.0
|
||||
|
||||
if temp < self.min_temp or temp > self.max_temp:
|
||||
self.printer.invoke_shutdown(
|
||||
"DS18B20 temperature %0.1f outside range of %0.1f:%.01f"
|
||||
% (temp, self.min_temp, self.max_temp))
|
||||
|
||||
next_clock = self._mcu.clock32_to_clock64(params['next_clock'])
|
||||
last_read_clock = next_clock - self._report_clock
|
||||
last_read_time = self._mcu.clock_to_print_time(last_read_clock)
|
||||
self._callback(last_read_time, temp)
|
||||
|
||||
def setup_minmax(self, min_temp, max_temp):
|
||||
self.min_temp = min_temp
|
||||
self.max_temp = max_temp
|
||||
|
||||
def fault(self, msg):
|
||||
self.printer.invoke_async_shutdown(msg)
|
||||
|
||||
def get_report_time_delta(self):
|
||||
return self.report_time
|
||||
|
||||
def setup_callback(self, cb):
|
||||
self._callback = cb
|
||||
|
||||
def get_status(self, eventtime):
|
||||
return {
|
||||
'temperature': self.temp,
|
||||
}
|
||||
|
||||
def load_config(config):
|
||||
# Register sensor
|
||||
pheaters = config.get_printer().load_object(config, "heaters")
|
||||
pheaters.add_sensor_factory("DS18B20", DS18B20)
|
|
@ -265,7 +265,8 @@ class PrinterHeaters:
|
|||
def setup_sensor(self, config):
|
||||
modules = ["thermistor", "adc_temperature", "spi_temperature",
|
||||
"bme280", "htu21d", "lm75", "rpi_temperature",
|
||||
"temperature_mcu"]
|
||||
"temperature_mcu", "ds18b20"]
|
||||
|
||||
for module_name in modules:
|
||||
self.printer.load_object(config, module_name)
|
||||
sensor_type = config.get('sensor_type')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue