PTC: Extend options, fix probing bugs (#18253)
This commit is contained in:
parent
2de22aae2d
commit
3bf990ec34
4 changed files with 100 additions and 21 deletions
|
@ -1662,6 +1662,37 @@
|
||||||
// Enable additional compensation using hotend temperature
|
// Enable additional compensation using hotend temperature
|
||||||
// Note: this values cannot be calibrated automatically but have to be set manually
|
// Note: this values cannot be calibrated automatically but have to be set manually
|
||||||
//#define USE_TEMP_EXT_COMPENSATION
|
//#define USE_TEMP_EXT_COMPENSATION
|
||||||
|
|
||||||
|
// Probe temperature calibration generates a table of values starting at PTC_SAMPLE_START
|
||||||
|
// (e.g. 30), in steps of PTC_SAMPLE_RES (e.g. 5) with PTC_SAMPLE_COUNT (e.g. 10) samples.
|
||||||
|
|
||||||
|
// #define PTC_SAMPLE_START 30.0f
|
||||||
|
// #define PTC_SAMPLE_RES 5.0f
|
||||||
|
// #define PTC_SAMPLE_COUNT 10U
|
||||||
|
|
||||||
|
// Bed temperature calibration builds a similar table.
|
||||||
|
|
||||||
|
// #define BTC_SAMPLE_START 60.0f
|
||||||
|
// #define BTC_SAMPLE_RES 5.0f
|
||||||
|
// #define BTC_SAMPLE_COUNT 10U
|
||||||
|
|
||||||
|
// The temperature the probe should be at while taking measurements during bed temperature
|
||||||
|
// calibration.
|
||||||
|
// #define BTC_PROBE_TEMP 30.0f
|
||||||
|
|
||||||
|
// Height above Z=0.0f to raise the nozzle. Lowering this can help the probe to heat faster.
|
||||||
|
// Note: the Z=0.0f offset is determined by the probe offset which can be set using M851.
|
||||||
|
// #define PTC_PROBE_HEATING_OFFSET 0.5f
|
||||||
|
|
||||||
|
// Height to raise the Z-probe between heating and taking the next measurement. Some probes
|
||||||
|
// may fail to untrigger if they have been triggered for a long time, which can be solved by
|
||||||
|
// increasing the height the probe is raised to.
|
||||||
|
// #define PTC_PROBE_RAISE 15U
|
||||||
|
|
||||||
|
// If the probe is outside of the defined range, use linear extrapolation using the closest
|
||||||
|
// point and the PTC_LINEAR_EXTRAPOLATION'th next point. E.g. if set to 4 it will use data[0]
|
||||||
|
// and data[4] to perform linear extrapolation for values below PTC_SAMPLE_START.
|
||||||
|
// #define PTC_LINEAR_EXTRAPOLATION 4
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -165,28 +165,41 @@ void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const float &
|
||||||
}
|
}
|
||||||
|
|
||||||
float ProbeTempComp::get_offset_for_temperature(const TempSensorID tsi, const float &temp) {
|
float ProbeTempComp::get_offset_for_temperature(const TempSensorID tsi, const float &temp) {
|
||||||
|
|
||||||
const uint8_t measurements = cali_info[tsi].measurements;
|
const uint8_t measurements = cali_info[tsi].measurements;
|
||||||
const float start_temp = cali_info[tsi].start_temp,
|
const float start_temp = cali_info[tsi].start_temp,
|
||||||
end_temp = cali_info[tsi].end_temp,
|
|
||||||
res_temp = cali_info[tsi].temp_res;
|
res_temp = cali_info[tsi].temp_res;
|
||||||
const int16_t * const data = sensor_z_offsets[tsi];
|
const int16_t * const data = sensor_z_offsets[tsi];
|
||||||
|
|
||||||
if (temp <= start_temp) return 0.0f;
|
auto point = [&](uint8_t i) {
|
||||||
if (temp >= end_temp) return static_cast<float>(data[measurements - 1]) / 1000.0f;
|
return xy_float_t({start_temp + i*res_temp, static_cast<float>(data[i])});
|
||||||
|
};
|
||||||
|
|
||||||
|
auto linear_interp = [](float x, xy_float_t p1, xy_float_t p2) {
|
||||||
|
return (p2.y - p1.y) / (p2.x - p2.y) * (x - p1.x) + p1.y;
|
||||||
|
};
|
||||||
|
|
||||||
// Linear interpolation
|
// Linear interpolation
|
||||||
int16_t val1 = 0, val2 = data[0];
|
uint8_t idx = static_cast<uint8_t>(temp - start_temp / res_temp);
|
||||||
uint8_t idx = 0;
|
|
||||||
float meas_temp = start_temp + res_temp;
|
// offset in um
|
||||||
while (meas_temp < temp) {
|
float offset = 0.0f;
|
||||||
if (++idx >= measurements) return static_cast<float>(val2) / 1000.0f;
|
|
||||||
meas_temp += res_temp;
|
#if !defined(PTC_LINEAR_EXTRAPOLATION) || PTC_LINEAR_EXTRAPOLATION <= 0
|
||||||
val1 = val2;
|
if (idx < 0)
|
||||||
val2 = data[idx];
|
offset = 0.0f;
|
||||||
}
|
else if (idx > measurements - 2)
|
||||||
const float factor = (meas_temp - temp) / static_cast<float>(res_temp);
|
offset = static_cast<float>(data[measurements - 1]);
|
||||||
return (static_cast<float>(val2) - static_cast<float>(val2 - val1) * factor) / 1000.0f;
|
#else
|
||||||
|
if (idx < 0)
|
||||||
|
offset = linear_interp(temp, point(0), point(PTC_LINEAR_EXTRAPOLATION));
|
||||||
|
else if (idx > measurements - 2)
|
||||||
|
offset = linear_interp(temp, point(measurements - PTC_LINEAR_EXTRAPOLATION - 1), point(measurements - 1));
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
offset = linear_interp(temp, point(idx), point(idx + 1));
|
||||||
|
|
||||||
|
// return offset in mm
|
||||||
|
return offset / 1000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d) {
|
bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d) {
|
||||||
|
|
|
@ -45,9 +45,44 @@ typedef struct {
|
||||||
* measurement errors/shifts due to changed temperature.
|
* measurement errors/shifts due to changed temperature.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Probe temperature calibration constants
|
||||||
|
#ifndef PTC_SAMPLE_COUNT
|
||||||
|
#define PTC_SAMPLE_COUNT 10U
|
||||||
|
#endif
|
||||||
|
#ifndef PTC_SAMPLE_RES
|
||||||
|
#define PTC_SAMPLE_RES 5.0f
|
||||||
|
#endif
|
||||||
|
#ifndef PTC_SAMPLE_START
|
||||||
|
#define PTC_SAMPLE_START 30.0f
|
||||||
|
#endif
|
||||||
|
#define PTC_SAMPLE_END ((PTC_SAMPLE_START) + (PTC_SAMPLE_COUNT) * (PTC_SAMPLE_RES))
|
||||||
|
|
||||||
|
// Bed temperature calibration constants
|
||||||
|
#ifndef BTC_PROBE_TEMP
|
||||||
|
#define BTC_PROBE_TEMP 30.0f
|
||||||
|
#endif
|
||||||
|
#ifndef BTC_SAMPLE_COUNT
|
||||||
|
#define BTC_SAMPLE_COUNT 10U
|
||||||
|
#endif
|
||||||
|
#ifndef BTC_SAMPLE_STEP
|
||||||
|
#define BTC_SAMPLE_RES 5.0f
|
||||||
|
#endif
|
||||||
|
#ifndef BTC_SAMPLE_START
|
||||||
|
#define BTC_SAMPLE_START 60.0f
|
||||||
|
#endif
|
||||||
|
#define BTC_SAMPLE_END ((BTC_SAMPLE_START) + (BTC_SAMPLE_COUNT) * (BTC_SAMPLE_RES))
|
||||||
|
|
||||||
|
#ifndef PTC_PROBE_HEATING_OFFSET
|
||||||
|
#define PTC_PROBE_HEATING_OFFSET 0.5f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PTC_PROBE_RAISE
|
||||||
|
#define PTC_PROBE_RAISE 10.0f
|
||||||
|
#endif
|
||||||
|
|
||||||
static constexpr temp_calib_t cali_info_init[TSI_COUNT] = {
|
static constexpr temp_calib_t cali_info_init[TSI_COUNT] = {
|
||||||
{ 10, 5, 30, 30 + 10 * 5 }, // Probe
|
{ PTC_SAMPLE_COUNT, PTC_SAMPLE_RES, PTC_SAMPLE_START, PTC_SAMPLE_END }, // Probe
|
||||||
{ 10, 5, 60, 60 + 10 * 5 }, // Bed
|
{ BTC_SAMPLE_COUNT, BTC_SAMPLE_RES, BTC_SAMPLE_START, BTC_SAMPLE_END }, // Bed
|
||||||
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
|
||||||
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
|
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
|
||||||
#endif
|
#endif
|
||||||
|
@ -66,7 +101,7 @@ class ProbeTempComp {
|
||||||
//measure_point = { 12.0f, 7.3f }; // Coordinates for the MK52 magnetic heatbed
|
//measure_point = { 12.0f, 7.3f }; // Coordinates for the MK52 magnetic heatbed
|
||||||
|
|
||||||
static constexpr int probe_calib_bed_temp = BED_MAX_TARGET, // Bed temperature while calibrating probe
|
static constexpr int probe_calib_bed_temp = BED_MAX_TARGET, // Bed temperature while calibrating probe
|
||||||
bed_calib_probe_temp = 30; // Probe temperature while calibrating bed
|
bed_calib_probe_temp = BTC_PROBE_TEMP; // Probe temperature while calibrating bed
|
||||||
|
|
||||||
static int16_t *sensor_z_offsets[TSI_COUNT],
|
static int16_t *sensor_z_offsets[TSI_COUNT],
|
||||||
z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // (µm)
|
z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // (µm)
|
||||||
|
|
|
@ -105,7 +105,7 @@ void GcodeSuite::G76() {
|
||||||
|
|
||||||
auto g76_probe = [](const TempSensorID sid, uint16_t &targ, const xy_pos_t &nozpos) {
|
auto g76_probe = [](const TempSensorID sid, uint16_t &targ, const xy_pos_t &nozpos) {
|
||||||
do_blocking_move_to_z(5.0); // Raise nozzle before probing
|
do_blocking_move_to_z(5.0); // Raise nozzle before probing
|
||||||
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_NONE, 0, false); // verbose=0, probe_relative=false
|
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
|
||||||
if (isnan(measured_z))
|
if (isnan(measured_z))
|
||||||
SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
|
SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
|
||||||
else {
|
else {
|
||||||
|
@ -132,8 +132,8 @@ void GcodeSuite::G76() {
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
const xyz_pos_t parkpos = temp_comp.park_point,
|
const xyz_pos_t parkpos = temp_comp.park_point,
|
||||||
probe_pos_xyz = temp_comp.measure_point + xyz_pos_t({ 0.0f, 0.0f, 0.5f }),
|
probe_pos_xyz = xyz_pos_t(temp_comp.measure_point) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }),
|
||||||
noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
|
noz_pos_xyz = probe_pos_xyz - xy_pos_t(probe.offset_xy); // Nozzle position based on probe position
|
||||||
|
|
||||||
if (do_bed_cal || do_probe_cal) {
|
if (do_bed_cal || do_probe_cal) {
|
||||||
// Ensure park position is reachable
|
// Ensure park position is reachable
|
||||||
|
|
Reference in a new issue