Basic Information:
Printer Model: Neptune 4 Max, Openneptune
MCU / Printerboard: MKS
Host / SBC: ???
klippy.log
klippy (5).zip (873.6 KB)
I am trying to understand the intended modern Klipper/Eddy workflow for reliable first-layer Z-offset persistence with a BTT Eddy Duo.
Setup
Printer: Elegoo Neptune 4 Max
Firmware/software: OpenNept4une / Klipper
Probe: BTT Eddy Duo / RP2040 USB-style Eddy MCU
Probe config: [probe_eddy_current btt_eddy]
Mesh workflow: KAMP adaptive mesh using BED_MESH_CALIBRATE ADAPTIVE=1
Goal: reliable first-layer Z persistence across firmware restarts, power cycles, and different material/bed-temperature workflows such as PETG vs PLA.
What I am trying to achieve
My desired workflow is:
1. Start a first-layer calibration print.
2. Adjust live Z / babystep in Fluidd during the print.
3. Save the corrected first-layer offset.
4. Restart firmware or power-cycle.
5. Print the same first-layer test again and get the same squish without re-adjusting.
6. Avoid custom variable-file workarounds if there is a correct stock Klipper/Eddy method.
7. Avoid modifying the Eddy calibration curve just to store a first-layer preference, unless that is truly the intended design.
What worked for me previously
I previously used a custom workaround that worked practically.
It intercepted Z_OFFSET_APPLY_PROBE, saved the current live Z adjustment from:
printer.gcode_move.homing_origin.z
into variables.cfg as a saved offset, then reapplied that value during PRINT_START using:
SET_GCODE_OFFSET Z=0
SET_GCODE_OFFSET Z_ADJUST={saved_offset} MOVE=0
That gave me very consistent first layers across firmware restarts and power cycles, and it worked fine with KAMP adaptive mesh.
However, I am trying to move away from this because it feels like an unofficial parallel Z-offset persistence system. I would prefer to use the intended Klipper/Eddy behavior if possible.
What confused me about stock non-tap Eddy behavior
When I removed my custom workaround and returned to stock Eddy behavior, it appeared that Z_OFFSET_APPLY_PROBE did not save a separate user Z-offset value. Instead, for non-tap Eddy behavior, it appears to persist the live Z adjustment by translating/modifying the Eddy calibration table.
From a user perspective, this is counterintuitive to me.
My mental model is:
Eddy calibration curve = physical sensor height/frequency calibration
Thermal drift calibration = compensation for temperature-related sensor drift
User Z offset / live baby-step = first-layer preference or nozzle-bed relationship
So I expected the first-layer Z adjustment to be saved as a separate persistent Z-offset value, not by modifying the Eddy sensor calibration curve.
Homing correction
I also found the documented Eddy homing-correction macro flow, where after G28 / CG28, an actual PROBE is run and then SET_KINEMATIC_POSITION is used to correct the Z coordinate frame.
The flow appears to be:
1. Clear runtime Z offset.
2. Home with G28 / CG28.
3. Run an Eddy PROBE.
4. Use the probe result to correct Klipper’s Z coordinate frame.
5. Run adaptive mesh.
6. Print.
Example macro:
[gcode_macro _RELOAD_Z_OFFSET_FROM_PROBE]
gcode:
{% set Z = printer.toolhead.position.z %}
SET_KINEMATIC_POSITION Z={Z - printer.probe.last_probe_position.z}
[gcode_macro SET_Z_FROM_PROBE]
gcode:
{% set METHOD = params.METHOD|default("automatic") %}
PROBE METHOD={METHOD}
_RELOAD_Z_OFFSET_FROM_PROBE
G0 Z5
This looks much closer to the kind of clean/official behavior I want, but I do not understand how it is intended to relate to persistent first-layer Z-offset storage.
Questions
-
Why does non-tap Eddy
Z_OFFSET_APPLY_PROBEpersist baby-step correction by modifying/translating the Eddy calibration table instead of saving a separate persistent Z-offset value? -
Is calibration-table translation still considered the recommended workflow for non-tap Eddy users?
-
Is there any stock-supported way to persist my first-layer Z preference without modifying the Eddy calibration curve and without using
SAVE_VARIABLE/ custom macros? -
Why does the official Eddy homing-correction macro correct the Z coordinate frame but not save or update a persistent Z offset?
-
Why do example configs not already include the Eddy homing-correction macro by default when Eddy is used as the Z virtual endstop?
-
For BTT Eddy Duo users who want reliable first-layer Z persistence across restarts, power cycles, and temperature changes, is tap-based probing now the intended clean path instead of non-tap
Z_OFFSET_APPLY_PROBE?
What I am trying to clarify
I am not claiming this is definitely a bug. I am trying to understand the intended design.
The custom variable-based workaround worked for me, but I would prefer not to keep using it if there is a correct stock Klipper/Eddy workflow.
What I am looking for is the recommended current path for:
BTT Eddy Duo
+
Eddy used as Z virtual endstop
+
KAMP adaptive mesh
+
live Z adjustment during first layer
+
persistent first-layer offset after SAVE_CONFIG/restart/power cycle
+
stable behavior across PLA/PETG bed temperatures
+
no custom variables.cfg workaround
+
no unexpected calibration-curve modification
Should I continue trying to make stock non-tap Eddy persistence work, or is the intended clean direction now to use tap-based probing / Eddy tap behavior?
…