diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 996bd60b91..637ebc5a71 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -36,6 +36,7 @@ #endif #endif // ENABLE_AUTO_BED_LEVELING +#define HAS_LCD_BUZZ (defined(ULTRALCD) || (defined(BEEPER) && BEEPER >= 0) || defined(LCD_USE_I2C_BUZZER)) #define SERVO_LEVELING (defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0) #ifdef MESH_BED_LEVELING @@ -189,6 +190,7 @@ * M410 - Quickstop. Abort all the planned moves * M420 - Enable/Disable Mesh Leveling (with current values) S1=enable S0=disable * M421 - Set a single Z coordinate in the Mesh Leveling grid. X Y Z + * M428 - Set the home_offset logically based on the current_position * M500 - Store parameters in EEPROM * M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily). * M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. @@ -4090,7 +4092,7 @@ inline void gcode_M226() { #endif // NUM_SERVOS > 0 -#if BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER) +#if HAS_LCD_BUZZ /** * M300: Play beep sound S P @@ -4102,7 +4104,7 @@ inline void gcode_M226() { lcd_buzz(beepP, beepS); } -#endif // BEEPER>0 || ULTRALCD || LCD_USE_I2C_BUZZER +#endif // HAS_LCD_BUZZ #ifdef PIDTEMP @@ -4504,6 +4506,54 @@ inline void gcode_M410() { quickStop(); } #endif +/** + * M428: Set home_offset based on the distance between the + * current_position and the nearest "reference point." + * If an axis is past center its endstop position + * is the reference-point. Otherwise it uses 0. This allows + * the Z offset to be set near the bed when using a max endstop. + * + * M428 can't be used more than 2cm away from 0 or an endstop. + * + * Use M206 to set these values directly. + */ +inline void gcode_M428() { + bool err = false; + float new_offs[3], new_pos[3]; + memcpy(new_pos, current_position, sizeof(new_pos)); + memcpy(new_offs, home_offset, sizeof(new_offs)); + for (int8_t i = X_AXIS; i <= Z_AXIS; i++) { + if (axis_known_position[i]) { + float base = (new_pos[i] > (min_pos[i] + max_pos[i]) / 2) ? base_home_pos(i) : 0, + diff = new_pos[i] - base; + if (diff > -20 && diff < 20) { + new_offs[i] -= diff; + new_pos[i] = base; + } + else { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR); + LCD_ALERTMESSAGEPGM("Err: Too far!"); + #if HAS_LCD_BUZZ + enqueuecommands_P(PSTR("M300 S40 P200")); + #endif + err = true; + break; + } + } + } + + if (!err) { + memcpy(current_position, new_pos, sizeof(new_pos)); + memcpy(home_offset, new_offs, sizeof(new_offs)); + sync_plan_position(); + LCD_ALERTMESSAGEPGM("Offset applied."); + #if HAS_LCD_BUZZ + enqueuecommands_P(PSTR("M300 S659 P200\nM300 S698 P200")); + #endif + } +} + /** * M500: Store settings in EEPROM */ @@ -5251,11 +5301,11 @@ void process_commands() { break; #endif // NUM_SERVOS > 0 - #if BEEPER > 0 || defined(ULTRALCD) || defined(LCD_USE_I2C_BUZZER) + #if HAS_LCD_BUZZ case 300: // M300 - Play beep tone gcode_M300(); break; - #endif // BEEPER > 0 || ULTRALCD || LCD_USE_I2C_BUZZER + #endif // HAS_LCD_BUZZ #ifdef PIDTEMP case 301: // M301 @@ -5353,6 +5403,10 @@ void process_commands() { break; #endif + case 428: // M428 Apply current_position to home_offset + gcode_M428(); + break; + case 500: // M500 Store settings in EEPROM gcode_M500(); break; diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 782b5d320a..362749a10f 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -676,7 +676,7 @@ void Config_PrintSettings(bool forReplay) { SERIAL_ECHOLNPGM("Mesh bed leveling:"); CONFIG_ECHO_START; } - SERIAL_ECHOPAIR(" M420 S", (int32_t)mbl.active); + SERIAL_ECHOPAIR(" M420 S", (unsigned long)mbl.active); SERIAL_ECHOPAIR(" X", MESH_NUM_X_POINTS); SERIAL_ECHOPAIR(" Y", MESH_NUM_Y_POINTS); SERIAL_EOL; diff --git a/Marlin/configurator/config/language.h b/Marlin/configurator/config/language.h index d8ceafb1a5..a56ee522f8 100644 --- a/Marlin/configurator/config/language.h +++ b/Marlin/configurator/config/language.h @@ -161,6 +161,7 @@ #define MSG_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" #define MSG_ERR_M421_REQUIRES_XYZ "M421 requires XYZ parameters" #define MSG_ERR_MESH_INDEX_OOB "Mesh XY index is out of bounds" +#define MSG_ERR_M428_TOO_FAR "Too far from reference point" #define MSG_M119_REPORT "Reporting endstop status" #define MSG_ENDSTOP_HIT "TRIGGERED" #define MSG_ENDSTOP_OPEN "open" diff --git a/Marlin/language.h b/Marlin/language.h index 252ee595ab..02cd675c8b 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -162,6 +162,7 @@ #define MSG_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" #define MSG_ERR_M421_REQUIRES_XYZ "M421 requires XYZ parameters" #define MSG_ERR_MESH_INDEX_OOB "Mesh XY index is out of bounds" +#define MSG_ERR_M428_TOO_FAR "Too far from reference point" #define MSG_M119_REPORT "Reporting endstop status" #define MSG_ENDSTOP_HIT "TRIGGERED" #define MSG_ENDSTOP_OPEN "open" diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 4dd32eb0de..5ca0943376 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -438,17 +438,12 @@ static void lcd_main_menu() { } #endif +/** + * Set the home offset based on the current_position + */ void lcd_set_home_offsets() { - for (int8_t i=0; i < NUM_AXIS; i++) { - if (i != E_AXIS) { - home_offset[i] -= current_position[i]; - current_position[i] = 0.0; - } - } - plan_set_position(0.0, 0.0, 0.0, current_position[E_AXIS]); - - // Audio feedback - enqueuecommands_P(PSTR("M300 S659 P200\nM300 S698 P200")); + // M428 Command + enqueuecommands_P(PSTR("M428")); lcd_return_to_status(); } @@ -1290,7 +1285,7 @@ void lcd_quick_feedback() { #define LCD_FEEDBACK_FREQUENCY_DURATION_MS (1000/6) #endif lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); - #elif defined(BEEPER) && BEEPER > -1 + #elif defined(BEEPER) && BEEPER >= 0 #ifndef LCD_FEEDBACK_FREQUENCY_HZ #define LCD_FEEDBACK_FREQUENCY_HZ 5000 #endif @@ -1723,12 +1718,12 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } void lcd_buzz(long duration, uint16_t freq) { if (freq > 0) { - #if BEEPER > 0 + #ifdef LCD_USE_I2C_BUZZER + lcd.buzz(duration, freq); + #elif defined(BEEPER) && BEEPER >= 0 SET_OUTPUT(BEEPER); tone(BEEPER, freq, duration); delay(duration); - #elif defined(LCD_USE_I2C_BUZZER) - lcd.buzz(duration, freq); #else delay(duration); #endif diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index 8f96f008ba..956b728286 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -106,7 +106,7 @@ FORCE_INLINE void lcd_setstatuspgm(const char* message, const uint8_t level=0) {} FORCE_INLINE void lcd_buttons_update() {} FORCE_INLINE void lcd_reset_alert_level() {} - FORCE_INLINE void lcd_buzz(long duration,uint16_t freq) {} + FORCE_INLINE void lcd_buzz(long duration, uint16_t freq) {} FORCE_INLINE bool lcd_detected(void) { return true; } #define LCD_MESSAGEPGM(x) do{}while(0)