Merge pull request #663 from mkbel/read_xyz_cal

Read xyz cal
This commit is contained in:
PavelSindler 2018-05-14 17:17:18 +02:00 committed by GitHub
commit 6e451c2780
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 197 additions and 135 deletions

View File

@ -343,7 +343,6 @@ extern unsigned long t_fan_rising_edge;
extern bool mesh_bed_leveling_flag;
extern bool mesh_bed_run_from_menu;
extern float distance_from_min[2];
extern bool sortAlpha;
extern char dir_names[3][9];

View File

@ -324,8 +324,6 @@ unsigned int custom_message_type;
unsigned int custom_message_state;
char snmm_filaments_used = 0;
float distance_from_min[2];
bool fan_state[2];
int fan_edge_counter[2];
int fan_speed[2];

View File

@ -1168,6 +1168,11 @@ const char * const MSG_MAX_LANG_TABLE[1] PROGMEM = {
MSG_MAX_EN
};
const char MSG_MEASURED_OFFSET_EN[] PROGMEM = "[0;0] point offset";
const char * const MSG_MEASURED_OFFSET_LANG_TABLE[1] PROGMEM = {
MSG_MEASURED_OFFSET_EN
};
const char MSG_MEASURED_SKEW_EN[] PROGMEM = "Measured skew:";
const char MSG_MEASURED_SKEW_CZ[] PROGMEM = "Merene zkoseni:";
const char * const MSG_MEASURED_SKEW_LANG_TABLE[LANG_NUM] PROGMEM = {

View File

@ -394,6 +394,8 @@ extern const char* const MSG_MARK_FIL_LANG_TABLE[LANG_NUM];
#define MSG_MARK_FIL LANG_TABLE_SELECT(MSG_MARK_FIL_LANG_TABLE)
extern const char* const MSG_MAX_LANG_TABLE[1];
#define MSG_MAX LANG_TABLE_SELECT_EXPLICIT(MSG_MAX_LANG_TABLE, 0)
extern const char* const MSG_MEASURED_OFFSET_LANG_TABLE[1];
#define MSG_MEASURED_OFFSET LANG_TABLE_SELECT_EXPLICIT(MSG_MEASURED_OFFSET_LANG_TABLE, 0)
extern const char* const MSG_MEASURED_SKEW_LANG_TABLE[LANG_NUM];
#define MSG_MEASURED_SKEW LANG_TABLE_SELECT(MSG_MEASURED_SKEW_LANG_TABLE)
extern const char* const MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_LANG_TABLE[LANG_NUM];

View File

@ -219,6 +219,7 @@
#define(length=17,lines=1) MSG_SHOW_END_STOPS "Show end stops"
#define MSG_CALIBRATE_BED "Calibrate XYZ"
#define MSG_CALIBRATE_BED_RESET "Reset XYZ calibr."
#define MSG_MEASURED_OFFSET "[0;0] point offset"
#define(length=20,lines=8) MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."
#define(length=20,lines=8) MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."

View File

@ -732,19 +732,24 @@ void world2machine_reset()
}
/**
* @brief Set calibration matrix to default value
* @brief Get calibration matrix default value
*
* This is used if no valid calibration data can be read from EEPROM.
* @param [out] vec_x axis x vector
* @param [out] vec_y axis y vector
* @param [out] cntr offset vector
*/
static void world2machine_default()
static void world2machine_default(float vec_x[2], float vec_y[2], float cntr[2])
{
vec_x[0] = 1.f;
vec_x[1] = 0.f;
vec_y[0] = 0.f;
vec_y[1] = 1.f;
cntr[0] = 0.f;
#ifdef DEFAULT_Y_OFFSET
const float vx[] = { 1.f, 0.f };
const float vy[] = { 0.f, 1.f };
const float cntr[] = { 0.f, DEFAULT_Y_OFFSET };
world2machine_update(vx, vy, cntr);
cntr[1] = DEFAULT_Y_OFFSET;
#else
world2machine_reset();
cntr[1] = 0.f;
#endif
}
/**
@ -768,93 +773,121 @@ static inline bool vec_undef(const float v[2])
return vx[0] == 0x0FFFFFFFF || vx[1] == 0x0FFFFFFFF;
}
/**
* @brief Read and apply calibration data from EEPROM
* @brief Read calibration data from EEPROM
*
* If no calibration data has been stored in EEPROM or invalid,
* world2machine_default() is used.
*
* If stored calibration data is invalid, EEPROM storage is cleared.
*
* @param [out] vec_x axis x vector
* @param [out] vec_y axis y vector
* @param [out] cntr offset vector
*/
void world2machine_initialize()
void world2machine_read_valid(float vec_x[2], float vec_y[2], float cntr[2])
{
//SERIAL_ECHOLNPGM("world2machine_initialize");
float cntr[2] = {
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+0)),
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+4))
};
float vec_x[2] = {
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +0)),
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +4))
};
float vec_y[2] = {
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +0)),
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +4))
};
vec_x[0] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +0));
vec_x[1] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_X +4));
vec_y[0] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +0));
vec_y[1] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y +4));
cntr[0] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+0));
cntr[1] = eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER+4));
bool reset = false;
if (vec_undef(cntr) || vec_undef(vec_x) || vec_undef(vec_y)) {
// SERIAL_ECHOLNPGM("Undefined bed correction matrix.");
if (vec_undef(cntr) || vec_undef(vec_x) || vec_undef(vec_y))
{
#if 0
SERIAL_ECHOLNPGM("Undefined bed correction matrix.");
#endif
reset = true;
}
else {
else
{
// Length of the vec_x shall be close to unity.
float l = sqrt(vec_x[0] * vec_x[0] + vec_x[1] * vec_x[1]);
if (l < 0.9 || l > 1.1) {
// SERIAL_ECHOLNPGM("X vector length:");
// MYSERIAL.println(l);
// SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the X vector out of range.");
if (l < 0.9 || l > 1.1)
{
#if 0
SERIAL_ECHOLNPGM("X vector length:");
MYSERIAL.println(l);
SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the X vector out of range.");
#endif
reset = true;
}
// Length of the vec_y shall be close to unity.
l = sqrt(vec_y[0] * vec_y[0] + vec_y[1] * vec_y[1]);
if (l < 0.9 || l > 1.1) {
// SERIAL_ECHOLNPGM("Y vector length:");
// MYSERIAL.println(l);
// SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the Y vector out of range.");
if (l < 0.9 || l > 1.1)
{
#if 0
SERIAL_ECHOLNPGM("Y vector length:");
MYSERIAL.println(l);
SERIAL_ECHOLNPGM("Invalid bed correction matrix. Length of the Y vector out of range.");
#endif
reset = true;
}
// Correction of the zero point shall be reasonably small.
l = sqrt(cntr[0] * cntr[0] + cntr[1] * cntr[1]);
if (l > 15.f) {
// SERIAL_ECHOLNPGM("Zero point correction:");
// MYSERIAL.println(l);
// SERIAL_ECHOLNPGM("Invalid bed correction matrix. Shift out of range.");
if (l > 15.f)
{
#if 0
SERIAL_ECHOLNPGM("Zero point correction:");
MYSERIAL.println(l);
SERIAL_ECHOLNPGM("Invalid bed correction matrix. Shift out of range.");
#endif
reset = true;
}
// vec_x and vec_y shall be nearly perpendicular.
l = vec_x[0] * vec_y[0] + vec_x[1] * vec_y[1];
if (fabs(l) > 0.1f) {
// SERIAL_ECHOLNPGM("Invalid bed correction matrix. X/Y axes are far from being perpendicular.");
if (fabs(l) > 0.1f)
{
#if 0
SERIAL_ECHOLNPGM("Invalid bed correction matrix. X/Y axes are far from being perpendicular.");
#endif
reset = true;
}
}
if (reset) {
// SERIAL_ECHOLNPGM("Invalid bed correction matrix. Resetting to identity.");
if (reset)
{
#if 0
SERIAL_ECHOLNPGM("Invalid bed correction matrix. Resetting to identity.");
#endif
reset_bed_offset_and_skew();
world2machine_default();
} else {
world2machine_update(vec_x, vec_y, cntr);
/*
SERIAL_ECHOPGM("world2machine_initialize() loaded: ");
MYSERIAL.print(world2machine_rotation_and_skew[0][0], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_rotation_and_skew[0][1], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_rotation_and_skew[1][0], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_rotation_and_skew[1][1], 5);
SERIAL_ECHOPGM(", offset ");
MYSERIAL.print(world2machine_shift[0], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_shift[1], 5);
SERIAL_ECHOLNPGM("");
*/
world2machine_default(vec_x, vec_y, cntr);
}
}
/**
* @brief Read and apply validated calibration data from EEPROM
*/
void world2machine_initialize()
{
#if 0
SERIAL_ECHOLNPGM("world2machine_initialize");
#endif
float vec_x[2];
float vec_y[2];
float cntr[2];
world2machine_read_valid(vec_x, vec_y, cntr);
world2machine_update(vec_x, vec_y, cntr);
#if 0
SERIAL_ECHOPGM("world2machine_initialize() loaded: ");
MYSERIAL.print(world2machine_rotation_and_skew[0][0], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_rotation_and_skew[0][1], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_rotation_and_skew[1][0], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_rotation_and_skew[1][1], 5);
SERIAL_ECHOPGM(", offset ");
MYSERIAL.print(world2machine_shift[0], 5);
SERIAL_ECHOPGM(", ");
MYSERIAL.print(world2machine_shift[1], 5);
SERIAL_ECHOLNPGM("");
#endif
}
/**
* @brief Update current position after switching to corrected coordinates
*
@ -2960,8 +2993,7 @@ void babystep_reset()
babystepLoadZ = 0;
}
void count_xyz_details() {
float a1, a2;
void count_xyz_details(float (&distanceMin)[2]) {
float cntr[2] = {
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER + 0)),
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_CENTER + 4))
@ -2974,12 +3006,14 @@ void count_xyz_details() {
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y + 0)),
eeprom_read_float((float*)(EEPROM_BED_CALIBRATION_VEC_Y + 4))
};
#if 0
a2 = -1 * asin(vec_y[0] / MACHINE_AXIS_SCALE_Y);
a1 = asin(vec_x[1] / MACHINE_AXIS_SCALE_X);
//angleDiff = fabs(a2 - a1);
angleDiff = fabs(a2 - a1);
#endif
for (uint8_t mesh_point = 0; mesh_point < 2; ++mesh_point) {
float y = vec_x[1] * pgm_read_float(bed_ref_points_4 + mesh_point * 2) + vec_y[1] * pgm_read_float(bed_ref_points_4 + mesh_point * 2 + 1) + cntr[1];
distance_from_min[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
distanceMin[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
}
}

View File

@ -26,16 +26,10 @@ extern float world2machine_rotation_and_skew_inv[2][2];
// Shift of the machine zero point, in the machine coordinates.
extern float world2machine_shift[2];
// Resets the transformation to identity.
extern void world2machine_reset();
// Resets the transformation to identity and update current_position[X,Y] from the servos.
extern void world2machine_revert_to_uncorrected();
// Loads the transformation from the EEPROM, if available.
extern void world2machine_initialize();
// When switching from absolute to corrected coordinates,
// this will apply an inverse world2machine transformation
// to current_position[x,y].
extern void world2machine_read_valid(float vec_x[2], float vec_y[2], float cntr[2]);
extern void world2machine_update_current();
inline void world2machine(float &x, float &y)
@ -181,7 +175,8 @@ extern void babystep_undo();
// Reset the current babystep counter without moving the axes.
extern void babystep_reset();
extern void count_xyz_details();
extern void count_xyz_details(float (&distanceMin)[2]);
extern bool sample_z();
#endif /* MESH_BED_CALIBRATION_H */

View File

@ -197,6 +197,8 @@ unsigned char firstrun = 1;
#include "ultralcd_implementation_hitachi_HD44780.h"
static const char separator[] PROGMEM = "--------------------";
/** forward declarations **/
static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg, uint8_t &nlines);
@ -227,6 +229,9 @@ static void prusa_stat_temperatures();
static void prusa_stat_printinfo();
static void lcd_farm_no();
static void lcd_menu_extruder_info();
static void lcd_menu_xyz_y_min();
static void lcd_menu_xyz_skew();
static void lcd_menu_xyz_offset();
#if defined(TMC2130) || defined(PAT9125)
static void lcd_menu_fails_stats();
#endif //TMC2130 or PAT9125
@ -1585,7 +1590,6 @@ static void lcd_menu_extruder_info()
if (lcd_clicked())
{
lcd_quick_feedback();
menu_action_back();
}
}
@ -1690,7 +1694,7 @@ static void lcd_menu_debug()
if (lcd_clicked())
{
lcd_quick_feedback();
lcd_return_to_status();
menu_action_back();
}
}
#endif /* DEBUG_BUILD */
@ -1706,7 +1710,6 @@ static void lcd_menu_temperatures()
if (lcd_clicked())
{
lcd_quick_feedback();
menu_action_back();
}
}
@ -1724,7 +1727,6 @@ static void lcd_menu_voltages()
fprintf_P(lcdout, PSTR( ESC_H(1,1)"PWR: %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr))) ;
if (lcd_clicked())
{
lcd_quick_feedback();
menu_action_back();
}
}
@ -1736,7 +1738,6 @@ static void lcd_menu_belt_status()
fprintf_P(lcdout, PSTR(ESC_H(1,0) "Belt status" ESC_H(2,1) "X %d" ESC_H(2,2) "Y %d" ), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X)), eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y)));
if (lcd_clicked())
{
lcd_quick_feedback();
menu_action_back();
}
}
@ -1835,7 +1836,7 @@ static void lcd_support_menu()
}
#ifndef MK1BP
MENU_ITEM(back, PSTR("------------"), 0);
if (!IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LCD_COMMAND_V2_CAL)) MENU_ITEM(function, MSG_XYZ_DETAILS, lcd_service_mode_show_result);
MENU_ITEM(submenu, MSG_XYZ_DETAILS, lcd_menu_xyz_y_min);
MENU_ITEM(submenu, MSG_INFO_EXTRUDER, lcd_menu_extruder_info);
#ifdef TMC2130
@ -2294,63 +2295,92 @@ static void lcd_move_e()
lcd_return_to_status();
}
}
/**
* @brief Show measured Y distance of front calibration points from Y_MIN_POS
*
* If those points are detected too close to edge of reachable area, their confidence is lowered.
* This functionality is applied more often for MK2 printers.
*/
static void lcd_menu_xyz_y_min()
{
lcd.setCursor(0,0);
lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
lcd_print_at_PGM(0, 1, separator);
lcd_print_at_PGM(0, 2, MSG_LEFT);
lcd_print_at_PGM(0, 3, MSG_RIGHT);
void lcd_service_mode_show_result() {
float angleDiff;
lcd_set_custom_characters_degree();
count_xyz_details();
angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
lcd_update_enable(false);
lcd_implementation_clear();
lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
lcd_print_at_PGM(0, 1, MSG_LEFT);
lcd_print_at_PGM(0, 2, MSG_RIGHT);
float distanceMin[2];
count_xyz_details(distanceMin);
for (int i = 0; i < 2; i++) {
if(distance_from_min[i] < 200) {
lcd_print_at_PGM(11, i + 1, PSTR(""));
lcd.print(distance_from_min[i]);
lcd_print_at_PGM((distance_from_min[i] < 0) ? 17 : 16, i + 1, PSTR("mm"));
} else lcd_print_at_PGM(11, i + 1, PSTR("N/A"));
}
delay_keep_alive(500);
KEEPALIVE_STATE(PAUSED_FOR_USER);
while (!lcd_clicked()) {
delay_keep_alive(100);
}
delay_keep_alive(500);
lcd_implementation_clear();
lcd_printPGM(MSG_MEASURED_SKEW);
if (angleDiff < 100) {
lcd.setCursor(15, 0);
lcd.print(angleDiff * 180 / M_PI);
lcd.print(LCD_STR_DEGREE);
}else lcd_print_at_PGM(16, 0, PSTR("N/A"));
lcd_print_at_PGM(0, 1, PSTR("--------------------"));
lcd_print_at_PGM(0, 2, MSG_SLIGHT_SKEW);
lcd_print_at_PGM(15, 2, PSTR(""));
lcd.print(bed_skew_angle_mild * 180 / M_PI);
lcd.print(LCD_STR_DEGREE);
lcd_print_at_PGM(0, 3, MSG_SEVERE_SKEW);
lcd_print_at_PGM(15, 3, PSTR(""));
lcd.print(bed_skew_angle_extreme * 180 / M_PI);
lcd.print(LCD_STR_DEGREE);
delay_keep_alive(500);
while (!lcd_clicked()) {
delay_keep_alive(100);
}
KEEPALIVE_STATE(NOT_BUSY);
delay_keep_alive(500);
lcd_set_custom_characters_arrows();
lcd_return_to_status();
lcd_update_enable(true);
lcd_update(2);
for (int i = 0; i < 2; i++) {
if(distanceMin[i] < 200) {
lcd_print_at_PGM(11, i + 2, PSTR(""));
lcd.print(distanceMin[i]);
lcd_print_at_PGM((distanceMin[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
} else lcd_print_at_PGM(11, i + 2, PSTR("N/A"));
}
if (lcd_clicked())
{
lcd_goto_menu(lcd_menu_xyz_skew);
}
}
/**
* @brief Show measured axis skewness
*/
static void lcd_menu_xyz_skew()
{
float angleDiff;
angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
lcd.setCursor(0,0);
lcd_printPGM(MSG_MEASURED_SKEW);
if (angleDiff < 100) {
lcd.setCursor(15, 0);
lcd.print(angleDiff * 180 / M_PI);
lcd.print(LCD_STR_DEGREE);
}else lcd_print_at_PGM(16, 0, PSTR("N/A"));
lcd_print_at_PGM(0, 1, separator);
lcd_print_at_PGM(0, 2, MSG_SLIGHT_SKEW);
lcd_print_at_PGM(15, 2, PSTR(""));
lcd.print(bed_skew_angle_mild * 180 / M_PI);
lcd.print(LCD_STR_DEGREE);
lcd_print_at_PGM(0, 3, MSG_SEVERE_SKEW);
lcd_print_at_PGM(15, 3, PSTR(""));
lcd.print(bed_skew_angle_extreme * 180 / M_PI);
lcd.print(LCD_STR_DEGREE);
if (lcd_clicked())
{
lcd_goto_menu(lcd_menu_xyz_offset);
}
}
/**
* @brief Show measured bed offset from expected position
*/
static void lcd_menu_xyz_offset()
{
lcd.setCursor(0,0);
lcd_printPGM(MSG_MEASURED_OFFSET);
lcd_print_at_PGM(0, 1, separator);
lcd_print_at_PGM(0, 2, PSTR("X"));
lcd_print_at_PGM(0, 3, PSTR("Y"));
float vec_x[2];
float vec_y[2];
float cntr[2];
world2machine_read_valid(vec_x, vec_y, cntr);
for (int i = 0; i < 2; i++)
{
lcd_print_at_PGM(11, i + 2, PSTR(""));
lcd.print(cntr[i]);
lcd_print_at_PGM((cntr[i] < 0) ? 17 : 16, i + 2, PSTR("mm"));
}
if (lcd_clicked())
{
menu_action_back();
}
}
// Save a single axis babystep value.
void EEPROM_save_B(int pos, int* value)
@ -7175,7 +7205,7 @@ static int lcd_selftest_screen(int _step, int _progress, int _progress_scale, bo
if (_step == 13) lcd_printPGM(PSTR("Calibrating home"));
lcd.setCursor(0, 1);
lcd.print("--------------------");
lcd_printPGM(separator);
if ((_step >= -1) && (_step <= 1))
{
//SERIAL_ECHOLNPGM("Fan test");

View File

@ -296,8 +296,6 @@ void lcd_temp_calibration_set();
void display_loading();
void lcd_service_mode_show_result();
#if !SDSORT_USES_RAM
void lcd_set_degree();
void lcd_set_progress();