lm75: Added support for LM75/LM75A I2C connected temperature sensors (#3101)

Signed-off-by: Boleslaw Ciesielski <combolek@users.noreply.github.com>
This commit is contained in:
combolek 2020-07-19 17:18:54 -07:00 committed by GitHub
parent b0901daa85
commit 3835654116
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 1 deletions

View File

@ -1036,6 +1036,30 @@
#htu21d_report_time: #htu21d_report_time:
# interval in seconds between readings. Default is 30 # interval in seconds between readings. Default is 30
# LM75/LM75A two wire (I2C) connected temperature sensors.
# These sensors have range up to 125 C, so are usable for e.g. chamber
# temperature monitoring. They can also function as simple
# fan/heater controllers but this mode is not used here.
#[temperature_sensor my_sensor]
# See the "temperature_sensor" section below for a description of its
# parameters. The parameters below describe LM75 family sensor parameters.
#sensor_type:
# Must be "LM75"
#i2c_address:
# Default is 72 (0x48). Normal range is 72-79 (0x48-0x4F) and the 3 low
# bits of the address are configured via pins on the chip (usually
# with jumpers or hard wired).
#i2c_mcu:
# MCU the sensor is connected to. Default is the primary mcu.
#i2c_bus:
# The I2C bus the sensor is connected to. On some MCU platforms the default
# is bus 0. On platforms without bus 0 this parameter is required.
#i2c_speed:
# The I2C speed (in Hz) to use when communicating with the sensor. Default
# is 100000. On some MCUs changing this value has no effect.
#lm75_report_time:
# interval in seconds between readings. Default is 0.8, with minimum 0.5
# Generic heaters (one may define any number of sections with a # Generic heaters (one may define any number of sections with a
# "heater_generic" prefix). These heaters behave similarly to standard # "heater_generic" prefix). These heaters behave similarly to standard
# heaters (extruders, heated beds). Use the SET_HEATER_TEMPERATURE # heaters (extruders, heated beds). Use the SET_HEATER_TEMPERATURE

View File

@ -261,7 +261,7 @@ class PrinterHeaters:
return self.heaters[heater_name] return self.heaters[heater_name]
def setup_sensor(self, config): def setup_sensor(self, config):
modules = ["thermistor", "adc_temperature", "spi_temperature", modules = ["thermistor", "adc_temperature", "spi_temperature",
"bme280", "htu21d"] "bme280", "htu21d", "lm75"]
for module_name in modules: for module_name in modules:
self.printer.load_object(config, module_name) self.printer.load_object(config, module_name)
sensor_type = config.get('sensor_type') sensor_type = config.get('sensor_type')

107
klippy/extras/lm75.py Normal file
View File

@ -0,0 +1,107 @@
# Support for I2C based LM75/LM75A temperature sensors
#
# Copyright (C) 2020 Boleslaw Ciesielski <combolek@users.noreply.github.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
from . import bus
LM75_CHIP_ADDR = 0x48
LM75_I2C_SPEED = 100000
LM75_REGS = {
'TEMP' : 0x00,
'CONF' : 0x01,
'THYST' : 0x02,
'TOS' : 0x03,
'PRODID' : 0x07 # TI LM75A chips only?
}
LM75_REPORT_TIME = .8
# Temperature can be sampled at any time but the read aborts
# the current conversion. Conversion time is 300ms so make
# sure not to read too often.
LM75_MIN_REPORT_TIME = .5
class LM75:
def __init__(self, config):
self.printer = config.get_printer()
self.name = config.get_name().split()[-1]
self.reactor = self.printer.get_reactor()
self.i2c = bus.MCU_I2C_from_config(
config,
default_addr=LM75_CHIP_ADDR,
default_speed=LM75_I2C_SPEED
)
self.mcu = self.i2c.get_mcu()
self.report_time = config.getint(
'lm75_report_time',
LM75_REPORT_TIME,
minval=LM75_MIN_REPORT_TIME
)
self.temp = 0.0
self.sample_timer = self.reactor.register_timer(self._sample_lm75)
self.printer.add_object("lm75 " + self.name, self)
self.printer.register_event_handler("klippy:ready", self.handle_ready)
def handle_ready(self):
self._init_lm75()
self.reactor.update_timer(self.sample_timer, self.reactor.NOW)
def setup_minmax(self, min_temp, max_temp):
pass
def setup_callback(self, cb):
self._callback = cb
def get_report_time_delta(self):
return self.report_time
def degrees_from_sample(self, x):
# The temp sample is encoded in the top 9 bits of a 16-bit
# value. Resolution is 0.5 degrees C.
return x[0] + (x[1] >> 7) * 0.5
def _init_lm75(self):
# Check and report the chip ID but ignore errors since many
# chips don't have it
try:
prodid = self.read_register('PRODID', 1)[0]
logging.info("lm75: Chip ID %#x" % prodid)
except:
pass
def _sample_lm75(self, eventtime):
try:
sample = self.read_register('TEMP', 2)
self.temp = self.degrees_from_sample(sample)
except Exception:
logging.exception("lm75: Error reading data")
self.temp = 0.0
return self.reactor.NEVER
measured_time = self.reactor.monotonic()
self._callback(self.mcu.estimated_print_time(measured_time), self.temp)
return measured_time + self.report_time
def read_register(self, reg_name, read_len):
# read a single register
regs = [LM75_REGS[reg_name]]
params = self.i2c.i2c_read(regs, read_len)
return bytearray(params['response'])
def write_register(self, reg_name, data):
if type(data) is not list:
data = [data]
reg = LM75_REGS[reg_name]
data.insert(0, reg)
self.i2c.i2c_write(data)
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("LM75", LM75)