Reject PA calibrations with no result or bad sensor data

bdpressure.py leaves the extruder at the last PA_CALIBRATE test value
(0.098) when it finds no result, and _PA_AFTER_CALIBRATE saved that as
the calibrated PA (lane1 after an AFC pause, lane5 after the sensor went
silent). A run is now rejected, with nothing cached or written to
Spoolman, when the PA is still at the end of the scan, the printer
paused during the test, or bd_pressure gave too few or too few different
readings. The previous valid PA (or fallback_pa) is applied instead.

bdpressure_check reports pa_points and pa_distinct from the bdpressure
module's last PA_CALIBRATE data for this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-12 21:10:06 +02:00
1 parent 82f9486160
commit 25891640b8
3 files changed
+60 -3

No files matched your search

@@ -196,6 +196,19 @@ variable_travel_speed: 300
variable_acc_to_decel_factor: 50
# Minimum PA delta before we bother re-saving the cached value
variable_write_threshold: 0.002
# A calibration is rejected (nothing cached or written to Spoolman, the
# previous PA is kept) when:
# - its result is the last PA_CALIBRATE test value: bdpressure.py found no
# result and left the extruder at the end of its scan (0..49 x 0.002),
# - the printer paused during the test (e.g. an AFC filament fault),
# - bd_pressure gave fewer than min_points readings or fewer than
# min_distinct different ones (sensor silent or hung; needs
# bdpressure_check.py, otherwise this check is skipped).
variable_sweep_end_pa: 0.098
variable_min_points: 10
variable_min_distinct: 8
# PA applied when a rejected lane has no earlier cached value
variable_fallback_pa: 0.04
# Spoolman URL and the custom "extra" field name used to push calibrated
# PA values back to the spool record (so the value travels with the
# spool, not just with this printer's local save_variables cache).
@@ -469,6 +482,34 @@ gcode:
# triggered -- which happens after PA_CALIBRATE (queued earlier by
# the caller) has fully completed. So this read is fresh and correct.
{% set new_pa = printer.extruder.pressure_advance|default(0.0)|float %}
# Reject runs where the sensor or the printer had a problem
{% set problems = [] %}
{% if new_pa >= cfg.sweep_end_pa|float - 0.0001 %}
{% set _ = problems.append("no result (PA left at the end of the test range, %.3f)" % new_pa) %}
{% endif %}
{% if printer.pause_resume.is_paused %}
{% set _ = problems.append("the printer paused during the test") %}
{% endif %}
{% if 'bdpressure_check' in printer %}
{% set bdp = printer.bdpressure_check %}
{% set points = bdp.pa_points|default(-1)|int %}
{% set distinct = bdp.pa_distinct|default(-1)|int %}
{% if points >= 0 and points < cfg.min_points|int %}
{% set _ = problems.append("only %d readings from bd_pressure (sensor not answering?)" % points) %}
{% elif distinct >= 0 and distinct < cfg.min_distinct|int %}
{% set _ = problems.append("only %d different readings out of %d (sensor stuck?)" % (distinct, points)) %}
{% endif %}
{% endif %}
{% if problems %}
# A cached value at the end of the scan is an earlier failed run, not a PA
{% set use_cache = cache_found and cached_pa < cfg.sweep_end_pa|float - 0.0001 %}
{% set keep = cached_pa if use_cache else cfg.fallback_pa|float %}
RESPOND TYPE=error MSG="PA calibration for {lane} (spool {spool_id}) rejected: {problems|join('; ')}. Nothing saved; using PA={'%.4f' % keep} ({'cached' if use_cache else 'fallback'}). Fix the cause, then LANE_CALIBRATE_PA LANE={lane} FORCE=1"
SET_PRESSURE_ADVANCE ADVANCE={keep}
M117 PA cal rejected: {lane}
{% else %}
{action_respond_info("Calibration complete for %s: PA=%.4f" % (lane, new_pa))}
M117 PA cal done: {new_pa|round(4)}
@@ -480,6 +521,7 @@ gcode:
{% else %}
{action_respond_info("PA change below threshold (%.4f), skipping cache/Spoolman write" % cfg.write_threshold|float)}
{% endif %}
{% endif %}