From 29604b2f1ee1175fa2408f7db0cb332b00e3702a Mon Sep 17 00:00:00 2001 From: MangaValk Date: Mon, 19 Oct 2026 16:29:02 +0200 Subject: [PATCH] PA calibration: wider PA range for TPU/TPE PA_CALIBRATE takes PA_STEP (default 0.002, 0-0.098 over 50 lines). _PA_CFG.material_pa_step uses 0.004 (0-0.196) for tpu/tpe/flex; soft TPU measured 0.094, close to the old end. The "no result" rejection uses the end of the range actually tested. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- macros/pressure_advance/bd_pa_spoolman.cfg | 29 ++++++++++++++++------ macros/pressure_advance/bd_pressure.cfg | 5 +++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3837942..cab40c3 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ everything below, grouped by topic. Comment out what you do not use there. | `purge_until_empty.cfg` | `PURGE_UNTIL_EMPTY`: purges a snapped filament out until there is no more nozzle pressure | same as `purge_check.cfg` | | **pressure_advance/** | | | | `bd_pressure.cfg` | `[bdpressure bd_pa]` (I2C on the Nitehawk) and the vendor macros `PA_CALIBRATE`, `PA_E`, `PA_RESET`, `PA_STATE`; `PA_CALIBRATE` no longer sets Z back to a value read before the test (wrong after a Z hop in `G28 XY`) | `bdpressure.py` from the bd_pressure repo | -| `bd_pa_spoolman.cfg` + `bd_pa_*.sh` | `LANE_CALIBRATE_PA`, `PA_CALIBRATE_ALL_LANES`, `LANE_RECAL_PA`, `SET_SPOOL_ID`, `PA_STATUS`: pressure advance per lane/spool, cached locally and in Spoolman; before a calibration the lane's spool is assigned again so a temperature just changed in Spoolman is used; a calibration with no result, a pause during the test or too few/stuck sensor readings is rejected and not saved | bd_pressure, AFC, Spoolman, `gcode_shell_command` | +| `bd_pa_spoolman.cfg` + `bd_pa_*.sh` | `LANE_CALIBRATE_PA`, `PA_CALIBRATE_ALL_LANES`, `LANE_RECAL_PA`, `SET_SPOOL_ID`, `PA_STATUS`: pressure advance per lane/spool, cached locally and in Spoolman; before a calibration the lane's spool is assigned again so a temperature just changed in Spoolman is used; flexible materials (TPU/TPE) calibrate at a lower flow (8 mm³/s) and over a wider PA range (0–0.196 in 0.004 steps instead of 0–0.098); a calibration with no result, a pause during the test or too few/stuck sensor readings is rejected and not saved | bd_pressure, AFC, Spoolman, `gcode_shell_command` | | **spoolman/** | | | | `active_spool.cfg` | `SET_ACTIVE_SPOOL`, `CLEAR_ACTIVE_SPOOL` | Spoolman in Moonraker | | **leds/** | | | diff --git a/macros/pressure_advance/bd_pa_spoolman.cfg b/macros/pressure_advance/bd_pa_spoolman.cfg index 6d6efb5..1bbf8b2 100644 --- a/macros/pressure_advance/bd_pa_spoolman.cfg +++ b/macros/pressure_advance/bd_pa_spoolman.cfg @@ -203,12 +203,17 @@ 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), +# result and left the extruder at the end of its scan (0..49 x the PA +# step: 0.098 at the default step, 0.196 for flexibles), # - 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_pa_step: 0.002 # PA_CALIBRATE tests 50 values: 0..49 x step +# Wider range for materials whose PA can be above 0.098 (soft TPU measured +# 0.094): same 50 lines and test time, coarser steps. Key contained in the +# lane's material (any case); with several matches the largest step wins. +variable_material_pa_step: {"tpu": 0.004, "tpe": 0.004, "flex": 0.004} variable_min_points: 10 variable_min_distinct: 8 # PA applied when a rejected lane has no earlier cached value @@ -464,7 +469,14 @@ gcode: {% endif %} {% endfor %} - {action_respond_info("Calibrating PA for %s (spool %d) at %.0fC, %g mm3/s..." % (lane, spool_id, nozzle_temp, vol.max))} + {% set step = namespace(pa=cfg.pa_step|float) %} + {% for key, s in cfg.material_pa_step.items() %} + {% if key in material and s|float > step.pa %} + {% set step.pa = s|float %} + {% endif %} + {% endfor %} + + {action_respond_info("Calibrating PA for %s (spool %d) at %.0fC, %g mm3/s, PA 0-%.3f..." % (lane, spool_id, nozzle_temp, vol.max, 49 * step.pa))} M117 Calibrating PA: {lane} G1 Z50 F3000 @@ -473,7 +485,7 @@ gcode: G4 P400 G1 Z0 F3000 G4 P400 - PA_CALIBRATE NOZZLE_TEMP={nozzle_temp} MAX_VOLUMETRIC={vol.max} ACC_WALL={cfg.acc_wall} TRAVEL_SPEED={cfg.travel_speed} ACC_TO_DECEL_FACTOR={cfg.acc_to_decel_factor} + PA_CALIBRATE NOZZLE_TEMP={nozzle_temp} MAX_VOLUMETRIC={vol.max} ACC_WALL={cfg.acc_wall} TRAVEL_SPEED={cfg.travel_speed} ACC_TO_DECEL_FACTOR={cfg.acc_to_decel_factor} PA_STEP={step.pa} # IMPORTANT: we do NOT read printer.extruder.pressure_advance # here. Klipper fully evaluates a macro's Jinja2 template @@ -493,7 +505,7 @@ gcode: # triggered (and its own template is rendered), PA_CALIBRATE # above has already finished and printer.extruder.pressure_advance # is current. - _PA_AFTER_CALIBRATE LANE={lane} SPOOL_ID={spool_id} CACHE_FOUND={1 if cache_found else 0} CACHED_PA={cached_pa} + _PA_AFTER_CALIBRATE LANE={lane} SPOOL_ID={spool_id} CACHE_FOUND={1 if cache_found else 0} CACHED_PA={cached_pa} SWEEP_END={49 * step.pa} BLOBIFIER_CLEAN G4 P400 G1 Z10 F3000 @@ -504,13 +516,14 @@ gcode: [gcode_macro _PA_AFTER_CALIBRATE] description: Internal -- runs immediately after PA_CALIBRATE completes; reads the fresh PA value and caches it -# LANE= SPOOL_ID= CACHE_FOUND=<0|1> CACHED_PA= +# LANE= SPOOL_ID= CACHE_FOUND=<0|1> CACHED_PA= SWEEP_END= gcode: {% set lane = params.LANE|default("")|string %} {% set spool_id = params.SPOOL_ID|default(0)|int %} {% set cache_found = params.CACHE_FOUND|default(0)|int %} {% set cached_pa = params.CACHED_PA|default(0.0)|float %} {% set cfg = printer["gcode_macro _PA_CFG"] %} + {% set sweep_end = params.SWEEP_END|default(49 * cfg.pa_step|float)|float %} # This template is evaluated only once this macro is actually # triggered -- which happens after PA_CALIBRATE (queued earlier by @@ -519,7 +532,7 @@ gcode: # Reject runs where the sensor or the printer had a problem {% set problems = [] %} - {% if new_pa >= cfg.sweep_end_pa|float - 0.0001 %} + {% if new_pa >= sweep_end - 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 %} @@ -538,7 +551,7 @@ gcode: {% 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 use_cache = cache_found and cached_pa < sweep_end - 0.0001 %} {% set keep = cached_pa if use_cache else cfg.fallback_pa|float %} _WARN 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" DISPLAY="PA cal rejected: {lane}, see console" SET_PRESSURE_ADVANCE ADVANCE={keep} diff --git a/macros/pressure_advance/bd_pressure.cfg b/macros/pressure_advance/bd_pressure.cfg index 63c3764..42f9ed9 100644 --- a/macros/pressure_advance/bd_pressure.cfg +++ b/macros/pressure_advance/bd_pressure.cfg @@ -131,7 +131,10 @@ gcode: G4 P1000 {% set y_step = 38.75 %} {% set pressure_ad = 0 %} - {% set pressure_step = 0.002 %} + # PA_STEP: PA increase per test line, 50 lines (0..49 x step); the + # vendor value 0.002 tests 0-0.098. bdpressure.py reports the VALUE + # sent with each reading, so a larger step widens the range. + {% set pressure_step = params.PA_STEP|default(0.002)|float %} G1 F{high_speed} G1 X78 Y{y_step} E9.92204