diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 8418db89..3c89fb22 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -5,7 +5,7 @@ #include "Configuration_prusa.h" // Firmware version -#define FW_version "3.0.6-rc2" +#define FW_version "3.0.6-rc3" #define FW_PRUSA3D_MAGIC "PRUSA3DFW" #define FW_PRUSA3D_MAGIC_LEN 10 @@ -33,6 +33,15 @@ #define EEPROM_FARM_MODE (EEPROM_BED_CALIBRATION_Z_JITTER-4) +// Correction of the bed leveling, in micrometers. +// Maximum 50 micrometers allowed. +// Bed correction is valid if set to 1. If set to zero or 255, the successive 4 bytes are invalid. +#define EEPROM_BED_CORRECTION_VALID (EEPROM_FARM_MODE-1) +#define EEPROM_BED_CORRECTION_LEFT (EEPROM_BED_CORRECTION_VALID-1) +#define EEPROM_BED_CORRECTION_RIGHT (EEPROM_BED_CORRECTION_LEFT-1) +#define EEPROM_BED_CORRECTION_FRONT (EEPROM_BED_CORRECTION_RIGHT-1) +#define EEPROM_BED_CORRECTION_REAR (EEPROM_BED_CORRECTION_FRONT-1) + // Currently running firmware, each digit stored as uint16_t. // The flavor differentiates a dev, alpha, beta, release candidate or a release version. #define EEPROM_FIRMWARE_VERSION_FLAVOR (FW_PRUSA3D_MAGIC_LEN+6) diff --git a/Firmware/ConfigurationStore.cpp b/Firmware/ConfigurationStore.cpp index b9ef874f..5c623df6 100644 --- a/Firmware/ConfigurationStore.cpp +++ b/Firmware/ConfigurationStore.cpp @@ -362,16 +362,7 @@ void Config_ResetDefault() max_jerk[Z_AXIS] = DEFAULT_ZJERK; max_jerk[E_AXIS] = DEFAULT_EJERK; add_homing[X_AXIS] = add_homing[Y_AXIS] = add_homing[Z_AXIS] = 0; -#ifdef ULTIPANEL - plaPreheatHotendTemp = PLA_PREHEAT_HOTEND_TEMP; - plaPreheatHPBTemp = PLA_PREHEAT_HPB_TEMP; - plaPreheatFanSpeed = PLA_PREHEAT_FAN_SPEED; - absPreheatHotendTemp = ABS_PREHEAT_HOTEND_TEMP; - absPreheatHPBTemp = ABS_PREHEAT_HPB_TEMP; - absPreheatFanSpeed = ABS_PREHEAT_FAN_SPEED; - -#endif #ifdef ENABLE_AUTO_BED_LEVELING zprobe_zoffset = -Z_PROBE_OFFSET_FROM_EXTRUDER; #endif diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c49eae32..563dc9b7 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -235,6 +235,8 @@ byte b[2]; int value; }; +#define BABYSTEP_LOADZ_BY_PLANNER + // Number of baby steps applied int babystepLoadZ = 0; @@ -1902,7 +1904,11 @@ void process_commands() // 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. +#ifdef BABYSTEP_LOADZ_BY_PLANNER + shift_z(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS])); +#else babystepsTodoZsubtract(babystepLoadZ); +#endif /* BABYSTEP_LOADZ_BY_PLANNER */ babystepLoadZ = 0; saved_feedrate = feedrate; @@ -2286,6 +2292,27 @@ void process_commands() #endif // ENABLE_AUTO_BED_LEVELING #ifdef MESH_BED_LEVELING + case 30: // G30 Single Z Probe + { + st_synchronize(); + // TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly + setup_for_endstop_move(); + + feedrate = homing_feedrate[Z_AXIS]; + + find_bed_induction_sensor_point_z(-10.f, 3); + SERIAL_PROTOCOLRPGM(MSG_BED); + SERIAL_PROTOCOLPGM(" X: "); + MYSERIAL.print(current_position[X_AXIS], 5); + SERIAL_PROTOCOLPGM(" Y: "); + MYSERIAL.print(current_position[Y_AXIS], 5); + SERIAL_PROTOCOLPGM(" Z: "); + MYSERIAL.print(current_position[Z_AXIS], 5); + SERIAL_PROTOCOLPGM("\n"); + clean_up_after_endstop_move(); + } + break; + /** * G80: Mesh-based Z probe, probes a grid and produces a * mesh to compensate for variable bed height @@ -2323,7 +2350,11 @@ void process_commands() // 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. +#ifdef BABYSTEP_LOADZ_BY_PLANNER + shift_z(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS])); +#else babystepsTodoZsubtract(babystepLoadZ); +#endif /* BABYSTEP_LOADZ_BY_PLANNER */ babystepLoadZ = 0; // Cycle through all points and probe them @@ -2412,6 +2443,81 @@ void process_commands() kill(kill_message); } clean_up_after_endstop_move(); + + // Apply Z height correction aka baby stepping before mesh bed leveing gets activated. + if(card.sdprinting || is_usb_printing ) + { + if(eeprom_read_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET) == 0x01) + { + // End of G80: Apply the baby stepping value. + EEPROM_read_B(EEPROM_BABYSTEP_Z,&babystepLoadZ); + #if 0 + SERIAL_ECHO("Z baby step: "); + SERIAL_ECHO(babystepLoadZ); + SERIAL_ECHO(", current Z: "); + SERIAL_ECHO(current_position[Z_AXIS]); + SERIAL_ECHO("correction: "); + SERIAL_ECHO(float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS])); + SERIAL_ECHOLN(""); + #endif + #ifdef BABYSTEP_LOADZ_BY_PLANNER + shift_z(- float(babystepLoadZ) / float(axis_steps_per_unit[Z_AXIS])); + #else + babystepsTodoZadd(babystepLoadZ); + #endif /* BABYSTEP_LOADZ_BY_PLANNER */ + } + } + + bool eeprom_bed_correction_valid = eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1; + for (uint8_t i = 0; i < 4; ++ i) { + unsigned char codes[4] = { 'L', 'R', 'F', 'B' }; + long correction = 0; + if (code_seen(codes[i])) + correction = code_value_long(); + else if (eeprom_bed_correction_valid) { + unsigned char *addr = (i < 2) ? + ((i == 0) ? (unsigned char*)EEPROM_BED_CORRECTION_LEFT : (unsigned char*)EEPROM_BED_CORRECTION_RIGHT) : + ((i == 2) ? (unsigned char*)EEPROM_BED_CORRECTION_FRONT : (unsigned char*)EEPROM_BED_CORRECTION_REAR); + correction = eeprom_read_int8(addr); + } + if (correction == 0) + continue; + float offset = float(correction) * 0.001f; + if (fabs(offset) > 0.101f) { + SERIAL_ERROR_START; + SERIAL_ECHOPGM("Excessive bed leveling correction: "); + SERIAL_ECHO(offset); + SERIAL_ECHOLNPGM(" microns"); + } else { + switch (i) { + case 0: + 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) { + 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) { + 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) { + mbl.z_values[1][col] += 0.5f * offset; + mbl.z_values[2][col] += offset; + } + break; + } + } + } + mbl.upsample_3x3(); mbl.active = 1; current_position[X_AXIS] = X_MIN_POS+0.2; @@ -2420,19 +2526,9 @@ void process_commands() world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); plan_buffer_line(current_position[X_AXIS], current_position[X_AXIS], current_position[Z_AXIS], current_position[E_AXIS], XY_AXIS_FEEDRATE, active_extruder); st_synchronize(); - - if(card.sdprinting || is_usb_printing ) - { - if(eeprom_read_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET) == 0x01) - { - // End of G80: Apply the baby stepping value. - EEPROM_read_B(EEPROM_BABYSTEP_Z,&babystepLoadZ); - babystepsTodoZadd(babystepLoadZ); - } - } } break; - + /** * G81: Print mesh bed leveling status and bed profile if activated */ @@ -4650,9 +4746,10 @@ void clamp_to_software_endstops(float target[3]) int n_segments = 0; if (mbl.active) { - float len = abs(dx) + abs(dy) + abs(dz); + float len = abs(dx) + abs(dy); if (len > 0) - n_segments = int(floor(len / 30.f)); + // Split to 3cm segments or shorter. + n_segments = int(ceil(len / 30.f)); } if (n_segments > 1) { @@ -4669,7 +4766,10 @@ void clamp_to_software_endstops(float target[3]) } // The rest of the path. plan_buffer_line(x, y, z, e, feed_rate, extruder); - set_current_to_destination(); + current_position[X_AXIS] = x; + current_position[Y_AXIS] = y; + current_position[Z_AXIS] = z; + current_position[E_AXIS] = e; } #endif // MESH_BED_LEVELING @@ -4688,9 +4788,9 @@ void prepare_move() } else { #ifdef MESH_BED_LEVELING - mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder); + mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder); #else - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder); + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder); #endif } diff --git a/Firmware/language_all.cpp b/Firmware/language_all.cpp index ac18f3aa..7f0b4841 100644 --- a/Firmware/language_all.cpp +++ b/Firmware/language_all.cpp @@ -135,6 +135,61 @@ const char * const MSG_BED_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_BED_PL }; +const char MSG_BED_CORRECTION_FRONT_EN[] PROGMEM = "Front side um"; +const char MSG_BED_CORRECTION_FRONT_CZ[] PROGMEM = "Vpredu [um]"; +const char * const MSG_BED_CORRECTION_FRONT_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_BED_CORRECTION_FRONT_EN, + MSG_BED_CORRECTION_FRONT_CZ, + MSG_BED_CORRECTION_FRONT_EN, + MSG_BED_CORRECTION_FRONT_EN, + MSG_BED_CORRECTION_FRONT_EN +}; + +const char MSG_BED_CORRECTION_LEFT_EN[] PROGMEM = "Left side um"; +const char MSG_BED_CORRECTION_LEFT_CZ[] PROGMEM = "Vlevo [um]"; +const char * const MSG_BED_CORRECTION_LEFT_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_BED_CORRECTION_LEFT_EN, + MSG_BED_CORRECTION_LEFT_CZ, + MSG_BED_CORRECTION_LEFT_EN, + MSG_BED_CORRECTION_LEFT_EN, + MSG_BED_CORRECTION_LEFT_EN +}; + +const char MSG_BED_CORRECTION_MENU_EN[] PROGMEM = "Bed level correct"; +const char MSG_BED_CORRECTION_MENU_CZ[] PROGMEM = "Korekce podlozky"; +const char * const MSG_BED_CORRECTION_MENU_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_BED_CORRECTION_MENU_EN, + MSG_BED_CORRECTION_MENU_CZ, + MSG_BED_CORRECTION_MENU_EN, + MSG_BED_CORRECTION_MENU_EN, + MSG_BED_CORRECTION_MENU_EN +}; + +const char MSG_BED_CORRECTION_REAR_EN[] PROGMEM = "Rear side um"; +const char MSG_BED_CORRECTION_REAR_CZ[] PROGMEM = "Vzadu [um]"; +const char * const MSG_BED_CORRECTION_REAR_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_BED_CORRECTION_REAR_EN, + MSG_BED_CORRECTION_REAR_CZ, + MSG_BED_CORRECTION_REAR_EN, + MSG_BED_CORRECTION_REAR_EN, + MSG_BED_CORRECTION_REAR_EN +}; + +const char MSG_BED_CORRECTION_RESET_EN[] PROGMEM = "Reset"; +const char * const MSG_BED_CORRECTION_RESET_LANG_TABLE[1] PROGMEM = { + MSG_BED_CORRECTION_RESET_EN +}; + +const char MSG_BED_CORRECTION_RIGHT_EN[] PROGMEM = "Right side um"; +const char MSG_BED_CORRECTION_RIGHT_CZ[] PROGMEM = "Vpravo [um]"; +const char * const MSG_BED_CORRECTION_RIGHT_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_BED_CORRECTION_RIGHT_EN, + MSG_BED_CORRECTION_RIGHT_CZ, + MSG_BED_CORRECTION_RIGHT_EN, + MSG_BED_CORRECTION_RIGHT_EN, + MSG_BED_CORRECTION_RIGHT_EN +}; + const char MSG_BED_DONE_EN[] PROGMEM = "Bed done"; const char MSG_BED_DONE_CZ[] PROGMEM = "Bed OK."; const char MSG_BED_DONE_IT[] PROGMEM = "Piatto fatto."; diff --git a/Firmware/language_all.h b/Firmware/language_all.h index 8b7b81f5..d968dc40 100644 --- a/Firmware/language_all.h +++ b/Firmware/language_all.h @@ -44,6 +44,18 @@ extern const char* const MSG_BABYSTEP_Z_NOT_SET_LANG_TABLE[LANG_NUM]; #define MSG_BABYSTEP_Z_NOT_SET LANG_TABLE_SELECT(MSG_BABYSTEP_Z_NOT_SET_LANG_TABLE) extern const char* const MSG_BED_LANG_TABLE[LANG_NUM]; #define MSG_BED LANG_TABLE_SELECT(MSG_BED_LANG_TABLE) +extern const char* const MSG_BED_CORRECTION_FRONT_LANG_TABLE[LANG_NUM]; +#define MSG_BED_CORRECTION_FRONT LANG_TABLE_SELECT(MSG_BED_CORRECTION_FRONT_LANG_TABLE) +extern const char* const MSG_BED_CORRECTION_LEFT_LANG_TABLE[LANG_NUM]; +#define MSG_BED_CORRECTION_LEFT LANG_TABLE_SELECT(MSG_BED_CORRECTION_LEFT_LANG_TABLE) +extern const char* const MSG_BED_CORRECTION_MENU_LANG_TABLE[LANG_NUM]; +#define MSG_BED_CORRECTION_MENU LANG_TABLE_SELECT(MSG_BED_CORRECTION_MENU_LANG_TABLE) +extern const char* const MSG_BED_CORRECTION_REAR_LANG_TABLE[LANG_NUM]; +#define MSG_BED_CORRECTION_REAR LANG_TABLE_SELECT(MSG_BED_CORRECTION_REAR_LANG_TABLE) +extern const char* const MSG_BED_CORRECTION_RESET_LANG_TABLE[1]; +#define MSG_BED_CORRECTION_RESET LANG_TABLE_SELECT_EXPLICIT(MSG_BED_CORRECTION_RESET_LANG_TABLE, 0) +extern const char* const MSG_BED_CORRECTION_RIGHT_LANG_TABLE[LANG_NUM]; +#define MSG_BED_CORRECTION_RIGHT LANG_TABLE_SELECT(MSG_BED_CORRECTION_RIGHT_LANG_TABLE) extern const char* const MSG_BED_DONE_LANG_TABLE[LANG_NUM]; #define MSG_BED_DONE LANG_TABLE_SELECT(MSG_BED_DONE_LANG_TABLE) extern const char* const MSG_BED_HEATING_LANG_TABLE[LANG_NUM]; diff --git a/Firmware/language_cz.h b/Firmware/language_cz.h index 0bd45449..7ac5f2aa 100644 --- a/Firmware/language_cz.h +++ b/Firmware/language_cz.h @@ -313,4 +313,11 @@ #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Prosim aktualizujte." #define MSG_BABYSTEP_Z_NOT_SET "Tiskarna nebyla jeste zkalibrovana. Spustte kalibracni G-kod a doladte Z." +#define MSG_BED_CORRECTION_MENU "Korekce podlozky" +#define MSG_BED_CORRECTION_LEFT "Vlevo [um]" +#define MSG_BED_CORRECTION_RIGHT "Vpravo [um]" +#define MSG_BED_CORRECTION_FRONT "Vpredu [um]" +#define MSG_BED_CORRECTION_REAR "Vzadu [um]" +#define MSG_BED_CORRECTION_RESET "Reset" + #endif // LANGUAGE_EN_H diff --git a/Firmware/language_en.h b/Firmware/language_en.h index bafb45d0..8cf21e71 100644 --- a/Firmware/language_en.h +++ b/Firmware/language_en.h @@ -307,4 +307,11 @@ #define MSG_BABYSTEP_Z_NOT_SET "Printer has not been calibrated yet. Run calibration G-code to adjust Z height." +#define MSG_BED_CORRECTION_MENU "Bed level correct" +#define MSG_BED_CORRECTION_LEFT "Left side um" +#define MSG_BED_CORRECTION_RIGHT "Right side um" +#define MSG_BED_CORRECTION_FRONT "Front side um" +#define MSG_BED_CORRECTION_REAR "Rear side um" +#define MSG_BED_CORRECTION_RESET "Reset" + #endif // LANGUAGE_EN_H diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index 95f1db19..0a13c095 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -2081,3 +2081,11 @@ bool scan_bed_induction_points(int8_t verbosity_level) enable_z_endstop(endstop_z_enabled); return true; } + +// Shift a Z axis by a given delta. +void shift_z(float delta) +{ + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] - delta, current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder); + st_synchronize(); + plan_set_z_position(current_position[Z_AXIS]); +} diff --git a/Firmware/mesh_bed_calibration.h b/Firmware/mesh_bed_calibration.h index 29e23d1a..20948a80 100644 --- a/Firmware/mesh_bed_calibration.h +++ b/Firmware/mesh_bed_calibration.h @@ -167,4 +167,7 @@ extern bool is_bed_z_jitter_data_valid(); // Useful for visualizing the behavior of the bed induction detector. extern bool scan_bed_induction_points(int8_t verbosity_level); +// To replace loading of the babystep correction. +extern void shift_z(float delta); + #endif /* MESH_BED_CALIBRATION_H */ diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index cce0b313..6bfea2a6 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -1030,7 +1030,7 @@ void babystep(const uint8_t axis,const bool direction) //perform step WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); { - float x=1./float(axis+1)/float(axis+2); //wait a tiny bit + volatile float x=1./float(axis+1)/float(axis+2); //wait a tiny bit } WRITE(X_STEP_PIN, INVERT_X_STEP_PIN); @@ -1049,7 +1049,7 @@ void babystep(const uint8_t axis,const bool direction) //perform step WRITE(Y_STEP_PIN, !INVERT_Y_STEP_PIN); { - float x=1./float(axis+1)/float(axis+2); //wait a tiny bit + volatile float x=1./float(axis+1)/float(axis+2); //wait a tiny bit } WRITE(Y_STEP_PIN, INVERT_Y_STEP_PIN); @@ -1075,7 +1075,7 @@ void babystep(const uint8_t axis,const bool direction) #endif //wait a tiny bit { - float x=1./float(axis+1); //absolutely useless + volatile float x=1./float(axis+1); //absolutely useless } WRITE(Z_STEP_PIN, INVERT_Z_STEP_PIN); #ifdef Z_DUAL_STEPPER_DRIVERS diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index d082fdfc..39859850 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -21,8 +21,60 @@ int8_t encoderDiff; /* encoderDiff is updated from interrupt context and added t extern int lcd_change_fil_state; -int babystepMem[3]; -float babystepMemMM[3]; +//Function pointer to menu functions. +typedef void (*menuFunc_t)(); + +struct EditMenuParentState +{ + //prevMenu and prevEncoderPosition are used to store the previous menu location when editing settings. + menuFunc_t prevMenu; + uint16_t prevEncoderPosition; +}; + +union MenuData +{ + struct BabyStep + { + // 29B total + int8_t status; + int babystepMem[3]; + float babystepMemMM[3]; + } babyStep; + + struct SupportMenu + { + // 6B+16B=22B total + int8_t status; + bool is_flash_air; + uint8_t ip[4]; + char ip_str[3*4+3+1]; + } supportMenu; + + struct AdjustBed + { + // 6+13=19B + // editMenuParentState is used when an edit menu is entered, so it knows + // the return menu and encoder state. + struct EditMenuParentState editMenuParentState; + int8_t status; + int8_t left; + int8_t right; + int8_t front; + int8_t rear; + int left2; + int right2; + int front2; + int rear2; + } adjustBed; + + // editMenuParentState is used when an edit menu is entered, so it knows + // the return menu and encoder state. + struct EditMenuParentState editMenuParentState; +}; + +// State of the currently active menu. +// C Union manages sharing of the static memory by all the menus. +union MenuData menuData = { 0 }; union Data { @@ -46,33 +98,6 @@ int farm_status = 0; bool menuExiting = false; -/* Configuration settings */ -int plaPreheatHotendTemp; -int plaPreheatHPBTemp; -int plaPreheatFanSpeed; - -int absPreheatHotendTemp; -int absPreheatHPBTemp; -int absPreheatFanSpeed; - -int ppPreheatHotendTemp = PP_PREHEAT_HOTEND_TEMP; -int ppPreheatHPBTemp = PP_PREHEAT_HPB_TEMP; -int ppPreheatFanSpeed = PP_PREHEAT_FAN_SPEED; - -int petPreheatHotendTemp = PET_PREHEAT_HOTEND_TEMP; -int petPreheatHPBTemp = PET_PREHEAT_HPB_TEMP; -int petPreheatFanSpeed = PET_PREHEAT_FAN_SPEED; - -int hipsPreheatHotendTemp = HIPS_PREHEAT_HOTEND_TEMP; -int hipsPreheatHPBTemp = HIPS_PREHEAT_HPB_TEMP; -int hipsPreheatFanSpeed = HIPS_PREHEAT_FAN_SPEED; - -int flexPreheatHotendTemp = FLEX_PREHEAT_HOTEND_TEMP; -int flexPreheatHPBTemp = FLEX_PREHEAT_HPB_TEMP; -int flexPreheatFanSpeed = FLEX_PREHEAT_FAN_SPEED; - - - #ifdef FILAMENT_LCD_DISPLAY unsigned long message_millis = 0; #endif @@ -83,9 +108,6 @@ static float manual_feedrate[] = MANUAL_FEEDRATE; /* !Configuration settings */ -//Function pointer to menu functions. -typedef void (*menuFunc_t)(); - uint8_t lcd_status_message_level; char lcd_status_message[LCD_WIDTH + 1] = ""; //////WELCOME! unsigned char firstrun = 1; @@ -153,6 +175,8 @@ static void menu_action_setting_edit_float5(const char* pstr, float* ptr, float static void menu_action_setting_edit_float51(const char* pstr, float* ptr, float minValue, float maxValue); static void menu_action_setting_edit_float52(const char* pstr, float* ptr, float minValue, float maxValue); static void menu_action_setting_edit_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue); + +/* static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, menuFunc_t callbackFunc); static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, menuFunc_t callbackFunc); static void menu_action_setting_edit_callback_float3(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); @@ -162,6 +186,7 @@ static void menu_action_setting_edit_callback_float5(const char* pstr, float* pt static void menu_action_setting_edit_callback_float51(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); static void menu_action_setting_edit_callback_float52(const char* pstr, float* ptr, float minValue, float maxValue, menuFunc_t callbackFunc); static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned long* ptr, unsigned long minValue, unsigned long maxValue, menuFunc_t callbackFunc); +*/ #define ENCODER_FEEDRATE_DEADZONE 10 @@ -243,9 +268,6 @@ bool ignore_click = false; bool wait_for_unclick; uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD needs to draw, decreased after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) */ -//prevMenu and prevEncoderPosition are used to store the previous menu location when editing settings. -menuFunc_t prevMenu = NULL; -uint16_t prevEncoderPosition; //Variables used when editing values. const char* editLabel; void* editValue; @@ -255,10 +277,15 @@ menuFunc_t callbackFunc; // place-holders for Ki and Kd edits float raw_Ki, raw_Kd; -static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const bool feedback = true) { +static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const bool feedback = true, bool reset_menu_state = true) { if (currentMenu != menu) { currentMenu = menu; encoderPosition = encoder; + if (reset_menu_state) { + // Resets the global shared C union. + // This ensures, that the menu entered will find out, that it shall initialize itself. + memset(&menuData, 0, sizeof(menuData)); + } if (feedback) lcd_quick_feedback(); // For LCD_PROGRESS_BAR re-initialize the custom characters @@ -643,8 +670,8 @@ static void lcd_move_menu_axis(); void lcd_preheat_pla() { - setTargetHotend0(plaPreheatHotendTemp); - setTargetBed(plaPreheatHPBTemp); + setTargetHotend0(PLA_PREHEAT_HOTEND_TEMP); + setTargetBed(PLA_PREHEAT_HPB_TEMP); fanSpeed = 0; lcd_return_to_status(); setWatch(); // heater sanity check timer @@ -652,8 +679,8 @@ void lcd_preheat_pla() void lcd_preheat_abs() { - setTargetHotend0(absPreheatHotendTemp); - setTargetBed(absPreheatHPBTemp); + setTargetHotend0(ABS_PREHEAT_HOTEND_TEMP); + setTargetBed(ABS_PREHEAT_HPB_TEMP); fanSpeed = 0; lcd_return_to_status(); setWatch(); // heater sanity check timer @@ -661,8 +688,8 @@ void lcd_preheat_abs() void lcd_preheat_pp() { - setTargetHotend0(ppPreheatHotendTemp); - setTargetBed(ppPreheatHPBTemp); + setTargetHotend0(PP_PREHEAT_HOTEND_TEMP); + setTargetBed(PP_PREHEAT_HPB_TEMP); fanSpeed = 0; lcd_return_to_status(); setWatch(); // heater sanity check timer @@ -670,8 +697,8 @@ void lcd_preheat_pp() void lcd_preheat_pet() { - setTargetHotend0(petPreheatHotendTemp); - setTargetBed(petPreheatHPBTemp); + setTargetHotend0(PET_PREHEAT_HOTEND_TEMP); + setTargetBed(PET_PREHEAT_HPB_TEMP); fanSpeed = 0; lcd_return_to_status(); setWatch(); // heater sanity check timer @@ -679,8 +706,8 @@ void lcd_preheat_pet() void lcd_preheat_hips() { - setTargetHotend0(hipsPreheatHotendTemp); - setTargetBed(hipsPreheatHPBTemp); + setTargetHotend0(HIPS_PREHEAT_HOTEND_TEMP); + setTargetBed(HIPS_PREHEAT_HPB_TEMP); fanSpeed = 0; lcd_return_to_status(); setWatch(); // heater sanity check timer @@ -688,8 +715,8 @@ void lcd_preheat_hips() void lcd_preheat_flex() { - setTargetHotend0(flexPreheatHotendTemp); - setTargetBed(flexPreheatHPBTemp); + setTargetHotend0(FLEX_PREHEAT_HOTEND_TEMP); + setTargetBed(FLEX_PREHEAT_HPB_TEMP); fanSpeed = 0; lcd_return_to_status(); setWatch(); // heater sanity check timer @@ -728,6 +755,23 @@ static void lcd_preheat_menu() static void lcd_support_menu() { + if (menuData.supportMenu.status == 0) { + // Menu was entered. + // Initialize its status. + menuData.supportMenu.status = 1; + menuData.supportMenu.is_flash_air = card.ToshibaFlashAir_GetIP(menuData.supportMenu.ip); + if (menuData.supportMenu.is_flash_air) + sprintf_P(menuData.supportMenu.ip_str, PSTR("%d.%d.%d.%d"), + menuData.supportMenu.ip[0], menuData.supportMenu.ip[1], + menuData.supportMenu.ip[2], menuData.supportMenu.ip[3]); + } else if (menuData.supportMenu.is_flash_air && + menuData.supportMenu.ip[0] == 0 && menuData.supportMenu.ip[1] == 0 && + menuData.supportMenu.ip[2] == 0 && menuData.supportMenu.ip[3] == 0 && + ++ menuData.supportMenu.status == 16) { + // Waiting for the FlashAir card to get an IP address from a router. Force an update. + menuData.supportMenu.status = 0; + } + START_MENU(); MENU_ITEM(back, MSG_MAIN, lcd_main_menu); @@ -752,14 +796,10 @@ static void lcd_support_menu() MENU_ITEM(back, PSTR(__DATE__), lcd_main_menu); // Show the FlashAir IP address, if the card is available. - uint8_t ip[4]; - bool hasIP = card.ToshibaFlashAir_GetIP(ip); - if (hasIP) { + if (menuData.supportMenu.is_flash_air) { MENU_ITEM(back, PSTR("------------"), lcd_main_menu); MENU_ITEM(back, PSTR("FlashAir IP Addr:"), lcd_main_menu); - char buf[30]; - sprintf_P(buf, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); - MENU_ITEM(back_RAM, buf, lcd_main_menu); + MENU_ITEM(back_RAM, menuData.supportMenu.ip_str, lcd_main_menu); } END_MENU(); @@ -1172,24 +1212,39 @@ static void lcd_move_z() { -static void _lcd_babystep(int axis, const char *msg) { +static void _lcd_babystep(int axis, const char *msg) +{ + if (menuData.babyStep.status == 0) { + // Menu was entered. + // Initialize its status. + menuData.babyStep.status = 1; + EEPROM_read_B(EEPROM_BABYSTEP_X, &menuData.babyStep.babystepMem[0]); + EEPROM_read_B(EEPROM_BABYSTEP_Y, &menuData.babyStep.babystepMem[1]); + EEPROM_read_B(EEPROM_BABYSTEP_Z, &menuData.babyStep.babystepMem[2]); + menuData.babyStep.babystepMemMM[0] = menuData.babyStep.babystepMem[0]/axis_steps_per_unit[X_AXIS]; + menuData.babyStep.babystepMemMM[1] = menuData.babyStep.babystepMem[1]/axis_steps_per_unit[Y_AXIS]; + menuData.babyStep.babystepMemMM[2] = menuData.babyStep.babystepMem[2]/axis_steps_per_unit[Z_AXIS]; + lcdDrawUpdate = true; + } + if (encoderPosition != 0) { CRITICAL_SECTION_START babystepsTodo[axis] += (int)encoderPosition; CRITICAL_SECTION_END - babystepMem[axis] += (int)encoderPosition; - babystepMemMM[axis] = babystepMem[axis]/axis_steps_per_unit[Z_AXIS]; + menuData.babyStep.babystepMem[axis] += (int)encoderPosition; + menuData.babyStep.babystepMemMM[axis] = menuData.babyStep.babystepMem[axis]/axis_steps_per_unit[Z_AXIS]; delay(50); encoderPosition = 0; - lcdDrawUpdate = 1; + lcdDrawUpdate = true; } - if (lcdDrawUpdate) lcd_implementation_drawedit_2(msg, ftostr13ns(babystepMemMM[axis])); + if (lcdDrawUpdate) + lcd_implementation_drawedit_2(msg, ftostr13ns(menuData.babyStep.babystepMemMM[axis])); if (LCD_CLICKED || menuExiting) { // Only update the EEPROM when leaving the menu. EEPROM_save_B( (axis == 0) ? EEPROM_BABYSTEP_X : ((axis == 1) ? EEPROM_BABYSTEP_Y : EEPROM_BABYSTEP_Z), - &babystepMem[axis]); + &menuData.babyStep.babystepMem[axis]); } if (LCD_CLICKED) lcd_goto_menu(lcd_main_menu); } @@ -1204,6 +1259,69 @@ static void lcd_babystep_z() { _lcd_babystep(Z_AXIS, (MSG_BABYSTEPPING_Z)); } +static void lcd_adjust_bed(); + +static void lcd_adjust_bed_reset() +{ + eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID, 1); + eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_LEFT , 0); + eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_RIGHT, 0); + eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_FRONT, 0); + eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_REAR , 0); + lcd_goto_menu(lcd_adjust_bed, 0, false); + // Because we did not leave the menu, the menuData did not reset. + // Force refresh of the bed leveling data. + menuData.adjustBed.status = 0; +} + +#define BED_ADJUSTMENT_UM_MAX 50 + +static void lcd_adjust_bed() +{ + if (menuData.adjustBed.status == 0) { + // Menu was entered. + // Initialize its status. + menuData.adjustBed.status = 1; + bool valid = false; + menuData.adjustBed.left = menuData.adjustBed.left2 = eeprom_read_int8((unsigned char*)EEPROM_BED_CORRECTION_LEFT); + menuData.adjustBed.right = menuData.adjustBed.right2 = eeprom_read_int8((unsigned char*)EEPROM_BED_CORRECTION_RIGHT); + menuData.adjustBed.front = menuData.adjustBed.front2 = eeprom_read_int8((unsigned char*)EEPROM_BED_CORRECTION_FRONT); + menuData.adjustBed.rear = menuData.adjustBed.rear2 = eeprom_read_int8((unsigned char*)EEPROM_BED_CORRECTION_REAR); + if (eeprom_read_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID) == 1 && + menuData.adjustBed.left >= -BED_ADJUSTMENT_UM_MAX && menuData.adjustBed.left < BED_ADJUSTMENT_UM_MAX && + menuData.adjustBed.right >= -BED_ADJUSTMENT_UM_MAX && menuData.adjustBed.right < BED_ADJUSTMENT_UM_MAX && + menuData.adjustBed.front >= -BED_ADJUSTMENT_UM_MAX && menuData.adjustBed.front < BED_ADJUSTMENT_UM_MAX && + menuData.adjustBed.rear >= -BED_ADJUSTMENT_UM_MAX && menuData.adjustBed.rear < BED_ADJUSTMENT_UM_MAX) + valid = true; + if (! valid) { + // Reset the values: simulate an edit. + menuData.adjustBed.left2 = 0; + menuData.adjustBed.right2 = 0; + menuData.adjustBed.front2 = 0; + menuData.adjustBed.rear2 = 0; + } + lcdDrawUpdate = true; + eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID, 1); + } + + if (menuData.adjustBed.left != menuData.adjustBed.left2) + eeprom_update_int8((unsigned char*)EEPROM_BED_CORRECTION_LEFT, menuData.adjustBed.left = menuData.adjustBed.left2); + if (menuData.adjustBed.right != menuData.adjustBed.right2) + eeprom_update_int8((unsigned char*)EEPROM_BED_CORRECTION_RIGHT, menuData.adjustBed.right = menuData.adjustBed.right2); + if (menuData.adjustBed.front != menuData.adjustBed.front2) + eeprom_update_int8((unsigned char*)EEPROM_BED_CORRECTION_FRONT, menuData.adjustBed.front = menuData.adjustBed.front2); + if (menuData.adjustBed.rear != menuData.adjustBed.rear2) + eeprom_update_int8((unsigned char*)EEPROM_BED_CORRECTION_REAR, menuData.adjustBed.rear = menuData.adjustBed.rear2); + + START_MENU(); + MENU_ITEM(back, MSG_SETTINGS, lcd_settings_menu); + MENU_ITEM_EDIT(int3, MSG_BED_CORRECTION_LEFT, &menuData.adjustBed.left2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX); + MENU_ITEM_EDIT(int3, MSG_BED_CORRECTION_RIGHT, &menuData.adjustBed.right2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX); + MENU_ITEM_EDIT(int3, MSG_BED_CORRECTION_FRONT, &menuData.adjustBed.front2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX); + MENU_ITEM_EDIT(int3, MSG_BED_CORRECTION_REAR, &menuData.adjustBed.rear2, -BED_ADJUSTMENT_UM_MAX, BED_ADJUSTMENT_UM_MAX); + MENU_ITEM(function, MSG_BED_CORRECTION_RESET, lcd_adjust_bed_reset); + END_MENU(); +} void lcd_adjust_z() { int enc_dif = 0; @@ -1269,20 +1387,16 @@ void lcd_adjust_z() { if (lcd_clicked()) { fsm = cursor_pos; if (fsm == 1) { - EEPROM_read_B(EEPROM_BABYSTEP_X, &babystepMem[0]); - EEPROM_read_B(EEPROM_BABYSTEP_Y, &babystepMem[1]); - EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystepMem[2]); + int babystepLoadZ = 0; + EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystepLoadZ); CRITICAL_SECTION_START - babystepsTodo[Z_AXIS] = babystepMem[2]; + babystepsTodo[Z_AXIS] = babystepLoadZ; CRITICAL_SECTION_END } else { - babystepMem[0] = 0; - babystepMem[1] = 0; - babystepMem[2] = 0; - - EEPROM_save_B(EEPROM_BABYSTEP_X, &babystepMem[0]); - EEPROM_save_B(EEPROM_BABYSTEP_Y, &babystepMem[1]); - EEPROM_save_B(EEPROM_BABYSTEP_Z, &babystepMem[2]); + int zero = 0; + EEPROM_save_B(EEPROM_BABYSTEP_X, &zero); + EEPROM_save_B(EEPROM_BABYSTEP_Y, &zero); + EEPROM_save_B(EEPROM_BABYSTEP_Z, &zero); } delay(500); } @@ -1817,9 +1931,9 @@ void lcd_pick_babystep(){ if (lcd_clicked()) { fsm = cursor_pos; - - EEPROM_read_B(EEPROM_BABYSTEP_Z0+((fsm-1)*2),&babystepMem[2]); - EEPROM_save_B(EEPROM_BABYSTEP_Z,&babystepMem[2]); + int babyStepZ; + EEPROM_read_B(EEPROM_BABYSTEP_Z0+((fsm-1)*2),&babyStepZ); + EEPROM_save_B(EEPROM_BABYSTEP_Z,&babyStepZ); eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0x01); delay(500); @@ -1947,7 +2061,7 @@ static void lcd_settings_menu() if (!isPrintPaused) { MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84")); - MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28")); + MENU_ITEM(gcode, MSG_AUTO_HOME, PSTR("G28 W")); } if (SilentModeMenu == 0) { @@ -1955,15 +2069,11 @@ static void lcd_settings_menu() } else { MENU_ITEM(function, MSG_SILENT_MODE_ON, lcd_silent_mode_set); } - - EEPROM_read_B(EEPROM_BABYSTEP_X, &babystepMem[0]); - EEPROM_read_B(EEPROM_BABYSTEP_Y, &babystepMem[1]); - EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystepMem[2]); - babystepMemMM[2] = babystepMem[2]/axis_steps_per_unit[Z_AXIS]; if (!isPrintPaused) { MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z);//8 + MENU_ITEM(submenu, MSG_BED_CORRECTION_MENU, lcd_adjust_bed); } MENU_ITEM(submenu, MSG_LANGUAGE_SELECT, lcd_language_menu); if (!isPrintPaused) @@ -2301,9 +2411,6 @@ static void lcd_main_menu() if ( ( IS_SD_PRINTING || is_usb_printing ) && (current_position[Z_AXIS] < 0.5) ) { - EEPROM_read_B(EEPROM_BABYSTEP_X, &babystepMem[0]); - EEPROM_read_B(EEPROM_BABYSTEP_Y, &babystepMem[1]); - EEPROM_read_B(EEPROM_BABYSTEP_Z, &babystepMem[2]); MENU_ITEM(submenu, MSG_BABYSTEP_Z, lcd_babystep_z);//8 } @@ -2578,7 +2685,7 @@ void lcd_sdcard_menu() if (LCD_CLICKED) \ { \ *((_type*)editValue) = ((_type)((int32_t)encoderPosition + minEditValue)) / scale; \ - lcd_goto_menu(prevMenu, prevEncoderPosition); \ + lcd_goto_menu(menuData.editMenuParentState.prevMenu, menuData.editMenuParentState.prevEncoderPosition, true, false); \ } \ } \ void menu_edit_callback_ ## _name () { \ @@ -2587,33 +2694,33 @@ void lcd_sdcard_menu() } \ static void menu_action_setting_edit_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue) \ { \ - prevMenu = currentMenu; \ - prevEncoderPosition = encoderPosition; \ + menuData.editMenuParentState.prevMenu = currentMenu; \ + menuData.editMenuParentState.prevEncoderPosition = encoderPosition; \ \ lcdDrawUpdate = 2; \ - currentMenu = menu_edit_ ## _name; \ + lcd_goto_menu(menu_edit_ ## _name, (*ptr) * scale - minEditValue, true, false); \ \ editLabel = pstr; \ editValue = ptr; \ minEditValue = minValue * scale; \ maxEditValue = maxValue * scale - minEditValue; \ - encoderPosition = (*ptr) * scale - minEditValue; \ }\ + /* static void menu_action_setting_edit_callback_ ## _name (const char* pstr, _type* ptr, _type minValue, _type maxValue, menuFunc_t callback) \ { \ - prevMenu = currentMenu; \ - prevEncoderPosition = encoderPosition; \ + menuData.editMenuParentState.prevMenu = currentMenu; \ + menuData.editMenuParentState.prevEncoderPosition = encoderPosition; \ \ lcdDrawUpdate = 2; \ - currentMenu = menu_edit_callback_ ## _name; \ + lcd_goto_menu(menu_edit_callback_ ## _name, (*ptr) * scale - minEditValue, true, false); \ \ editLabel = pstr; \ editValue = ptr; \ minEditValue = minValue * scale; \ maxEditValue = maxValue * scale - minEditValue; \ - encoderPosition = (*ptr) * scale - minEditValue; \ callbackFunc = callback;\ } + */ menu_edit_type(int, int3, itostr3, 1) menu_edit_type(float, float3, ftostr3, 1) menu_edit_type(float, float32, ftostr32, 100) @@ -3048,11 +3155,13 @@ static void menu_action_setting_edit_bool(const char* pstr, bool* ptr) { *ptr = !(*ptr); } +/* static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, menuFunc_t callback) { menu_action_setting_edit_bool(pstr, ptr); (*callback)(); } +*/ #endif//ULTIPANEL /** LCD API **/ diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 32e50d5b..5867e5db 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -79,14 +79,6 @@ FORCE_INLINE void lcd_buttons_update() {} #endif extern int lcd_commands_type; - - extern int plaPreheatHotendTemp; - extern int plaPreheatHPBTemp; - extern int plaPreheatFanSpeed; - - extern int absPreheatHotendTemp; - extern int absPreheatHPBTemp; - extern int absPreheatFanSpeed; extern bool farm_mode; extern int farm_no; diff --git a/Firmware/ultralcd_implementation_hitachi_HD44780.h b/Firmware/ultralcd_implementation_hitachi_HD44780.h index bb03c142..c2b7f7a5 100644 --- a/Firmware/ultralcd_implementation_hitachi_HD44780.h +++ b/Firmware/ultralcd_implementation_hitachi_HD44780.h @@ -658,10 +658,13 @@ static void lcd_implementation_status_screen() lcd.print(" "); //Print the Z coordinates + // if (custom_message_type != 1) { + // Not in a bed calibration mode. lcd.setCursor(LCD_WIDTH - 8-2, 0); lcd.print(" Z"); lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001)); lcd.print(' '); + //} //Print the Bedtemperature lcd.setCursor(0, 1); diff --git a/Firmware/util.h b/Firmware/util.h index 04e499fd..d740aaf4 100644 --- a/Firmware/util.h +++ b/Firmware/util.h @@ -21,4 +21,15 @@ extern bool show_upgrade_dialog_if_version_newer(const char *version_string); extern void update_current_firmware_version_to_eeprom(); + + +inline int8_t eeprom_read_int8(unsigned char* addr) { + uint8_t v = eeprom_read_byte(addr); + return *reinterpret_cast(&v); +} + +inline void eeprom_update_int8(unsigned char* addr, int8_t v) { + eeprom_update_byte(addr, *reinterpret_cast(&v)); +} + #endif /* UTIL_H */