From db05938a5fd04206ec297c816f5f7fbd0a86e421 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Thu, 16 Jul 2020 14:17:04 -0400 Subject: [PATCH] servo: Set initial value via mcu_servo.setup_start_value() Using the setup_start_value() method avoids the PWM output line transitioning to an intermediate state prior to setting the initial value. Signed-off-by: Kevin O'Connor --- config/example-extras.cfg | 16 ++++++------ klippy/extras/servo.py | 51 ++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 39 deletions(-) diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 6082992b..419c8f94 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1245,15 +1245,13 @@ # The maximum pulse width time (in seconds). This should correspond # with an angle of maximum_servo_angle. The default is 0.002 # seconds. -#initial_angle: 70 -# Initial angle to set the servo to when the mcu resets. Must be between -# 0 and maximum_servo_angle This parameter is optional. If both -# initial_angle and initial_pulse_width are set initial_angle will be used. -#initial_pulse_width: 0.0015 -# Initial pulse width time (in seconds) to set the servo to when -# the mcu resets. Must be between minimum_pulse_width and maximum_pulse_width. -# This parameter is optional. If both initial_angle and initial_pulse_width -# are set initial_angle will be used +#initial_angle: +# Initial angle (in degrees) to set the servo to. The default is to +# not send any signal at startup. +#initial_pulse_width: +# Initial pulse width time (in seconds) to set the servo to. (This +# is only valid if initial_angle is not set.) The default is to not +# send any signal at startup. # Neopixel (aka WS2812) LED support (one may define any number of # sections with a "neopixel" prefix). One may set the LED color via diff --git a/klippy/extras/servo.py b/klippy/extras/servo.py index 8225a0f9..c05c9f81 100644 --- a/klippy/extras/servo.py +++ b/klippy/extras/servo.py @@ -1,6 +1,6 @@ # Support for servos # -# Copyright (C) 2017,2018 Kevin O'Connor +# Copyright (C) 2017-2020 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. @@ -10,44 +10,35 @@ PIN_MIN_TIME = 0.100 class PrinterServo: def __init__(self, config): self.printer = config.get_printer() - ppins = self.printer.lookup_object('pins') - self.mcu_servo = ppins.setup_pin('pwm', config.get('pin')) - self.mcu_servo.setup_max_duration(0.) - self.mcu_servo.setup_cycle_time(SERVO_SIGNAL_PERIOD) - self.min_width = config.getfloat( - 'minimum_pulse_width', .001, above=0., below=SERVO_SIGNAL_PERIOD) - self.max_width = config.getfloat( - 'maximum_pulse_width', .002 - , above=self.min_width, below=SERVO_SIGNAL_PERIOD) + self.min_width = config.getfloat('minimum_pulse_width', .001, + above=0., below=SERVO_SIGNAL_PERIOD) + self.max_width = config.getfloat('maximum_pulse_width', .002, + above=self.min_width, + below=SERVO_SIGNAL_PERIOD) self.max_angle = config.getfloat('maximum_servo_angle', 180.) self.angle_to_width = (self.max_width - self.min_width) / self.max_angle self.width_to_value = 1. / SERVO_SIGNAL_PERIOD self.last_value = self.last_value_time = 0. + initial_pwm = 0. + iangle = config.getfloat('initial_angle', None, minval=0., maxval=360.) + if iangle is not None: + initial_pwm = self._get_pwm_from_angle(iangle) + else: + iwidth = config.getfloat('initial_pulse_width', 0., + minval=0., maxval=self.max_width) + initial_pwm = self._get_pwm_from_pulse_width(iwidth) + # Setup mcu_servo pin + ppins = self.printer.lookup_object('pins') + self.mcu_servo = ppins.setup_pin('pwm', config.get('pin')) + self.mcu_servo.setup_max_duration(0.) + self.mcu_servo.setup_cycle_time(SERVO_SIGNAL_PERIOD) + self.mcu_servo.setup_start_value(initial_pwm, 0.) + # Register commands servo_name = config.get_name().split()[1] gcode = self.printer.lookup_object('gcode') gcode.register_mux_command("SET_SERVO", "SERVO", servo_name, self.cmd_SET_SERVO, desc=self.cmd_SET_SERVO_help) - # Check to see if an initial angle or pulse width is - # configured and set it as required - self.initial_pwm_value = None - initial_angle = config.getfloat('initial_angle', None, - minval=0., maxval=360.) - if initial_angle is not None: - self.initial_pwm_value = self._get_pwm_from_angle(initial_angle) - else: - initial_pulse_width = config.getfloat('initial_pulse_width', None, - minval=self.min_width, - maxval=self.max_width) - if initial_pulse_width is not None: - self.initial_pwm_value = self._get_pwm_from_pulse_width( - initial_pulse_width) - self.printer.register_event_handler("klippy:ready", self.handle_ready) - def handle_ready(self): - if self.initial_pwm_value is not None: - toolhead = self.printer.lookup_object('toolhead') - print_time = toolhead.get_last_move_time() - self._set_pwm(print_time, self.initial_pwm_value) def get_status(self, eventtime): return {'value': self.last_value} def _set_pwm(self, print_time, value):