PTC: Extend options, fix probing bugs (#18253)

This commit is contained in:
rudihorn 2020-06-11 00:25:17 +01:00 committed by GitHub
parent 2de22aae2d
commit 3bf990ec34
Signed by: GitHub
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 21 deletions

View file

@ -1662,6 +1662,37 @@
// Enable additional compensation using hotend temperature
// Note: this values cannot be calibrated automatically but have to be set manually
//#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

View file

@ -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) {
const uint8_t measurements = cali_info[tsi].measurements;
const float start_temp = cali_info[tsi].start_temp,
end_temp = cali_info[tsi].end_temp,
res_temp = cali_info[tsi].temp_res;
const int16_t * const data = sensor_z_offsets[tsi];
if (temp <= start_temp) return 0.0f;
if (temp >= end_temp) return static_cast<float>(data[measurements - 1]) / 1000.0f;
auto point = [&](uint8_t i) {
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
int16_t val1 = 0, val2 = data[0];
uint8_t idx = 0;
float meas_temp = start_temp + res_temp;
while (meas_temp < temp) {
if (++idx >= measurements) return static_cast<float>(val2) / 1000.0f;
meas_temp += res_temp;
val1 = val2;
val2 = data[idx];
}
const float factor = (meas_temp - temp) / static_cast<float>(res_temp);
return (static_cast<float>(val2) - static_cast<float>(val2 - val1) * factor) / 1000.0f;
uint8_t idx = static_cast<uint8_t>(temp - start_temp / res_temp);
// offset in um
float offset = 0.0f;
#if !defined(PTC_LINEAR_EXTRAPOLATION) || PTC_LINEAR_EXTRAPOLATION <= 0
if (idx < 0)
offset = 0.0f;
else if (idx > measurements - 2)
offset = static_cast<float>(data[measurements - 1]);
#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) {

View file

@ -45,9 +45,44 @@ typedef struct {
* 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] = {
{ 10, 5, 30, 30 + 10 * 5 }, // Probe
{ 10, 5, 60, 60 + 10 * 5 }, // Bed
{ PTC_SAMPLE_COUNT, PTC_SAMPLE_RES, PTC_SAMPLE_START, PTC_SAMPLE_END }, // Probe
{ BTC_SAMPLE_COUNT, BTC_SAMPLE_RES, BTC_SAMPLE_START, BTC_SAMPLE_END }, // Bed
#if ENABLED(USE_TEMP_EXT_COMPENSATION)
{ 20, 5, 180, 180 + 5 * 20 } // Extruder
#endif
@ -66,7 +101,7 @@ class ProbeTempComp {
//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
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],
z_offsets_probe[cali_info_init[TSI_PROBE].measurements], // (µm)

View file

@ -105,7 +105,7 @@ void GcodeSuite::G76() {
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
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))
SERIAL_ECHOLNPGM("!Received NAN. Aborting.");
else {
@ -132,8 +132,8 @@ void GcodeSuite::G76() {
planner.synchronize();
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 }),
noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position
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 - xy_pos_t(probe.offset_xy); // Nozzle position based on probe position
if (do_bed_cal || do_probe_cal) {
// Ensure park position is reachable