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 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-19 16:29:02 +02:00
1 parent 8a5f6b6dd9
commit 29604b2f1e
3 files changed
+26 -10

No files matched your search

+1 -1
View File
@@ -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` | | `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/** | | | | **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_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/** | | | | **spoolman/** | | |
| `active_spool.cfg` | `SET_ACTIVE_SPOOL`, `CLEAR_ACTIVE_SPOOL` | Spoolman in Moonraker | | `active_spool.cfg` | `SET_ACTIVE_SPOOL`, `CLEAR_ACTIVE_SPOOL` | Spoolman in Moonraker |
| **leds/** | | | | **leds/** | | |
+21 -8
View File
@@ -203,12 +203,17 @@ variable_write_threshold: 0.002
# A calibration is rejected (nothing cached or written to Spoolman, the # A calibration is rejected (nothing cached or written to Spoolman, the
# previous PA is kept) when: # previous PA is kept) when:
# - its result is the last PA_CALIBRATE test value: bdpressure.py found no # - 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), # - the printer paused during the test (e.g. an AFC filament fault),
# - bd_pressure gave fewer than min_points readings or fewer than # - bd_pressure gave fewer than min_points readings or fewer than
# min_distinct different ones (sensor silent or hung; needs # min_distinct different ones (sensor silent or hung; needs
# bdpressure_check.py, otherwise this check is skipped). # 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_points: 10
variable_min_distinct: 8 variable_min_distinct: 8
# PA applied when a rejected lane has no earlier cached value # PA applied when a rejected lane has no earlier cached value
@@ -464,7 +469,14 @@ gcode:
{% endif %} {% endif %}
{% endfor %} {% 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} M117 Calibrating PA: {lane}
G1 Z50 F3000 G1 Z50 F3000
@@ -473,7 +485,7 @@ gcode:
G4 P400 G4 P400
G1 Z0 F3000 G1 Z0 F3000
G4 P400 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 # IMPORTANT: we do NOT read printer.extruder.pressure_advance
# here. Klipper fully evaluates a macro's Jinja2 template # here. Klipper fully evaluates a macro's Jinja2 template
@@ -493,7 +505,7 @@ gcode:
# triggered (and its own template is rendered), PA_CALIBRATE # triggered (and its own template is rendered), PA_CALIBRATE
# above has already finished and printer.extruder.pressure_advance # above has already finished and printer.extruder.pressure_advance
# is current. # 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 BLOBIFIER_CLEAN
G4 P400 G4 P400
G1 Z10 F3000 G1 Z10 F3000
@@ -504,13 +516,14 @@ gcode:
[gcode_macro _PA_AFTER_CALIBRATE] [gcode_macro _PA_AFTER_CALIBRATE]
description: Internal -- runs immediately after PA_CALIBRATE completes; reads the fresh PA value and caches it description: Internal -- runs immediately after PA_CALIBRATE completes; reads the fresh PA value and caches it
# LANE=<lane_name> SPOOL_ID=<int> CACHE_FOUND=<0|1> CACHED_PA=<float> # LANE=<lane_name> SPOOL_ID=<int> CACHE_FOUND=<0|1> CACHED_PA=<float> SWEEP_END=<last PA tested>
gcode: gcode:
{% set lane = params.LANE|default("")|string %} {% set lane = params.LANE|default("")|string %}
{% set spool_id = params.SPOOL_ID|default(0)|int %} {% set spool_id = params.SPOOL_ID|default(0)|int %}
{% set cache_found = params.CACHE_FOUND|default(0)|int %} {% set cache_found = params.CACHE_FOUND|default(0)|int %}
{% set cached_pa = params.CACHED_PA|default(0.0)|float %} {% set cached_pa = params.CACHED_PA|default(0.0)|float %}
{% set cfg = printer["gcode_macro _PA_CFG"] %} {% 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 # This template is evaluated only once this macro is actually
# triggered -- which happens after PA_CALIBRATE (queued earlier by # 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 # Reject runs where the sensor or the printer had a problem
{% set problems = [] %} {% 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) %} {% set _ = problems.append("no result (PA left at the end of the test range, %.3f)" % new_pa) %}
{% endif %} {% endif %}
{% if printer.pause_resume.is_paused %} {% if printer.pause_resume.is_paused %}
@@ -538,7 +551,7 @@ gcode:
{% if problems %} {% if problems %}
# A cached value at the end of the scan is an earlier failed run, not a PA # 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 %} {% 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" _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} SET_PRESSURE_ADVANCE ADVANCE={keep}
+4 -1
View File
@@ -131,7 +131,10 @@ gcode:
G4 P1000 G4 P1000
{% set y_step = 38.75 %} {% set y_step = 38.75 %}
{% set pressure_ad = 0 %} {% 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 F{high_speed}
G1 X78 Y{y_step} E9.92204 G1 X78 Y{y_step} E9.92204