diff --git a/docs/G-Codes.md b/docs/G-Codes.md index 68e65911..8e588a70 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -242,7 +242,10 @@ is enabled: The following command is available when an "output_pin" config section is enabled: -- `SET_PIN PIN=config_name VALUE=` +- `SET_PIN PIN=config_name VALUE= CYCLE_TIME=` + +Note: Hardware PWM does not currently support the CYCLE_TIME parameter and will +use the cycle time defined in the config. ## Manually Controlled Fans Commands diff --git a/klippy/extras/multi_pin.py b/klippy/extras/multi_pin.py index efa9676a..fcaf0bb6 100644 --- a/klippy/extras/multi_pin.py +++ b/klippy/extras/multi_pin.py @@ -46,9 +46,9 @@ class PrinterMultiPin: def set_digital(self, print_time, value): for mcu_pin in self.mcu_pins: mcu_pin.set_digital(print_time, value) - def set_pwm(self, print_time, value): + def set_pwm(self, print_time, value, cycle_time=None): for mcu_pin in self.mcu_pins: - mcu_pin.set_pwm(print_time, value) + mcu_pin.set_pwm(print_time, value, cycle_time) def load_config_prefix(config): return PrinterMultiPin(config) diff --git a/klippy/extras/output_pin.py b/klippy/extras/output_pin.py index 92c055fd..549c788b 100644 --- a/klippy/extras/output_pin.py +++ b/klippy/extras/output_pin.py @@ -17,11 +17,12 @@ class PrinterOutputPin: hardware_pwm = config.getboolean('hardware_pwm', False) self.mcu_pin.setup_cycle_time(cycle_time, hardware_pwm) self.scale = config.getfloat('scale', 1., above=0.) + self.last_cycle_time = self.default_cycle_time = cycle_time else: self.mcu_pin = ppins.setup_pin('digital_out', config.get('pin')) self.scale = 1. self.mcu_pin.setup_max_duration(0.) - self.last_value_time = 0. + self.last_print_time = 0. static_value = config.getfloat('static_value', None, minval=0., maxval=self.scale) if static_value is not None: @@ -45,18 +46,23 @@ class PrinterOutputPin: def cmd_SET_PIN(self, gcmd): value = gcmd.get_float('VALUE', minval=0., maxval=self.scale) value /= self.scale - if value == self.last_value: - return print_time = self.printer.lookup_object('toolhead').get_last_move_time() - print_time = max(print_time, self.last_value_time + PIN_MIN_TIME) + print_time = max(print_time, self.last_print_time + PIN_MIN_TIME) if self.is_pwm: - self.mcu_pin.set_pwm(print_time, value) + cycle_time = gcmd.get_float('CYCLE_TIME', self.default_cycle_time, + above=0.) + if value == self.last_value and cycle_time == self.last_cycle_time: + return + self.mcu_pin.set_pwm(print_time, value, cycle_time) + self.last_cycle_time = cycle_time else: + if value == self.last_value: + return if value not in [0., 1.]: raise gcmd.error("Invalid pin value") self.mcu_pin.set_digital(print_time, value) self.last_value = value - self.last_value_time = print_time + self.last_print_time = print_time def load_config_prefix(config): return PrinterOutputPin(config) diff --git a/klippy/extras/replicape.py b/klippy/extras/replicape.py index 9236264f..27def9f3 100644 --- a/klippy/extras/replicape.py +++ b/klippy/extras/replicape.py @@ -74,7 +74,7 @@ class pca9685_pwm: cmd_queue = self._mcu.alloc_command_queue() self._set_cmd = self._mcu.lookup_command( "schedule_pca9685_out oid=%c clock=%u value=%hu", cq=cmd_queue) - def set_pwm(self, print_time, value): + def set_pwm(self, print_time, value, cycle_time=None): clock = self._mcu.print_time_to_clock(print_time) if self._invert: value = 1. - value diff --git a/klippy/extras/sx1509.py b/klippy/extras/sx1509.py index 7a4f24db..8b19dda8 100644 --- a/klippy/extras/sx1509.py +++ b/klippy/extras/sx1509.py @@ -134,7 +134,7 @@ class SX1509_digital_out(object): else: self._sx1509.clear_bits_in_register(REG_DATA, self._bitmask) self._sx1509.send_register(REG_DATA, print_time) - def set_pwm(self, print_time, value): + def set_pwm(self, print_time, value, cycle_time=None): self.set_digital(print_time, value >= 0.5) class SX1509_pwm(object): @@ -191,7 +191,7 @@ class SX1509_pwm(object): self._start_value = max(0., min(1., start_value)) self._shutdown_value = max(0., min(1., shutdown_value)) self._is_static = is_static - def set_pwm(self, print_time, value): + def set_pwm(self, print_time, value, cycle_time=None): self._sx1509.set_register(self._i_on_reg, ~int(255 * value) if not self._invert else int(255 * value) & 0xFF) diff --git a/klippy/mcu.py b/klippy/mcu.py index 70e6b969..53d1ff74 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -160,7 +160,7 @@ class MCU_digital_out: self._set_cmd.send([self._oid, clock, (not not value) ^ self._invert], minclock=self._last_clock, reqclock=clock) self._last_clock = clock - def set_pwm(self, print_time, value): + def set_pwm(self, print_time, value, cycle_time=None): self.set_digital(print_time, value >= 0.5) class MCU_pwm: @@ -249,8 +249,10 @@ class MCU_pwm: self._set_cmd = self._mcu.lookup_command( "schedule_soft_pwm_out oid=%c clock=%u on_ticks=%u off_ticks=%u", cq=cmd_queue) - def set_pwm(self, print_time, value): - cycle_ticks = self._mcu.seconds_to_clock(self._cycle_time) + def set_pwm(self, print_time, value, cycle_time=None): + if cycle_time is None: + cycle_time = self._cycle_time + cycle_ticks = self._mcu.seconds_to_clock(cycle_time) clock = self._mcu.print_time_to_clock(print_time) if self._invert: value = 1. - value