Просмотр исходного кода

Improve UBL mesh report. Add M420 T, M421 N

Scott Lahteine 7 лет назад
Родитель
Сommit
0746aff595

+ 78
- 58
Marlin/src/feature/bedlevel/ubl/ubl.cpp Просмотреть файл

@@ -51,7 +51,7 @@
51 51
   ) {
52 52
     if (!leveling_is_valid()) return;
53 53
     SERIAL_ECHO_START_P(port);
54
-    SERIAL_ECHOLNPGM_P(port, "  G29 I 999");
54
+    SERIAL_ECHOLNPGM_P(port, "  G29 I99");
55 55
     for (uint8_t x = 0; x < GRID_MAX_POINTS_X; x++)
56 56
       for (uint8_t y = 0;  y < GRID_MAX_POINTS_Y; y++)
57 57
         if (!isnan(z_values[x][y])) {
@@ -59,9 +59,7 @@
59 59
           SERIAL_ECHOPAIR_P(port, "  M421 I", x);
60 60
           SERIAL_ECHOPAIR_P(port, " J", y);
61 61
           SERIAL_ECHOPGM_P(port, " Z");
62
-          SERIAL_ECHO_F_P(port, z_values[x][y], 6);
63
-          SERIAL_ECHOPAIR_P(port, " ; X", LOGICAL_X_POSITION(mesh_index_to_xpos(x)));
64
-          SERIAL_ECHOPAIR_P(port, ", Y", LOGICAL_Y_POSITION(mesh_index_to_ypos(y)));
62
+          SERIAL_ECHO_F_P(port, z_values[x][y], 2);
65 63
           SERIAL_EOL_P(port);
66 64
           safe_delay(75); // Prevent Printrun from exploding
67 65
         }
@@ -83,15 +81,6 @@
83 81
     safe_delay(50);
84 82
   }
85 83
 
86
-  static void serial_echo_xy(const int16_t x, const int16_t y) {
87
-    SERIAL_CHAR('(');
88
-    SERIAL_ECHO(x);
89
-    SERIAL_CHAR(',');
90
-    SERIAL_ECHO(y);
91
-    SERIAL_CHAR(')');
92
-    safe_delay(10);
93
-  }
94
-
95 84
   #if ENABLED(UBL_DEVEL_DEBUGGING)
96 85
 
97 86
     static void debug_echo_axis(const AxisEnum axis) {
@@ -189,78 +178,109 @@
189 178
     }
190 179
   }
191 180
 
192
-  // display_map() currently produces three different mesh map types
193
-  // 0 : suitable for PronterFace and Repetier's serial console
194
-  // 1 : .CSV file suitable for importation into various spread sheets
195
-  // 2 : disply of the map data on a RepRap Graphical LCD Panel
181
+  static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) {
182
+    SERIAL_ECHO_SP(sp);
183
+    SERIAL_CHAR('(');
184
+    if (x < 100) { SERIAL_CHAR(' '); if (x < 10) SERIAL_CHAR(' '); }
185
+    SERIAL_ECHO(x);
186
+    SERIAL_CHAR(',');
187
+    if (y < 100) { SERIAL_CHAR(' '); if (y < 10) SERIAL_CHAR(' '); }
188
+    SERIAL_ECHO(y);
189
+    SERIAL_CHAR(')');
190
+    safe_delay(5);
191
+  }
192
+
193
+  static void serial_echo_column_labels(const uint8_t sp) {
194
+    SERIAL_ECHO_SP(7);
195
+    for (int8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
196
+      if (i < 10) SERIAL_CHAR(' ');
197
+      SERIAL_ECHO(i);
198
+      SERIAL_ECHO_SP(sp);
199
+    }
200
+    safe_delay(10);
201
+  }
196 202
 
203
+  /**
204
+   * Produce one of these mesh maps:
205
+   *   0: Human-readable
206
+   *   1: CSV format for spreadsheet import
207
+   *   2: TODO: Display on Graphical LCD
208
+   *   4: Compact Human-Readable
209
+   */
197 210
   void unified_bed_leveling::display_map(const int map_type) {
198 211
     #if HAS_AUTO_REPORTING || ENABLED(HOST_KEEPALIVE_FEATURE)
199 212
       suspend_auto_report = true;
200 213
     #endif
201 214
 
202
-    constexpr uint8_t spaces = 8 * (GRID_MAX_POINTS_X - 2);
215
+    constexpr uint8_t eachsp = 1 + 6 + 1,                           // [-3.567]
216
+                      twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each
203 217
 
204
-    SERIAL_PROTOCOLPGM("\nBed Topography Report");
205
-    if (map_type == 0) {
206
-      SERIAL_PROTOCOLPGM(":\n\n");
207
-      serial_echo_xy(0, GRID_MAX_POINTS_Y - 1);
208
-      SERIAL_ECHO_SP(spaces + 3);
209
-      serial_echo_xy(GRID_MAX_POINTS_X - 1, GRID_MAX_POINTS_Y - 1);
210
-      SERIAL_EOL();
211
-      serial_echo_xy(MESH_MIN_X, MESH_MAX_Y);
212
-      SERIAL_ECHO_SP(spaces);
213
-      serial_echo_xy(MESH_MAX_X, MESH_MAX_Y);
218
+    const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4;
219
+
220
+    SERIAL_ECHOPGM("\nBed Topography Report");
221
+    if (human) {
222
+      SERIAL_ECHOPGM(":\n\n");
223
+      serial_echo_xy(4, MESH_MIN_X, MESH_MAX_Y);
224
+      serial_echo_xy(twixt, MESH_MAX_X, MESH_MAX_Y);
214 225
       SERIAL_EOL();
226
+      serial_echo_column_labels(eachsp - 2);
215 227
     }
216 228
     else {
217
-      SERIAL_PROTOCOLPGM(" for ");
218
-      serialprintPGM(map_type == 1 ? PSTR("CSV:\n\n") : PSTR("LCD:\n\n"));
229
+      SERIAL_ECHOPGM(" for ");
230
+      serialprintPGM(csv ? PSTR("CSV:\n") : PSTR("LCD:\n"));
219 231
     }
220 232
 
221 233
     const float current_xi = get_cell_index_x(current_position[X_AXIS] + (MESH_X_DIST) / 2.0),
222 234
                 current_yi = get_cell_index_y(current_position[Y_AXIS] + (MESH_Y_DIST) / 2.0);
223 235
 
236
+    if (!lcd) SERIAL_EOL();
224 237
     for (int8_t j = GRID_MAX_POINTS_Y - 1; j >= 0; j--) {
238
+
239
+      // Row Label (J index)
240
+      if (human) {
241
+        if (j < 10) SERIAL_CHAR(' ');
242
+        SERIAL_ECHO(j);
243
+        SERIAL_ECHOPGM(" |");
244
+      }
245
+
246
+      // Row Values (I indexes)
225 247
       for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
226
-        const bool is_current = i == current_xi && j == current_yi;
227 248
 
228
-        // is the nozzle here? then mark the number
229
-        if (map_type == 0) SERIAL_CHAR(is_current ? '[' : ' ');
249
+        // Opening Brace or Space
250
+        const bool is_current = i == current_xi && j == current_yi;
251
+        if (human) SERIAL_CHAR(is_current ? '[' : ' ');
230 252
 
253
+        // Z Value at current I, J
231 254
         const float f = z_values[i][j];
232
-        if (isnan(f)) {
233
-          serialprintPGM(map_type == 0 ? PSTR("    .   ") : PSTR("NAN"));
255
+        if (lcd) {
256
+          // TODO: Display on Graphical LCD
234 257
         }
235
-        else if (map_type <= 1) {
236
-          // if we don't do this, the columns won't line up nicely
237
-          if (map_type == 0 && f >= 0.0) SERIAL_CHAR(' ');
238
-          SERIAL_PROTOCOL_F(f, 3);
258
+        else if (isnan(f))
259
+          serialprintPGM(human ? PSTR("  .   ") : PSTR("NAN"));
260
+        else if (human || csv) {
261
+          if (human && f >= 0.0) SERIAL_CHAR(f > 0 ? '+' : ' ');  // Space for positive ('-' for negative)
262
+          SERIAL_ECHO_F(f, 3);                                    // Positive: 5 digits, Negative: 6 digits
239 263
         }
240
-        idle();
241
-        if (map_type == 1 && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR(',');
264
+        if (csv && i < GRID_MAX_POINTS_X - 1) SERIAL_CHAR('\t');
265
+
266
+        // Closing Brace or Space
267
+        if (human) SERIAL_CHAR(is_current ? ']' : ' ');
268
+
242 269
         SERIAL_FLUSHTX();
243
-        safe_delay(15);
244
-        if (map_type == 0) {
245
-          SERIAL_CHAR(is_current ? ']' : ' ');
246
-          SERIAL_CHAR(' ');
247
-        }
248
-      }
249
-      SERIAL_EOL();
250
-      if (j && map_type == 0) { // we want the (0,0) up tight against the block of numbers
251
-        SERIAL_CHAR(' ');
252
-        SERIAL_EOL();
270
+        idle();
253 271
       }
272
+      if (!lcd) SERIAL_EOL();
273
+
274
+      // A blank line between rows (unless compact)
275
+      if (j && human && !comp) SERIAL_ECHOLNPGM("   |");
254 276
     }
255 277
 
256
-    if (map_type == 0) {
257
-      serial_echo_xy(MESH_MIN_X, MESH_MIN_Y);
258
-      SERIAL_ECHO_SP(spaces + 4);
259
-      serial_echo_xy(MESH_MAX_X, MESH_MIN_Y);
278
+    if (human) {
279
+      serial_echo_column_labels(eachsp - 2);
280
+      SERIAL_EOL();
281
+      serial_echo_xy(4, MESH_MIN_X, MESH_MIN_Y);
282
+      serial_echo_xy(twixt, MESH_MAX_X, MESH_MIN_Y);
260 283
       SERIAL_EOL();
261
-      serial_echo_xy(0, 0);
262
-      SERIAL_ECHO_SP(spaces + 5);
263
-      serial_echo_xy(GRID_MAX_POINTS_X - 1, 0);
264 284
       SERIAL_EOL();
265 285
     }
266 286
 

+ 1
- 3
Marlin/src/feature/bedlevel/ubl/ubl_G29.cpp Просмотреть файл

@@ -252,9 +252,7 @@
252 252
    *                    for subsequent Load and Store operations. Valid storage slot numbers begin at 0 and
253 253
    *                    extend to a limit related to the available EEPROM storage.
254 254
    *
255
-   *   S -1  Store      Store the current Mesh as a print out that is suitable to be feed back into the system
256
-   *                    at a later date. The GCode output can be saved and later replayed by the host software
257
-   *                    to reconstruct the current mesh on another machine.
255
+   *   S -1  Store      Print the current Mesh as G-code that can be used to restore the mesh anytime.
258 256
    *
259 257
    *   T     Topology   Display the Mesh Map Topology.
260 258
    *                    'T' can be used alone (e.g., G29 T) or in combination with most of the other commands.

+ 2
- 1
Marlin/src/gcode/bedlevel/M420.cpp Просмотреть файл

@@ -42,6 +42,7 @@
42 42
  * With AUTO_BED_LEVELING_UBL only:
43 43
  *
44 44
  *   L[index]  Load UBL mesh from index (0 is default)
45
+ *   T[map]    0:Human-readable 1:CSV 2:"LCD" 4:Compact
45 46
  */
46 47
 void GcodeSuite::M420() {
47 48
 
@@ -80,7 +81,7 @@ void GcodeSuite::M420() {
80 81
 
81 82
     // L or V display the map info
82 83
     if (parser.seen('L') || parser.seen('V')) {
83
-      ubl.display_map(0);  // Currently only supports one map type
84
+      ubl.display_map(parser.byteval('T'));
84 85
       SERIAL_ECHOLNPAIR("ubl.mesh_is_valid = ", ubl.mesh_is_valid());
85 86
       SERIAL_ECHOLNPAIR("ubl.storage_slot = ", ubl.storage_slot);
86 87
     }

+ 4
- 2
Marlin/src/gcode/bedlevel/ubl/M421.cpp Просмотреть файл

@@ -37,6 +37,7 @@
37 37
  * Usage:
38 38
  *   M421 I<xindex> J<yindex> Z<linear>
39 39
  *   M421 I<xindex> J<yindex> Q<offset>
40
+ *   M421 I<xindex> J<yindex> N
40 41
  *   M421 C Z<linear>
41 42
  *   M421 C Q<offset>
42 43
  */
@@ -45,6 +46,7 @@ void GcodeSuite::M421() {
45 46
   const bool hasI = ix >= 0,
46 47
              hasJ = iy >= 0,
47 48
              hasC = parser.seen('C'),
49
+             hasN = parser.seen('N'),
48 50
              hasZ = parser.seen('Z'),
49 51
              hasQ = !hasZ && parser.seen('Q');
50 52
 
@@ -54,7 +56,7 @@ void GcodeSuite::M421() {
54 56
     iy = location.y_index;
55 57
   }
56 58
 
57
-  if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ)) {
59
+  if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ || hasN)) {
58 60
     SERIAL_ERROR_START();
59 61
     SERIAL_ERRORLNPGM(MSG_ERR_M421_PARAMETERS);
60 62
   }
@@ -63,7 +65,7 @@ void GcodeSuite::M421() {
63 65
     SERIAL_ERRORLNPGM(MSG_ERR_MESH_XY);
64 66
   }
65 67
   else
66
-    ubl.z_values[ix][iy] = parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0);
68
+    ubl.z_values[ix][iy] = hasN ? NAN : parser.value_linear_units() + (hasQ ? ubl.z_values[ix][iy] : 0);
67 69
 }
68 70
 
69 71
 #endif // AUTO_BED_LEVELING_UBL

Загрузка…
Отмена
Сохранить