aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2020-09-09 21:32:03 -0400
committerKevin O'Connor <kevin@koconnor.net>2020-09-09 22:20:54 -0400
commit1f5848fc1a388b764fc507ccc3d56538605d5500 (patch)
tree256d10cddaab0e7ce912d8191949e0cd25c938d7
parent9b2816477b3101c4a6a749d094b690145c50f24b (diff)
downloadkutter-1f5848fc1a388b764fc507ccc3d56538605d5500.tar.gz
kutter-1f5848fc1a388b764fc507ccc3d56538605d5500.tar.xz
kutter-1f5848fc1a388b764fc507ccc3d56538605d5500.zip
adc_scaled: Add support for Duet2 Maestro "vref monitoring"
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--config/example-extras.cfg17
-rw-r--r--config/generic-duet2-maestro.cfg9
-rw-r--r--klippy/extras/adc_scaled.py79
3 files changed, 103 insertions, 2 deletions
diff --git a/config/example-extras.cfg b/config/example-extras.cfg
index ce981c7e..8ea8413b 100644
--- a/config/example-extras.cfg
+++ b/config/example-extras.cfg
@@ -2222,6 +2222,23 @@
# communication. The pin must have a valid pinmux configuration
# for the given SERCOM peripheral. This parameter must be provided.
+# Duet2 Maestro analog scaling by vref and vssa readings. Defining an
+# adc_scaled section enables virtual adc pins (such as "my_name:PB0")
+# that are automatically adjusted by the board's vref and vssa
+# monitoring pins. Be sure to define this config section above any
+# config sections that use one these virtual pins.
+#[adc_scaled my_name]
+#vref_pin:
+# The ADC pin to use for VREF monitoring. This parameter must be
+# provided.
+#vssa_pin:
+# The ADC pin to use for VSSA monitoring. This parameter must be
+# provided.
+#smooth_time: 2.0
+# A time value (in seconds) over which the vref and vssa
+# measurements will be smoothed to reduce the impact of measurement
+# noise. The default is 2 seconds.
+
# Replicape support - see the generic-replicape.cfg file for further
# details.
#[replicape]
diff --git a/config/generic-duet2-maestro.cfg b/config/generic-duet2-maestro.cfg
index 6715c87e..a5c6bbea 100644
--- a/config/generic-duet2-maestro.cfg
+++ b/config/generic-duet2-maestro.cfg
@@ -59,6 +59,11 @@ microsteps: 16
run_current: 0.800
stealthchop_threshold: 30
+# Support analog sensor adjustments using VREF/VSSA pins
+[adc_scaled vref_scaled]
+vref_pin: PA17
+vssa_pin: PA19
+
[extruder]
step_pin: PC4
dir_pin: PB7
@@ -69,7 +74,7 @@ filament_diameter: 1.750
heater_pin: !PC1
sensor_type: EPCOS 100K B57560G104F
pullup_resistor: 2200
-sensor_pin: PB0
+sensor_pin: vref_scaled:PB0
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
@@ -110,7 +115,7 @@ stealthchop_threshold: 5
heater_pin: !PC0
sensor_type: EPCOS 100K B57560G104F
pullup_resistor: 2200
-sensor_pin: PA20
+sensor_pin: vref_scaled:PA20
control: watermark
min_temp: 0
max_temp: 130
diff --git a/klippy/extras/adc_scaled.py b/klippy/extras/adc_scaled.py
new file mode 100644
index 00000000..c2d2cb87
--- /dev/null
+++ b/klippy/extras/adc_scaled.py
@@ -0,0 +1,79 @@
+# Support for scaling ADC values based on measured VREF and VSSA
+#
+# Copyright (C) 2020 Kevin O'Connor <kevin@koconnor.net>
+#
+# This file may be distributed under the terms of the GNU GPLv3 license.
+
+SAMPLE_TIME = 0.001
+SAMPLE_COUNT = 8
+REPORT_TIME = 0.300
+RANGE_CHECK_COUNT = 4
+
+class MCU_scaled_adc:
+ def __init__(self, main, pin_params):
+ self._main = main
+ self._last_state = (0., 0.)
+ self._mcu_adc = main.mcu.setup_pin('adc', pin_params)
+ query_adc = main.printer.lookup_object('query_adc')
+ qname = main.name + ":" + pin_params['pin']
+ query_adc.register_adc(qname, self._mcu_adc)
+ self._callback = None
+ self.setup_minmax = self._mcu_adc.setup_minmax
+ self.get_mcu = self._mcu_adc.get_mcu
+ def _handle_callback(self, read_time, read_value):
+ max_adc = self._main.last_vref[1]
+ min_adc = self._main.last_vssa[1]
+ scaled_val = (read_value - min_adc) / (max_adc - min_adc)
+ self._last_state = (scaled_val, read_time)
+ self._callback(read_time, scaled_val)
+ def setup_adc_callback(self, report_time, callback):
+ self._callback = callback
+ self._mcu_adc.setup_adc_callback(report_time, self._handle_callback)
+ def get_last_value(self):
+ return self._last_state
+
+class PrinterADCScaled:
+ def __init__(self, config):
+ self.printer = config.get_printer()
+ self.name = config.get_name().split()[1]
+ self.last_vref = (0., 0.)
+ self.last_vssa = (0., 0.)
+ # Configure vref and vssa pins
+ self.mcu_vref = self._config_pin(config, 'vref', self.vref_callback)
+ self.mcu_vssa = self._config_pin(config, 'vssa', self.vssa_callback)
+ smooth_time = config.getfloat('smooth_time', 2., above=0.)
+ self.inv_smooth_time = 1. / smooth_time
+ self.mcu = self.mcu_vref.get_mcu()
+ if self.mcu is not self.mcu_vssa.get_mcu():
+ raise config.error("vref and vssa must be on same mcu")
+ # Register setup_pin
+ ppins = self.printer.lookup_object('pins')
+ ppins.register_chip(self.name, self)
+ def _config_pin(self, config, name, callback):
+ pin_name = config.get(name + '_pin')
+ ppins = self.printer.lookup_object('pins')
+ mcu_adc = ppins.setup_pin('adc', pin_name)
+ mcu_adc.setup_adc_callback(REPORT_TIME, callback)
+ mcu_adc.setup_minmax(SAMPLE_TIME, SAMPLE_COUNT, minval=0., maxval=1.,
+ range_check_count=RANGE_CHECK_COUNT)
+ query_adc = config.get_printer().load_object(config, 'query_adc')
+ query_adc.register_adc(self.name + ":" + name, mcu_adc)
+ return mcu_adc
+ def setup_pin(self, pin_type, pin_params):
+ if pin_type != 'adc':
+ raise self.printer.config_error("adc_scaled only supports adc pins")
+ return MCU_scaled_adc(self, pin_params)
+ def calc_smooth(self, read_time, read_value, last):
+ last_time, last_value = last
+ time_diff = read_time - last_time
+ value_diff = read_value - last_value
+ adj_time = min(time_diff * self.inv_smooth_time, 1.)
+ smoothed_value = last_value + value_diff * adj_time
+ return (read_time, smoothed_value)
+ def vref_callback(self, read_time, read_value):
+ self.last_vref = self.calc_smooth(read_time, read_value, self.last_vref)
+ def vssa_callback(self, read_time, read_value):
+ self.last_vssa = self.calc_smooth(read_time, read_value, self.last_vssa)
+
+def load_config_prefix(config):
+ return PrinterADCScaled(config)