diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 67015c322..2b45f8133 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -108,7 +108,6 @@ uint16_t max_display_update_time = 0; extern bool powersupply_on; #endif - //////////////////////////////////////////// ///////////////// Menu Tree //////////////// //////////////////////////////////////////// @@ -790,7 +789,7 @@ void kill_screen(const char* lcd_msg) { encoderPosition = 0; lcd_implementation_drawmenu_static(0, PSTR(MSG_PROGRESS_BAR_TEST), true, true); lcd.setCursor((LCD_WIDTH) / 2 - 2, LCD_HEIGHT - 2); - lcd.print(itostr3(bar_percent)); lcd.print('%'); + lcd.print(itostr3(bar_percent)); lcd.write('%'); lcd.setCursor(0, LCD_HEIGHT - 1); lcd_draw_progress_bar(bar_percent); } @@ -2145,8 +2144,12 @@ void kill_screen(const char* lcd_msg) { void _lcd_ubl_map_homing() { if (lcdDrawUpdate) lcd_implementation_drawedit(PSTR(MSG_LEVEL_BED_HOMING), NULL); 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]) { + #if DISABLED(DOGLCD) + lcd_set_ubl_map_plot_chars(); + #endif lcd_goto_screen(_lcd_ubl_output_map_lcd); + } } /** @@ -2163,97 +2166,6 @@ void kill_screen(const char* lcd_msg) { enqueue_and_echo_command(ubl_lcd_gcode); } - #if ENABLED(DOGLCD) - - /** - * UBL LCD "radar" map data - */ - #define MAP_UPPER_LEFT_CORNER_X 35 // These probably should be moved to the .h file But for now, - #define MAP_UPPER_LEFT_CORNER_Y 8 // it is easier to play with things having them here - #define MAP_MAX_PIXELS_X 53 - #define MAP_MAX_PIXELS_Y 49 - - void _lcd_ubl_plot_drawing_prep() { - uint8_t i, j, x_offset, y_offset, x_map_pixels, y_map_pixels, - pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt, inverted_y; - - /*********************************************************/ - /************ Scale the box pixels appropriately *********/ - /*********************************************************/ - x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X); - y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y); - - pixels_per_X_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X); - pixels_per_Y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y); - - x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2; - y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2; - - /*********************************************************/ - /************ Clear the Mesh Map Box**********************/ - /*********************************************************/ - - u8g.setColorIndex(1); // First draw the bigger box in White so we have a border around the mesh map box - u8g.drawBox(x_offset - 2, y_offset - 2, x_map_pixels + 4, y_map_pixels + 4); - - u8g.setColorIndex(0); // Now actually clear the mesh map box - u8g.drawBox(x_offset, y_offset, x_map_pixels, y_map_pixels); - - /*********************************************************/ - /************ Display Mesh Point Locations ***************/ - /*********************************************************/ - - u8g.setColorIndex(1); - for (i = 0; i < GRID_MAX_POINTS_X; i++) { - for (j = 0; j < GRID_MAX_POINTS_Y; j++) { - u8g.drawBox(x_offset + i * pixels_per_X_mesh_pnt + pixels_per_X_mesh_pnt / 2, - y_offset + j * pixels_per_Y_mesh_pnt + pixels_per_Y_mesh_pnt / 2, 1, 1); - } - } - - /*********************************************************/ - /************ Fill in the Specified Mesh Point ***********/ - /*********************************************************/ - - inverted_y = GRID_MAX_POINTS_Y - y_plot - 1; // The origin is typically in the lower right corner. We need to - // invert the Y to get it to plot in the right location. - u8g.drawBox(x_offset + x_plot * pixels_per_X_mesh_pnt, y_offset + inverted_y * pixels_per_Y_mesh_pnt, - pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt); - - /*********************************************************/ - /************** Put Relevent Text on Display *************/ - /*********************************************************/ - - // Show X and Y positions at top of screen - u8g.setColorIndex(1); - u8g.setPrintPos(5, 7); - lcd_print("X:"); - lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])))); - u8g.setPrintPos(74, 7); - lcd_print("Y:"); - lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])))); - - // Print plot position - u8g.setPrintPos(5, 64); - lcd_print('('); - u8g.print(x_plot); - lcd_print(','); - u8g.print(y_plot); - lcd_print(')'); - - // Show the location value - u8g.setPrintPos(74, 64); - lcd_print("Z:"); - if (!isnan(ubl.z_values[x_plot][y_plot])) { - lcd_print(ftostr43sign(ubl.z_values[x_plot][y_plot])); - } - else { - lcd_print(" -----"); - } - } - - #endif // DOGLCD - /** * UBL LCD Map Movement */ @@ -2309,19 +2221,13 @@ void kill_screen(const char* lcd_msg) { #if IS_KINEMATIC n_edit_pts = 9; //TODO: Delta accessible edit points #else - if (x_plot < 1 || x_plot >= GRID_MAX_POINTS_X - 1) - if (y_plot < 1 || y_plot >= GRID_MAX_POINTS_Y - 1) n_edit_pts = 4; // Corners - else n_edit_pts = 6; - else if (y_plot < 1 || y_plot >= GRID_MAX_POINTS_Y - 1) n_edit_pts = 6; // Edges - else n_edit_pts = 9; // Field + const bool xc = WITHIN(x_plot, 1, GRID_MAX_POINTS_X - 2), + yc = WITHIN(y_plot, 1, GRID_MAX_POINTS_Y - 2); + n_edit_pts = yc ? (xc ? 9 : 6) : (xc ? 6 : 4); // Corners #endif if (lcdDrawUpdate) { - #if ENABLED(DOGLCD) - _lcd_ubl_plot_drawing_prep(); - #else - _lcd_ubl_output_char_lcd(); - #endif + lcd_implementation_ubl_plot(x_plot, y_plot); ubl_map_move_to_xy(); // Move to current location diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h index 406f1c317..c9cbf452e 100644 --- a/Marlin/ultralcd_impl_DOGM.h +++ b/Marlin/ultralcd_impl_DOGM.h @@ -688,7 +688,7 @@ static void lcd_implementation_status_screen() { #define STATUS_BASELINE (55 + INFO_FONT_HEIGHT) - if (PAGE_CONTAINS(STATUS_BASELINE + 1 - INFO_FONT_HEIGHT, STATUS_BASELINE)) { + if (PAGE_CONTAINS(STATUS_BASELINE - (INFO_FONT_HEIGHT - 1), STATUS_BASELINE)) { u8g.setPrintPos(0, STATUS_BASELINE); #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) @@ -939,6 +939,95 @@ static void lcd_implementation_status_screen() { #endif // SDSUPPORT + #if ENABLED(AUTO_BED_LEVELING_UBL) + + /** + * UBL LCD "radar" map data + */ + #define MAP_UPPER_LEFT_CORNER_X 35 // These probably should be moved to the .h file But for now, + #define MAP_UPPER_LEFT_CORNER_Y 8 // it is easier to play with things having them here + #define MAP_MAX_PIXELS_X 53 + #define MAP_MAX_PIXELS_Y 49 + + void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + // Scale the box pixels appropriately + uint8_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X), + y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y), + + pixels_per_X_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X), + pixels_per_Y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y), + + x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2, + y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2; + + // Clear the Mesh Map + + if (PAGE_CONTAINS(y_offset - 2, y_offset + y_map_pixels + 4)) { + u8g.setColorIndex(1); // First draw the bigger box in White so we have a border around the mesh map box + u8g.drawBox(x_offset - 2, y_offset - 2, x_map_pixels + 4, y_map_pixels + 4); + if (PAGE_CONTAINS(y_offset, y_offset + y_map_pixels)) { + u8g.setColorIndex(0); // Now actually clear the mesh map box + u8g.drawBox(x_offset, y_offset, x_map_pixels, y_map_pixels); + } + } + + // Display Mesh Point Locations + + u8g.setColorIndex(1); + const uint8_t sx = x_offset + pixels_per_X_mesh_pnt / 2; + uint8_t y = y_offset + pixels_per_Y_mesh_pnt / 2; + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++, y += pixels_per_Y_mesh_pnt) + if (PAGE_CONTAINS(y, y)) + for (uint8_t i = 0, x = sx; i < GRID_MAX_POINTS_X; i++, x += pixels_per_X_mesh_pnt) + u8g.drawBox(sx, y, 1, 1); + + // Fill in the Specified Mesh Point + + uint8_t inverted_y = GRID_MAX_POINTS_Y - y_plot - 1; // The origin is typically in the lower right corner. We need to + // invert the Y to get it to plot in the right location. + + const uint8_t by = y_offset + inverted_y * pixels_per_Y_mesh_pnt; + if (PAGE_CONTAINS(by, by + pixels_per_Y_mesh_pnt)) + u8g.drawBox( + x_offset + x_plot * pixels_per_X_mesh_pnt, by, + pixels_per_X_mesh_pnt, pixels_per_Y_mesh_pnt + ); + + // Put Relevant Text on Display + + // Show X and Y positions at top of screen + u8g.setColorIndex(1); + if (PAGE_UNDER(7)) { + u8g.setPrintPos(5, 7); + lcd_print("X:"); + lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])))); + u8g.setPrintPos(74, 7); + lcd_print("Y:"); + lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])))); + } + + // Print plot position + if (PAGE_CONTAINS(64 - (INFO_FONT_HEIGHT - 1), 64)) { + u8g.setPrintPos(5, 64); + lcd_print('('); + u8g.print(x_plot); + lcd_print(','); + u8g.print(y_plot); + lcd_print(')'); + + // Show the location value + u8g.setPrintPos(74, 64); + lcd_print("Z:"); + if (!isnan(ubl.z_values[x_plot][y_plot])) + lcd_print(ftostr43sign(ubl.z_values[x_plot][y_plot])); + else + lcd_printPGM(PSTR(" -----")); + } + + } + + #endif // AUTO_BED_LEVELING_UBL + #endif // ULTIPANEL #endif // __ULTRALCD_IMPL_DOGM_H diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h index 71496ae75..2824ed088 100644 --- a/Marlin/ultralcd_impl_HD44780.h +++ b/Marlin/ultralcd_impl_HD44780.h @@ -31,6 +31,10 @@ #include "utility.h" #include "duration_t.h" +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "ubl.h" +#endif + extern volatile uint8_t buttons; //an extended version of the last checked buttons in a bit array. //////////////////////////////////// @@ -417,7 +421,7 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { void lcd_erase_line(const int16_t line) { lcd.setCursor(0, line); for (uint8_t i = LCD_WIDTH + 1; --i;) - lcd.print(' '); + lcd.write(' '); } // Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line @@ -434,9 +438,9 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { static void logo_lines(const char* const extra) { int16_t indent = (LCD_WIDTH - 8 - lcd_strlen_P(extra)) / 2; - lcd.setCursor(indent, 0); lcd.print('\x00'); lcd_printPGM(PSTR( "------" )); lcd.print('\x01'); + lcd.setCursor(indent, 0); lcd.print('\x00'); lcd_printPGM(PSTR( "------" )); lcd.write('\x01'); lcd.setCursor(indent, 1); lcd_printPGM(PSTR("|Marlin|")); lcd_printPGM(extra); - lcd.setCursor(indent, 2); lcd.print('\x02'); lcd_printPGM(PSTR( "------" )); lcd.print('\x03'); + lcd.setCursor(indent, 2); lcd.write('\x02'); lcd_printPGM(PSTR( "------" )); lcd.write('\x03'); } void bootscreen() { @@ -577,11 +581,11 @@ FORCE_INLINE void _draw_axis_label(const AxisEnum axis, const char* const pstr, lcd_printPGM(pstr); else { if (!axis_homed[axis]) - lcd.print('?'); + lcd.write('?'); else { #if DISABLED(DISABLE_REDUCED_ACCURACY_WARNING) if (!axis_known_position[axis]) - lcd.print(' '); + lcd.write(' '); else #endif lcd_printPGM(pstr); @@ -598,7 +602,7 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co if (prefix >= 0) lcd.print(prefix); lcd.print(itostr3(t1 + 0.5)); - lcd.print('/'); + lcd.write('/'); #if HEATER_IDLE_HANDLER const bool is_idle = (!isBed ? thermalManager.is_heater_idle(heater) : @@ -610,9 +614,9 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co ); if (!blink && is_idle) { - lcd.print(' '); - if (t2 >= 10) lcd.print(' '); - if (t2 >= 100) lcd.print(' '); + lcd.write(' '); + if (t2 >= 10) lcd.write(' '); + if (t2 >= 100) lcd.write(' '); } else #endif @@ -620,8 +624,8 @@ FORCE_INLINE void _draw_heater_status(const int8_t heater, const char prefix, co if (prefix >= 0) { lcd.print((char)LCD_DEGREE_CHAR); - lcd.print(' '); - if (t2 < 10) lcd.print(' '); + lcd.write(' '); + if (t2 < 10) lcd.write(' '); } } @@ -738,7 +742,7 @@ static void lcd_implementation_status_screen() { lcd.print(itostr3(card.percentDone())); else lcd_printPGM(PSTR("---")); - lcd.print('%'); + lcd.write('%'); #endif // SDSUPPORT #else // LCD_WIDTH >= 20 @@ -760,7 +764,7 @@ static void lcd_implementation_status_screen() { _draw_axis_label(X_AXIS, PSTR(MSG_X), blink); lcd.print(ftostr4sign(current_position[X_AXIS])); - lcd.print(' '); + lcd.write(' '); _draw_axis_label(Y_AXIS, PSTR(MSG_Y), blink); lcd.print(ftostr4sign(current_position[Y_AXIS])); @@ -784,7 +788,7 @@ static void lcd_implementation_status_screen() { lcd.setCursor(0, 2); lcd.print((char)LCD_FEEDRATE_CHAR); lcd.print(itostr3(feedrate_percentage)); - lcd.print('%'); + lcd.write('%'); #if LCD_WIDTH >= 20 && ENABLED(SDSUPPORT) @@ -794,7 +798,7 @@ static void lcd_implementation_status_screen() { lcd.print(itostr3(card.percentDone())); else lcd_printPGM(PSTR("---")); - lcd.print('%'); + lcd.write('%'); #endif // LCD_WIDTH >= 20 && SDSUPPORT @@ -833,7 +837,7 @@ static void lcd_implementation_status_screen() { lcd.print(ftostr12ns(filament_width_meas)); lcd_printPGM(PSTR(" V")); lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); - lcd.print('%'); + lcd.write('%'); return; } @@ -854,10 +858,10 @@ static void lcd_implementation_status_screen() { lcd_print_utf(stat); // The string leaves space chars -= slen - status_scroll_pos; // Amount of space left } - lcd.print('.'); // Always at 1+ spaces left, draw a dot + lcd.write('.'); // Always at 1+ spaces left, draw a dot if (--chars) { if (status_scroll_pos < slen + 1) // Draw a second dot if there's space - --chars, lcd.print('.'); + --chars, lcd.write('.'); if (chars) lcd_print_utf(lcd_status_message, chars); // Print a second copy of the message } } @@ -893,7 +897,7 @@ static void lcd_implementation_status_screen() { lcd.setCursor(0, row); if (center && !valstr) { int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; - while (--pad >= 0) { lcd.print(' '); n--; } + while (--pad >= 0) { lcd.write(' '); n--; } } while (n > 0 && (c = pgm_read_byte(pstr))) { n -= charset_mapper(c); @@ -903,7 +907,7 @@ static void lcd_implementation_status_screen() { n -= charset_mapper(c); valstr++; } - while (n-- > 0) lcd.print(' '); + while (n-- > 0) lcd.write(' '); } static void lcd_implementation_drawmenu_generic(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char post_char) { @@ -915,7 +919,7 @@ static void lcd_implementation_status_screen() { n -= charset_mapper(c); pstr++; } - while (n--) lcd.print(' '); + while (n--) lcd.write(' '); lcd.print(post_char); } @@ -928,8 +932,8 @@ static void lcd_implementation_status_screen() { n -= charset_mapper(c); pstr++; } - lcd.print(':'); - while (n--) lcd.print(' '); + lcd.write(':'); + while (n--) lcd.write(' '); lcd_print(data); } static void lcd_implementation_drawmenu_setting_edit_generic_P(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char* const data) { @@ -941,8 +945,8 @@ static void lcd_implementation_status_screen() { n -= charset_mapper(c); pstr++; } - lcd.print(':'); - while (n--) lcd.print(' '); + lcd.write(':'); + while (n--) lcd.write(' '); lcd_printPGM(data); } @@ -977,10 +981,10 @@ static void lcd_implementation_status_screen() { lcd.setCursor(1, 1); lcd_printPGM(pstr); if (value != NULL) { - lcd.print(':'); + lcd.write(':'); const uint8_t valrow = (lcd_strlen_P(pstr) + 1 + lcd_strlen(value) + 1) > (LCD_WIDTH - 2) ? 2 : 1; // Value on the next row if it won't fit lcd.setCursor((LCD_WIDTH - 1) - (lcd_strlen(value) + 1), valrow); // Right-justified, padded by spaces - lcd.print(' '); // overwrite char if value gets shorter + lcd.write(' '); // overwrite char if value gets shorter lcd_print(value); } } @@ -1001,7 +1005,7 @@ static void lcd_implementation_status_screen() { n -= charset_mapper(c); filename++; } - while (n--) lcd.print(' '); + while (n--) lcd.write(' '); lcd.print(post_char); } @@ -1079,10 +1083,152 @@ static void lcd_implementation_status_screen() { #endif // LCD_HAS_STATUS_INDICATORS -#ifdef AUTO_BED_LEVELING_UBL - void lcd_return_to_status(); // These are just place holders for the 20x4 LCD work that - void _lcd_ubl_output_char_lcd() { // is coming up very soon. Soon this will morph into the - lcd_return_to_status(); // real code. +#if ENABLED(AUTO_BED_LEVELING_UBL) + + /* + * These are just basic data for the 20x4 LCD work that + * is coming up very soon. + * Soon this will morph into a map code. + */ + + /** + Possible map screens: + + 16x2 |X000.00 Y000.00| + |(00,00) Z00.000| + + 20x2 | X:000.00 Y:000.00 | + | (00,00) Z:00.000 | + + 16x4 |+-------+(00,00)| + || |X000.00| + || |Y000.00| + |+-------+Z00.000| + + 20x4 | +-------+ (00,00) | + | | | X:000.00| + | | | Y:000.00| + | +-------+ Z:00.000| + */ + + void lcd_set_ubl_map_plot_chars() { + #if LCD_HEIGHT > 3 + //#include "_ubl_lcd_map_characters.h" + const static byte _lcd_box_top[8] PROGMEM = { + B11111, + B00000, + B00000, + B00000, + B00000, + B00000, + B00000, + B00000 + }; + const static byte _lcd_box_bottom[8] PROGMEM = { + B00000, + B00000, + B00000, + B00000, + B00000, + B00000, + B00000, + B11111 + }; + createChar_P(1, _lcd_box_top); + createChar_P(2, _lcd_box_bottom); + #endif + } + + void lcd_implementation_ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + + #if LCD_WIDTH >= 20 + #define _LCD_W_POS 12 + #define _PLOT_X 1 + #define _MAP_X 3 + #define _LABEL(C,X,Y) lcd.setCursor(X, Y); lcd.print(C) + #define _XLABEL(X,Y) _LABEL("X:",X,Y) + #define _YLABEL(X,Y) _LABEL("Y:",X,Y) + #define _ZLABEL(X,Y) _LABEL("Z:",X,Y) + #else + #define _LCD_W_POS 8 + #define _PLOT_X 0 + #define _MAP_X 1 + #define _LABEL(X,Y,C) lcd.setCursor(X, Y); lcd.write(C) + #define _XLABEL(X,Y) _LABEL('X',X,Y) + #define _YLABEL(X,Y) _LABEL('Y',X,Y) + #define _ZLABEL(X,Y) _LABEL('Z',X,Y) + #endif + + #if LCD_HEIGHT <= 3 // 16x2 or 20x2 display + + /** + * Show X and Y positions + */ + _XLABEL(_PLOT_X, 0); + lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])))); + + _YLABEL(_LCD_W_POS, 0); + lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])))); + + lcd.setCursor(_PLOT_X, 0); + + #else // 16x4 or 20x4 display + + /** + * Draw the Mesh Map Box + */ + uint8_t m; + lcd.setCursor(_MAP_X, 0); for (m = 0; m < 5; m++) lcd.write(1); // Top + lcd.setCursor(_MAP_X, 3); for (m = 0; m < 5; m++) lcd.write(2); // Bottom + for (m = 0; m <= 3; m++) { + lcd.setCursor(2, m); lcd.write('|'); // Left + lcd.setCursor(8, m); lcd.write('|'); // Right + } + + lcd.setCursor(_LCD_W_POS, 0); + + #endif + + /** + * Print plot position + */ + lcd.write('('); + lcd.print(x_plot); + lcd.write(','); + lcd.print(y_plot); + lcd.write(')'); + + #if LCD_HEIGHT <= 3 // 16x2 or 20x2 display + + /** + * Print Z values + */ + _ZLABEL(_LCD_W_POS, 1); + if (!isnan(ubl.z_values[x_plot][y_plot])) + lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot])); + else + lcd_printPGM(PSTR(" -----")); + + #else // 16x4 or 20x4 display + + /** + * Show all values at right of screen + */ + _XLABEL(_LCD_W_POS, 1); + lcd.print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot])))); + _YLABEL(_LCD_W_POS, 2); + lcd.print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot])))); + + /** + * Show the location value + */ + _ZLABEL(_LCD_W_POS, 3); + if (!isnan(ubl.z_values[x_plot][y_plot])) + lcd.print(ftostr43sign(ubl.z_values[x_plot][y_plot])); + else + lcd_printPGM(PSTR(" -----")); + + #endif // LCD_HEIGHT > 3 } #endif // AUTO_BED_LEVELING_UBL