Skip to content

Commit

Permalink
heaters: make PWM instantaneous
Browse files Browse the repository at this point in the history
Heaters control is reactive,
the faster we apply new PWM - the better.
Add command to directly apply PWM as fast as it arrives.

Signed-off-by: Timofey Titovets <[email protected]>
  • Loading branch information
nefelim4ag committed Nov 25, 2024
1 parent f2e69a3 commit db91f1e
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 8 deletions.
13 changes: 6 additions & 7 deletions klippy/extras/heaters.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def __init__(self, config, sensor):
self.max_temp = config.getfloat('max_temp', above=self.min_temp)
self.sensor.setup_minmax(self.min_temp, self.max_temp)
self.sensor.setup_callback(self.temperature_callback)
self.pwm_delay = self.sensor.get_report_time_delta()
# Setup temperature checks
self.min_extrude_temp = config.getfloat(
'min_extrude_temp', 170.,
Expand All @@ -52,8 +51,9 @@ def __init__(self, config, sensor):
heater_pin = config.get('heater_pin')
ppins = self.printer.lookup_object('pins')
self.mcu_pwm = ppins.setup_pin('pwm', heater_pin)
self.pwm_pending_delay = 0.3
pwm_cycle_time = config.getfloat('pwm_cycle_time', 0.100, above=0.,
maxval=self.pwm_delay)
maxval=self.pwm_pending_delay)
self.mcu_pwm.setup_cycle_time(pwm_cycle_time)
self.mcu_pwm.setup_max_duration(MAX_HEAT_TIME)
# Load additional modules
Expand All @@ -72,10 +72,11 @@ def set_pwm(self, read_time, value):
and abs(value - self.last_pwm_value) < 0.05):
# No significant change in value - can suppress update
return
pwm_time = read_time + self.pwm_delay
self.next_pwm_time = pwm_time + 0.75 * MAX_HEAT_TIME
# PWM will apply on arrival, expect less then pending delay
pwm_time = read_time + self.pwm_pending_delay
self.next_pwm_time = pwm_time + 0.7 * MAX_HEAT_TIME
self.last_pwm_value = value
self.mcu_pwm.set_pwm(pwm_time, value)
self.mcu_pwm.set_pwm_now(pwm_time, value)
#logging.debug("%s: pwm=%.3f@%.3f (from %.3f@%.3f [%.3f])",
# self.name, value, pwm_time,
# self.last_temp, self.last_temp_time, self.target_temp)
Expand All @@ -95,8 +96,6 @@ def _handle_shutdown(self):
# External commands
def get_name(self):
return self.name
def get_pwm_delay(self):
return self.pwm_delay
def get_max_power(self):
return self.max_power
def get_smooth_time(self):
Expand Down
2 changes: 1 addition & 1 deletion klippy/extras/pid_calibrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def __init__(self, heater, target):
def set_pwm(self, read_time, value):
if value != self.last_pwm:
self.pwm_samples.append(
(read_time + self.heater.get_pwm_delay(), value))
(read_time, value))
self.last_pwm = value
self.heater.set_pwm(read_time, value)
def temperature_update(self, read_time, temp, target_temp):
Expand Down
10 changes: 10 additions & 0 deletions klippy/mcu.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ def _build_config(self):
% (self._oid, self._last_clock, svalue), is_init=True)
self._set_cmd = self._mcu.lookup_command(
"queue_digital_out oid=%c clock=%u on_ticks=%u", cq=cmd_queue)
self._set_now_cmd = self._mcu.lookup_command(
"queue_digital_out_now oid=%c clock=%u on_ticks=%u", cq=cmd_queue)
def set_pwm(self, print_time, value):
if self._invert:
value = 1. - value
Expand All @@ -481,6 +483,14 @@ def set_pwm(self, print_time, value):
self._set_cmd.send([self._oid, clock, v],
minclock=self._last_clock, reqclock=clock)
self._last_clock = clock
def set_pwm_now(self, print_time, value):
if self._invert:
value = 1. - value
v = int(max(0., min(1., value)) * self._pwm_max + 0.5)
clock = self._mcu.print_time_to_clock(print_time)
self._set_now_cmd.send([self._oid, clock, v],
minclock=self._last_clock, reqclock=clock)
self._last_clock = clock

class MCU_adc:
def __init__(self, mcu, pin_params):
Expand Down
14 changes: 14 additions & 0 deletions src/gpiocmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,20 @@ command_queue_digital_out(uint32_t *args)
DECL_COMMAND(command_queue_digital_out,
"queue_digital_out oid=%c clock=%u on_ticks=%u");

void command_queue_digital_out_now(uint32_t *args)
{
uint32_t oid = args[0];
uint32_t time = args[1];
uint32_t on_duration = args[2];
uint32_t time_now = timer_read_time() + timer_from_us(1000);
if (timer_is_before(time_now, time))
time = time_now;
uint32_t new_args[] = {oid, time, on_duration};
command_queue_digital_out(new_args);
}
DECL_COMMAND(command_queue_digital_out_now,
"queue_digital_out_now oid=%c clock=%u on_ticks=%u");

void
command_update_digital_out(uint32_t *args)
{
Expand Down

0 comments on commit db91f1e

Please sign in to comment.