Comments (346)
Tonight's lesson is: "No good deed goes unpunished."
from marlin.
I take that back.... I still need to scale up the 3x3 grid.
from marlin.
Ok... Scaling issues..
Still trying to get this right.
void _lcd_ubl_plot_drawing(uint8_t x_plot, uint8_t y_plot) {
uint8_t x_frame_offset, y_frame_offset,
x_frame_max, y_frame_max,
x_pixel_scaling, y_pixel_scaling,
x_pixel, y_pixel;
// Starting points for the "box"
x_frame_offset = (LCD_PIXEL_WIDTH / 6);
y_frame_offset = (LCD_PIXEL_HEIGHT / 10);
// Ending points for the "box"
x_frame_max = x_frame_offset - 2;
y_frame_max = y_frame_offset + 13;
// Scaling for the pixel placement
x_pixel_scaling = map(GRID_MAX_POINTS_X, 3, 15, 75, 10);
y_pixel_scaling = map(GRID_MAX_POINTS_Y, 3, 15, 75, 10);
// Points for pixel placement
x_pixel = (x_plot * (x_pixel_scaling / 10)) + x_frame_offset + 2;
y_pixel = (y_plot * (y_pixel_scaling / 10)) + y_frame_offset + 2;
// Show X and Y positions at top of screen
u8g.setColorIndex(1);
u8g.setPrintPos(10, 8);
lcd_print("X:");
lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
u8g.setPrintPos(70, 8);
lcd_print("Y:");
lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
// Draw frame and location pixel
#if IS_KINEMATIC
u8g.drawCircle(x_frame_offset * 2,
y_frame_offset * 2, y_frame_max / 2);
#endif
// Double the size of the "box" and pixel
u8g.setScale2x2();
// Draw the "box"
u8g.drawFrame(x_frame_offset, y_frame_offset, x_frame_max, y_frame_max);
// Plot the pixel
u8g.drawPixel(x_pixel, y_pixel);
// Print plot position
u8g.undoScale();
u8g.setPrintPos(10, 63);
lcd_print("(");
u8g.print(x_plot);
lcd_print(",");
u8g.print(y_plot);
lcd_print(")");
// Show the location value
u8g.setPrintPos(60, 63);
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(" -----");
}
}
from marlin.
I don't see the problem yet...
from marlin.
Okay, I've somewhat made progress, but still not ready.
3x3 maps just fine.... maybe I need the box to be the same size as the 15x15 that also maps just fine.
But, anything else between those are all jacked up.
from marlin.
Okay, @Roxy-3D, I created a new branch to get it updated with the latest bugfix-1.1.x
.
This is also the latest I have that works with 3x3 and 15x15 and removed most of the BS math that was only getting confusing and not helping much.
I've updated the posts above with current link and snipplet.
from marlin.
I'll load it up as soon as I can....
from marlin.
I think I found that I need to scale another number.
x_pixel = (x_plot * (x_pixel_scaling / 10)) + <<x_frame_offset + 2>>; <-- This one.
y_pixel = (y_plot * (y_pixel_scaling / 10)) + <<y_frame_offset + 2>>; <-- And this one.
I will try in the morning with:
x_pixel_offset = map(GRID_MAX_POINTS_X, 3, 15, x_frame-offset +2, 0);
y_pixel_offset = map(GRID_MAX_POINTS_Y, 3, 15, y_frame-offset +2, 0);
x_pixel = x_plot * (x_pixel_scaling / 10) + x_pixel_offset;
y_pixel = y_plot * (y_pixel_scaling / 10) + y_pixel_offset;
from marlin.
It seems like I'm at a stand still.... I need the Configuration.h files that cause the UBL Z lift problem and they are not posted yet. So... If you can have the 'current code' in your branch, I'll start debugging it tomorrow. Most likely, it will be easier to just do a re-write. But I'll start with what you have.
from marlin.
I'm not pushing you... I'm just keeping you up to date.
It is up to date as of this morning.
https://github.com/Tannoo/Marlin/tree/UBL_Mesh_Plotting
from marlin.
I have some serial outputs happening to see what each variable is at any given point.
from marlin.
OK! Great! If I don't have the needed Configuration.h files to duplicate the problem... I'll start trying to get the Postage Stamp map to work for all mesh dimensions in the morning....
from marlin.
x_pixel and y_pixel are the only ones that go out of range now.
from marlin.
I'm starting to dip my toes into the water.
Probably _lcd_ubl_plot_draw(x_plot, y_plot); should be in ultralcd.cpp instead of in a .h file. If you keep working on that function.... In a day or two, I'll have a different implementation of it. And you can take what ever ideas you like and incorporate them into your code.
UPDATE: Oh! I think I see why you did that. That is the graphical version of the function. But the thing is, it is enough C++ code, it probably still belongs in ultralcd.cpp with conditional compilation flags around it.
YET ANOTHER UPDATE: I've got some problems trying to do things with Map Type 3. I have trouble even selecting it because my encoder wheel multiplier is too large. So, I have to back up and re-tune some of my settings. If you are open to suggestions.... You can work to get the title for each map type to display as the user rotates the dial. Maybe 'Map Type' should be a whole menu page with line items and when you pick one, it does it???
- Topography to Host
- CVS for Spreadsheet
- Output to LCD Grid
And if you are willing to work together on this... I'll just focus on the 'Output to LCD Grid' version. The way you have 'Output to LCD Grid' setup looks nice. It would seem it isn't just a map option. It probably belongs in the map category also, but it would seem it should be a line item right under Activate and Deactivate. And maybe with a title 'Edit Mesh'.
And in fact, you have it setup so when a click happens, the mesh point gets edited. So, if you have other things you don't mind working on... Let me see if I can get the display to work right for all screen dimensions and maybe you can just paste the code in???
from marlin.
Yeah.... I couldn't get the u8g.fuctions to work in ultralcd.cpp.
After drowning in this for the last month or so, I was going to try and move it into ultralcd.cpp after getting it working.
from marlin.
I have found that the scaling is not working because it's not linear. So, I'm trying to get everything to work individually and then incorporate a multimap
function I found. Like mapping an array.
from marlin.
The K.I.S.S. method is what I reminding myself. lol
from marlin.
I didn't see these comments until after I edited my post up above.
from marlin.
I didn't post them until after your edit. lol
from marlin.
So far, I have gotten 3x3 - 11x11 to work, the numbers are all over the place to make it work. Now, I can see why the maps were giving me such a fit.
from marlin.
OK! I'm not sure how fast I'll make progress. Even with no interruptions (like more important things coming up) this is tricky code (as you know)!!!! But, it should be a fun piece of code to write!
Who knows... I might be able to get it working for all mesh sizes within 3 or 4 days....
from marlin.
I have some "dirty" code that works for most of it now. And I want to clean it up by implementing the multimap function:
// note: the _in array should have increasing values
int multiMap(int val, int* _in, int* _out, uint8_t size)
{
// take care the value is within range
// val = constrain(val, _in[0], _in[size-1]);
if (val <= _in[0]) return _out[0];
if (val >= _in[size-1]) return _out[size-1];
// search right interval
uint8_t pos = 1; // _in[0] allready tested
while(val > _in[pos]) pos++;
// this will handle all exact "points" in the _in array
if (val == _in[pos]) return _out[pos];
// interpolate in the right segment for the rest
return (val - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
}
Unless you have a better way to handle data that looks more like an X,Y scatter chart. lol
from marlin.
It would seem the simplest way would be to just enque a command for the .CSV and Topography Map to host. That would be just a "G29 T0" or a "G29 T1".
I think the problem with the current LCD Map and that code up above is I think differently than that. So I'll have to work through both and see what I can do with it.
from marlin.
My code enques G29 T3 for the lcd map.
I have:
T0 for host output.
T1 for CSV.
T2 for X,Y list // Not sure what else you call it.
T3 for lcd map
from marlin.
G29 T2:
Bed Topography Report List:
M421 I 0 J 0 Z 0.000000 ; X 10.00, Y 10.00
M421 I 0 J 1 Z 0.000000 ; X 10.00, Y 26.50
M421 I 0 J 2 Z 0.000000 ; X 10.00, Y 43.00
M421 I 0 J 3 Z 0.000000 ; X 10.00, Y 59.50
M421 I 0 J 4 Z 0.000000 ; X 10.00, Y 76.00
M421 I 0 J 5 Z 0.000000 ; X 10.00, Y 92.50
M421 I 0 J 6 Z 0.000000 ; X 10.00, Y 109.00
M421 I 0 J 7 Z 0.000000 ; X 10.00, Y 125.50
M421 I 0 J 8 Z 0.000000 ; X 10.00, Y 142.00
M421 I 0 J 9 Z 0.000000 ; X 10.00, Y 158.50
M421 I 0 J 10 Z 0.000000 ; X 10.00, Y 175.00
M421 I 1 J 0 Z 0.000000 ; X 28.00, Y 10.00
M421 I 1 J 1 Z 0.000000 ; X 28.00, Y 26.50
M421 I 1 J 2 Z 0.000000 ; X 28.00, Y 43.00
M421 I 1 J 3 Z 0.000000 ; X 28.00, Y 59.50
...
from marlin.
T2 for X,Y list // Not sure what else you call it.
I'm not sure how to convert it to a short and descriptive name. But it produces the gcode so that you can later print it and get it re-absorbed into the printer. Pretty much, it is an 'off printer backup of your mesh'
from marlin.
Pretty much, it is an 'off printer backup of your mesh'
OOOOhhhh.
from marlin.
I'll change the name to "Mesh Backup Output".
from marlin.
OR "Mesh G-coded Output"
from marlin.
Even "Off Printer Backup" would be good. And when people look at it and see the M421 commands... They will understand what is happening.
from marlin.
K...done.
from marlin.
Here's my "dirty" code so far:
void _lcd_ubl_plot_drawing(uint8_t x_plot, uint8_t y_plot) {
uint8_t x_frame_offset, y_frame_offset,
x_frame_max, y_frame_max,
x_pixel_scaling, y_pixel_scaling,
x_pixel, y_pixel;
// Starting points for the "box"
if (GRID_MAX_POINTS_Y == GRID_MAX_POINTS_X) {
if(GRID_MAX_POINTS_X == 3) { x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 4) { x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 5) { x_frame_offset = LCD_PIXEL_WIDTH / 6; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 6) { x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 7) { x_frame_offset = LCD_PIXEL_WIDTH / 6 + 3; y_frame_offset = LCD_PIXEL_HEIGHT / 9; }
if(GRID_MAX_POINTS_X == 8) { x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 9) { x_frame_offset = LCD_PIXEL_WIDTH / 6 + 1; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 10) { x_frame_offset = LCD_PIXEL_WIDTH / 6; y_frame_offset = LCD_PIXEL_HEIGHT / 10 - 1; }
if(GRID_MAX_POINTS_X == 11) { x_frame_offset = LCD_PIXEL_WIDTH / 5; y_frame_offset = LCD_PIXEL_HEIGHT / 8 + 1; }
if(GRID_MAX_POINTS_X == 12) { x_frame_offset = LCD_PIXEL_WIDTH / 5; y_frame_offset = LCD_PIXEL_HEIGHT / 8; }
if(GRID_MAX_POINTS_X == 13) { x_frame_offset = LCD_PIXEL_WIDTH / 5; y_frame_offset = LCD_PIXEL_HEIGHT / 8; }
if(GRID_MAX_POINTS_X == 14) { x_frame_offset = LCD_PIXEL_WIDTH / 6; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
if(GRID_MAX_POINTS_X == 15) { x_frame_offset = LCD_PIXEL_WIDTH / 6; y_frame_offset = LCD_PIXEL_HEIGHT / 10; }
}
else {
x_frame_offset = LCD_PIXEL_WIDTH / 6;
y_frame_offset = LCD_PIXEL_HEIGHT / 10;
}
// Ending points for the "box"
if (GRID_MAX_POINTS_Y == GRID_MAX_POINTS_X) {
if(GRID_MAX_POINTS_X == 3) { x_frame_max = x_frame_offset - 4; y_frame_max = y_frame_offset + 13; }
if(GRID_MAX_POINTS_X == 4) { x_frame_max = x_frame_offset - 3; y_frame_max = y_frame_offset + 14; }
if(GRID_MAX_POINTS_X == 5) { x_frame_max = x_frame_offset; y_frame_max = y_frame_offset + 15; }
if(GRID_MAX_POINTS_X == 6) { x_frame_max = x_frame_offset - 3; y_frame_max = y_frame_offset + 14; }
if(GRID_MAX_POINTS_X == 7) { x_frame_max = x_frame_offset - 7; y_frame_max = y_frame_offset + 10; }
if(GRID_MAX_POINTS_X == 8) { x_frame_max = x_frame_offset - 4; y_frame_max = y_frame_offset + 13; }
if(GRID_MAX_POINTS_X == 9) { x_frame_max = x_frame_offset - 1; y_frame_max = y_frame_offset + 15; }
if(GRID_MAX_POINTS_X == 10) { x_frame_max = x_frame_offset - 2; y_frame_max = y_frame_offset + 15; }
if(GRID_MAX_POINTS_X == 11) { x_frame_max = x_frame_offset - 10; y_frame_max = y_frame_offset + 6; }
if(GRID_MAX_POINTS_X == 12) { x_frame_max = x_frame_offset - 9; y_frame_max = y_frame_offset + 8; }
if(GRID_MAX_POINTS_X == 13) { x_frame_max = x_frame_offset - 8; y_frame_max = y_frame_offset + 10; }
if(GRID_MAX_POINTS_X == 14) { x_frame_max = x_frame_offset - 2; y_frame_max = y_frame_offset + 14; }
if(GRID_MAX_POINTS_X == 15) { x_frame_max = x_frame_offset - 2; y_frame_max = y_frame_offset + 14; }
}
else {
x_frame_max = x_frame_offset - 2;
y_frame_max = y_frame_offset + 14;
}
// Scaling for the pixel placement
if (GRID_MAX_POINTS_Y == GRID_MAX_POINTS_X) {
if(GRID_MAX_POINTS_X == 3) x_pixel_scaling = 75;
if(GRID_MAX_POINTS_X == 4) x_pixel_scaling = 50;
if(GRID_MAX_POINTS_X == 5) x_pixel_scaling = 40;
if(GRID_MAX_POINTS_X == 6) x_pixel_scaling = 30;
if(GRID_MAX_POINTS_X == 7) x_pixel_scaling = 28;
if(GRID_MAX_POINTS_X == 8) x_pixel_scaling = 20;
if(GRID_MAX_POINTS_X == 9) x_pixel_scaling = 20;
if(GRID_MAX_POINTS_X == 10) x_pixel_scaling = 20;
if(GRID_MAX_POINTS_X == 11) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 12) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 13) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 14) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 15) x_pixel_scaling = 10;
y_pixel_scaling = x_pixel_scaling;
}
else {
x_pixel_scaling = map(GRID_MAX_POINTS_X, 3, 15, 55, 1) / 10;
y_pixel_scaling = map(GRID_MAX_POINTS_Y, 3, 15, 55, 1) / 10;
}
// Points for pixel placement
x_pixel = x_plot * (x_pixel_scaling / 10) + x_frame_offset + 2;
y_pixel = y_plot * (y_pixel_scaling / 10) + y_frame_offset + 2;
// Show X and Y positions at top of screen
u8g.setColorIndex(1);
u8g.setPrintPos(10, 8);
lcd_print("X:");
lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
u8g.setPrintPos(70, 8);
lcd_print("Y:");
lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
// Draw frame and location pixel
#if IS_KINEMATIC
u8g.drawCircle(x_frame_offset * 2,
y_frame_offset * 2, y_frame_max / 2);
#endif
// Double the size of the "box" and pixel
u8g.setScale2x2();
// Draw the "box"
u8g.drawFrame(x_frame_offset, y_frame_offset, x_frame_max, y_frame_max);
// Plot the pixel
u8g.drawPixel(x_pixel, y_pixel);
// Print plot position
u8g.undoScale();
u8g.setPrintPos(10, 63);
lcd_print("(");
u8g.print(x_plot);
lcd_print(",");
u8g.print(y_plot);
lcd_print(")");
// Show the location value
u8g.setPrintPos(60, 63);
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(" -----");
}
SERIAL_ECHOLNPAIR("LCD_PIXEL_WIDTH: ", LCD_PIXEL_WIDTH);
SERIAL_ECHOLNPAIR("LCD_PIXEL_HEIGHT: ", LCD_PIXEL_HEIGHT);
SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X: ", GRID_MAX_POINTS_X);
SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y: ", GRID_MAX_POINTS_Y);
SERIAL_ECHOLNPAIR("x_frame_offset: ", x_frame_offset);
SERIAL_ECHOLNPAIR("y_frame_offset: ", y_frame_offset);
SERIAL_ECHOLNPAIR("x_frame_max: ", x_frame_max);
SERIAL_ECHOLNPAIR("y_frame_max: ", y_frame_max);
SERIAL_ECHOLNPAIR("x_pixel_scaling: ", x_pixel_scaling);
SERIAL_ECHOLNPAIR("y_pixel_scaling: ", y_pixel_scaling);
SERIAL_ECHOLNPAIR("x_pixel: ", x_pixel);
SERIAL_ECHOLNPAIR("y_pixel: ", y_pixel);
SERIAL_EOL;
}
from marlin.
I'll start with yours...
from marlin.
Ok. I would love to see what you end up with. Being the math and code wizard you are, you are bound to come up with something better and more elegant than I.
from marlin.
I've got to get another Mega.... I know I'm wearing it out. lol
from marlin.
I've got to get another Mega.... I know I'm wearing it out. lol
nah... You get a minimum of 10,000 different firmware uploads. (That is the guaranteed number. Most likely it is 4 or 5 times that high.) but for $10 (including shipping) you can get a new one. So it doesn't hurt to have an extra one sitting around.
I've been thinking how I'm going to write the code. I'm going to add a new M command (just for development) where I can set the mesh dimensions. And I'm going to point the Double Click handler at my code so I don't have to go through a complicated menu path to try things.
I'm also going to do some something like:
const expression int _GRID_MAX_POINTS_X = GRID_MAX_POINTS_X;
const expression int _GRID_MAX_POINTS_Y = GRID_MAX_POINTS_Y;
so I can set the GRID_MAX_POINTS_X&Y with the M command but when you are done testing, you just delete the M command and those 2 lines... (and delete the '' in front of any GRID_MAX_POINT and everything is back to normal.
I think you can work in any part of the code and you won't affect me. And my guess is, what ever I do, will just be a cut and paste for you to make use of... Do I still have write privileges to your repository? If so.... I can easily update your repository so you can see where I'm at.
from marlin.
I have not removed you.... I'm not sure if you are a collaborator, but I will invite you anyway to be sure.
Also, I have some "dirty" code that works now. Even for asymmetrical matrices.
void _lcd_ubl_plot_drawing(uint8_t x_plot, uint8_t y_plot) {
uint8_t x_frame_offset, y_frame_offset,
x_frame_max, y_frame_max,
x_pixel_scaling, y_pixel_scaling,
x_pixel, y_pixel;
// Starting X point for the "box"
if(GRID_MAX_POINTS_X == 3) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2;
if(GRID_MAX_POINTS_X == 4) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2;
if(GRID_MAX_POINTS_X == 5) x_frame_offset = LCD_PIXEL_WIDTH / 6;
if(GRID_MAX_POINTS_X == 6) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2;
if(GRID_MAX_POINTS_X == 7) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 3;
if(GRID_MAX_POINTS_X == 8) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2;
if(GRID_MAX_POINTS_X == 9) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 1;
if(GRID_MAX_POINTS_X == 10) x_frame_offset = LCD_PIXEL_WIDTH / 6;
if(GRID_MAX_POINTS_X == 11) x_frame_offset = LCD_PIXEL_WIDTH / 5;
if(GRID_MAX_POINTS_X == 12) x_frame_offset = LCD_PIXEL_WIDTH / 5;
if(GRID_MAX_POINTS_X == 13) x_frame_offset = LCD_PIXEL_WIDTH / 5 - 1;
if(GRID_MAX_POINTS_X == 14) x_frame_offset = LCD_PIXEL_WIDTH / 5 - 1;
if(GRID_MAX_POINTS_X == 15) x_frame_offset = LCD_PIXEL_WIDTH / 6 + 2;
// Starting Y point for the "box"
if(GRID_MAX_POINTS_Y == 3) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
if(GRID_MAX_POINTS_Y == 4) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
if(GRID_MAX_POINTS_Y == 5) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
if(GRID_MAX_POINTS_Y == 6) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
if(GRID_MAX_POINTS_Y == 7) y_frame_offset = LCD_PIXEL_HEIGHT / 9;
if(GRID_MAX_POINTS_Y == 8) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
if(GRID_MAX_POINTS_Y == 9) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
if(GRID_MAX_POINTS_Y == 10) y_frame_offset = LCD_PIXEL_HEIGHT / 10 - 2;
if(GRID_MAX_POINTS_Y == 11) y_frame_offset = LCD_PIXEL_HEIGHT / 8 + 1;
if(GRID_MAX_POINTS_Y == 12) y_frame_offset = LCD_PIXEL_HEIGHT / 8;
if(GRID_MAX_POINTS_Y == 13) y_frame_offset = LCD_PIXEL_HEIGHT / 8;
if(GRID_MAX_POINTS_Y == 14) y_frame_offset = LCD_PIXEL_HEIGHT / 9;
if(GRID_MAX_POINTS_Y == 15) y_frame_offset = LCD_PIXEL_HEIGHT / 10;
// Ending X point for the "box"
if(GRID_MAX_POINTS_X == 3) x_frame_max = x_frame_offset - 4;
if(GRID_MAX_POINTS_X == 4) x_frame_max = x_frame_offset - 3;
if(GRID_MAX_POINTS_X == 5) x_frame_max = x_frame_offset;
if(GRID_MAX_POINTS_X == 6) x_frame_max = x_frame_offset - 3;
if(GRID_MAX_POINTS_X == 7) x_frame_max = x_frame_offset - 7;
if(GRID_MAX_POINTS_X == 8) x_frame_max = x_frame_offset - 4;
if(GRID_MAX_POINTS_X == 9) x_frame_max = x_frame_offset - 1;
if(GRID_MAX_POINTS_X == 10) x_frame_max = x_frame_offset + 2;
if(GRID_MAX_POINTS_X == 11) x_frame_max = x_frame_offset - 10;
if(GRID_MAX_POINTS_X == 12) x_frame_max = x_frame_offset - 9;
if(GRID_MAX_POINTS_X == 13) x_frame_max = x_frame_offset - 7;
if(GRID_MAX_POINTS_X == 14) x_frame_max = x_frame_offset - 6;
if(GRID_MAX_POINTS_X == 15) x_frame_max = x_frame_offset - 4;
// Ending Y point for the "box"
if(GRID_MAX_POINTS_Y == 3) y_frame_max = y_frame_offset + 13;
if(GRID_MAX_POINTS_Y == 4) y_frame_max = y_frame_offset + 14;
if(GRID_MAX_POINTS_Y == 5) y_frame_max = y_frame_offset + 15;
if(GRID_MAX_POINTS_Y == 6) y_frame_max = y_frame_offset + 14;
if(GRID_MAX_POINTS_Y == 7) y_frame_max = y_frame_offset + 10;
if(GRID_MAX_POINTS_Y == 8) y_frame_max = y_frame_offset + 13;
if(GRID_MAX_POINTS_Y == 9) y_frame_max = y_frame_offset + 15;
if(GRID_MAX_POINTS_Y == 10) y_frame_max = y_frame_offset + 19;
if(GRID_MAX_POINTS_Y == 11) y_frame_max = y_frame_offset + 6;
if(GRID_MAX_POINTS_Y == 12) y_frame_max = y_frame_offset + 8;
if(GRID_MAX_POINTS_Y == 13) y_frame_max = y_frame_offset + 9;
if(GRID_MAX_POINTS_Y == 14) y_frame_max = y_frame_offset + 11;
if(GRID_MAX_POINTS_Y == 15) y_frame_max = y_frame_offset + 13;
// Scaling for X pixel placement
if(GRID_MAX_POINTS_X == 3) x_pixel_scaling = 75;
if(GRID_MAX_POINTS_X == 4) x_pixel_scaling = 50;
if(GRID_MAX_POINTS_X == 5) x_pixel_scaling = 40;
if(GRID_MAX_POINTS_X == 6) x_pixel_scaling = 30;
if(GRID_MAX_POINTS_X == 7) x_pixel_scaling = 28;
if(GRID_MAX_POINTS_X == 8) x_pixel_scaling = 20;
if(GRID_MAX_POINTS_X == 9) x_pixel_scaling = 20;
if(GRID_MAX_POINTS_X == 10) x_pixel_scaling = 20;
if(GRID_MAX_POINTS_X == 11) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 12) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 13) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 14) x_pixel_scaling = 15;
if(GRID_MAX_POINTS_X == 15) x_pixel_scaling = 10;
// Scaling for Y pixel placement
if(GRID_MAX_POINTS_Y == 3) y_pixel_scaling = 75;
if(GRID_MAX_POINTS_Y == 4) y_pixel_scaling = 50;
if(GRID_MAX_POINTS_Y == 5) y_pixel_scaling = 40;
if(GRID_MAX_POINTS_Y == 6) y_pixel_scaling = 30;
if(GRID_MAX_POINTS_Y == 7) y_pixel_scaling = 28;
if(GRID_MAX_POINTS_Y == 8) y_pixel_scaling = 20;
if(GRID_MAX_POINTS_Y == 9) y_pixel_scaling = 20;
if(GRID_MAX_POINTS_Y == 10) y_pixel_scaling = 20;
if(GRID_MAX_POINTS_Y == 11) y_pixel_scaling = 15;
if(GRID_MAX_POINTS_Y == 12) y_pixel_scaling = 15;
if(GRID_MAX_POINTS_Y == 13) y_pixel_scaling = 15;
if(GRID_MAX_POINTS_Y == 14) y_pixel_scaling = 15;
if(GRID_MAX_POINTS_Y == 15) y_pixel_scaling = 10;
// Points for pixel placement
x_pixel = x_plot * (x_pixel_scaling / 10) + x_frame_offset + 2;
y_pixel = y_plot * (y_pixel_scaling / 10) + y_frame_offset + 2;
// Show X and Y positions at top of screen
u8g.setColorIndex(1);
u8g.setPrintPos(10, 7);
lcd_print("X:");
lcd_print(ftostr32(LOGICAL_X_POSITION(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]))));
u8g.setPrintPos(70, 7);
lcd_print("Y:");
lcd_print(ftostr32(LOGICAL_Y_POSITION(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]))));
// Draw frame and location pixel
#if IS_KINEMATIC
u8g.drawCircle(x_frame_offset * 2,
y_frame_offset * 2, y_frame_max / 2);
#endif
// Double the size of the "box" and pixel
u8g.setScale2x2();
// Draw the "box"
u8g.drawFrame(x_frame_offset, y_frame_offset, x_frame_max, y_frame_max);
// Plot the pixel
u8g.drawPixel(x_pixel, y_pixel);
// Print plot position
u8g.undoScale();
u8g.setPrintPos(10, 64);
lcd_print("(");
u8g.print(x_plot);
lcd_print(",");
u8g.print(y_plot);
lcd_print(")");
// Show the location value
u8g.setPrintPos(64, 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(" -----");
}
SERIAL_ECHOLNPAIR("LCD_PIXEL_WIDTH: ", LCD_PIXEL_WIDTH);
SERIAL_ECHOLNPAIR("LCD_PIXEL_HEIGHT: ", LCD_PIXEL_HEIGHT);
SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_X: ", GRID_MAX_POINTS_X);
SERIAL_ECHOLNPAIR("GRID_MAX_POINTS_Y: ", GRID_MAX_POINTS_Y);
SERIAL_ECHOLNPAIR("x_frame_offset: ", x_frame_offset);
SERIAL_ECHOLNPAIR("y_frame_offset: ", y_frame_offset);
SERIAL_ECHOLNPAIR("x_frame_max: ", x_frame_max);
SERIAL_ECHOLNPAIR("y_frame_max: ", y_frame_max);
SERIAL_ECHOLNPAIR("x_pixel_scaling: ", x_pixel_scaling);
SERIAL_ECHOLNPAIR("y_pixel_scaling: ", y_pixel_scaling);
SERIAL_ECHOLNPAIR("x_pixel: ", x_pixel);
SERIAL_ECHOLNPAIR("y_pixel: ", y_pixel);
SERIAL_EOL;
}
from marlin.
3x3 -- 15x15 all work along with some tested variants like 10x15, 3x15, 15x3, 7x11.
Now, I'm on to make the new multiMap
function work for me to clean it up.
from marlin.
If you really enjoy messing with this.... Great! But there isn't a lot of sense to duplicating effort. Software takes so much time to develop, it just makes sense to do new stuff that somebody else isn't already doing. And the UBL LCD Menu code is pretty big already.... For sure, there is a lot of stuff you can do that isn't a duplication of what I'm working on.
Seriously... You will like what I'm cooking up...
from marlin.
Okay. Should I stop and see what you get?
from marlin.
Yeah... Just for a few days.... And you can cut & paste pieces that you like into your stuff.
Please keep your branch up to date. I think I can keep out of your way. But it wouldn't hurt for us to both see where the other person is.
from marlin.
I have not updated the branch with this... this is just the local I am working on.
from marlin.
Okay... I will be working Sunday night, so you won't have me messing with anything then.. lol
from marlin.
I sent you a collaborator invite.
Roxy Edit: You are behind the game. I've already accepted! :) Time to go to bed. But I'll be doing merges tomorrow afternoon (with lots of comments) so you can see what I'm up to.
from marlin.
I know there is more than one way to skin a cat....I'm sure that I've been using a butcher knife. lol
from marlin.
Maybe 'Map Type' should be a whole menu page with line items and when you pick one, it does it???
Topography to Host
CVS for Spreadsheet
Output to LCD Grid
I can do that....
Done, tested, and updated the branch.
from marlin.
I've been fighting computer issues ever since I got up this morning. But I finally cloned your fork. And then it took me a while to find the correct branch. (What I always do after a fork is go to the web page / settings and set the default branch to bugfix-v1.1.0)
Any way... I finally figured things out and it looks like you beat me to it. But I have a couple of things to change... I'll sync in a little bit. I added some comments here and there. But one thing we need to do is start turning off sub-options that require a Graphical LCD Panel if the system doesn't have one. For example... The new map type 2.
Also... Your multiMap() function's logic is very similar to what I was thinking should be done. But what I was going to do was have a couple of #define's to set the max number of X and Y pixels that could be used on the LCD Panel. And those numbers should roughly be of square shape on the LCD Panel.
Then what I was going to do was subtract off a couple of pixels just because I was going to draw a line all around the box. And at that point.... I was going to calculate how many pixels were required for each mesh cell.
I was going to have very similar logic to yours. But I was going to make it so there were not magical hard coded constants in the mix. I'll see if I can get it converted to what I was thinking.
Mean while... I already made a change so I could compile! :)
WOW!!!! Very nice. So far, I've only played with the LCD Mesh Map. There are a couple of small things to change. The (X,Y) = (0,0) should be in the lower left corner. That probably isn't going to be hard to invert. And the other thing we need to add is to let the user click on a 'dot' to edit it. Right now, if you click, it doesn't go to the mesh editor. But when the LCD Display times out... It does go there. And once that screen is active... You can't get out of the mesh editor.
BUT.... VERY NICE!!!!!
from marlin.
Do you see my changes? Later... I'll try to collapse all the hard coded constants and see if I can get that stuff to magically adjust.
from marlin.
The (X,Y) = (0,0) should be in the lower left corner.
I think it should be the upper-right, but if you make a dynamic generator, you should be able to change the starting point based on the printer setup, correct?
And the other thing we need to add is to let the user click on a 'dot' to edit it. Right now, if you click, it doesn't go to the mesh editor.
For me, it works just fine, I can select a dot and click to edit it and upto 9 points around that dot. Then after the editing is complete, it returns to the "radar". Mine will not time out from that screen, I have to click and hold for several seconds for the edit routine to exit.
from marlin.
Do you see my changes?
I cannot fine where you did anything other than Marlin's site.
from marlin.
Look at: https://github.com/Tannoo/Marlin/tree/UBL_Mesh_Plotting/Marlin
I committed things with a 'First Pass Clean Up' You should see changes.... I bet your encoder wheel has 1 step per pulse. I have 5. So, I'm adding some scaling right now to the map scanner....
I'll go fight the edit issue next.
The reason for the (0,0) being in the lower left corner is that is how most Cartesian printers are setup. It makes it easier for people to just look at the map and visualize where they are on the printer. And on graph paper, that is typically where (0,0) is also. So mostly, it is just to try to help people.
from marlin.
I was going to have very similar logic to yours. But I was going to make it so there were not magical hard coded constants in the mix.
That's what I was originally going for, but that was giving me migraines. This is exactly what I was hoping you could help with.
from marlin.
OK... Let me get things working nicely on my display. Mostly it is the encoder wheel that is causing trouble. And I'll see if I can collapse that code...
from marlin.
How did you send that message "Okay, I see now." ???
It got emailed to me, but it isn't here???
from marlin.
On the commit page: 70affd3
from marlin.
Oh! OK! You learn something new every day! I've seen that before where I get an email but there is no associated issue or pull request. I couldn't figure out how people were able to send me an email because GitHub hides the email addresses of everybody.
from marlin.
Yup. I was also trying to figure out where you made the commit. With the link you sent me, there was a link for your commit's title, but I couldn't find the branch to download.
Git desktop also didn't show anything new.
from marlin.
I have a few more encoder wheel changes merged into your branch. Tomorrow I'll play with it some more and see if I can figure out why the interactive editing isn't working from the LCD Mesh Map on my machine.
from marlin.
I am unsure why you have encoder issues. I don't.
from marlin.
It was because you have a different Graphics LCD than I do. In Conditionals_lcd.cpp there are these lines:
// Set encoder detents for well-known controllers
#if ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) || ENABLED(OLED_PANEL_TINYBOY2) \
|| ENABLED(BQ_LCD_SMART_CONTROLLER) || ENABLED(LCD_I2C_PANELOLU2) || ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#endif
It is just something that needed to be tried on several machines...
from marlin.
Maps look okay on yours?
from marlin.
I thought you had a 20x4 display.
from marlin.
I still need to get one of those again. I ordered 2 of them and got jacked.... They sent me a full graphic and then sent a 20x4 that was broken. So, I gave up for a little while on that.
from marlin.
Maps look okay on yours?
I only tried it on 10 x 10 so far...
I thought you had a 20x4 display.
The machine I use for development is a 20x4.
I have one very nice machine with a Graphics controller. I don't usually do development on it. Mostly because it is usually busy but also because I don't want to do things that risk doing a nozzle crash.
But it was not doing anything today and I was using it for this.
from marlin.
Also, for the 20x4, I don't think a radar map would work, but, it could show (X, Y) coordinates and the z_value at the given location. And still click to edit that point.
from marlin.
Similar to the bottom line of my map screen.
from marlin.
Also, for the 20x4, I don't think a radar map would work, but, it could show (X, Y) coordinates and the z_value at the given location. And still click to edit that point.
There are a number of options. One would be to define custom characters and print those. But it would be easier to just move the nozzle to correspond to the location.
from marlin.
So, far, I don't have it moving anything until you click to edit, then it homes and moves to the selected point and starts from there.
from marlin.
But, that could be a neat option.
from marlin.
Yeah... The bad thing about it is it takes so much time. If you over shoot on the encoder wheel, it will take time to get there, and then time to back track. And... as you drop down to a new row, it has to retrace to the beginning of the next line.
It might not be as bad as I'm worried about. It is probably worth trying and seeing how it looks and feels.
from marlin.
That's exactly why I said option. Lol
from marlin.
Maybe a 1 or 2 sec delay before moving.
from marlin.
Sorry... editing posts on the phone is a pita.
1 or 2 sec delay, then move to the position indicated at that time. No buffer.
from marlin.
Yeah.... And with some clever coding... We could have it do non-blocking moves. It might be it can be done in a way that the nozzle trying to get to where the dot is, isn't annoying....
from marlin.
Fyi, I really do appreciate your help on this.
from marlin.
Or... We start moving any time the dot isn't where the nozzle is. But then we do one of two things.
Option 1 is we don't queue up any new moves until the nozzle completes the current move. And where ever the dot currently is, we tell it to move there. That wouldn't be too bad.
Option 2 is if the dot moves to a new location we cancel the current move and start heading to the new dot location. It will be a little schizoid because of the back and fort on the X axis. But it would get to where it is supposed to be very quickly.
from marlin.
With constant movement, the LCD will seem sluggish.
Waiting for the dot to stop moving for a sec then move?
But, if it is moving, stop movement if the dot changes...wait for the dot to stop moving before moving to the new spot.
from marlin.
With constant movement, the LCD will seem sluggish.
No... We would do non-blocking moves. The nozzle movement and the LCD activity would be independent of each other. Kind of like if a print was going... You can still do things on the LCD Panel. It is a little bit trickier because we need to cancel some moves (if we did Option 2). But end stop movement (or Z-Probeing) does that today. We would have to figure out how to do that. But there is example code we can look at.
from marlin.
Okay.
from marlin.
You know all about the movement stuff. Have at it. ;)
from marlin.
Actually... I've been looking at the custom characters. I think we can do a Postage Stamp map with a dot on the 20x4 LCD Displays... It will take some experimenting. But it can be done.
And the movement stuff will be fun to play with too.
from marlin.
That would be hard to see for some people, but ok.
from marlin.
The 20x4 characters are 5x8 pixels. If the map (not including the border lines) was 6 characters wide in size and 4 high, that would leave a pixel between each dot location. And then you combine in the movement of the nozzle as the dial is turned, people will be able to figure out what they are editing.
It maybe that just the nozzle movement is enough and we don't need to mess with trying to use custom characters on the 20x4 displays. On the 20x4 displays we still get to display the (X,Y) coordinate and indexes. So... Yeah... Maybe that doesn't make sense to do??? But I think I can get 60 or 70 bytes of RAM back by making some simple changes to the custom characters. That doesn't help this problem but it is a good thing to do.
Probably figuring out how to get the nozzle to track the edit location nicely is more important right now.
from marlin.
I was thinking that there's not enough room for a map on the 20x4's.
So.. on those, will this be enough:
enqueue_and_echo_commands_P("M117 " PSTR("(" x_plot ", " y_plot ") " pgm_read_float(ubl.z_values[x_plot][y_plot]));
Or something like that?
from marlin.
I wouldn't do it that way. There is no need to enqueue commands to write data to the LCD Panel.
The LCD library lets you say where to start the write (column and row), and you just give it the data you want there.
from marlin.
Yes, I was just thinking to use the M117 due to the new scrolling on the status screen for the 20x4's.
from marlin.
Okay, I just had the chance to test the new additions you applied.
All is good on my end. Even click to edit and Click and hold to quit.
The click and hold is tricky...because there is a VERY short delay (if any) to release the button once the edit has been stopped. If you hold it too long, it goes back to the map. If you let off "just in time", it's stops and all is good staying at the status screen.
from marlin.
Actually....not any more. I held it longer and it stopped with no returning.
from marlin.
Okay I'm going to update and squash the branch... done.
from marlin.
BTW... this is where I got that "multiMap" function:
http://playground.arduino.cc/Main/MultiMap
I moved it to utility.cpp
. Is there a better file to put this in?
from marlin.
Menu editing screen having refresh issues again and also shows that sometimes it doesn't leave the editing mode:
https://drive.google.com/open?id=0B560i8PeUNEraWdUYjlrVjJqQ2s
from marlin.
Putting the lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT;
back in, helps with the edit screen. It's never blank or just the bottom line of the numbers.
float lcd_mesh_edit() {
lcd_goto_screen(_lcd_mesh_edit_NOP);
lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT;
_lcd_mesh_fine_tune(PSTR("Mesh Editor"));
return mesh_edit_value;
from marlin.
I found that trying to exit while it's moving, gives issues....wait until it's not moving and it will exit fine.
from marlin.
I shifted stuff around. And it all still works.
I moved most of the math stuff into ultralcd.cpp
.
from marlin.
I have company so that is going to limit how much time I can spend playing with stuff today and tomorrow. But I'll start trying different things to get the Postage Stamp to move the nozzle in a reasonable way.
I'll probably just do something very simple (and not nice) first... And then start making changes depending on how annoying this or that is.
from marlin.
Same here and I have it moving already but not with blocking moves. I'm trying that next.
I was just hammering out the details of homing before the map is displayed. I have that part done now and can commit the changes so you can see what's there now.
I am headed to bed for the day.
from marlin.
I have it moving already but not with blocking moves.
Did you say that wrong? Making it move with blocking moves is easier. Making it move with non-blocking moves is harder.
Please keep it the branch up to date (but in a working state). That way if I have an hour, I can sync... and where we are at and maybe add something or another.
from marlin.
I am doing that just now. My IDE just locked up... mid-upload... So, my printer was stuck at a blank screen and I had to restart my 'puter. Got it and uploaded again.
I was trying do_blocking_move_to_xy
and that didn't work... maybe it was just my implementation of it.
I set it back were it worked and I'm going to update the branch with what I have.
FYI: It homes and displays Homing XYZ
and then goes to the map when homing is done.
---
ALSO FYI: I need to stop the stepper timeout OR go back to status screen if it does timeout. Because it gets locked up on the map and nothing happens without resetting the printer.
from marlin.
Okay. It's sync'ed. I'm off to bed.
from marlin.
That movement for the LCD Mesh Map is nice. It works very well. I wonder, would it make sense to Zig-Zag the nozzle when it switches to the next row? Instead of going back to X=0 when the Y changes, maybe the X should stay in the same location (kind of like the old Grid Based Leveling did with the probe) ? That logic is more complicated so maybe it doesn't make sense to do that.
The motion feels nice. I'm not sure we are going to have to do much more with it.
I wonder if that exit bug I'm seeing is because I don't know how to use the LCD Mesh Map? Shouldn't a Press & Hold get me out of the LCD Mesh Map? Well... What ever is causing it... I'll find it when I get a chance to dig in a little bit.
PS. How many times did you crash your nozzle trying to get the motion working? I'm pretty sure I would have had a few nozzle crashes!!!
from marlin.
Related Issues (13)
- UBL Menu Sytem HOT 102
- Re-ARM and 20x4 LCD Panel
- Array troubles HOT 85
- LCD SD Print HOT 3
- Help wanted HOT 4
- UBL LCD "Radar" HOT 54
- UBL matrix plotting HOT 126
- LCD Interactive Mesh HOT 209
- LCD not displaying on a second attempt. HOT 1
- UBL character radar code HOT 102
- Does this have anything to do with our recent merge? HOT 23
- MKS TFT32 HOT 41
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from marlin.