For Printers where (0,0) is front and left on the bed:
This little mod takes the grid point data printed out in the serial monitor at the end of G29 for Bilinear leveling, and simply reformats it so that you can see it in Plan View as well, as if you are looking down from above at the printer bed below.
The original output is printed to the serial monitor first, and this Plan View is printed below it.
I did this because I am an old CADD guy, and my head wouldn't wrap around the original display quite right.
Beginning around line 2436 in Marlin_Main..cpp is the " static void print_bilinear_leveling_grid() " function definition, below that the final line in the definition is line 2462 " SERIAL_EOL; " and then the end bracket " } " below it on line 2463 - insert the code below IN BETWEEN those two lines, 2462 and 2463:
SERIAL_ECHOLNPGM("PLAN VIEW of Bed Bilinear Leveling Grid:");
SERIAL_EOL;
for (int y = ABL_GRID_MAX_POINTS_Y - 1; y >= 0; y--) {
if (y >= 0) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y);
for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++) {
SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid[x][y];
if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2);
}
else
SERIAL_PROTOCOLPGM(" ====");
}
SERIAL_EOL;
}
for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++) {
SERIAL_PROTOCOLPGM(" ");
if (x < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x);
}
SERIAL_EOL;
SERIAL_ECHOPGM(" PLAN VIEW - FRONT of Bed\n ");
SERIAL_EOL;
Can you do a cut and paste showing us how it displays for your bed?
Certainly! Sorry for the delay - had to attach it to keep the formatting intact:
FEB24PLANVIEWprint_log.txt
It's basically just a mirror image flip.
I suppose this could be the standard output, or we can adjust the display based on where the origin is set in the config.
or we can adjust the display based on where the origin is set in the config.
I think this is the right way to go.
Cool..
This code is very dated now.... But if you check out: http://3dprintboard.com/showthread.php?3105-Auto_Bed_Leveling-Enhanced-G29-command you will see these configuration options:
//#define ORIGIN_BACK_LEFT
//#define ORIGIN_FRONT_RIGHT
//#define ORIGIN_BACK_RIGHT
#define ORIGIN_FRONT_LEFT
Those options were pruned out of the code when it was merged into the main Marlin code base. But I think it would be helpful for people to have the various bed maps orientated correctly. If we do this, it would be good to see if we can consolidate all of the various bed map routines to use the same base routine to perform the orientation (or rotation). We don't want to have four different pieces of code to orientate each and every bed map display (as was done in this original extension of the G29 code).
Ok, here is my code to handle the four cases - (0,0) being at Front Left, Front Right, Rear Right - Rear Left being the current default. I figure a Switch - Case can be used to determine which section of code is run via User selected define in configuration.h:
SERIAL_ECHOPGM("PLAN VIEW of Bed Bilinear Leveling Grid, 0,0 LEFT FRONT:\n "); //akw
SERIAL_EOL;
for (int y = ABL_GRID_MAX_POINTS_Y-1; y >=0; y--) {
if (y >= 0) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y); //printed y-index number, 0-4
for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++) {
SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid[x][y];
if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2);
}
else
SERIAL_PROTOCOLPGM(" ====");
}
SERIAL_EOL;
}
for (uint8_t x = 0; x < ABL_GRID_MAX_POINTS_X; x++) {
SERIAL_PROTOCOLPGM(" ");
if (x < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x);
}
SERIAL_EOL;
SERIAL_ECHOPGM(" PLAN VIEW - FRONT of Bed\n "); //akw
SERIAL_EOL;
////////PLAN VIEW GRID.. RIGHT front
SERIAL_ECHOPGM("PLAN VIEW of Bed Bilinear Leveling Grid, 0,0 RIGHT FRONT:\n "); //akw
SERIAL_EOL;
for (int y = ABL_GRID_MAX_POINTS_Y-1; y >=0; y--) {
if (y >= 0) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y); //printed y-index number, 0-4
for (int x = ABL_GRID_MAX_POINTS_X-1; x>=0; x--) {//AKW
SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid[x][y];
if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2);
}
else
SERIAL_PROTOCOLPGM(" ====");
}
SERIAL_EOL;
}
for (int x = ABL_GRID_MAX_POINTS_X-1; x>=0; x--) {
SERIAL_PROTOCOLPGM(" ");
if ((x < 10) && (x >=0)) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x);
}
SERIAL_EOL;
SERIAL_ECHOPGM(" PLAN VIEW - FRONT of Bed\n "); //akw
SERIAL_EOL;
////////PLAN VIEW GRID..RIGHT REAR
SERIAL_ECHOPGM("PLAN VIEW of Bed Bilinear Leveling Grid, 0,0 RIGHT REAR:\n "); //akw
SERIAL_EOL;
for (uint8_t y = 0; y < ABL_GRID_MAX_POINTS_Y; y++) {
if (y < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y); //printed y-index number, 0-4
for (int x = ABL_GRID_MAX_POINTS_X-1; x>=0; x--) {//AKW
SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid[x][y];
if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2);
}
else
SERIAL_PROTOCOLPGM(" ====");
}
SERIAL_EOL;
}
for (int x = ABL_GRID_MAX_POINTS_X-1; x>=0; x--) {
SERIAL_PROTOCOLPGM(" ");
if ((x < 10) && (x >=0)) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x);
}
SERIAL_EOL;
SERIAL_ECHOPGM(" PLAN VIEW - FRONT of Bed\n "); //akw
SERIAL_EOL;
}
Attached is what I get in Serial Monitor off of Arduino 1.8.1:
March2MultiPlan Views 2.txt
That looks nice! I'm wondering if we should display 3 decimal places instead of 2 ? Especially with the mesh editing, the extra digit of precision would be helpful. Albeit, that might force an extra blank line between the rows to keep the display somewhat square.
And one more question: Can we change this to be a stand alone file? This would be for two reasons. First, we need to start taking stuff out of Marlin_main.cpp and make it smaller instead of making it bigger. But the other reason is it would be helpful if this was defined as a function where we could pass in the matrix to dump (along with the matrix dimensions). In your case you would call it:
display_topographical_map( bed_level_grid, ABL_GRID_MAX_POINTS_X, ABL_GRID_MAX_POINTS_Y);
Doing this would allow the UBL code to dump the mesh by just changing the first parameter. (To the name of the mesh matrix)
Wups - transposed some numbers, let me fix.
Edit: Fixed - I transposed the leveling test data, swapping around X and Y - THIS is what happens when you are 55 and decide 11:30 pm is a GOOD time to get interested in a little project, I guess. I attached the corrected Serial print out, March2MultiPlan Views 2.txt, above.
Attached: Bed_display.h where ABL report formatting is moved out of Marlin_main.cpp and AllFormatsTest.txt which shows the Serial Output of each report format for the different origin options.
Modifications to Marlin Files:
Marlin_main.cpp: added #include for the Bed_display header, line 235 -
#if HAS_ABL
+ #include "Bed_display.h"
#include "vector_3.h"
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
#include "qr_solve.h"
#endif
#elif ENABLED(MESH_BED_LEVELING)
#include "mesh_bed_leveling.h"
#endif
and added call to printBed(), line 2243, in the bilinear_leveling_grid function, deleting the rest of the code in function -
static void print_bilinear_leveling_grid() {
+ printBed();
}
Configuration.h: added #defines for printer (0,0) orientations, beginning at line 424 in Mechanical Settings:
// Uncomment one of these options to describe where your machine's (0,0)
// is located on the bed, for the Automated Bed Leveling results to display
// correctly oriented:
//#define ORIGIN_BACK_LEFT
//#define ORIGIN_FRONT_RIGHT
//#define ORIGIN_BACK_RIGHT
#define ORIGIN_FRONT_LEFT
Bed_display.h header code follows:
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* . . .
*/
//Option set in Configuration.h
//#define ORIGIN_BACK_LEFT
//#define ORIGIN_FRONT_RIGHT
//#define ORIGIN_BACK_RIGHT
//#define ORIGIN_FRONT_LEFT
#include "Marlin.h"
#define UNPROBED 9999.0f
static void printBed() {
#if ENABLED(ORIGIN_BACK_LEFT)
#define ORIGIN_STR "Left Rear"
#define BL_FWD_X true
#define BL_FWD_Y true
#elif ENABLED(ORIGIN_FRONT_LEFT)
#define ORIGIN_STR "Left Front"
#define BL_FWD_X true
#define BL_FWD_Y false
#elif ENABLED(ORIGIN_FRONT_RIGHT)
#define ORIGIN_STR "Right Front"
#define BL_FWD_X false
#define BL_FWD_Y false
#elif ENABLED(ORIGIN_BACK_RIGHT)
#define ORIGIN_STR "Right Rear"
#define BL_FWD_X false
#define BL_FWD_Y true
#endif
#define BL_FIRST_X (BL_FWD_X ? ABL_GRID_MAX_POINTS_X - 1 : 0)
#define BL_LAST_X (BL_FWD_X ? 0 : ABL_GRID_MAX_POINTS_X - 1)
#define BL_FIRST_Y (BL_FWD_Y ? ABL_GRID_MAX_POINTS_Y - 1 : 0)
#define BL_LAST_Y (BL_FWD_Y ? 0 : ABL_GRID_MAX_POINTS_Y - 1)
#define BL_NEXT_X (BL_FWD_X ? ++x : --x)
#define BL_NEXT_Y (BL_FWD_Y ? ++y : --y)
SERIAL_ECHOLNPGM("\n Bilinear Leveling Grid\n PLAN VIEW - (0,0) " ORIGIN_STR ":");
for (int8_t x = BL_FIRST_X; x <= BL_LAST_X; BL_NEXT_X) {
SERIAL_PROTOCOLPGM(" ");
if (x < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x);
}
SERIAL_EOL;
for (int8_t y = BL_FIRST_Y; y <= BL_LAST_Y; BL_NEXT_Y) {
if (y < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y);
for (int8_t x = BL_FIRST_X; x <= BL_LAST_X; BL_NEXT_X) {
SERIAL_PROTOCOLCHAR(' ');
float offset = bed_level_grid[x][y];
if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2);
}
else
SERIAL_PROTOCOLPGM(" ====");
}
SERIAL_EOL;
}
SERIAL_ECHOLNPGM(" FRONT of Bed\n");
I've tested these mods out on my [only] printer, a corexy machine with Ramps 1.4 running the latest Bugfix. I am green as grass to Github methodology, so is there anything more I need to do?
I'll re-write this, create a PR, and merge it soon.
Something like…
static void printBed() {
#if ENABLED(ORIGIN_FRONT_LEFT) || ENABLED(BED_CENTER_AT_0_0)
#define BL_ORIGIN "Left Front"
#define BL_FWD_X true
#define BL_FWD_Y false
#elif ENABLED(ORIGIN_FRONT_RIGHT)
#define BL_ORIGIN "Right Front"
#define BL_FWD_X false
#define BL_FWD_Y false
#elif ENABLED(ORIGIN_BACK_RIGHT)
#define BL_ORIGIN "Right Rear"
#define BL_FWD_X false
#define BL_FWD_Y true
#elif ENABLED(ORIGIN_BACK_LEFT)
#define BL_ORIGIN "Left Rear"
#define BL_FWD_X true
#define BL_FWD_Y true
#endif
#define BL_FIRST_X (BL_FWD_X ? 0 : ABL_GRID_MAX_POINTS_X - 1)
#define BL_FIRST_Y (BL_FWD_Y ? 0 : ABL_GRID_MAX_POINTS_Y - 1)
#define BL_LAST_X (BL_FWD_X ? ABL_GRID_MAX_POINTS_X : -1)
#define BL_LAST_Y (BL_FWD_Y ? ABL_GRID_MAX_POINTS_Y : -1)
#define BL_NEXT_X (BL_FWD_X ? ++x : --x)
#define BL_NEXT_Y (BL_FWD_Y ? ++y : --y)
SERIAL_ECHOLNPGM("\n Bilinear Leveling Grid\n PLAN VIEW - (0,0) " BL_ORIGIN ":");
for (int8_t x = BL_FIRST_X; x != BL_LAST_X; BL_NEXT_X) {
SERIAL_PROTOCOLPGM(" ");
if (x < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)x);
}
SERIAL_EOL;
for (int8_t y = BL_FIRST_Y; y != BL_LAST_Y; BL_NEXT_Y) {
if (y < 10) SERIAL_PROTOCOLCHAR(' ');
SERIAL_PROTOCOL((int)y);
for (int8_t x = BL_FIRST_X; x != BL_LAST_X; BL_NEXT_X) {
SERIAL_PROTOCOLCHAR(' ');
const float offset = bed_level_grid[x][y];
if (offset != UNPROBED) {
if (offset > 0) SERIAL_CHAR('+');
SERIAL_PROTOCOL_F(offset, 2);
}
else
SERIAL_PROTOCOLPGM(" ====");
}
SERIAL_EOL;
}
SERIAL_ECHOLNPGM(" FRONT of Bed\n");
}
Umm.. has something untoward happened on Github?
Nevermind..
thinkyhead added this to the 1.1.1 milestone an hour ago
SERIAL_ECHOLNPGM("\n Bilinear Leveling Grid\n PLAN VIEW - (0,0) " BL_ORIGIN ":");
const float offset = bed_level_grid[x][y];
This is another example where we would benefit if all the (in this case Mesh) bed leveling schemes used the same names and indexes. If we all used the same array name, we could have a common display routine that rotated the perspective to match the user's bed orientation.
Most helpful comment
Something like…