diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp index 061183632..8018cb741 100644 --- a/Marlin/G26_Mesh_Validation_Tool.cpp +++ b/Marlin/G26_Mesh_Validation_Tool.cpp @@ -164,50 +164,49 @@ static int8_t g26_prime_flag; #if ENABLED(NEWPANEL) + /** * Detect is_lcd_clicked, debounce it, and return true for cancel */ bool user_canceled() { - if (!is_lcd_clicked()) return false; - safe_delay(10); // Wait for click to settle + if (!is_lcd_clicked()) return false; // Return if the button isn't pressed #if ENABLED(ULTRA_LCD) lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99); lcd_quick_feedback(); #endif - while (!is_lcd_clicked()) idle(); // Wait for button release + safe_delay(10); // Wait for click to settle + while (!is_lcd_clicked()) idle(); // Wait for button press again? // If the button is suddenly pressed again, // ask the user to resolve the issue lcd_setstatusPGM(PSTR("Release button"), 99); // will never appear... - while (is_lcd_clicked()) idle(); // unless this loop happens + wait_for_release(); lcd_reset_status(); - return true; } - #endif - #if ENABLED(NEWPANEL) bool exit_from_g26() { lcd_setstatusPGM(PSTR("Leaving G26"), -1); - while (is_lcd_clicked()) idle(); + wait_for_release(); return G26_ERR; } + #endif void G26_line_to_destination(const float &feed_rate) { const float save_feedrate = feedrate_mm_s; feedrate_mm_s = feed_rate; // use specified feed rate - prepare_move_to_destination(); // will ultimately call ubl.line_to_destination_cartesian for UBL or ubl.prepare_linear_move_to for UBL_DELTA + prepare_move_to_destination(); // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_DELTA feedrate_mm_s = save_feedrate; // restore global feed rate } - void move_to(const float &x, const float &y, const float &z, const float &e_delta) { + void move_to(const float &rx, const float &ry, const float &z, const float &e_delta) { float feed_value; static float last_z = -999.99; - bool has_xy_component = (x != current_position[X_AXIS] || y != current_position[Y_AXIS]); // Check if X or Y is involved in the movement. + bool has_xy_component = (rx != current_position[X_AXIS] || ry != current_position[Y_AXIS]); // Check if X or Y is involved in the movement. if (z != last_z) { last_z = z; @@ -230,8 +229,8 @@ if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value); - destination[X_AXIS] = x; - destination[Y_AXIS] = y; + destination[X_AXIS] = rx; + destination[Y_AXIS] = ry; destination[E_AXIS] += e_delta; G26_line_to_destination(feed_value); @@ -291,15 +290,13 @@ idle(); } - while (is_lcd_clicked()) idle(); // Debounce Encoder Wheel + wait_for_release(); - #if ENABLED(ULTRA_LCD) - strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue; - // So... We cheat to get a message up. - lcd_setstatusPGM(PSTR("Done Priming"), 99); - lcd_quick_feedback(); - lcd_external_control = false; - #endif + strcpy_P(lcd_status_message, PSTR("Done Priming")); // We can't do lcd_setstatusPGM() without having it continue; + // So... We cheat to get a message up. + lcd_setstatusPGM(PSTR("Done Priming"), 99); + lcd_quick_feedback(); + lcd_external_control = false; } else #endif @@ -491,17 +488,11 @@ return false; } - float valid_trig_angle(float d) { - while (d > 360.0) d -= 360.0; - while (d < 0.0) d += 360.0; - return d; - } - /** * Turn on the bed and nozzle heat and * wait for them to get up to temperature. */ - bool turn_on_heaters() { + inline bool turn_on_heaters() { millis_t next = millis() + 5000UL; #if HAS_TEMP_BED #if ENABLED(ULTRA_LCD) @@ -519,7 +510,7 @@ if (ELAPSED(millis(), next)) { next = millis() + 5000UL; - print_heaterstates(); + thermalManager.print_heaterstates(); SERIAL_EOL(); } idle(); @@ -541,7 +532,7 @@ if (ELAPSED(millis(), next)) { next = millis() + 5000UL; - print_heaterstates(); + thermalManager.print_heaterstates(); SERIAL_EOL(); } idle(); @@ -555,10 +546,16 @@ return G26_OK; } + float valid_trig_angle(float d) { + while (d > 360.0) d -= 360.0; + while (d < 0.0) d += 360.0; + return d; + } + /** * G26: Mesh Validation Pattern generation. * - * Used to interactively edit UBL's Mesh by placing the + * Used to interactively edit the mesh by placing the * nozzle in a problem area and doing a G29 P4 R command. */ void gcode_G26() { @@ -704,12 +701,12 @@ set_current_from_destination(); } - if (turn_on_heaters()) goto LEAVE; + if (turn_on_heaters() != G26_OK) goto LEAVE; current_position[E_AXIS] = 0.0; sync_plan_position_e(); - if (g26_prime_flag && prime_nozzle()) goto LEAVE; + if (g26_prime_flag && prime_nozzle() != G26_OK) goto LEAVE; /** * Bed is preheated diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index f39a764e6..7c3178192 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -457,10 +457,6 @@ void report_current_position(); // Handling multiple extruders pins extern uint8_t active_extruder; -#if HAS_TEMP_HOTEND || HAS_TEMP_BED - void print_heaterstates(); -#endif - #if ENABLED(MIXING_EXTRUDER) extern float mixing_factor[MIXING_STEPPERS]; #endif diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index a81219434..928b721b1 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -519,7 +519,7 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL #define BUZZ(d,f) NOOP #endif -static uint8_t target_extruder; +uint8_t target_extruder; #if HAS_BED_PROBE float zprobe_zoffset; // Initialized by settings.load() @@ -7570,80 +7570,6 @@ inline void gcode_M104() { #endif } -#if HAS_TEMP_HOTEND || HAS_TEMP_BED - - void print_heater_state(const float &c, const float &t, - #if ENABLED(SHOW_TEMP_ADC_VALUES) - const float r, - #endif - const int8_t e=-2 - ) { - #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1 - UNUSED(e); - #endif - - SERIAL_PROTOCOLCHAR(' '); - SERIAL_PROTOCOLCHAR( - #if HAS_TEMP_BED && HAS_TEMP_HOTEND - e == -1 ? 'B' : 'T' - #elif HAS_TEMP_HOTEND - 'T' - #else - 'B' - #endif - ); - #if HOTENDS > 1 - if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); - #endif - SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL(c); - SERIAL_PROTOCOLPAIR(" /" , t); - #if ENABLED(SHOW_TEMP_ADC_VALUES) - SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); - SERIAL_PROTOCOLCHAR(')'); - #endif - } - - void print_heaterstates() { - #if HAS_TEMP_HOTEND - print_heater_state(thermalManager.degHotend(target_extruder), thermalManager.degTargetHotend(target_extruder) - #if ENABLED(SHOW_TEMP_ADC_VALUES) - , thermalManager.rawHotendTemp(target_extruder) - #endif - ); - #endif - #if HAS_TEMP_BED - print_heater_state(thermalManager.degBed(), thermalManager.degTargetBed(), - #if ENABLED(SHOW_TEMP_ADC_VALUES) - thermalManager.rawBedTemp(), - #endif - -1 // BED - ); - #endif - #if HOTENDS > 1 - HOTEND_LOOP() print_heater_state(thermalManager.degHotend(e), thermalManager.degTargetHotend(e), - #if ENABLED(SHOW_TEMP_ADC_VALUES) - thermalManager.rawHotendTemp(e), - #endif - e - ); - #endif - SERIAL_PROTOCOLPGM(" @:"); - SERIAL_PROTOCOL(thermalManager.getHeaterPower(target_extruder)); - #if HAS_TEMP_BED - SERIAL_PROTOCOLPGM(" B@:"); - SERIAL_PROTOCOL(thermalManager.getHeaterPower(-1)); - #endif - #if HOTENDS > 1 - HOTEND_LOOP() { - SERIAL_PROTOCOLPAIR(" @", e); - SERIAL_PROTOCOLCHAR(':'); - SERIAL_PROTOCOL(thermalManager.getHeaterPower(e)); - } - #endif - } -#endif - /** * M105: Read hot end and bed temperature */ @@ -7652,7 +7578,7 @@ inline void gcode_M105() { #if HAS_TEMP_HOTEND || HAS_TEMP_BED SERIAL_PROTOCOLPGM(MSG_OK); - print_heaterstates(); + thermalManager.print_heaterstates(); #else // !HAS_TEMP_HOTEND && !HAS_TEMP_BED SERIAL_ERROR_START(); SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS); @@ -7663,26 +7589,12 @@ inline void gcode_M105() { #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) - static uint8_t auto_report_temp_interval; - static millis_t next_temp_report_ms; - /** * M155: Set temperature auto-report interval. M155 S */ inline void gcode_M155() { - if (parser.seenval('S')) { - auto_report_temp_interval = parser.value_byte(); - NOMORE(auto_report_temp_interval, 60); - next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; - } - } - - inline void auto_report_temperatures() { - if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) { - next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; - print_heaterstates(); - SERIAL_EOL(); - } + if (parser.seenval('S')) + thermalManager.set_auto_report_interval(parser.value_byte()); } #endif // AUTO_REPORT_TEMPERATURES @@ -7851,7 +7763,7 @@ inline void gcode_M109() { now = millis(); if (ELAPSED(now, next_temp_ms)) { //Print temp & remaining time every 1s while waiting next_temp_ms = now + 1000UL; - print_heaterstates(); + thermalManager.print_heaterstates(); #if TEMP_RESIDENCY_TIME > 0 SERIAL_PROTOCOLPGM(" W:"); if (residency_start_ms) @@ -7988,7 +7900,7 @@ inline void gcode_M109() { now = millis(); if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up. next_temp_ms = now + 1000UL; - print_heaterstates(); + thermalManager.print_heaterstates(); #if TEMP_BED_RESIDENCY_TIME > 0 SERIAL_PROTOCOLPGM(" W:"); if (residency_start_ms) @@ -9917,7 +9829,7 @@ inline void gcode_M502() { * M503: print settings currently in memory */ inline void gcode_M503() { - (void)settings.report(parser.boolval('S')); + (void)settings.report(parser.seen('S') && !parser.value_bool()); } #endif @@ -13672,7 +13584,7 @@ void idle( host_keepalive(); #if ENABLED(AUTO_REPORT_TEMPERATURES) && (HAS_TEMP_HOTEND || HAS_TEMP_BED) - auto_report_temperatures(); + thermalManager.auto_report_temperatures(); #endif manage_inactivity( diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h index 72bdf8dd0..446aa2086 100644 --- a/Marlin/SanityCheck.h +++ b/Marlin/SanityCheck.h @@ -298,11 +298,15 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, #if ENABLED(LCD_PROGRESS_BAR) #if DISABLED(SDSUPPORT) #error "LCD_PROGRESS_BAR requires SDSUPPORT." + #elif DISABLED(ULTRA_LCD) + #error "LCD_PROGRESS_BAR requires a character LCD." #elif ENABLED(DOGLCD) #error "LCD_PROGRESS_BAR does not apply to graphical displays." #elif ENABLED(FILAMENT_LCD_DISPLAY) #error "LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both." #endif +#elif ENABLED(LCD_SET_PROGRESS_MANUALLY) && DISABLED(DOGLCD) + #error "LCD_SET_PROGRESS_MANUALLY requires LCD_PROGRESS_BAR or Graphical LCD." #endif /** diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 7beba4510..364f3532e 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -1547,7 +1547,7 @@ void MarlinSettings::reset() { * * Unless specifically disabled, M503 is available even without EEPROM */ - void MarlinSettings::report(bool forReplay) { + void MarlinSettings::report(const bool forReplay) { /** * Announce current units, in case inches are being displayed diff --git a/Marlin/configuration_store.h b/Marlin/configuration_store.h index 99e951120..b20a8d488 100644 --- a/Marlin/configuration_store.h +++ b/Marlin/configuration_store.h @@ -52,10 +52,10 @@ class MarlinSettings { #endif #if DISABLED(DISABLE_M503) - static void report(bool forReplay=false); + static void report(const bool forReplay=false); #else FORCE_INLINE - static void report(bool forReplay=false) { UNUSED(forReplay); } + static void report(const bool forReplay=false) { UNUSED(forReplay); } #endif private: diff --git a/Marlin/language_en.h b/Marlin/language_en.h index 69d40d1ad..879a6fa01 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -813,8 +813,8 @@ #ifndef MSG_DELTA_HEIGHT_CALIBRATE #define MSG_DELTA_HEIGHT_CALIBRATE _UxGT("Set Delta Height") #endif -#ifndef MSG_DELTA_DIAG_ROG - #define MSG_DELTA_DIAG_ROG _UxGT("Diag Rod") +#ifndef MSG_DELTA_DIAG_ROD + #define MSG_DELTA_DIAG_ROD _UxGT("Diag Rod") #endif #ifndef MSG_DELTA_HEIGHT #define MSG_DELTA_HEIGHT _UxGT("Height") diff --git a/Marlin/pins_MELZI_CREALITY.h b/Marlin/pins_MELZI_CREALITY.h index 477a9b8e0..02f849110 100644 --- a/Marlin/pins_MELZI_CREALITY.h +++ b/Marlin/pins_MELZI_CREALITY.h @@ -60,7 +60,7 @@ #define ST7920_DELAY_3 DELAY_2_NOP #if ENABLED(MINIPANEL) - #undef DOGLCD_CS + #undef DOGLCD_CS #define DOGLCD_CS LCD_PINS_RS #endif diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 1b893b158..39715c0cf 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -124,15 +124,20 @@ float Planner::min_feedrate_mm_s, Planner::inverse_z_fade_height, Planner::last_fade_z; #endif +#else + constexpr bool Planner::leveling_active; #endif #if ENABLED(SKEW_CORRECTION) #if ENABLED(SKEW_CORRECTION_GCODE) - // Initialized by settings.load() float Planner::xy_skew_factor; - #if ENABLED(SKEW_CORRECTION_FOR_Z) - float Planner::xz_skew_factor, Planner::yz_skew_factor; - #endif + #else + constexpr float Planner::xy_skew_factor; + #endif + #if ENABLED(SKEW_CORRECTION_FOR_Z) && ENABLED(SKEW_CORRECTION_GCODE) + float Planner::xz_skew_factor, Planner::yz_skew_factor; + #else + constexpr float Planner::xz_skew_factor, Planner::yz_skew_factor; #endif #endif diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index e085206ef..a74c317e8 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -83,7 +83,7 @@ block_t* Stepper::current_block = NULL; // A pointer to the block currently bei // private: uint8_t Stepper::last_direction_bits = 0; // The next stepping-bits to be output -uint16_t Stepper::cleaning_buffer_counter = 0; +int16_t Stepper::cleaning_buffer_counter = 0; #if ENABLED(X_DUAL_ENDSTOPS) bool Stepper::locked_x_motor = false, Stepper::locked_x2_motor = false; @@ -381,8 +381,8 @@ void Stepper::isr() { uint16_t ocr_val; - #define ENDSTOP_NOMINAL_OCR_VAL 3000 // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch - #define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms + #define ENDSTOP_NOMINAL_OCR_VAL 3000 // Check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch + #define OCR_VAL_TOLERANCE 1000 // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms #if DISABLED(LIN_ADVANCE) // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars) @@ -393,9 +393,13 @@ void Stepper::isr() { #define _SPLIT(L) (ocr_val = (uint16_t)L) #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #define SPLIT(L) _SPLIT(L) - #else // sample endstops in between step pulses + + #else // !ENDSTOP_INTERRUPTS_FEATURE : Sample endstops between stepping ISRs + static uint32_t step_remaining = 0; + #define SPLIT(L) do { \ _SPLIT(L); \ if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \ @@ -407,33 +411,34 @@ void Stepper::isr() { if (step_remaining && ENDSTOPS_ENABLED) { // Just check endstops - not yet time for a step endstops.update(); - if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) { - step_remaining -= ENDSTOP_NOMINAL_OCR_VAL; - ocr_val = ENDSTOP_NOMINAL_OCR_VAL; - } - else { - ocr_val = step_remaining; - step_remaining = 0; // last one before the ISR that does the step - } + // Next ISR either for endstops or stepping + ocr_val = step_remaining <= ENDSTOP_NOMINAL_OCR_VAL ? step_remaining : ENDSTOP_NOMINAL_OCR_VAL; + step_remaining -= ocr_val; _NEXT_ISR(ocr_val); - NOLESS(OCR1A, TCNT1 + 16); - _ENABLE_ISRs(); // re-enable ISRs return; } - #endif + #endif // !ENDSTOP_INTERRUPTS_FEATURE + + // + // When cleaning, discard the current block and run fast + // if (cleaning_buffer_counter) { - --cleaning_buffer_counter; current_block = NULL; planner.discard_current_block(); - #ifdef SD_FINISHED_RELEASECOMMAND - if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); - #endif - _NEXT_ISR(200); // Run at max speed - 10 KHz - _ENABLE_ISRs(); // re-enable ISRs + if (cleaning_buffer_counter < 0) + ++cleaning_buffer_counter; // Count up for endstop hit + else { + --cleaning_buffer_counter; // Count down for abort print + #ifdef SD_FINISHED_RELEASECOMMAND + if (!cleaning_buffer_counter && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND)); + #endif + } + _NEXT_ISR(200); // Run at max speed - 10 KHz + _ENABLE_ISRs(); return; } diff --git a/Marlin/stepper.h b/Marlin/stepper.h index 7724eed14..a19810376 100644 --- a/Marlin/stepper.h +++ b/Marlin/stepper.h @@ -104,7 +104,7 @@ class Stepper { private: static uint8_t last_direction_bits; // The next stepping-bits to be output - static uint16_t cleaning_buffer_counter; + static int16_t cleaning_buffer_counter; #if ENABLED(X_DUAL_ENDSTOPS) static bool locked_x_motor, locked_x2_motor; diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index efc8e8199..8a0786e06 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -1273,7 +1273,7 @@ void Temperature::init() { * their target temperature by a configurable margin. * This is called when the temperature is set. (M104, M109) */ - void Temperature::start_watching_heater(uint8_t e) { + void Temperature::start_watching_heater(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -2186,3 +2186,95 @@ void Temperature::isr() { in_temp_isr = false; SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR } + +#if HAS_TEMP_HOTEND || HAS_TEMP_BED + + void print_heater_state(const float &c, const float &t, + #if ENABLED(SHOW_TEMP_ADC_VALUES) + const float r, + #endif + const int8_t e=-2 + ) { + #if !(HAS_TEMP_BED && HAS_TEMP_HOTEND) && HOTENDS <= 1 + UNUSED(e); + #endif + + SERIAL_PROTOCOLCHAR(' '); + SERIAL_PROTOCOLCHAR( + #if HAS_TEMP_BED && HAS_TEMP_HOTEND + e == -1 ? 'B' : 'T' + #elif HAS_TEMP_HOTEND + 'T' + #else + 'B' + #endif + ); + #if HOTENDS > 1 + if (e >= 0) SERIAL_PROTOCOLCHAR('0' + e); + #endif + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(c); + SERIAL_PROTOCOLPAIR(" /" , t); + #if ENABLED(SHOW_TEMP_ADC_VALUES) + SERIAL_PROTOCOLPAIR(" (", r / OVERSAMPLENR); + SERIAL_PROTOCOLCHAR(')'); + #endif + } + + extern uint8_t target_extruder; + + void Temperature::print_heaterstates() { + #if HAS_TEMP_HOTEND + print_heater_state(degHotend(target_extruder), degTargetHotend(target_extruder) + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , rawHotendTemp(target_extruder) + #endif + ); + #endif + #if HAS_TEMP_BED + print_heater_state(degBed(), degTargetBed() + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , rawBedTemp() + #endif + , -1 // BED + ); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() print_heater_state(degHotend(e), degTargetHotend(e) + #if ENABLED(SHOW_TEMP_ADC_VALUES) + , rawHotendTemp(e) + #endif + , e + ); + #endif + SERIAL_PROTOCOLPGM(" @:"); + SERIAL_PROTOCOL(getHeaterPower(target_extruder)); + #if HAS_TEMP_BED + SERIAL_PROTOCOLPGM(" B@:"); + SERIAL_PROTOCOL(getHeaterPower(-1)); + #endif + #if HOTENDS > 1 + HOTEND_LOOP() { + SERIAL_PROTOCOLPAIR(" @", e); + SERIAL_PROTOCOLCHAR(':'); + SERIAL_PROTOCOL(getHeaterPower(e)); + } + #endif + } + + #if ENABLED(AUTO_REPORT_TEMPERATURES) + + uint8_t Temperature::auto_report_temp_interval; + millis_t Temperature::next_temp_report_ms; + + void Temperature::auto_report_temperatures() { + if (auto_report_temp_interval && ELAPSED(millis(), next_temp_report_ms)) { + next_temp_report_ms = millis() + 1000UL * auto_report_temp_interval; + print_heaterstates(); + SERIAL_EOL(); + } + } + + #endif // AUTO_REPORT_TEMPERATURES + +#endif // HAS_TEMP_HOTEND || HAS_TEMP_BED diff --git a/Marlin/temperature.h b/Marlin/temperature.h index 03fecb08a..f67c7d83d 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -370,14 +370,14 @@ class Temperature { static int16_t degTargetBed() { return target_temperature_bed; } #if WATCH_HOTENDS - static void start_watching_heater(uint8_t e = 0); + static void start_watching_heater(const uint8_t e = 0); #endif #if WATCH_THE_BED static void start_watching_bed(); #endif - static void setTargetHotend(const int16_t celsius, uint8_t e) { + static void setTargetHotend(const int16_t celsius, const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -455,7 +455,7 @@ class Temperature { #if ENABLED(BABYSTEPPING) - static void babystep_axis(const AxisEnum axis, const int distance) { + static void babystep_axis(const AxisEnum axis, const int16_t distance) { if (axis_known_position[axis]) { #if IS_CORE #if ENABLED(BABYSTEP_XY) @@ -539,6 +539,20 @@ class Temperature { #endif #endif + #if HAS_TEMP_HOTEND || HAS_TEMP_BED + static void print_heaterstates(); + #if ENABLED(AUTO_REPORT_TEMPERATURES) + static uint8_t auto_report_temp_interval; + static millis_t next_temp_report_ms; + static void auto_report_temperatures(void); + FORCE_INLINE void set_auto_report_interval(uint8_t v) { + NOMORE(v, 60); + auto_report_temp_interval = v; + next_temp_report_ms = millis() + 1000UL * v; + } + #endif + #endif + private: static void set_current_temp_raw(); diff --git a/Marlin/ubl.h b/Marlin/ubl.h index 2b73d3cfd..ba76ace42 100644 --- a/Marlin/ubl.h +++ b/Marlin/ubl.h @@ -81,19 +81,23 @@ static int g29_grid_size; #endif - static float measure_point_with_encoder(); - static float measure_business_card_thickness(float); + #if ENABLED(NEWPANEL) + static void move_z_with_encoder(const float &multiplier); + static float measure_point_with_encoder(); + static float measure_business_card_thickness(const float&); + static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool); + static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map); + #endif + static bool g29_parameter_parsing(); static void find_mean_mesh_height(); static void shift_mesh_height(); static void probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest); - static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool); static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3); static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map); static void g29_what_command(); static void g29_eeprom_dump(); static void g29_compare_current_mesh_to_stored_mesh(); - static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map); static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir); static void smart_fill_mesh(); diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index d02da79bf..0acc398ff 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -24,6 +24,8 @@ #if ENABLED(AUTO_BED_LEVELING_UBL) + //#define UBL_DEVEL_DEBUGGING + #include "ubl.h" #include "Marlin.h" #include "hex_print_routines.h" @@ -43,7 +45,7 @@ #if ENABLED(NEWPANEL) void lcd_return_to_status(); - void lcd_mesh_edit_setup(float initial); + void lcd_mesh_edit_setup(const float initial); float lcd_mesh_edit(); void lcd_z_offset_edit_setup(float); extern void _lcd_ubl_output_map_lcd(); @@ -55,8 +57,9 @@ extern float probe_pt(const float &rx, const float &ry, const bool, const uint8_t, const bool=true); extern bool set_probe_deployed(bool); extern void set_bed_leveling_enabled(bool); + typedef void (*screenFunc_t)(); - extern void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder = 0); + extern void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder=0); #define SIZE_OF_LITTLE_RAISE 1 #define BIG_RAISE_NOT_NEEDED 0 @@ -642,8 +645,8 @@ SERIAL_ECHOPAIR(" J ", y); SERIAL_ECHOPGM(" Z "); SERIAL_ECHO_F(z_values[x][y], 6); - SERIAL_ECHOPAIR(" ; X ", mesh_index_to_xpos(x)); - SERIAL_ECHOPAIR(", Y ", mesh_index_to_ypos(y)); + SERIAL_ECHOPAIR(" ; X ", LOGICAL_X_POSITION(mesh_index_to_xpos(x))); + SERIAL_ECHOPAIR(", Y ", LOGICAL_Y_POSITION(mesh_index_to_ypos(y))); SERIAL_EOL(); } return; @@ -728,6 +731,30 @@ z_values[x][y] += g29_constant; } + #if ENABLED(NEWPANEL) + + typedef void (*clickFunc_t)(); + + bool click_and_hold(const clickFunc_t func=NULL) { + if (is_lcd_clicked()) { + lcd_quick_feedback(); + const millis_t nxt = millis() + 1500UL; + while (is_lcd_clicked()) { // Loop while the encoder is pressed. Uses hardware flag! + idle(); // idle, of course + if (ELAPSED(millis(), nxt)) { // After 1.5 seconds + lcd_quick_feedback(); + if (func) (*func)(); + wait_for_release(); + safe_delay(50); // Debounce the Encoder wheel + return true; + } + } + } + return false; + } + + #endif // NEWPANEL + #if HAS_BED_PROBE /** * Probe all invalidated locations of the mesh that can be reached by the probe. @@ -753,10 +780,9 @@ SERIAL_PROTOCOLLNPGM("\nMesh only partially populated.\n"); lcd_quick_feedback(); STOW_PROBE(); - while (is_lcd_clicked()) idle(); + wait_for_release(); lcd_external_control = false; restore_ubl_active_state_and_leave(); - safe_delay(50); // Debounce the Encoder wheel return; } #endif @@ -774,7 +800,6 @@ z_values[location.x_index][location.y_index] = measured_z; } - } while (location.x_index >= 0 && --max_iterations); STOW_PROBE(); @@ -889,30 +914,32 @@ } } } + #endif // HAS_BED_PROBE #if ENABLED(NEWPANEL) - float unified_bed_leveling::measure_point_with_encoder() { - - while (is_lcd_clicked()) delay(50); // wait for user to release encoder wheel - delay(50); // debounce - - KEEPALIVE_STATE(PAUSED_FOR_USER); - while (!is_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here! + void unified_bed_leveling::move_z_with_encoder(const float &multiplier) { + wait_for_release(); + while (!is_lcd_clicked()) { idle(); if (encoder_diff) { - do_blocking_move_to_z(current_position[Z_AXIS] + 0.01 * float(encoder_diff)); + do_blocking_move_to_z(current_position[Z_AXIS] + float(encoder_diff) * multiplier); encoder_diff = 0; } } + } + + float unified_bed_leveling::measure_point_with_encoder() { + KEEPALIVE_STATE(PAUSED_FOR_USER); + move_z_with_encoder(0.01); KEEPALIVE_STATE(IN_HANDLER); return current_position[Z_AXIS]; } static void echo_and_take_a_measurement() { SERIAL_PROTOCOLLNPGM(" and take a measurement."); } - float unified_bed_leveling::measure_business_card_thickness(float in_height) { + float unified_bed_leveling::measure_business_card_thickness(const float &in_height) { lcd_external_control = true; save_ubl_active_state_and_disable(); // Disable bed level correction for probing @@ -945,8 +972,6 @@ SERIAL_PROTOCOLLNPGM("mm thick."); } - in_height = current_position[Z_AXIS]; // do manual probing at lower height - lcd_external_control = false; restore_ubl_active_state_and_leave(); @@ -954,6 +979,14 @@ return thickness; } + void abort_manual_probe_remaining_mesh() { + SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + lcd_external_control = false; + KEEPALIVE_STATE(IN_HANDLER); + ubl.restore_ubl_active_state_and_leave(); + } + void unified_bed_leveling::manually_probe_remaining_mesh(const float &rx, const float &ry, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) { lcd_external_control = true; @@ -989,36 +1022,15 @@ const float z_step = 0.01; // existing behavior: 0.01mm per click, occasionally step //const float z_step = 1.0 / planner.axis_steps_per_mm[Z_AXIS]; // approx one step each click - while (is_lcd_clicked()) delay(50); // wait for user to release encoder wheel - delay(50); // debounce - while (!is_lcd_clicked()) { // we need the loop to move the nozzle based on the encoder wheel here! - idle(); - if (encoder_diff) { - do_blocking_move_to_z(current_position[Z_AXIS] + float(encoder_diff) * z_step); - encoder_diff = 0; - } - } + move_z_with_encoder(z_step); - // this sequence to detect an is_lcd_clicked() debounce it and leave if it is - // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This - // should be redone and compressed. - const millis_t nxt = millis() + 1500L; - while (is_lcd_clicked()) { // debounce and watch for abort - idle(); - if (ELAPSED(millis(), nxt)) { - SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); - do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); - - #if ENABLED(NEWPANEL) - lcd_quick_feedback(); - while (is_lcd_clicked()) idle(); - lcd_external_control = false; - #endif - - KEEPALIVE_STATE(IN_HANDLER); - restore_ubl_active_state_and_leave(); - return; - } + if (click_and_hold()) { + SERIAL_PROTOCOLLNPGM("\nMesh only partially populated."); + do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); + lcd_external_control = false; + KEEPALIVE_STATE(IN_HANDLER); + restore_ubl_active_state_and_leave(); + return; } z_values[location.x_index][location.y_index] = current_position[Z_AXIS] - thick; @@ -1152,36 +1164,39 @@ return UBL_OK; } - static int ubl_state_at_invocation = 0, - ubl_state_recursion_chk = 0; + static uint8_t ubl_state_at_invocation = 0; - void unified_bed_leveling::save_ubl_active_state_and_disable() { - ubl_state_recursion_chk++; - if (ubl_state_recursion_chk != 1) { - SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); - - #if ENABLED(NEWPANEL) - LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); - lcd_quick_feedback(); - #endif + #ifdef UBL_DEVEL_DEBUGGING + static uint8_t ubl_state_recursion_chk = 0; + #endif - return; - } + void unified_bed_leveling::save_ubl_active_state_and_disable() { + #ifdef UBL_DEVEL_DEBUGGING + ubl_state_recursion_chk++; + if (ubl_state_recursion_chk != 1) { + SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); + #if ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_SAVE_ERROR); + lcd_quick_feedback(); + #endif + return; + } + #endif ubl_state_at_invocation = planner.leveling_active; set_bed_leveling_enabled(false); } void unified_bed_leveling::restore_ubl_active_state_and_leave() { - if (--ubl_state_recursion_chk) { - SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); - - #if ENABLED(NEWPANEL) - LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); - lcd_quick_feedback(); - #endif - - return; - } + #ifdef UBL_DEVEL_DEBUGGING + if (--ubl_state_recursion_chk) { + SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); + #if ENABLED(NEWPANEL) + LCD_MESSAGEPGM(MSG_UBL_RESTORE_ERROR); + lcd_quick_feedback(); + #endif + return; + } + #endif set_bed_leveling_enabled(ubl_state_at_invocation); } @@ -1253,28 +1268,30 @@ SERIAL_EOL(); safe_delay(50); - SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation); - SERIAL_EOL(); - SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk); - SERIAL_EOL(); - safe_delay(50); + #ifdef UBL_DEVEL_DEBUGGING + SERIAL_PROTOCOLLNPAIR("ubl_state_at_invocation :", ubl_state_at_invocation); + SERIAL_EOL(); + SERIAL_PROTOCOLLNPAIR("ubl_state_recursion_chk :", ubl_state_recursion_chk); + SERIAL_EOL(); + safe_delay(50); - SERIAL_PROTOCOLPAIR("Meshes go from ", hex_address((void*)settings.get_start_of_meshes())); - SERIAL_PROTOCOLLNPAIR(" to ", hex_address((void*)settings.get_end_of_meshes())); - safe_delay(50); + SERIAL_PROTOCOLPAIR("Meshes go from ", hex_address((void*)settings.get_start_of_meshes())); + SERIAL_PROTOCOLLNPAIR(" to ", hex_address((void*)settings.get_end_of_meshes())); + safe_delay(50); - SERIAL_PROTOCOLLNPAIR("sizeof(ubl) : ", (int)sizeof(ubl)); - SERIAL_EOL(); - SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values)); - SERIAL_EOL(); - safe_delay(25); + SERIAL_PROTOCOLLNPAIR("sizeof(ubl) : ", (int)sizeof(ubl)); + SERIAL_EOL(); + SERIAL_PROTOCOLLNPAIR("z_value[][] size: ", (int)sizeof(z_values)); + SERIAL_EOL(); + safe_delay(25); - SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.get_end_of_meshes() - settings.get_start_of_meshes()))); - safe_delay(50); + SERIAL_PROTOCOLLNPAIR("EEPROM free for UBL: ", hex_address((void*)(settings.get_end_of_meshes() - settings.get_start_of_meshes()))); + safe_delay(50); - SERIAL_PROTOCOLPAIR("EEPROM can hold ", settings.calc_num_meshes()); - SERIAL_PROTOCOLLNPGM(" meshes.\n"); - safe_delay(25); + SERIAL_PROTOCOLPAIR("EEPROM can hold ", settings.calc_num_meshes()); + SERIAL_PROTOCOLLNPGM(" meshes.\n"); + safe_delay(25); + #endif // UBL_DEVEL_DEBUGGING if (!sanity_check()) { echo_name(); @@ -1344,11 +1361,10 @@ z_values[x][y] -= tmp_z_values[x][y]; } - mesh_index_pair unified_bed_leveling::find_furthest_invalid_mesh_point() { - bool found_a_NAN = false; - bool found_a_real = false; + bool found_a_NAN = false, found_a_real = false; + mesh_index_pair out_mesh; out_mesh.x_index = out_mesh.y_index = -1; out_mesh.distance = -99999.99; @@ -1356,12 +1372,12 @@ for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) { for (int8_t j = 0; j < GRID_MAX_POINTS_Y; j++) { - if ( isnan(z_values[i][j])) { // Check to see if this location holds an invalid mesh point + if (isnan(z_values[i][j])) { // Check to see if this location holds an invalid mesh point const float mx = mesh_index_to_xpos(i), my = mesh_index_to_ypos(j); - if ( !position_is_reachable_by_probe(mx, my)) // make sure the probe can get to the mesh point + if (!position_is_reachable_by_probe(mx, my)) // make sure the probe can get to the mesh point continue; found_a_NAN = true; @@ -1443,10 +1459,9 @@ float distance = HYPOT(px - mx, py - my); - // factor in the distance from the current location for the normal case - // so the nozzle isn't running all over the bed. - distance += HYPOT(current_position[X_AXIS] - mx, current_position[Y_AXIS] - my) * 0.1; - + // factor in the distance from the current location for the normal case + // so the nozzle isn't running all over the bed. + distance += HYPOT(current_position[X_AXIS] - mx, current_position[Y_AXIS] - my) * 0.1; if (distance < best_so_far) { best_so_far = distance; // We found a closer location with out_mesh.x_index = i; // the specified type of mesh value. @@ -1462,6 +1477,12 @@ #if ENABLED(NEWPANEL) + void abort_fine_tune() { + lcd_return_to_status(); + do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + LCD_MESSAGEPGM(MSG_EDITING_STOPPED); + } + void unified_bed_leveling::fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) { if (!parser.seen('R')) // fine_tune_mesh() is special. If no repetition count flag is specified g29_repetition_cnt = 1; // do exactly one mesh location. Otherwise use what the parser decided. @@ -1495,8 +1516,8 @@ if (location.x_index < 0) break; // stop when we can't find any more reachable points. - bitmap_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a - // different location the next time through the loop + bitmap_clear(not_done, location.x_index, location.y_index); // Mark this location as 'adjusted' so we will find a + // different location the next time through the loop const float rawx = mesh_index_to_xpos(location.x_index), rawy = mesh_index_to_ypos(location.y_index); @@ -1504,15 +1525,8 @@ if (!position_is_reachable(rawx, rawy)) // SHOULD NOT OCCUR because find_closest_mesh_point_of_type will only return reachable break; - float new_z = z_values[location.x_index][location.y_index]; - - if (isnan(new_z)) // if the mesh point is invalid, set it to 0.0 so it can be edited - new_z = 0.0; - do_blocking_move_to(rawx, rawy, Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to the edit point - new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place - KEEPALIVE_STATE(PAUSED_FOR_USER); lcd_external_control = true; @@ -1520,15 +1534,19 @@ lcd_refresh(); + float new_z = z_values[location.x_index][location.y_index]; + if (isnan(new_z)) new_z = 0.0; // Set invalid mesh points to 0.0 so they can be edited + new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place + lcd_mesh_edit_setup(new_z); - do { + while (!is_lcd_clicked()) { new_z = lcd_mesh_edit(); #if ENABLED(UBL_MESH_EDIT_MOVES_Z) do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited #endif idle(); - } while (!is_lcd_clicked()); + } if (!lcd_map_control) lcd_return_to_status(); @@ -1540,19 +1558,8 @@ // this sequence to detect an is_lcd_clicked() debounce it and leave if it is // a Press and Hold is repeated in a lot of places (including G26_Mesh_Validation.cpp). This // should be redone and compressed. - const millis_t nxt = millis() + 1500UL; - while (is_lcd_clicked()) { // debounce and watch for abort - idle(); - if (ELAPSED(millis(), nxt)) { - lcd_return_to_status(); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - LCD_MESSAGEPGM(MSG_EDITING_STOPPED); - - while (is_lcd_clicked()) idle(); - - goto FINE_TUNE_EXIT; - } - } + if (click_and_hold(abort_fine_tune)) + goto FINE_TUNE_EXIT; safe_delay(20); // We don't want any switch noise. diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 6a1c0e8da..3add5adae 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -57,16 +57,12 @@ #endif #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) - bool lcd_external_control; + bool lcd_external_control; // = false #endif // Initialized by settings.load() int16_t lcd_preheat_hotend_temp[2], lcd_preheat_bed_temp[2], lcd_preheat_fan_speed[2]; -#if ENABLED(LCD_SET_PROGRESS_MANUALLY) && (ENABLED(LCD_PROGRESS_BAR) || ENABLED(DOGLCD)) - uint8_t progress_bar_percent; -#endif - #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) millis_t previous_lcd_status_ms = 0; #endif @@ -92,6 +88,10 @@ char lcd_status_message[3 * (LCD_WIDTH) + 1] = WELCOME_MSG; // worst case is kan uint8_t filename_scroll_pos, filename_scroll_max, filename_scroll_hash; #endif +#if ENABLED(LCD_SET_PROGRESS_MANUALLY) + uint8_t progress_bar_percent; +#endif + #if ENABLED(DOGLCD) #include "ultralcd_impl_DOGM.h" #include @@ -259,10 +259,6 @@ uint16_t max_display_update_time = 0; //////////// Menu System Macros //////////// //////////////////////////////////////////// - #ifndef ENCODER_FEEDRATE_DEADZONE - #define ENCODER_FEEDRATE_DEADZONE 6 - #endif - /** * MENU_ITEM generates draw & handler code for a menu item, potentially calling: * @@ -734,7 +730,7 @@ void kill_screen(const char* lcd_msg) { * Audio feedback for controller clicks * */ - void lcd_buzz(long duration, uint16_t freq) { + void lcd_buzz(const long duration, const uint16_t freq) { #if ENABLED(LCD_USE_I2C_BUZZER) lcd.buzz(duration, freq); #elif PIN_EXISTS(BEEPER) @@ -1180,7 +1176,7 @@ void kill_screen(const char* lcd_msg) { return mesh_edit_value; } - void lcd_mesh_edit_setup(float initial) { + void lcd_mesh_edit_setup(const float initial) { mesh_edit_value = mesh_edit_accumulator = initial; lcd_goto_screen(_lcd_mesh_edit_NOP); } @@ -1332,9 +1328,9 @@ void kill_screen(const char* lcd_msg) { #if FAN_COUNT > 0 #if HAS_FAN0 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED FAN_SPEED_1_SUFFIX, &fanSpeeds[0], 0, 255); - #if ENABLED(EXTRA_FAN_SPEED) + #if ENABLED(EXTRA_FAN_SPEED) MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_EXTRA_FAN_SPEED FAN_SPEED_1_SUFFIX, &new_fanSpeeds[0], 3, 255); - #endif + #endif #endif #if HAS_FAN1 MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED " 2", &fanSpeeds[1], 0, 255); @@ -1836,7 +1832,6 @@ void kill_screen(const char* lcd_msg) { /** * Step 6: Display "Next point: 1 / 9" while waiting for move to finish */ - void _lcd_level_bed_moving() { if (lcdDrawUpdate) { char msg[10]; @@ -2306,11 +2301,12 @@ void kill_screen(const char* lcd_msg) { void _lcd_ubl_map_homing() { defer_return_to_status = true; - ubl.lcd_map_control = true; // Return to the map screen if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT < 3 ? 0 : (LCD_HEIGHT > 4 ? 2 : 1), PSTR(MSG_LEVEL_BED_HOMING)); lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW; - if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) + if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) { + ubl.lcd_map_control = true; // Return to the map screen lcd_goto_screen(_lcd_ubl_output_map_lcd); + } } /** @@ -2648,7 +2644,7 @@ void kill_screen(const char* lcd_msg) { void lcd_move_z(); - void _man_probe_pt(const float rx, const float ry) { + void _man_probe_pt(const float &rx, const float &ry) { #if HAS_LEVELING reset_bed_level(); // After calibration bed-level data is no longer valid #endif @@ -2711,7 +2707,7 @@ void kill_screen(const char* lcd_msg) { void lcd_delta_settings() { START_MENU(); MENU_BACK(MSG_DELTA_CALIBRATE); - MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_DIAG_ROG, &delta_diagonal_rod, delta_diagonal_rod - 5.0, delta_diagonal_rod + 5.0, recalc_delta_settings); + MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_DIAG_ROD, &delta_diagonal_rod, delta_diagonal_rod - 5.0, delta_diagonal_rod + 5.0, recalc_delta_settings); MENU_ITEM_EDIT_CALLBACK(float52, MSG_DELTA_HEIGHT, &delta_height, delta_height - 10.0, delta_height + 10.0, recalc_delta_settings); MENU_ITEM_EDIT_CALLBACK(float43, "Ex", &delta_endstop_adj[A_AXIS], -5.0, 5.0, recalc_delta_settings); MENU_ITEM_EDIT_CALLBACK(float43, "Ey", &delta_endstop_adj[B_AXIS], -5.0, 5.0, recalc_delta_settings); @@ -2784,10 +2780,7 @@ void kill_screen(const char* lcd_msg) { manual_move_offset = 0.0; manual_move_axis = (int8_t)NO_AXIS; - // DELTA and SCARA machines use segmented moves, which could fill the planner during the call to - // move_to_destination. This will cause idle() to be called, which can then call this function while the - // previous invocation is being blocked. Modifications to manual_move_offset shouldn't be made while - // processing_manual_move is true or the planner will get out of sync. + // Set a blocking flag so no new moves can be added until all segments are done processing_manual_move = true; prepare_move_to_destination(); // will call set_current_from_destination() processing_manual_move = false; @@ -2867,7 +2860,6 @@ void kill_screen(const char* lcd_msg) { #if ENABLED(MAX_SOFTWARE_ENDSTOP_Z) max = soft_endstop_max[Z_AXIS]; #endif - break; default: break; } #endif // MIN_SOFTWARE_ENDSTOPS || MAX_SOFTWARE_ENDSTOPS @@ -3141,7 +3133,7 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM(submenu, MSG_FILAMENT, lcd_control_filament_menu); #if HAS_LCD_CONTRAST - MENU_ITEM_EDIT_CALLBACK(int3, MSG_CONTRAST, (int*)&lcd_contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, lcd_callback_set_contrast, true); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_CONTRAST, &lcd_contrast, LCD_CONTRAST_MIN, LCD_CONTRAST_MAX, lcd_callback_set_contrast, true); #endif #if ENABLED(FWRETRACT) MENU_ITEM(submenu, MSG_RETRACT, lcd_control_retract_menu); @@ -4338,6 +4330,7 @@ void kill_screen(const char* lcd_msg) { } \ typedef void _name + DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01); DEFINE_MENU_EDIT_TYPE(int16_t, int3, itostr3, 1); DEFINE_MENU_EDIT_TYPE(uint8_t, int8, i8tostr3, 1); DEFINE_MENU_EDIT_TYPE(float, float3, ftostr3, 1.0); @@ -4347,7 +4340,6 @@ void kill_screen(const char* lcd_msg) { DEFINE_MENU_EDIT_TYPE(float, float51, ftostr51sign, 10.0); DEFINE_MENU_EDIT_TYPE(float, float52, ftostr52sign, 100.0); DEFINE_MENU_EDIT_TYPE(float, float62, ftostr62rj, 100.0); - DEFINE_MENU_EDIT_TYPE(uint32_t, long5, ftostr5rj, 0.01); /** * @@ -4610,8 +4602,13 @@ void lcd_update() { #if ENABLED(ULTIPANEL) static millis_t return_to_status_ms = 0; + + // Handle any queued Move Axis motion manage_manual_move(); + // Update button states for LCD_CLICKED, etc. + // After state changes the next button update + // may be delayed 300-500ms. lcd_buttons_update(); #if ENABLED(AUTO_BED_LEVELING_UBL) @@ -4946,7 +4943,7 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } #define encrot3 1 #endif - #define GET_BUTTON_STATES(DST) \ + #define GET_SHIFT_BUTTON_STATES(DST) \ uint8_t new_##DST = 0; \ WRITE(SHIFT_LD, LOW); \ WRITE(SHIFT_LD, HIGH); \ @@ -4965,7 +4962,7 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } */ void lcd_buttons_update() { static uint8_t lastEncoderBits; - millis_t now = millis(); + const millis_t now = millis(); if (ELAPSED(now, next_button_update_ms)) { #if ENABLED(NEWPANEL) @@ -5046,13 +5043,15 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } #elif ENABLED(REPRAPWORLD_KEYPAD) - GET_BUTTON_STATES(buttons_reprapworld_keypad); + GET_SHIFT_BUTTON_STATES(buttons_reprapworld_keypad); #endif - #else - GET_BUTTON_STATES(buttons); - #endif // !NEWPANEL + #else // !NEWPANEL + + GET_SHIFT_BUTTON_STATES(buttons); + + #endif } // next_button_update_ms @@ -5111,6 +5110,10 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) bool is_lcd_clicked() { return LCD_CLICKED; } + void wait_for_release() { + while (is_lcd_clicked()) safe_delay(50); + safe_delay(50); + } #endif #endif // ULTIPANEL diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index 69a536a8f..ab2ce15a3 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -23,10 +23,12 @@ #ifndef ULTRALCD_H #define ULTRALCD_H -#include "Marlin.h" +#include "MarlinConfig.h" #if ENABLED(ULTRA_LCD) + #include "Marlin.h" + #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) extern bool lcd_external_control; #if ENABLED(G26_MESH_VALIDATION) @@ -57,7 +59,7 @@ inline void lcd_refresh() { lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; } #if HAS_BUZZER - void lcd_buzz(long duration, uint16_t freq); + void lcd_buzz(const long duration, const uint16_t freq); #endif #if ENABLED(LCD_PROGRESS_BAR) && PROGRESS_MSG_EXPIRE > 0 @@ -176,6 +178,7 @@ #if ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(G26_MESH_VALIDATION) bool is_lcd_clicked(); + void wait_for_release(); #endif #if ENABLED(LCD_SET_PROGRESS_MANUALLY) && (ENABLED(LCD_PROGRESS_BAR) || ENABLED(DOGLCD)) @@ -204,7 +207,7 @@ void lcd_reset_status(); #if ENABLED(AUTO_BED_LEVELING_UBL) - void lcd_mesh_edit_setup(float initial); + void lcd_mesh_edit_setup(const float initial); float lcd_mesh_edit(); void lcd_z_offset_edit_setup(float); float lcd_z_offset_edit();