Merged PINDA temp calibration branch into MK2

This commit is contained in:
PavelSindler 2017-04-10 11:10:03 +02:00
commit fc221fbea5
11 changed files with 590 additions and 194 deletions

View file

@ -5,7 +5,7 @@
#include "Configuration_prusa.h"
// Firmware version
#define FW_version "3.0.10-9"
#define FW_version "3.0.11-alpha"
#define FW_PRUSA3D_MAGIC "PRUSA3DFW"
#define FW_PRUSA3D_MAGIC_LEN 10
@ -44,6 +44,8 @@
#define EEPROM_BED_CORRECTION_REAR (EEPROM_BED_CORRECTION_FRONT-1)
#define EEPROM_TOSHIBA_FLASH_AIR_COMPATIBLITY (EEPROM_BED_CORRECTION_REAR-1)
#define EEPROM_PRINT_FLAG (EEPROM_TOSHIBA_FLASH_AIR_COMPATIBLITY-1)
#define EEPROM_PROBE_TEMP_SHIFT (EEPROM_PRINT_FLAG - 2*5) //5 x int for storing pinda probe temp shift relative to 50 C; unit: motor steps
#define EEPROM_TEMP_CAL_ACTIVE (EEPROM_PROBE_TEMP_SHIFT - 1)
// Currently running firmware, each digit stored as uint16_t.
// The flavor differentiates a dev, alpha, beta, release candidate or a release version.
@ -711,6 +713,9 @@ enum CalibrationStatus
// The XYZ calibration has been performed, now it remains to run the V2Calibration.gcode.
CALIBRATION_STATUS_LIVE_ADJUST = 230,
//V2 calibration has been run, now run PINDA probe temperature calibration
CALIBRATION_STATUS_PINDA = 220,
// Calibrated, ready to print.
CALIBRATION_STATUS_CALIBRATED = 1,

View file

@ -284,6 +284,7 @@ extern unsigned long starttime;
extern unsigned long stoptime;
extern bool is_usb_printing;
extern bool homing_flag;
extern bool temp_cal_active;
extern bool loading_flag;
extern unsigned int usb_printing_counter;
@ -323,7 +324,7 @@ extern void calculate_volumetric_multipliers();
// Similar to the default Arduino delay function,
// but it keeps the background tasks running.
extern void delay_keep_alive(int ms);
extern void delay_keep_alive(unsigned int ms);
extern void check_babystep();
@ -336,5 +337,7 @@ float d_ReadData();
void bed_analysis(float x_dimension, float y_dimension, int x_points_num, int y_points_num, float shift_x, float shift_y);
#endif
float temp_comp_interpolation(float temperature);
void temp_compensation_apply();
void temp_compensation_start();
void wait_for_heater(long codenum);

View file

@ -27,14 +27,6 @@
http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
*/
#include "Marlin.h"
#ifdef ENABLE_AUTO_BED_LEVELING
@ -62,6 +54,7 @@
#include "pins_arduino.h"
#include "math.h"
#include "util.h"
//#include "spline.h"
#ifdef BLINKM
#include "BlinkM.h"
@ -257,6 +250,8 @@ int extruder_multiply[EXTRUDERS] = {100
bool is_usb_printing = false;
bool homing_flag = false;
bool temp_cal_active = false;
unsigned long kicktime = millis()+100000;
unsigned int usb_printing_counter;
@ -1156,6 +1151,7 @@ void setup()
// EEPROM_LANG to number lower than 0x0ff.
// 1) Set a high power mode.
eeprom_write_byte((uint8_t*)EEPROM_SILENT, 0);
eeprom_write_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE, 0);
}
// In the future, somewhere here would one compare the current firmware version against the firmware version stored in the EEPROM.
@ -1165,7 +1161,7 @@ void setup()
if (lang_selected >= LANG_NUM){
lcd_mylang();
}
temp_cal_active = eeprom_read_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE);
check_babystep(); //checking if Z babystep is in allowed range
if (calibration_status() == CALIBRATION_STATUS_ASSEMBLED ||
@ -1177,6 +1173,10 @@ void setup()
} else if (calibration_status() == CALIBRATION_STATUS_LIVE_ADJUST) {
// Show the message.
lcd_show_fullscreen_message_and_wait_P(MSG_BABYSTEP_Z_NOT_SET);
lcd_update_enable(true);
} else if (calibration_status() == CALIBRATION_STATUS_PINDA && temp_cal_active == true) {
lcd_show_fullscreen_message_and_wait_P(MSG_PINDA_NOT_CALIBRATED);
lcd_update_enable(true);
} else if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION) {
// Show the message.
lcd_show_fullscreen_message_and_wait_P(MSG_FOLLOW_CALIBRATION_FLOW);
@ -2785,6 +2785,99 @@ void process_commands()
}
break;
case 76: //PINDA probe temperature calibration
{
setTargetBed(PINDA_MIN_T);
float zero_z;
int z_shift = 0; //unit: steps
int t_c; // temperature
if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) {
// We don't know where we are! HOME!
// Push the commands to the front of the message queue in the reverse order!
// There shall be always enough space reserved for these commands.
repeatcommand_front(); // repeat G76 with all its parameters
enquecommand_front_P((PSTR("G28 W0")));
break;
}
custom_message = true;
custom_message_type = 4;
custom_message_state = 1;
custom_message = MSG_TEMP_CALIBRATION;
current_position[X_AXIS] = PINDA_PREHEAT_X;
current_position[Y_AXIS] = PINDA_PREHEAT_Y;
current_position[Z_AXIS] = 0;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
st_synchronize();
while (degBed() < PINDA_MIN_T) delay_keep_alive(1000);
//enquecommand_P(PSTR("M190 S50"));
for (int i = 0; i < PINDA_HEAT_T; i++) delay_keep_alive(1000);
current_position[Z_AXIS] = 5;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
current_position[X_AXIS] = pgm_read_float(bed_ref_points);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 1);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
st_synchronize();
find_bed_induction_sensor_point_z(-1.f);
zero_z = current_position[Z_AXIS];
//current_position[Z_AXIS]
SERIAL_ECHOLNPGM("");
SERIAL_ECHOPGM("ZERO: ");
MYSERIAL.print(current_position[Z_AXIS]);
SERIAL_ECHOLNPGM("");
for (int i = 0; i<5; i++) {
custom_message_state = i + 2;
t_c = 60 + i * 10;
setTargetBed(t_c);
current_position[X_AXIS] = PINDA_PREHEAT_X;
current_position[Y_AXIS] = PINDA_PREHEAT_Y;
current_position[Z_AXIS] = 0;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
st_synchronize();
while (degBed() < t_c) delay_keep_alive(1000);
for (int i = 0; i < PINDA_HEAT_T; i++) delay_keep_alive(1000);
current_position[Z_AXIS] = 5;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
current_position[X_AXIS] = pgm_read_float(bed_ref_points);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 1);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
st_synchronize();
find_bed_induction_sensor_point_z(-1.f);
z_shift = (int)((current_position[Z_AXIS] - zero_z)*axis_steps_per_unit[Z_AXIS]);
SERIAL_ECHOLNPGM("");
SERIAL_ECHOPGM("Temperature: ");
MYSERIAL.print(t_c);
SERIAL_ECHOPGM(" Z shift (mm):");
MYSERIAL.print(current_position[Z_AXIS] - zero_z);
SERIAL_ECHOLNPGM("");
EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + i*2, &z_shift);
}
custom_message_type = 0;
custom_message = false;
calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
lcd_show_fullscreen_message_and_wait_P(MSG_TEMP_CALIBRATION_DONE);
lcd_update_enable(true);
lcd_update(2);
setTargetBed(0); //set bed target temperature back to 0
}
break;
#ifdef DIS
case 77:
{
@ -2827,13 +2920,20 @@ void process_commands()
* v Y-axis
*
*/
case 80:
case_G80:
{
mesh_bed_leveling_flag = true;
int8_t verbosity_level = 0;
static bool run = false;
if (code_seen('V')) {
// Just 'V' without a number counts as V1.
char c = strchr_pointer[1];
verbosity_level = (c == ' ' || c == '\t' || c == 0) ? 1 : code_value_short();
}
// Firstly check if we know where we are
if ( !( axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS] ) ){
if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) {
// We don't know where we are! HOME!
// Push the commands to the front of the message queue in the reverse order!
// There shall be always enough space reserved for these commands.
@ -2842,6 +2942,15 @@ void process_commands()
break;
}
if (run == false && card.sdprinting == true && temp_cal_active == true) {
temp_compensation_start();
run = true;
repeatcommand_front(); // repeat G80 with all its parameters
enquecommand_front_P((PSTR("G28 W0")));
break;
}
run = false;
// Save custom message state, set a new custom message state to display: Calibrating point 9.
bool custom_message_old = custom_message;
unsigned int custom_message_type_old = custom_message_type;
@ -2851,7 +2960,7 @@ void process_commands()
custom_message_state = (MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) + 10;
lcd_update(1);
mbl.reset();
mbl.reset(); //reset mesh bed leveling
// Reset baby stepping to zero, if the babystepping has already been loaded before. The babystepsTodo value will be
// consumed during the first movements following this statement.
@ -2860,43 +2969,53 @@ void process_commands()
// Cycle through all points and probe them
// First move up. During this first movement, the babystepping will be reverted.
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS]/60, active_extruder);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[Z_AXIS] / 60, active_extruder);
// The move to the first calibration point.
current_position[X_AXIS] = pgm_read_float(bed_ref_points);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points+1);
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
// mbl.get_meas_xy(0, 0, current_position[X_AXIS], current_position[Y_AXIS], false);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/30, active_extruder);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 1);
bool clamped = world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
if (verbosity_level >= 1) {
clamped ? SERIAL_PROTOCOLPGM("First calibration point clamped.\n") : SERIAL_PROTOCOLPGM("No clamping for first calibration point.\n");
}
// mbl.get_meas_xy(0, 0, current_position[X_AXIS], current_position[Y_AXIS], false);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS] / 30, active_extruder);
// Wait until the move is finished.
st_synchronize();
int mesh_point = 0;
int mesh_point = 0; //index number of calibration point
int ix = 0;
int iy = 0;
int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS]/20;
int Z_PROBE_FEEDRATE = homing_feedrate[Z_AXIS]/60;
int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS]/40;
bool has_z = is_bed_z_jitter_data_valid();
setup_for_endstop_move(false);
int XY_AXIS_FEEDRATE = homing_feedrate[X_AXIS] / 20;
int Z_PROBE_FEEDRATE = homing_feedrate[Z_AXIS] / 60;
int Z_LIFT_FEEDRATE = homing_feedrate[Z_AXIS] / 40;
bool has_z = is_bed_z_jitter_data_valid(); //checks if we have data from Z calibration (offsets of the Z heiths of the 8 calibration points from the first point)
if (verbosity_level >= 1) {
has_z ? SERIAL_PROTOCOLPGM("Z jitter data from Z cal. valid.\n") : SERIAL_PROTOCOLPGM("Z jitter data from Z cal. not valid.\n");
}
setup_for_endstop_move(false); //save feedrate and feedmultiply, sets feedmultiply to 100
const char *kill_message = NULL;
while (mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) {
if (verbosity_level >= 1) SERIAL_ECHOLNPGM("");
// Get coords of a measuring point.
ix = mesh_point % MESH_MEAS_NUM_X_POINTS;
ix = mesh_point % MESH_MEAS_NUM_X_POINTS; // from 0 to MESH_NUM_X_POINTS - 1
iy = mesh_point / MESH_MEAS_NUM_X_POINTS;
if (iy & 1) ix = (MESH_MEAS_NUM_X_POINTS - 1) - ix; // Zig zag
float z0 = 0.f;
if (has_z && mesh_point > 0) {
uint16_t z_offset_u = eeprom_read_word((uint16_t*)(EEPROM_BED_CALIBRATION_Z_JITTER + 2 * (ix + iy * 3 - 1)));
z0 = mbl.z_values[0][0] + *reinterpret_cast<int16_t*>(&z_offset_u) * 0.01;
#if 0
//#if 0
if (verbosity_level >= 1) {
SERIAL_ECHOPGM("Bed leveling, point: ");
MYSERIAL.print(mesh_point);
SERIAL_ECHOPGM(", calibration z: ");
MYSERIAL.print(z0, 5);
SERIAL_ECHOLNPGM("");
#endif
}
//#endif
}
// Move Z up to MESH_HOME_Z_SEARCH.
@ -2905,15 +3024,25 @@ void process_commands()
st_synchronize();
// Move to XY position of the sensor point.
current_position[X_AXIS] = pgm_read_float(bed_ref_points+2*mesh_point);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points+2*mesh_point+1);
current_position[X_AXIS] = pgm_read_float(bed_ref_points + 2 * mesh_point);
current_position[Y_AXIS] = pgm_read_float(bed_ref_points + 2 * mesh_point + 1);
world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]);
if (verbosity_level >= 1) {
SERIAL_PROTOCOL(mesh_point);
clamped ? SERIAL_PROTOCOLPGM(": xy clamped.\n") : SERIAL_PROTOCOLPGM(": no xy clamping\n");
}
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], XY_AXIS_FEEDRATE, active_extruder);
st_synchronize();
// Go down until endstop is hit
const float Z_CALIBRATION_THRESHOLD = 1.f;
if (! find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f)) {
if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point
kill_message = MSG_BED_LEVELING_FAILED_POINT_LOW;
break;
}
@ -2921,30 +3050,55 @@ void process_commands()
kill_message = MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED;
break;
}
if (has_z && fabs(z0 - current_position[Z_AXIS]) > Z_CALIBRATION_THRESHOLD) {
if (has_z && fabs(z0 - current_position[Z_AXIS]) > Z_CALIBRATION_THRESHOLD) { //if we have data from z calibration, max. allowed difference is 1mm for each point
kill_message = MSG_BED_LEVELING_FAILED_POINT_HIGH;
break;
}
mbl.set_z(ix, iy, current_position[Z_AXIS]);
if (verbosity_level >= 10) {
SERIAL_ECHOPGM("X: ");
MYSERIAL.print(current_position[X_AXIS], 5);
SERIAL_ECHOLNPGM("");
SERIAL_ECHOPGM("Y: ");
MYSERIAL.print(current_position[Y_AXIS], 5);
SERIAL_PROTOCOLPGM("\n");
}
if (verbosity_level >= 1) {
SERIAL_ECHOPGM("mesh bed leveling: ");
MYSERIAL.print(current_position[Z_AXIS], 5);
SERIAL_ECHOLNPGM("");
}
mbl.set_z(ix, iy, current_position[Z_AXIS]); //store measured z values z_values[iy][ix] = z;
custom_message_state--;
mesh_point++;
lcd_update(1);
}
if (verbosity_level >= 20) SERIAL_ECHOLNPGM("Mesh bed leveling while loop finished.");
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], Z_LIFT_FEEDRATE, active_extruder);
if (verbosity_level >= 20) {
SERIAL_ECHOLNPGM("MESH_HOME_Z_SEARCH: ");
MYSERIAL.print(current_position[Z_AXIS], 5);
}
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], Z_LIFT_FEEDRATE, active_extruder);
st_synchronize();
if (mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS) {
kill(kill_message);
SERIAL_ECHOLNPGM("killed");
}
clean_up_after_endstop_move();
// Apply Z height correction aka baby stepping before mesh bed leveing gets activated.
babystep_apply();
SERIAL_ECHOLNPGM("clean up finished ");
if(temp_cal_active == true) temp_compensation_apply(); //apply PINDA temperature compensation
babystep_apply(); // Apply Z height correction aka baby stepping before mesh bed leveing gets activated.
SERIAL_ECHOLNPGM("babystep applied");
bool eeprom_bed_correction_valid = eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1;
for (uint8_t i = 0; i < 4; ++ i) {
if (verbosity_level >= 1) {
eeprom_bed_correction_valid ? SERIAL_PROTOCOLPGM("Bed correction data valid\n") : SERIAL_PROTOCOLPGM("Bed correction data not valid\n");
}
for (uint8_t i = 0; i < 4; ++i) {
unsigned char codes[4] = { 'L', 'R', 'F', 'B' };
long correction = 0;
if (code_seen(codes[i]))
@ -2963,28 +3117,29 @@ void process_commands()
SERIAL_ECHOPGM("Excessive bed leveling correction: ");
SERIAL_ECHO(offset);
SERIAL_ECHOLNPGM(" microns");
} else {
}
else {
switch (i) {
case 0:
for (uint8_t row = 0; row < 3; ++ row) {
for (uint8_t row = 0; row < 3; ++row) {
mbl.z_values[row][1] += 0.5f * offset;
mbl.z_values[row][0] += offset;
}
break;
case 1:
for (uint8_t row = 0; row < 3; ++ row) {
for (uint8_t row = 0; row < 3; ++row) {
mbl.z_values[row][1] += 0.5f * offset;
mbl.z_values[row][2] += offset;
}
break;
case 2:
for (uint8_t col = 0; col < 3; ++ col) {
for (uint8_t col = 0; col < 3; ++col) {
mbl.z_values[1][col] += 0.5f * offset;
mbl.z_values[0][col] += offset;
}
break;
case 3:
for (uint8_t col = 0; col < 3; ++ col) {
for (uint8_t col = 0; col < 3; ++col) {
mbl.z_values[1][col] += 0.5f * offset;
mbl.z_values[2][col] += offset;
}
@ -2992,17 +3147,23 @@ void process_commands()
}
}
}
mbl.upsample_3x3();
mbl.active = 1;
SERIAL_ECHOLNPGM("Bed leveling correction finished");
mbl.upsample_3x3(); //bilinear interpolation from 3x3 to 7x7 points while using the same array z_values[iy][ix] for storing (just coppying measured data to new destination and interpolating between them)
SERIAL_ECHOLNPGM("Upsample finished");
mbl.active = 1; //activate mesh bed leveling
SERIAL_ECHOLNPGM("Mesh bed leveling activated");
go_home_with_z_lift();
SERIAL_ECHOLNPGM("Go home finished");
//unretract (after PINDA preheat retraction)
if (card.sdprinting == true && degHotend(active_extruder) > EXTRUDE_MINTEMP && temp_cal_active == true) {
current_position[E_AXIS] += DEFAULT_RETRACTION;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 400, active_extruder);
}
// Restore custom message state
custom_message = custom_message_old;
custom_message_type = custom_message_type_old;
custom_message_state = custom_message_state_old;
mesh_bed_leveling_flag = false;
lcd_update(2);
lcd_update(1);
}
break;
@ -3100,7 +3261,7 @@ void process_commands()
* This G-code will be performed at the end of a calibration script.
*/
case 87:
calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
calibration_status_store(CALIBRATION_STATUS_PINDA);
break;
/**
@ -5817,7 +5978,7 @@ void calculate_volumetric_multipliers() {
#endif
}
void delay_keep_alive(int ms)
void delay_keep_alive(unsigned int ms)
{
for (;;) {
manage_heater();
@ -6135,6 +6296,119 @@ void bed_analysis(float x_dimension, float y_dimension, int x_points_num, int y_
}
card.closefile();
}
#endif
void temp_compensation_start() {
custom_message = true;
custom_message_type = 5;
if (degHotend(active_extruder)>EXTRUDE_MINTEMP) current_position[E_AXIS] -= DEFAULT_RETRACTION;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 400, active_extruder);
current_position[X_AXIS] = PINDA_PREHEAT_X;
current_position[Y_AXIS] = PINDA_PREHEAT_Y;
current_position[Z_AXIS] = 0;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
st_synchronize();
while (fabs(degBed() - target_temperature_bed) > 3) delay_keep_alive(1000);
for(int i = 0; i < PINDA_HEAT_T; i++) delay_keep_alive(1000);
custom_message_type = 0;
custom_message = false;
}
void temp_compensation_apply() {
int i_add;
int compensation_value;
int z_shift = 0;
float z_shift_mm;
if (calibration_status() == CALIBRATION_STATUS_CALIBRATED) {
if (target_temperature_bed % 10 == 0 && target_temperature_bed >= 50 && target_temperature_bed <= 100) {
i_add = (target_temperature_bed - 60) / 10;
EEPROM_read_B(EEPROM_PROBE_TEMP_SHIFT + i_add * 2, &z_shift);
z_shift_mm = z_shift / axis_steps_per_unit[Z_AXIS];
}
else {
//interpolation
z_shift_mm = temp_comp_interpolation(target_temperature_bed) / axis_steps_per_unit[Z_AXIS];
}
SERIAL_PROTOCOLPGM("\n");
SERIAL_PROTOCOLPGM("Z shift applied:");
MYSERIAL.print(z_shift_mm);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] - z_shift_mm, current_position[E_AXIS], homing_feedrate[Z_AXIS] / 40, active_extruder);
st_synchronize();
plan_set_z_position(current_position[Z_AXIS]);
}
else {
//message that we have no temp compensation data ?
}
}
float temp_comp_interpolation(float inp_temperature) {
//cubic spline interpolation
int n, i, j, k;
float h[10], a, b, c, d, sum, s[10] = { 0 }, x[10], F[10], f[10], p, m[10][10] = { 0 }, temp;
int shift[10];
int temp_C[10];
p = inp_temperature;
n = 6; //number of measured points
shift[0] = 0;
for (i = 0; i < n; i++) {
//scanf_s("%f%f", &x[i], &f[i]);
if (i>0) EEPROM_read_B(EEPROM_PROBE_TEMP_SHIFT + (i-1) * 2, &shift[i]); //read shift in steps from EEPROM
temp_C[i] = 50 + i * 10; //temperature in C
x[i] = (float)temp_C[i];
f[i] = (float)shift[i];
}
for (i = n - 1; i>0; i--) {
F[i] = (f[i] - f[i - 1]) / (x[i] - x[i - 1]);
h[i - 1] = x[i] - x[i - 1];
}
//*********** formation of h, s , f matrix **************
for (i = 1; i<n - 1; i++) {
m[i][i] = 2 * (h[i - 1] + h[i]);
if (i != 1) {
m[i][i - 1] = h[i - 1];
m[i - 1][i] = h[i - 1];
}
m[i][n - 1] = 6 * (F[i + 1] - F[i]);
}
//*********** forward elimination **************
for (i = 1; i<n - 2; i++) {
temp = (m[i + 1][i] / m[i][i]);
for (j = 1; j <= n - 1; j++)
m[i + 1][j] -= temp*m[i][j];
}
//*********** backward substitution *********
for (i = n - 2; i>0; i--) {
sum = 0;
for (j = i; j <= n - 2; j++)
sum += m[i][j] * s[j];
s[i] = (m[i][n - 1] - sum) / m[i][i];
}
for (i = 0; i<n - 1; i++)
if (x[i] <= p&&p <= x[i + 1]) {
a = (s[i + 1] - s[i]) / (6 * h[i]);
b = s[i] / 2;
c = (f[i + 1] - f[i]) / h[i] - (2 * h[i] * s[i] + s[i + 1] * h[i]) / 6;
d = f[i];
sum = a*pow((p - x[i]), 3) + b*pow((p - x[i]), 2) + c*(p - x[i]) + d;
}
return sum;
}
#endif

View file

@ -494,6 +494,16 @@ const char * const MSG_CALIBRATE_E_LANG_TABLE[LANG_NUM] PROGMEM = {
MSG_CALIBRATE_E_DE
};
const char MSG_CALIBRATE_PINDA_EN[] PROGMEM = "Temp. calibration";
const char * const MSG_CALIBRATE_PINDA_LANG_TABLE[1] PROGMEM = {
MSG_CALIBRATE_PINDA_EN
};
const char MSG_CALIBRATION_PINDA_MENU_EN[] PROGMEM = "Temp. calibration";
const char * const MSG_CALIBRATION_PINDA_MENU_LANG_TABLE[1] PROGMEM = {
MSG_CALIBRATION_PINDA_MENU_EN
};
const char MSG_CARD_MENU_EN[] PROGMEM = "Print from SD";
const char MSG_CARD_MENU_CZ[] PROGMEM = "Tisk z SD";
const char MSG_CARD_MENU_IT[] PROGMEM = "Stampa da SD";
@ -1761,6 +1771,16 @@ const char * const MSG_PID_RUNNING_LANG_TABLE[1] PROGMEM = {
MSG_PID_RUNNING_EN
};
const char MSG_PINDA_NOT_CALIBRATED_EN[] PROGMEM = "Temperature calibration has not been run yet";
const char * const MSG_PINDA_NOT_CALIBRATED_LANG_TABLE[1] PROGMEM = {
MSG_PINDA_NOT_CALIBRATED_EN
};
const char MSG_PINDA_PREHEAT_EN[] PROGMEM = "Preheating";
const char * const MSG_PINDA_PREHEAT_LANG_TABLE[1] PROGMEM = {
MSG_PINDA_PREHEAT_EN
};
const char MSG_PLANNER_BUFFER_BYTES_EN[] PROGMEM = " PlannerBufferBytes: ";
const char * const MSG_PLANNER_BUFFER_BYTES_LANG_TABLE[1] PROGMEM = {
MSG_PLANNER_BUFFER_BYTES_EN
@ -2728,6 +2748,26 @@ const char * const MSG_TEMPERATURE_LANG_TABLE[LANG_NUM] PROGMEM = {
MSG_TEMPERATURE_DE
};
const char MSG_TEMP_CALIBRATION_EN[] PROGMEM = "Temp. calibration ";
const char * const MSG_TEMP_CALIBRATION_LANG_TABLE[1] PROGMEM = {
MSG_TEMP_CALIBRATION_EN
};
const char MSG_TEMP_CALIBRATION_DONE_EN[] PROGMEM = "Temperature calibration is finished. Click to continue.";
const char * const MSG_TEMP_CALIBRATION_DONE_LANG_TABLE[1] PROGMEM = {
MSG_TEMP_CALIBRATION_DONE_EN
};
const char MSG_TEMP_CALIBRATION_OFF_EN[] PROGMEM = "Temp. cal. [OFF]";
const char * const MSG_TEMP_CALIBRATION_OFF_LANG_TABLE[1] PROGMEM = {
MSG_TEMP_CALIBRATION_OFF_EN
};
const char MSG_TEMP_CALIBRATION_ON_EN[] PROGMEM = "Temp. cal. [ON]";
const char * const MSG_TEMP_CALIBRATION_ON_LANG_TABLE[1] PROGMEM = {
MSG_TEMP_CALIBRATION_ON_EN
};
const char MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_EN[] PROGMEM = "SD card [normal]";
const char MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_PL[] PROGMEM = "karta SD [normal]";
const char * const MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_LANG_TABLE[LANG_NUM] PROGMEM = {

View file

@ -107,6 +107,10 @@ extern const char* const MSG_CALIBRATE_BED_RESET_LANG_TABLE[LANG_NUM];
#define MSG_CALIBRATE_BED_RESET LANG_TABLE_SELECT(MSG_CALIBRATE_BED_RESET_LANG_TABLE)
extern const char* const MSG_CALIBRATE_E_LANG_TABLE[LANG_NUM];
#define MSG_CALIBRATE_E LANG_TABLE_SELECT(MSG_CALIBRATE_E_LANG_TABLE)
extern const char* const MSG_CALIBRATE_PINDA_LANG_TABLE[1];
#define MSG_CALIBRATE_PINDA LANG_TABLE_SELECT_EXPLICIT(MSG_CALIBRATE_PINDA_LANG_TABLE, 0)
extern const char* const MSG_CALIBRATION_PINDA_MENU_LANG_TABLE[1];
#define MSG_CALIBRATION_PINDA_MENU LANG_TABLE_SELECT_EXPLICIT(MSG_CALIBRATION_PINDA_MENU_LANG_TABLE, 0)
extern const char* const MSG_CARD_MENU_LANG_TABLE[LANG_NUM];
#define MSG_CARD_MENU LANG_TABLE_SELECT(MSG_CARD_MENU_LANG_TABLE)
extern const char* const MSG_CHANGE_EXTR_LANG_TABLE[LANG_NUM];
@ -355,6 +359,10 @@ extern const char* const MSG_PID_FINISHED_LANG_TABLE[1];
#define MSG_PID_FINISHED LANG_TABLE_SELECT_EXPLICIT(MSG_PID_FINISHED_LANG_TABLE, 0)
extern const char* const MSG_PID_RUNNING_LANG_TABLE[1];
#define MSG_PID_RUNNING LANG_TABLE_SELECT_EXPLICIT(MSG_PID_RUNNING_LANG_TABLE, 0)
extern const char* const MSG_PINDA_NOT_CALIBRATED_LANG_TABLE[1];
#define MSG_PINDA_NOT_CALIBRATED LANG_TABLE_SELECT_EXPLICIT(MSG_PINDA_NOT_CALIBRATED_LANG_TABLE, 0)
extern const char* const MSG_PINDA_PREHEAT_LANG_TABLE[1];
#define MSG_PINDA_PREHEAT LANG_TABLE_SELECT_EXPLICIT(MSG_PINDA_PREHEAT_LANG_TABLE, 0)
extern const char* const MSG_PLANNER_BUFFER_BYTES_LANG_TABLE[1];
#define MSG_PLANNER_BUFFER_BYTES LANG_TABLE_SELECT_EXPLICIT(MSG_PLANNER_BUFFER_BYTES_LANG_TABLE, 0)
extern const char* const MSG_PLEASE_WAIT_LANG_TABLE[LANG_NUM];
@ -535,6 +543,14 @@ extern const char* const MSG_TAKE_EFFECT_LANG_TABLE[LANG_NUM];
#define MSG_TAKE_EFFECT LANG_TABLE_SELECT(MSG_TAKE_EFFECT_LANG_TABLE)
extern const char* const MSG_TEMPERATURE_LANG_TABLE[LANG_NUM];
#define MSG_TEMPERATURE LANG_TABLE_SELECT(MSG_TEMPERATURE_LANG_TABLE)
extern const char* const MSG_TEMP_CALIBRATION_LANG_TABLE[1];
#define MSG_TEMP_CALIBRATION LANG_TABLE_SELECT_EXPLICIT(MSG_TEMP_CALIBRATION_LANG_TABLE, 0)
extern const char* const MSG_TEMP_CALIBRATION_DONE_LANG_TABLE[1];
#define MSG_TEMP_CALIBRATION_DONE LANG_TABLE_SELECT_EXPLICIT(MSG_TEMP_CALIBRATION_DONE_LANG_TABLE, 0)
extern const char* const MSG_TEMP_CALIBRATION_OFF_LANG_TABLE[1];
#define MSG_TEMP_CALIBRATION_OFF LANG_TABLE_SELECT_EXPLICIT(MSG_TEMP_CALIBRATION_OFF_LANG_TABLE, 0)
extern const char* const MSG_TEMP_CALIBRATION_ON_LANG_TABLE[1];
#define MSG_TEMP_CALIBRATION_ON LANG_TABLE_SELECT_EXPLICIT(MSG_TEMP_CALIBRATION_ON_LANG_TABLE, 0)
extern const char* const MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_LANG_TABLE[LANG_NUM];
#define MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF LANG_TABLE_SELECT(MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF_LANG_TABLE)
extern const char* const MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON_LANG_TABLE[LANG_NUM];

View file

@ -275,3 +275,12 @@
#define MSG_PID_FINISHED "PID cal. finished"
#define MSG_PID_RUNNING "PID cal. "
#define MSG_EEPROM_SAVING "Saving"
#define MSG_CALIBRATE_PINDA "Temp. calibration"
#define MSG_CALIBRATION_PINDA_MENU "Temp. calibration"
#define MSG_PINDA_NOT_CALIBRATED "Temperature calibration has not been run yet"
#define MSG_PINDA_PREHEAT "Preheating"
#define MSG_TEMP_CALIBRATION "Temp. calibration "
#define MSG_TEMP_CALIBRATION_DONE "Temperature calibration is finished. Click to continue."
#define MSG_TEMP_CALIBRATION_ON "Temp. cal. [ON]"
#define MSG_TEMP_CALIBRATION_OFF "Temp. cal. [OFF]"

View file

@ -249,3 +249,4 @@
#define MSG_FILAMENT_CLEAN "Il colore e' nitido?"
#define MSG_UNLOADING_FILAMENT "Rilasc. filamento"
#define MSG_PAPER "Porre un foglio sotto l'ugello durante la calibrazione dei primi 4 punti. In caso l'ugello muova il foglio spegnere prontamente la stampante."

View file

@ -2309,7 +2309,7 @@ static int babystepLoadZ = 0;
void babystep_apply()
{
// Apply Z height correction aka baby stepping before mesh bed leveling gets activated.
if(calibration_status() == CALIBRATION_STATUS_CALIBRATED)
if(calibration_status() <= CALIBRATION_STATUS_PINDA)
{
check_babystep(); //checking if babystep is in allowed range, otherwise setting babystep to 0

View file

@ -2429,6 +2429,33 @@ void lcd_mesh_calibration_z()
lcd_return_to_status();
}
void lcd_pinda_calibration_menu()
{
START_MENU();
MENU_ITEM(back, MSG_MENU_CALIBRATION, lcd_calibration_menu);
MENU_ITEM(submenu, MSG_CALIBRATE_PINDA, lcd_calibrate_pinda);
//MENU_ITEM(back, MSG_SETTINGS, lcd_settings_menu);
if (temp_cal_active == false) {
MENU_ITEM(function, MSG_TEMP_CALIBRATION_OFF, lcd_temp_calibration_set);
}
else {
MENU_ITEM(function, MSG_TEMP_CALIBRATION_ON, lcd_temp_calibration_set);
}
END_MENU();
}
void lcd_temp_calibration_set() {
temp_cal_active = !temp_cal_active;
eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, temp_cal_active);
digipot_init();
lcd_goto_menu(lcd_pinda_calibration_menu, 2);
}
void lcd_calibrate_pinda() {
enquecommand_P(PSTR("G76"));
lcd_return_to_status();
}
#ifndef SNMM
/*void lcd_calibrate_extruder() {
@ -2592,6 +2619,7 @@ static void lcd_calibration_menu()
MENU_ITEM(function, MSG_CALIBRATE_BED, lcd_mesh_calibration);
// "Calibrate Z" with storing the reference values to EEPROM.
MENU_ITEM(submenu, MSG_HOMEYZ, lcd_mesh_calibration_z);
MENU_ITEM(submenu, MSG_CALIBRATION_PINDA_MENU, lcd_pinda_calibration_menu);
#ifndef SNMM
//MENU_ITEM(function, MSG_CALIBRATE_E, lcd_calibrate_extruder);
#endif

View file

@ -238,4 +238,8 @@ void lcd_extr_cal_reset();
union MenuData;
char reset_menu();
void lcd_pinda_calibration_menu();
void lcd_calibrate_pinda();
void lcd_temp_calibration_set();
#endif //ULTRALCD_H

View file

@ -959,6 +959,22 @@ static void lcd_implementation_status_screen()
lcd.print(itostr3left(pid_number_of_cycles));
}
}
// PINDA temp calibration in progress
if (custom_message_type == 4) {
char progress[4];
lcd.setCursor(0, 3);
lcd_printPGM(MSG_TEMP_CALIBRATION);
lcd.setCursor(17, 3);
sprintf(progress, "%d/6", custom_message_state);
lcd.print(progress);
}
// temp compensation preheat
if (custom_message_type == 5) {
lcd.setCursor(0, 3);
lcd_printPGM(MSG_PINDA_PREHEAT);
}
}
else
{