1
0
mirror of https://github.com/MarlinFirmware/Marlin.git synced 2024-11-29 23:07:42 +00:00

️ Implement CALIBRATION_GCODE as endstop (#27204)

This commit is contained in:
Jonathan Brazier 2024-06-24 20:52:49 +01:00 committed by GitHub
parent 60d843b540
commit f2248f79d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 116 additions and 30 deletions

View File

@ -1331,8 +1331,6 @@
//#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..."
//#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved"
#define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm
#define CALIBRATION_FEEDRATE_SLOW 60 // mm/min
#define CALIBRATION_FEEDRATE_FAST 1200 // mm/min
#define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/min

View File

@ -345,6 +345,14 @@ void setup_endstop_interrupts() {
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
#if USE_CALIBRATION
#if (digitalPinToInterrupt(CALIBRATION_PIN) != NOT_AN_INTERRUPT)
_ATTACH(CALIBRATION_PIN);
#else
static_assert(digitalPinHasPCICR(CALIBRATION_PIN), "CALIBRATION_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(CALIBRATION_PIN);
#endif
#endif
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
}

View File

@ -64,6 +64,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -59,6 +59,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -101,12 +101,14 @@ void setup_endstop_interrupts() {
SETUP(Z_MIN_PROBE);
SETUP(CALIBRATION);
#undef SETUP
}
// Ensure 1 - 10 IRQs are registered
// Disable some endstops if you encounter this error
#define ENDSTOPS_INTERRUPTS_COUNT COUNT_ENABLED(USE_X_MAX, USE_X_MIN, USE_X2_MAX, USE_X2_MIN, USE_Y_MAX, USE_Y_MIN, USE_Y2_MAX, USE_Y2_MIN, USE_Z_MAX, USE_Z_MIN, USE_Z2_MAX, USE_Z2_MIN, USE_Z3_MAX, USE_Z3_MIN, USE_Z4_MAX, USE_Z4_MIN, USE_Z_MIN_PROBE)
#define ENDSTOPS_INTERRUPTS_COUNT COUNT_ENABLED(USE_X_MAX, USE_X_MIN, USE_X2_MAX, USE_X2_MIN, USE_Y_MAX, USE_Y_MIN, USE_Y2_MAX, USE_Y2_MIN, USE_Z_MAX, USE_Z_MIN, USE_Z2_MAX, USE_Z2_MIN, USE_Z3_MAX, USE_Z3_MIN, USE_Z4_MAX, USE_Z4_MIN, USE_Z_MIN_PROBE, USE_CALIBRATION)
#if ENDSTOPS_INTERRUPTS_COUNT > 10
#error "Too many endstop interrupts! HC32F460 only supports 10 endstop interrupts."
#elif ENDSTOPS_INTERRUPTS_COUNT == 0

View File

@ -146,6 +146,12 @@ void setup_endstop_interrupts() {
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
#if USE_CALIBRATION
#if !LPC1768_PIN_INTERRUPT_M(CALIBRATION_PIN)
#error "CALIBRATION_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(CALIBRATION_PIN);
#endif
#if USE_I_MAX
#if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN)
#error "I_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."

View File

@ -83,6 +83,7 @@
#define MATCH_Z4_MAX_EILINE(P) TERN0(USE_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN))
#define MATCH_Z4_MIN_EILINE(P) TERN0(USE_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN))
#define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(USE_Z_MIN_PROBE, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN))
#define MATCH_CALIBRATION_EILINE(P) TERN0(USE_CALIBRATION, DEFER4(MATCH_EILINE)(P, CALIBRATION_PIN))
#define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \
&& !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \
@ -99,7 +100,8 @@
&& !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \
&& !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \
&& !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \
&& !MATCH_Z_MIN_PROBE_EILINE(P) )
&& !MATCH_Z_MIN_PROBE_EILINE(P) \
&& !MATCH_CALIBRATION_EILINE(P) )
// One ISR for all EXT-Interrupts
void endstop_ISR() { endstops.update(); }
@ -208,6 +210,12 @@ void setup_endstop_interrupts() {
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
#if USE_CALIBRATION
#if !AVAILABLE_EILINE(CALIBRATION_PIN)
#error "CALIBRATION_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(CALIBRATION_PIN);
#endif
#if USE_I_MAX
#if !AVAILABLE_EILINE(I_MAX_PIN)
#error "I_MAX_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."

View File

@ -82,6 +82,7 @@
#define MATCH_Z4_MAX_EILINE(P) TERN0(USE_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN))
#define MATCH_Z4_MIN_EILINE(P) TERN0(USE_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN))
#define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(USE_Z_MIN_PROBE, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN))
#define MATCH_CALIBRATION_EILINE(P) TERN0(USE_CALIBRATION, DEFER4(MATCH_EILINE)(P, CALIBRATION_PIN))
#define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \
&& !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \
@ -98,7 +99,8 @@
&& !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \
&& !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \
&& !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \
&& !MATCH_Z_MIN_PROBE_EILINE(P) )
&& !MATCH_Z_MIN_PROBE_EILINE(P) \
&& !MATCH_CALIBRATION_EILINE(P) )
// One ISR for all EXT-Interrupts
void endstop_ISR() { endstops.update(); }
@ -183,6 +185,12 @@ void setup_endstop_interrupts() {
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
#if USE_CALIBRATION
#if !AVAILABLE_EILINE(CALIBRATION_PIN)
#error "CALIBRATION_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(CALIBRATION_PIN);
#endif
#if USE_I_MAX
#if !AVAILABLE_EILINE(I_MAX_PIN)
#error "I_MAX_PIN has no EXTINT line available. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."

View File

@ -45,6 +45,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -70,6 +70,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -64,6 +64,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -63,6 +63,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -63,6 +63,7 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));

View File

@ -355,6 +355,8 @@
#define STR_PROBE_EN "probe_en"
#define STR_FILAMENT "filament"
#define STR_CALIBRATION "calibration"
// General axis names
#define STR_X "X"
#define STR_Y "Y"

View File

@ -181,20 +181,6 @@ inline void park_above_object(measurements_t &m, const float uncertainty) {
#endif
#if !PIN_EXISTS(CALIBRATION)
#include "../../module/probe.h"
#endif
inline bool read_calibration_pin() {
return (
#if PIN_EXISTS(CALIBRATION)
READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING
#else
PROBE_TRIGGERED()
#endif
);
}
/**
* Move along axis in the specified dir until the probe value becomes stop_state,
* then return the axis value.
@ -205,18 +191,18 @@ inline bool read_calibration_pin() {
* fast in - Fast vs. precise measurement
*/
float measuring_movement(const AxisEnum axis, const int dir, const bool stop_state, const bool fast) {
const float step = fast ? 0.25 : CALIBRATION_MEASUREMENT_RESOLUTION;
const feedRate_t mms = fast ? MMM_TO_MMS(CALIBRATION_FEEDRATE_FAST) : MMM_TO_MMS(CALIBRATION_FEEDRATE_SLOW);
const float limit = fast ? 50 : 5;
destination = current_position;
for (float travel = 0; travel < limit; travel += step) {
destination[axis] += dir * step;
do_blocking_move_to((xyz_pos_t)destination, mms);
planner.synchronize();
if (read_calibration_pin() == stop_state) break;
}
return destination[axis];
destination[axis] += dir * limit;
endstops.enable_calibration_probe(true, stop_state);
do_blocking_move_to((xyz_pos_t)destination, mms);
endstops.enable_calibration_probe(false);
endstops.hit_on_purpose();
set_current_from_steppers_for_axis(axis);
sync_plan_position();
return current_position[axis];
}
/**

View File

@ -697,6 +697,8 @@
#error "Z_PROBE_END_SCRIPT is now EVENT_GCODE_AFTER_G29."
#elif defined(WIFI_SERIAL)
#error "WIFI_SERIAL is now WIFI_SERIAL_PORT."
#elif defined(CALIBRATION_MEASUREMENT_RESOLUTION)
#error "CALIBRATION_MEASUREMENT_RESOLUTION is no longer needed and should be removed."
#endif
// Changes to Probe Temp Compensation (#17392)

View File

@ -2200,6 +2200,11 @@
#define HAS_Z_PROBE_STATE 1
#endif
#if PIN_EXISTS(CALIBRATION)
#define USE_CALIBRATION 1
#define HAS_CALIBRATION_STATE 1
#endif
#undef _ANY_STOP
#undef _USE_STOP
#undef _HAS_STATE

View File

@ -87,6 +87,11 @@ Endstops::endstop_mask_t Endstops::live_state = 0;
volatile bool Endstops::z_probe_enabled = false;
#endif
#if ENABLED(CALIBRATION_GCODE)
volatile bool Endstops::calibration_probe_enabled = false;
volatile bool Endstops::calibration_stop_state;
#endif
// Initialized by settings.load()
#if ENABLED(X_DUAL_ENDSTOPS)
float Endstops::x2_endstop_adj;
@ -203,7 +208,7 @@ void Endstops::init() {
_INIT_ENDSTOP(MAX,W,);
#endif
#if PIN_EXISTS(CALIBRATION)
#if USE_CALIBRATION
#if ENABLED(CALIBRATION_PIN_PULLUP)
SET_INPUT_PULLUP(CALIBRATION_PIN);
#elif ENABLED(CALIBRATION_PIN_PULLDOWN)
@ -283,6 +288,17 @@ void Endstops::not_homing() {
}
#endif
// Enable / disable calibration probe checking
#if ENABLED(CALIBRATION_GCODE)
void Endstops::enable_calibration_probe(const bool onoff, const bool stop_state) {
// Avoid race condition by setting stop state first
if (onoff) calibration_stop_state = stop_state;
calibration_probe_enabled = onoff;
resync();
}
#endif
// Get the stable endstop states when enabled
void Endstops::resync() {
if (!abort_enabled()) return; // If endstops/probes are disabled the loop below can hang
@ -485,6 +501,9 @@ void __O2 Endstops::report_states() {
#if USE_Z_MIN_PROBE
print_es_state(PROBE_TRIGGERED(), F(STR_Z_PROBE));
#endif
#if USE_CALIBRATION
print_es_state(READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING, F(STR_CALIBRATION));
#endif
#if MULTI_FILAMENT_SENSOR
#define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; state = FIL_RUNOUT##N##_STATE; break;
for (uint8_t i = 1; i <= NUM_RUNOUT_SENSORS; ++i) {
@ -530,6 +549,16 @@ void Endstops::update() {
if (G38_move) UPDATE_LIVE_STATE(Z, TERN(USE_Z_MIN_PROBE, MIN_PROBE, MIN));
#endif
#if ENABLED(CALIBRATION_GCODE)
if (calibration_probe_enabled) {
#if HAS_CALIBRATION_STATE
SET_BIT_TO(live_state, CALIBRATION, READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING);
#else
UPDATE_LIVE_STATE(Z, TERN(USE_Z_MIN_PROBE, MIN_PROBE, MIN));
#endif
}
#endif
// With Dual X, endstops are only checked in the homing direction for the active extruder
#define X_MIN_TEST() TERN1(DUAL_X_CARRIAGE, stepper.last_moved_extruder == 0) // Check min for the left carriage
#define X_MAX_TEST() TERN1(DUAL_X_CARRIAGE, stepper.last_moved_extruder != 0) // Check max for the right carriage
@ -797,6 +826,15 @@ void Endstops::update() {
}
#endif
#if ENABLED(CALIBRATION_GCODE)
if (calibration_probe_enabled) {
#if HAS_CALIBRATION_STATE
if (TEST(live_state, CALIBRATION) == calibration_stop_state) stepper.quick_stop();
#else
if (TEST(live_state, Z_MIN_PROBE) == calibration_stop_state) stepper.quick_stop();
#endif
}
#endif
// Signal, after validation, if an endstop limit is pressed or not
bool moving_neg;
@ -1173,6 +1211,9 @@ void Endstops::update() {
#if USE_Z_MIN_PROBE
ES_GET_STATE(Z_MIN_PROBE);
#endif
#if USE_CALIBRATION
ES_GET_STATE(CALIBRATION);
#endif
#if USE_X2_MIN
ES_GET_STATE(X2_MIN);
#endif
@ -1265,6 +1306,9 @@ void Endstops::update() {
#if USE_Z_MIN_PROBE
ES_REPORT_CHANGE(Z_MIN_PROBE);
#endif
#if USE_CALIBRATION
ES_REPORT_STATE(CALIBRATION);
#endif
#if USE_X2_MIN
ES_REPORT_CHANGE(X2_MIN);
#endif

View File

@ -66,6 +66,9 @@ enum EndstopEnum : char {
// Extra Endstops for XYZ
ES_MINMAX(X2) ES_MINMAX(Y2) ES_MINMAX(Z2) ES_MINMAX(Z3) ES_MINMAX(Z4)
// Calibration pin state
ES_ITEM(HAS_CALIBRATION_STATE, CALIBRATION)
// Bed Probe state is distinct or shared with Z_MIN (i.e., when the probe is the only Z endstop)
ES_ITEM(HAS_Z_PROBE_STATE, Z_MIN_PROBE IF_DISABLED(USE_Z_MIN_PROBE, = Z_MIN))
@ -165,10 +168,10 @@ class Endstops {
static void init();
/**
* Are endstops or the probe set to abort the move?
* Are endstops or the Z min probe or the CALIBRATION probe set to abort the move?
*/
FORCE_INLINE static bool abort_enabled() {
return enabled || TERN0(HAS_BED_PROBE, z_probe_enabled);
return enabled || TERN0(HAS_BED_PROBE, z_probe_enabled) || TERN0(CALIBRATION_GCODE, calibration_probe_enabled);
}
static bool global_enabled() { return enabled_globally; }
@ -251,6 +254,13 @@ class Endstops {
static void enable_z_probe(const bool onoff=true);
#endif
// Enable / disable calibration probe checking
#if ENABLED(CALIBRATION_GCODE)
static volatile bool calibration_probe_enabled;
static volatile bool calibration_stop_state;
static void enable_calibration_probe(const bool onoff,const bool stop_state = true);
#endif
static void resync();
// Debugging of endstops