Bläddra i källkod

Backlash cleanup (#13659)

…And save backlash, fil. sensor, ExtUI userdata to EEPROM.
Marcio Teixeira 5 år sedan
förälder
incheckning
15357af67c

+ 9
- 7
Marlin/src/Marlin.cpp Visa fil

939
 
939
 
940
   queue_setup();
940
   queue_setup();
941
 
941
 
942
+  // UI must be initialized before EEPROM
943
+  // (because EEPROM code calls the UI).
944
+  ui.init();
945
+  ui.reset_status();
946
+
947
+  #if HAS_SPI_LCD && ENABLED(SHOW_BOOTSCREEN)
948
+    ui.show_bootscreen();
949
+  #endif
950
+
942
   #if ENABLED(SDIO_SUPPORT) && SD_DETECT_PIN == -1
951
   #if ENABLED(SDIO_SUPPORT) && SD_DETECT_PIN == -1
943
     // Auto-mount the SD for EEPROM.dat emulation
952
     // Auto-mount the SD for EEPROM.dat emulation
944
     if (!card.isDetected()) card.initsd();
953
     if (!card.isDetected()) card.initsd();
1044
     fanmux_init();
1053
     fanmux_init();
1045
   #endif
1054
   #endif
1046
 
1055
 
1047
-  ui.init();
1048
-  ui.reset_status();
1049
-
1050
-  #if HAS_SPI_LCD && ENABLED(SHOW_BOOTSCREEN)
1051
-    ui.show_bootscreen();
1052
-  #endif
1053
-
1054
   #if ENABLED(MIXING_EXTRUDER)
1056
   #if ENABLED(MIXING_EXTRUDER)
1055
     mixer.init();
1057
     mixer.init();
1056
   #endif
1058
   #endif

+ 139
- 0
Marlin/src/feature/backlash.cpp Visa fil

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "../Marlin.h"
24
+
25
+#if ENABLED(BACKLASH_COMPENSATION)
26
+
27
+#include "backlash.h"
28
+#include "../module/planner.h"
29
+
30
+#if ENABLED(BACKLASH_GCODE)
31
+  uint8_t Backlash::correction = (BACKLASH_CORRECTION) * 0xFF;
32
+  #ifdef BACKLASH_DISTANCE_MM
33
+    float Backlash::distance_mm[XYZ] = BACKLASH_DISTANCE_MM;
34
+  #endif
35
+  #ifdef BACKLASH_SMOOTHING_MM
36
+    float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM;
37
+  #endif
38
+#endif
39
+
40
+#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
41
+  float Backlash::measured_mm[XYZ] = { 0 };
42
+  uint8_t Backlash::measured_count[XYZ] = { 0 };
43
+#endif
44
+
45
+Backlash backlash;
46
+
47
+/**
48
+ * To minimize seams in the printed part, backlash correction only adds
49
+ * steps to the current segment (instead of creating a new segment, which
50
+ * causes discontinuities and print artifacts).
51
+ *
52
+ * With a non-zero BACKLASH_SMOOTHING_MM value the backlash correction is
53
+ * spread over multiple segments, smoothing out artifacts even more.
54
+ */
55
+
56
+void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const uint8_t dm, block_t * const block) {
57
+  static uint8_t last_direction_bits;
58
+  uint8_t changed_dir = last_direction_bits ^ dm;
59
+  // Ignore direction change if no steps are taken in that direction
60
+  if (da == 0) CBI(changed_dir, X_AXIS);
61
+  if (db == 0) CBI(changed_dir, Y_AXIS);
62
+  if (dc == 0) CBI(changed_dir, Z_AXIS);
63
+  last_direction_bits ^= changed_dir;
64
+
65
+  if (correction == 0) return;
66
+
67
+  #ifdef BACKLASH_SMOOTHING_MM
68
+    // The segment proportion is a value greater than 0.0 indicating how much residual_error
69
+    // is corrected for in this segment. The contribution is based on segment length and the
70
+    // smoothing distance. Since the computation of this proportion involves a floating point
71
+    // division, defer computation until needed.
72
+    float segment_proportion = 0;
73
+
74
+    // Residual error carried forward across multiple segments, so correction can be applied
75
+    // to segments where there is no direction change.
76
+    static int32_t residual_error[XYZ] = { 0 };
77
+  #else
78
+    // No leftover residual error from segment to segment
79
+    int32_t residual_error[XYZ] = { 0 };
80
+    // No direction change, no correction.
81
+    if (!changed_dir) return;
82
+  #endif
83
+
84
+  const float f_corr = float(correction) / 255.0f;
85
+
86
+  LOOP_XYZ(axis) {
87
+    if (distance_mm[axis]) {
88
+      const bool reversing = TEST(dm,axis);
89
+
90
+      // When an axis changes direction, add axis backlash to the residual error
91
+      if (TEST(changed_dir, axis))
92
+        residual_error[axis] += (reversing ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
93
+
94
+      // Decide how much of the residual error to correct in this segment
95
+      int32_t error_correction = residual_error[axis];
96
+      #ifdef BACKLASH_SMOOTHING_MM
97
+        if (error_correction && smoothing_mm != 0) {
98
+          // Take up a portion of the residual_error in this segment, but only when
99
+          // the current segment travels in the same direction as the correction
100
+          if (reversing == (error_correction < 0)) {
101
+            if (segment_proportion == 0)
102
+              segment_proportion = MIN(1.0f, block->millimeters / smoothing_mm);
103
+            error_correction = ceil(segment_proportion * error_correction);
104
+          }
105
+          else
106
+            error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
107
+        }
108
+      #endif
109
+      // Making a correction reduces the residual error and modifies delta_mm
110
+      if (error_correction) {
111
+        block->steps[axis] += ABS(error_correction);
112
+        residual_error[axis] -= error_correction;
113
+      }
114
+    }
115
+  }
116
+}
117
+
118
+#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
119
+  #if USES_Z_MIN_PROBE_ENDSTOP
120
+    #define TEST_PROBE_PIN (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
121
+  #else
122
+    #define TEST_PROBE_PIN (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
123
+  #endif
124
+
125
+  // Measure Z backlash by raising nozzle in increments until probe deactivates
126
+  void Backlash::measure_with_probe() {
127
+    if (measured_count[Z_AXIS] == 255) return;
128
+
129
+    float start_height = current_position[Z_AXIS];
130
+    while (current_position[Z_AXIS] < (start_height + BACKLASH_MEASUREMENT_LIMIT) && TEST_PROBE_PIN)
131
+      do_blocking_move_to_z(current_position[Z_AXIS] + BACKLASH_MEASUREMENT_RESOLUTION, MMM_TO_MMS(BACKLASH_MEASUREMENT_FEEDRATE));
132
+
133
+    // The backlash from all probe points is averaged, so count the number of measurements
134
+    measured_mm[Z_AXIS] += current_position[Z_AXIS] - start_height;
135
+    measured_count[Z_AXIS]++;
136
+  }
137
+#endif
138
+
139
+#endif // BACKLASH_COMPENSATION

+ 88
- 0
Marlin/src/feature/backlash.h Visa fil

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+#pragma once
23
+
24
+#include "../inc/MarlinConfigPre.h"
25
+#include "../module/planner.h"
26
+
27
+class Backlash {
28
+public:
29
+  #if ENABLED(BACKLASH_GCODE)
30
+    static uint8_t correction;
31
+    #ifdef BACKLASH_DISTANCE_MM
32
+      static float distance_mm[XYZ];
33
+    #endif
34
+    #ifdef BACKLASH_SMOOTHING_MM
35
+      static float smoothing_mm;
36
+    #endif
37
+    static inline void set_correction(const float &v) { correction = MAX(0, MIN(1.0, v)) * all_on; }
38
+    static inline float get_correction() { return float(ui8_to_percent(correction)) / 100.0f; }
39
+  #elif ENABLED(BACKLASH_COMPENSATION)
40
+    static constexpr uint8_t correction = (BACKLASH_CORRECTION) * 0xFF;
41
+    #ifdef BACKLASH_DISTANCE_MM
42
+      static constexpr float distance_mm[XYZ] = BACKLASH_DISTANCE_MM;
43
+    #endif
44
+    #ifdef BACKLASH_SMOOTHING_MM
45
+      static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM;
46
+    #endif
47
+    static inline void set_correction(float) { }
48
+    static inline float get_correction() { return float(ui8_to_percent(correction)) / 100.0f; }
49
+  #else
50
+    static constexpr uint8_t correction = 0;
51
+    static inline void set_correction(float) { }
52
+    static inline float get_correction() { return 0; }
53
+  #endif
54
+
55
+  #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
56
+    private:
57
+      static float measured_mm[XYZ];
58
+      static uint8_t measured_count[XYZ];
59
+    public:
60
+      static void measure_with_probe();
61
+  #endif
62
+
63
+  static inline float get_measurement(const uint8_t e) {
64
+    // Return the measurement averaged over all readings
65
+    return (
66
+      #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
67
+        measured_count[e] > 0 ? measured_mm[e] / measured_count[e] :
68
+      #endif
69
+      0
70
+    );
71
+  }
72
+
73
+  static inline bool has_measurement(const uint8_t e) {
74
+    return (false
75
+      #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
76
+        || (measured_count[e] > 0)
77
+      #endif
78
+    );
79
+  }
80
+
81
+  static inline bool has_any_measurement() {
82
+    return has_measurement(X_AXIS) || has_measurement(Y_AXIS) || has_measurement(Z_AXIS);
83
+  }
84
+
85
+  void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const uint8_t dm, block_t * const block);
86
+};
87
+
88
+extern Backlash backlash;

+ 1
- 1
Marlin/src/feature/runout.cpp Visa fil

51
   uint8_t FilamentSensorEncoder::motion_detected;
51
   uint8_t FilamentSensorEncoder::motion_detected;
52
 #endif
52
 #endif
53
 
53
 
54
-#if FILAMENT_RUNOUT_DISTANCE_MM > 0
54
+#ifdef FILAMENT_RUNOUT_DISTANCE_MM
55
   float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM;
55
   float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM;
56
   volatile float RunoutResponseDelayed::runout_mm_countdown[EXTRUDERS];
56
   volatile float RunoutResponseDelayed::runout_mm_countdown[EXTRUDERS];
57
 #else
57
 #else

+ 12
- 6
Marlin/src/feature/runout.h Visa fil

78
       response.filament_present(extruder);
78
       response.filament_present(extruder);
79
     }
79
     }
80
 
80
 
81
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
82
+      static inline float& runout_distance() { return response.runout_distance_mm; }
83
+      static inline void set_runout_distance(const float &mm) { response.runout_distance_mm = mm; }
84
+    #endif
85
+
81
     // Handle a block completion. RunoutResponseDelayed uses this to
86
     // Handle a block completion. RunoutResponseDelayed uses this to
82
     // add up the length of filament moved while the filament is out.
87
     // add up the length of filament moved while the filament is out.
83
     static inline void block_completed(const block_t* const b) {
88
     static inline void block_completed(const block_t* const b) {
90
     // Give the response a chance to update its counter.
95
     // Give the response a chance to update its counter.
91
     static inline void run() {
96
     static inline void run() {
92
       if (enabled && !filament_ran_out && (IS_SD_PRINTING() || print_job_timer.isRunning() || did_pause_print)) {
97
       if (enabled && !filament_ran_out && (IS_SD_PRINTING() || print_job_timer.isRunning() || did_pause_print)) {
93
-        #if FILAMENT_RUNOUT_DISTANCE_MM > 0
98
+        #ifdef FILAMENT_RUNOUT_DISTANCE_MM
94
           cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here
99
           cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here
95
         #endif
100
         #endif
96
         response.run();
101
         response.run();
97
         sensor.run();
102
         sensor.run();
98
         const bool ran_out = response.has_run_out();
103
         const bool ran_out = response.has_run_out();
99
-        #if FILAMENT_RUNOUT_DISTANCE_MM > 0
104
+        #ifdef FILAMENT_RUNOUT_DISTANCE_MM
100
           sei();
105
           sei();
101
         #endif
106
         #endif
102
         if (ran_out) {
107
         if (ran_out) {
272
 
277
 
273
 /********************************* RESPONSE TYPE *********************************/
278
 /********************************* RESPONSE TYPE *********************************/
274
 
279
 
275
-#if FILAMENT_RUNOUT_DISTANCE_MM > 0
280
+#ifdef FILAMENT_RUNOUT_DISTANCE_MM
276
 
281
 
277
   // RunoutResponseDelayed triggers a runout event only if the length
282
   // RunoutResponseDelayed triggers a runout event only if the length
278
   // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed
283
   // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed
347
 /********************************* TEMPLATE SPECIALIZATION *********************************/
352
 /********************************* TEMPLATE SPECIALIZATION *********************************/
348
 
353
 
349
 typedef TFilamentMonitor<
354
 typedef TFilamentMonitor<
350
-  #if FILAMENT_RUNOUT_DISTANCE_MM > 0
355
+  #ifdef FILAMENT_RUNOUT_DISTANCE_MM
356
+    RunoutResponseDelayed,
351
     #if ENABLED(FILAMENT_MOTION_SENSOR)
357
     #if ENABLED(FILAMENT_MOTION_SENSOR)
352
-      RunoutResponseDelayed, FilamentSensorEncoder
358
+      FilamentSensorEncoder
353
     #else
359
     #else
354
-      RunoutResponseDelayed, FilamentSensorSwitch
360
+      FilamentSensorSwitch
355
     #endif
361
     #endif
356
   #else
362
   #else
357
     RunoutResponseDebounced, FilamentSensorSwitch
363
     RunoutResponseDebounced, FilamentSensorSwitch

+ 10
- 14
Marlin/src/gcode/calibrate/G425.cpp Visa fil

31
 #include "../../module/tool_change.h"
31
 #include "../../module/tool_change.h"
32
 #include "../../module/endstops.h"
32
 #include "../../module/endstops.h"
33
 #include "../../feature/bedlevel/bedlevel.h"
33
 #include "../../feature/bedlevel/bedlevel.h"
34
+#include "../../feature/backlash.h"
34
 
35
 
35
 
36
 
36
 /**
37
 /**
55
 #define HAS_X_CENTER BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
56
 #define HAS_X_CENTER BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
56
 #define HAS_Y_CENTER BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
57
 #define HAS_Y_CENTER BOTH(CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
57
 
58
 
58
-#if ENABLED(BACKLASH_GCODE)
59
-  extern float backlash_distance_mm[], backlash_smoothing_mm;
60
-  extern uint8_t backlash_correction;
61
-#endif
62
-
63
 enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
59
 enum side_t : uint8_t { TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES };
64
 
60
 
65
 struct measurements_t {
61
 struct measurements_t {
79
 #define TEMPORARY_SOFT_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable);
75
 #define TEMPORARY_SOFT_ENDSTOP_STATE(enable) REMEMBER(tes, soft_endstops_enabled, enable);
80
 
76
 
81
 #if ENABLED(BACKLASH_GCODE)
77
 #if ENABLED(BACKLASH_GCODE)
82
-  #define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash_correction, value)
78
+  #define TEMPORARY_BACKLASH_CORRECTION(value) REMEMBER(tbst, backlash.correction, value)
83
 #else
79
 #else
84
   #define TEMPORARY_BACKLASH_CORRECTION(value)
80
   #define TEMPORARY_BACKLASH_CORRECTION(value)
85
 #endif
81
 #endif
86
 
82
 
87
 #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
83
 #if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM)
88
-  #define TEMPORARY_BACKLASH_SMOOTHING(value) REMEMBER(tbsm, backlash_smoothing_mm, value)
84
+  #define TEMPORARY_BACKLASH_SMOOTHING(value) REMEMBER(tbsm, backlash.smoothing_mm, value)
89
 #else
85
 #else
90
   #define TEMPORARY_BACKLASH_SMOOTHING(value)
86
   #define TEMPORARY_BACKLASH_SMOOTHING(value)
91
 #endif
87
 #endif
454
 
450
 
455
     #if ENABLED(BACKLASH_GCODE)
451
     #if ENABLED(BACKLASH_GCODE)
456
       #if HAS_X_CENTER
452
       #if HAS_X_CENTER
457
-        backlash_distance_mm[X_AXIS] = (m.backlash[LEFT] + m.backlash[RIGHT]) / 2;
453
+        backlash.distance_mm[X_AXIS] = (m.backlash[LEFT] + m.backlash[RIGHT]) / 2;
458
       #elif ENABLED(CALIBRATION_MEASURE_LEFT)
454
       #elif ENABLED(CALIBRATION_MEASURE_LEFT)
459
-        backlash_distance_mm[X_AXIS] = m.backlash[LEFT];
455
+        backlash.distance_mm[X_AXIS] = m.backlash[LEFT];
460
       #elif ENABLED(CALIBRATION_MEASURE_RIGHT)
456
       #elif ENABLED(CALIBRATION_MEASURE_RIGHT)
461
-        backlash_distance_mm[X_AXIS] = m.backlash[RIGHT];
457
+        backlash.distance_mm[X_AXIS] = m.backlash[RIGHT];
462
       #endif
458
       #endif
463
 
459
 
464
       #if HAS_Y_CENTER
460
       #if HAS_Y_CENTER
465
-        backlash_distance_mm[Y_AXIS] = (m.backlash[FRONT] + m.backlash[BACK]) / 2;
461
+        backlash.distance_mm[Y_AXIS] = (m.backlash[FRONT] + m.backlash[BACK]) / 2;
466
       #elif ENABLED(CALIBRATION_MEASURE_FRONT)
462
       #elif ENABLED(CALIBRATION_MEASURE_FRONT)
467
-        backlash_distance_mm[Y_AXIS] = m.backlash[FRONT];
463
+        backlash.distance_mm[Y_AXIS] = m.backlash[FRONT];
468
       #elif ENABLED(CALIBRATION_MEASURE_BACK)
464
       #elif ENABLED(CALIBRATION_MEASURE_BACK)
469
-        backlash_distance_mm[Y_AXIS] = m.backlash[BACK];
465
+        backlash.distance_mm[Y_AXIS] = m.backlash[BACK];
470
       #endif
466
       #endif
471
 
467
 
472
-      backlash_distance_mm[Z_AXIS] = m.backlash[TOP];
468
+      backlash.distance_mm[Z_AXIS] = m.backlash[TOP];
473
     #endif
469
     #endif
474
   }
470
   }
475
 
471
 

+ 13
- 31
Marlin/src/gcode/calibrate/M425.cpp Visa fil

24
 
24
 
25
 #if ENABLED(BACKLASH_GCODE)
25
 #if ENABLED(BACKLASH_GCODE)
26
 
26
 
27
+#include "../../feature/backlash.h"
27
 #include "../../module/planner.h"
28
 #include "../../module/planner.h"
28
 
29
 
29
-float   backlash_distance_mm[XYZ] = BACKLASH_DISTANCE_MM;
30
-uint8_t backlash_correction = BACKLASH_CORRECTION * all_on;
31
-
32
-#ifdef BACKLASH_SMOOTHING_MM
33
-  float backlash_smoothing_mm = BACKLASH_SMOOTHING_MM;
34
-#endif
35
-
36
-#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
37
-  float backlash_measured_mm[XYZ] = { 0 };
38
-  uint8_t backlash_measured_num[XYZ] = { 0 };
39
-#endif
40
-
41
 #include "../gcode.h"
30
 #include "../gcode.h"
42
 
31
 
43
 /**
32
 /**
60
   LOOP_XYZ(i) {
49
   LOOP_XYZ(i) {
61
     if (parser.seen(axis_codes[i])) {
50
     if (parser.seen(axis_codes[i])) {
62
       planner.synchronize();
51
       planner.synchronize();
63
-      const float measured_backlash = (
64
-        #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
65
-          backlash_measured_num[i] > 0 ? backlash_measured_mm[i] / backlash_measured_num[i] : 0
66
-        #else
67
-          0
68
-        #endif
69
-      );
70
-      backlash_distance_mm[i] = parser.has_value() ? parser.value_linear_units() : measured_backlash;
52
+      backlash.distance_mm[i] = parser.has_value() ? parser.value_linear_units() : backlash.get_measurement(i);
71
       noArgs = false;
53
       noArgs = false;
72
     }
54
     }
73
   }
55
   }
74
 
56
 
75
   if (parser.seen('F')) {
57
   if (parser.seen('F')) {
76
     planner.synchronize();
58
     planner.synchronize();
77
-    backlash_correction = MAX(0, MIN(1.0, parser.value_float())) * all_on;
59
+    backlash.set_correction(parser.value_float());
78
     noArgs = false;
60
     noArgs = false;
79
   }
61
   }
80
 
62
 
81
   #ifdef BACKLASH_SMOOTHING_MM
63
   #ifdef BACKLASH_SMOOTHING_MM
82
     if (parser.seen('S')) {
64
     if (parser.seen('S')) {
83
       planner.synchronize();
65
       planner.synchronize();
84
-      backlash_smoothing_mm = parser.value_linear_units();
66
+      backlash.smoothing_mm = parser.value_linear_units();
85
       noArgs = false;
67
       noArgs = false;
86
     }
68
     }
87
   #endif
69
   #endif
88
 
70
 
89
   if (noArgs) {
71
   if (noArgs) {
90
-    SERIAL_ECHOPGM("Backlash correction is ");
91
-    if (!backlash_correction) SERIAL_ECHOPGM("in");
72
+    SERIAL_ECHOPGM("Backlash Correction ");
73
+    if (!backlash.correction) SERIAL_ECHOPGM("in");
92
     SERIAL_ECHOLNPGM("active:");
74
     SERIAL_ECHOLNPGM("active:");
93
-    SERIAL_ECHOLNPAIR("  Correction Amount/Fade-out:     F", float(ui8_to_percent(backlash_correction)) / 100, "     (F1.0 = full, F0.0 = none)");
75
+    SERIAL_ECHOLNPAIR("  Correction Amount/Fade-out:     F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)");
94
     SERIAL_ECHOPGM("  Backlash Distance (mm):        ");
76
     SERIAL_ECHOPGM("  Backlash Distance (mm):        ");
95
     LOOP_XYZ(a) {
77
     LOOP_XYZ(a) {
96
       SERIAL_CHAR(' ');
78
       SERIAL_CHAR(' ');
97
       SERIAL_CHAR(axis_codes[a]);
79
       SERIAL_CHAR(axis_codes[a]);
98
-      SERIAL_ECHO(backlash_distance_mm[a]);
80
+      SERIAL_ECHO(backlash.distance_mm[a]);
99
       SERIAL_EOL();
81
       SERIAL_EOL();
100
     }
82
     }
101
 
83
 
102
     #ifdef BACKLASH_SMOOTHING_MM
84
     #ifdef BACKLASH_SMOOTHING_MM
103
-      SERIAL_ECHOLNPAIR("  Smoothing (mm):                 S", backlash_smoothing_mm);
85
+      SERIAL_ECHOLNPAIR("  Smoothing (mm):                 S", backlash.smoothing_mm);
104
     #endif
86
     #endif
105
 
87
 
106
     #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
88
     #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
107
       SERIAL_ECHOPGM("  Average measured backlash (mm):");
89
       SERIAL_ECHOPGM("  Average measured backlash (mm):");
108
-      LOOP_XYZ(a) {
109
-        if (backlash_measured_num[a] > 0) {
90
+      if (backlash.has_any_measurement()) {
91
+        LOOP_XYZ(a) if (backlash.has_measurement(a)) {
110
           SERIAL_CHAR(' ');
92
           SERIAL_CHAR(' ');
111
           SERIAL_CHAR(axis_codes[a]);
93
           SERIAL_CHAR(axis_codes[a]);
112
-          SERIAL_ECHO(backlash_measured_mm[a] / backlash_measured_num[a]);
94
+          SERIAL_ECHO(backlash.get_measurement(a));
113
         }
95
         }
114
       }
96
       }
115
-      if (!backlash_measured_num[X_AXIS] && !backlash_measured_num[Y_AXIS] && !backlash_measured_num[Z_AXIS])
97
+      else
116
         SERIAL_ECHOPGM(" (Not yet measured)");
98
         SERIAL_ECHOPGM(" (Not yet measured)");
117
       SERIAL_EOL();
99
       SERIAL_EOL();
118
     #endif
100
     #endif

+ 9
- 0
Marlin/src/gcode/feature/runout/M412.cpp Visa fil

32
  */
32
  */
33
 void GcodeSuite::M412() {
33
 void GcodeSuite::M412() {
34
   if (parser.seen("HS"
34
   if (parser.seen("HS"
35
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
36
+      "D"
37
+    #endif
35
     #if ENABLED(HOST_ACTION_COMMANDS)
38
     #if ENABLED(HOST_ACTION_COMMANDS)
36
       "R"
39
       "R"
37
     #endif
40
     #endif
42
     const bool seenR = parser.seen('R'), seenS = parser.seen('S');
45
     const bool seenR = parser.seen('R'), seenS = parser.seen('S');
43
     if (seenR || seenS) runout.reset();
46
     if (seenR || seenS) runout.reset();
44
     if (seenS) runout.enabled = parser.value_bool();
47
     if (seenS) runout.enabled = parser.value_bool();
48
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
49
+      if (parser.seen('D')) runout.set_runout_distance(parser.value_linear_units());
50
+    #endif
45
   }
51
   }
46
   else {
52
   else {
47
     SERIAL_ECHO_START();
53
     SERIAL_ECHO_START();
48
     SERIAL_ECHOPGM("Filament runout ");
54
     SERIAL_ECHOPGM("Filament runout ");
49
     serialprintln_onoff(runout.enabled);
55
     serialprintln_onoff(runout.enabled);
56
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
57
+      SERIAL_ECHOLNPAIR("Filament runout distance (mm): ", runout.runout_distance());
58
+    #endif
50
   }
59
   }
51
 }
60
 }
52
 
61
 

+ 3
- 0
Marlin/src/inc/Conditionals_LCD.h Visa fil

516
   #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y))
516
   #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y))
517
 #endif
517
 #endif
518
 
518
 
519
+#if ENABLED(MALYAN_LCD)
520
+  #define EXTENSIBLE_UI
521
+#endif
519
 #define HAS_SOFTWARE_ENDSTOPS EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
522
 #define HAS_SOFTWARE_ENDSTOPS EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
520
 #define HAS_RESUME_CONTINUE   ANY(EXTENSIBLE_UI, NEWPANEL, EMERGENCY_PARSER)
523
 #define HAS_RESUME_CONTINUE   ANY(EXTENSIBLE_UI, NEWPANEL, EMERGENCY_PARSER)
521
 #define HAS_COLOR_LEDS        ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED)
524
 #define HAS_COLOR_LEDS        ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED)

+ 3
- 1
Marlin/src/inc/SanityCheck.h Visa fil

613
     #error "FILAMENT_RUNOUT_SENSOR with NUM_RUNOUT_SENSORS > 5 requires FIL_RUNOUT6_PIN."
613
     #error "FILAMENT_RUNOUT_SENSOR with NUM_RUNOUT_SENSORS > 5 requires FIL_RUNOUT6_PIN."
614
   #elif DISABLED(SDSUPPORT, PRINTJOB_TIMER_AUTOSTART)
614
   #elif DISABLED(SDSUPPORT, PRINTJOB_TIMER_AUTOSTART)
615
     #error "FILAMENT_RUNOUT_SENSOR requires SDSUPPORT or PRINTJOB_TIMER_AUTOSTART."
615
     #error "FILAMENT_RUNOUT_SENSOR requires SDSUPPORT or PRINTJOB_TIMER_AUTOSTART."
616
+  #elif FILAMENT_RUNOUT_DISTANCE_MM < 0
617
+    #error "FILAMENT_RUNOUT_DISTANCE_MM must be greater than or equal to zero."
616
   #elif DISABLED(ADVANCED_PAUSE_FEATURE)
618
   #elif DISABLED(ADVANCED_PAUSE_FEATURE)
617
     static_assert(NULL == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with FILAMENT_RUNOUT_SENSOR.");
619
     static_assert(NULL == strstr(FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with FILAMENT_RUNOUT_SENSOR.");
618
   #endif
620
   #endif
1784
   + ENABLED(OLED_PANEL_TINYBOY2) \
1786
   + ENABLED(OLED_PANEL_TINYBOY2) \
1785
   + ENABLED(ZONESTAR_LCD) \
1787
   + ENABLED(ZONESTAR_LCD) \
1786
   + ENABLED(ULTI_CONTROLLER) \
1788
   + ENABLED(ULTI_CONTROLLER) \
1787
-  + ENABLED(EXTENSIBLE_UI)
1789
+  + (ENABLED(EXTENSIBLE_UI) && DISABLED(MALYAN_LCD))
1788
   #error "Please select no more than one LCD controller option."
1790
   #error "Please select no more than one LCD controller option."
1789
 #endif
1791
 #endif
1790
 
1792
 

+ 35
- 7
Marlin/src/lcd/extensible_ui/lib/example.cpp Visa fil

1
-/*************
2
- * dummy.cpp *
3
- *************/
1
+/***************
2
+ * example.cpp *
3
+ ***************/
4
 
4
 
5
 /****************************************************************************
5
 /****************************************************************************
6
  *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
6
  *   Written By Marcio Teixeira 2018 - Aleph Objects, Inc.                  *
21
 
21
 
22
 #include "../../../inc/MarlinConfigPre.h"
22
 #include "../../../inc/MarlinConfigPre.h"
23
 
23
 
24
-#if ENABLED(EXTENSIBLE_UI)
24
+#if BOTH(EXTUI_EXAMPLE, EXTENSIBLE_UI)
25
 
25
 
26
 #include "../ui_api.h"
26
 #include "../ui_api.h"
27
 
27
 
58
   void onUserConfirmRequired(const char * const msg) {}
58
   void onUserConfirmRequired(const char * const msg) {}
59
   void onStatusChanged(const char * const msg) {}
59
   void onStatusChanged(const char * const msg) {}
60
   void onFactoryReset() {}
60
   void onFactoryReset() {}
61
-  void onLoadSettings() {}
62
-  void onStoreSettings() {}
61
+
62
+  void onStoreSettings(char *buff) {
63
+    // This is called when saving to EEPROM (i.e. M500). If the ExtUI needs
64
+    // permanent data to be stored, it can write up to eeprom_data_size bytes
65
+    // into buff.
66
+
67
+    // Example:
68
+    //  static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
69
+    //  memcpy(buff, &myDataStruct, sizeof(myDataStruct));
70
+  }
71
+
72
+  void onLoadSettings(const char *buff) {
73
+    // This is called while loading settings from EEPROM. If the ExtUI
74
+    // needs to retrieve data, it should copy up to eeprom_data_size bytes
75
+    // from buff
76
+
77
+    // Example:
78
+    //  static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
79
+    //  memcpy(&myDataStruct, buff, sizeof(myDataStruct));
80
+  }
81
+
82
+  void onConfigurationStoreWritten(bool success) {
83
+    // This is called after the entire EEPROM has been written,
84
+    // whether successful or not.
85
+  }
86
+
87
+  void onConfigurationStoreRead(bool success) {
88
+    // This is called after the entire EEPROM has been read,
89
+    // whether successful or not.
90
+  }
63
 }
91
 }
64
 
92
 
65
-#endif // EXTENSIBLE_UI
93
+#endif // EXTUI_EXAMPLE && EXTENSIBLE_UI

+ 11
- 16
Marlin/src/lcd/extensible_ui/ui_api.cpp Visa fil

82
 #include "ui_api.h"
82
 #include "ui_api.h"
83
 
83
 
84
 #if ENABLED(BACKLASH_GCODE)
84
 #if ENABLED(BACKLASH_GCODE)
85
-  extern float backlash_distance_mm[XYZ];
86
-  extern uint8_t backlash_correction;
87
-  #ifdef BACKLASH_SMOOTHING_MM
88
-    extern float backlash_smoothing_mm;
89
-  #endif
85
+  #include "../../feature/backlash.h"
90
 #endif
86
 #endif
91
 
87
 
92
 #if HAS_LEVELING
88
 #if HAS_LEVELING
111
 } flags;
107
 } flags;
112
 
108
 
113
 namespace ExtUI {
109
 namespace ExtUI {
114
-
115
   #ifdef __SAM3X8E__
110
   #ifdef __SAM3X8E__
116
     /**
111
     /**
117
      * Implement a special millis() to allow time measurement
112
      * Implement a special millis() to allow time measurement
517
     bool getFilamentRunoutEnabled()                 { return runout.enabled; }
512
     bool getFilamentRunoutEnabled()                 { return runout.enabled; }
518
     void setFilamentRunoutEnabled(const bool value) { runout.enabled = value; }
513
     void setFilamentRunoutEnabled(const bool value) { runout.enabled = value; }
519
 
514
 
520
-    #if FILAMENT_RUNOUT_DISTANCE_MM > 0
515
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
521
       float getFilamentRunoutDistance_mm() {
516
       float getFilamentRunoutDistance_mm() {
522
-        return RunoutResponseDelayed::runout_distance_mm;
517
+        return runout.runout_distance();
523
       }
518
       }
524
 
519
 
525
       void setFilamentRunoutDistance_mm(const float value) {
520
       void setFilamentRunoutDistance_mm(const float value) {
526
-        RunoutResponseDelayed::runout_distance_mm = clamp(value, 0, 999);
521
+        runout.set_runout_distance(clamp(value, 0, 999));
527
       }
522
       }
528
     #endif
523
     #endif
529
   #endif
524
   #endif
687
   #endif // HAS_HOTEND_OFFSET
682
   #endif // HAS_HOTEND_OFFSET
688
 
683
 
689
   #if ENABLED(BACKLASH_GCODE)
684
   #if ENABLED(BACKLASH_GCODE)
690
-    float getAxisBacklash_mm(const axis_t axis)       { return backlash_distance_mm[axis]; }
685
+    float getAxisBacklash_mm(const axis_t axis)       { return backlash.distance_mm[axis]; }
691
     void setAxisBacklash_mm(const float value, const axis_t axis)
686
     void setAxisBacklash_mm(const float value, const axis_t axis)
692
-                                                      { backlash_distance_mm[axis] = clamp(value,0,5); }
687
+                                                      { backlash.distance_mm[axis] = clamp(value,0,5); }
693
 
688
 
694
-    float getBacklashCorrection_percent()             { return ui8_to_percent(backlash_correction); }
695
-    void setBacklashCorrection_percent(const float value) { backlash_correction = map(clamp(value, 0, 100), 0, 100, 0, 255); }
689
+    float getBacklashCorrection_percent()             { return ui8_to_percent(backlash.correction); }
690
+    void setBacklashCorrection_percent(const float value) { backlash.correction = map(clamp(value, 0, 100), 0, 100, 0, 255); }
696
 
691
 
697
     #ifdef BACKLASH_SMOOTHING_MM
692
     #ifdef BACKLASH_SMOOTHING_MM
698
-      float getBacklashSmoothing_mm()                 { return backlash_smoothing_mm; }
699
-      void setBacklashSmoothing_mm(const float value) { backlash_smoothing_mm = clamp(value, 0, 999); }
693
+      float getBacklashSmoothing_mm()                 { return backlash.smoothing_mm; }
694
+      void setBacklashSmoothing_mm(const float value) { backlash.smoothing_mm = clamp(value, 0, 999); }
700
     #endif
695
     #endif
701
   #endif
696
   #endif
702
 
697
 
750
   }
745
   }
751
 
746
 
752
   bool commandsInQueue() { return (planner.movesplanned() || commands_in_queue); }
747
   bool commandsInQueue() { return (planner.movesplanned() || commands_in_queue); }
753
-  
748
+
754
   bool isAxisPositionKnown(const axis_t axis) {
749
   bool isAxisPositionKnown(const axis_t axis) {
755
     return TEST(axis_known_position, axis);
750
     return TEST(axis_known_position, axis);
756
   }
751
   }

+ 10
- 3
Marlin/src/lcd/extensible_ui/ui_api.h Visa fil

46
 #include "../../inc/MarlinConfig.h"
46
 #include "../../inc/MarlinConfig.h"
47
 
47
 
48
 namespace ExtUI {
48
 namespace ExtUI {
49
+  // The ExtUI implementation can store up to this many bytes
50
+  // in the EEPROM when the methods onStoreSettings and
51
+  // onLoadSettings are called.
52
+
53
+  static constexpr size_t eeprom_data_size = 48;
49
 
54
 
50
   enum axis_t     : uint8_t { X, Y, Z };
55
   enum axis_t     : uint8_t { X, Y, Z };
51
   enum extruder_t : uint8_t { E0, E1, E2, E3, E4, E5 };
56
   enum extruder_t : uint8_t { E0, E1, E2, E3, E4, E5 };
207
     bool getFilamentRunoutEnabled();
212
     bool getFilamentRunoutEnabled();
208
     void setFilamentRunoutEnabled(const bool);
213
     void setFilamentRunoutEnabled(const bool);
209
 
214
 
210
-    #if FILAMENT_RUNOUT_DISTANCE_MM > 0
215
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
211
       float getFilamentRunoutDistance_mm();
216
       float getFilamentRunoutDistance_mm();
212
       void setFilamentRunoutDistance_mm(const float);
217
       void setFilamentRunoutDistance_mm(const float);
213
     #endif
218
     #endif
283
   void onUserConfirmRequired(const char * const msg);
288
   void onUserConfirmRequired(const char * const msg);
284
   void onStatusChanged(const char * const msg);
289
   void onStatusChanged(const char * const msg);
285
   void onFactoryReset();
290
   void onFactoryReset();
286
-  void onStoreSettings();
287
-  void onLoadSettings();
291
+  void onStoreSettings(char *);
292
+  void onLoadSettings(const char *);
293
+  void onConfigurationStoreWritten(bool success);
294
+  void onConfigurationStoreRead(bool success);
288
 };
295
 };
289
 
296
 
290
 /**
297
 /**

+ 107
- 71
Marlin/src/lcd/malyanlcd.cpp Visa fil

41
  * Copyright (c) 2017 Jason Nelson (xC0000005)
41
  * Copyright (c) 2017 Jason Nelson (xC0000005)
42
  */
42
  */
43
 
43
 
44
-#include "../inc/MarlinConfig.h"
44
+#include "../inc/MarlinConfigPre.h"
45
 
45
 
46
 #if ENABLED(MALYAN_LCD)
46
 #if ENABLED(MALYAN_LCD)
47
 
47
 
48
+#include "extensible_ui/ui_api.h"
49
+
48
 #include "ultralcd.h"
50
 #include "ultralcd.h"
49
 #include "../module/temperature.h"
51
 #include "../module/temperature.h"
50
-#include "../module/planner.h"
51
 #include "../module/stepper.h"
52
 #include "../module/stepper.h"
52
 #include "../module/motion.h"
53
 #include "../module/motion.h"
53
-#include "../module/probe.h"
54
 #include "../libs/duration_t.h"
54
 #include "../libs/duration_t.h"
55
 #include "../module/printcounter.h"
55
 #include "../module/printcounter.h"
56
-#include "../gcode/gcode.h"
57
 #include "../gcode/queue.h"
56
 #include "../gcode/queue.h"
58
-#include "../module/configuration_store.h"
59
-
60
-#include "../Marlin.h"
61
 
57
 
62
 #if ENABLED(SDSUPPORT)
58
 #if ENABLED(SDSUPPORT)
63
   #include "../sd/cardreader.h"
59
   #include "../sd/cardreader.h"
412
   }
408
   }
413
 }
409
 }
414
 
410
 
415
-/**
416
- * - from printer on startup:
417
- * {SYS:STARTED}{VER:29}{SYS:STARTED}{R:UD}
418
- * The optimize attribute fixes a register Compile
419
- * error for amtel.
420
- */
421
-void MarlinUI::update() {
422
-  static char inbound_buffer[MAX_CURLY_COMMAND];
423
-
424
-  // First report USB status.
425
-  update_usb_status(false);
426
-
427
-  // now drain commands...
428
-  while (LCD_SERIAL.available()) {
429
-    const byte b = (byte)LCD_SERIAL.read() & 0x7F;
430
-    inbound_buffer[inbound_count++] = b;
431
-    if (b == '}' || inbound_count == sizeof(inbound_buffer) - 1) {
432
-      inbound_buffer[inbound_count - 1] = '\0';
433
-      process_lcd_command(inbound_buffer);
434
-      inbound_count = 0;
435
-      inbound_buffer[0] = 0;
436
-    }
411
+namespace ExtUI {
412
+  void onStartup() {
413
+    /**
414
+     * The Malyan LCD actually runs as a separate MCU on Serial 1.
415
+     * This code's job is to siphon the weird curly-brace commands from
416
+     * it and translate into gcode, which then gets injected into
417
+     * the command queue where possible.
418
+     */
419
+    inbound_count = 0;
420
+    LCD_SERIAL.begin(500000);
421
+
422
+    // Signal init
423
+    write_to_lcd_P(PSTR("{SYS:STARTED}\r\n"));
424
+
425
+    // send a version that says "unsupported"
426
+    write_to_lcd_P(PSTR("{VER:99}\r\n"));
427
+
428
+    // No idea why it does this twice.
429
+    write_to_lcd_P(PSTR("{SYS:STARTED}\r\n"));
430
+    update_usb_status(true);
437
   }
431
   }
438
 
432
 
439
-  #if ENABLED(SDSUPPORT)
440
-    // The way last printing status works is simple:
441
-    // The UI needs to see at least one TQ which is not 100%
442
-    // and then when the print is complete, one which is.
443
-    static uint8_t last_percent_done = 100;
444
-
445
-    // If there was a print in progress, we need to emit the final
446
-    // print status as {TQ:100}. Reset last percent done so a new print will
447
-    // issue a percent of 0.
448
-    const uint8_t percent_done = IS_SD_PRINTING() ? card.percentDone() : last_printing_status ? 100 : 0;
449
-    if (percent_done != last_percent_done) {
450
-      char message_buffer[10];
451
-      sprintf_P(message_buffer, PSTR("{TQ:%03i}"), percent_done);
452
-      write_to_lcd(message_buffer);
453
-      last_percent_done = percent_done;
454
-      last_printing_status = IS_SD_PRINTING();
433
+  void onIdle() {
434
+    /**
435
+     * - from printer on startup:
436
+     * {SYS:STARTED}{VER:29}{SYS:STARTED}{R:UD}
437
+     * The optimize attribute fixes a register Compile
438
+     * error for amtel.
439
+     */
440
+    static char inbound_buffer[MAX_CURLY_COMMAND];
441
+
442
+    // First report USB status.
443
+    update_usb_status(false);
444
+
445
+    // now drain commands...
446
+    while (LCD_SERIAL.available()) {
447
+      const byte b = (byte)LCD_SERIAL.read() & 0x7F;
448
+      inbound_buffer[inbound_count++] = b;
449
+      if (b == '}' || inbound_count == sizeof(inbound_buffer) - 1) {
450
+        inbound_buffer[inbound_count - 1] = '\0';
451
+        process_lcd_command(inbound_buffer);
452
+        inbound_count = 0;
453
+        inbound_buffer[0] = 0;
454
+      }
455
     }
455
     }
456
-  #endif
457
-}
458
 
456
 
459
-/**
460
- * The Malyan LCD actually runs as a separate MCU on Serial 1.
461
- * This code's job is to siphon the weird curly-brace commands from
462
- * it and translate into gcode, which then gets injected into
463
- * the command queue where possible.
464
- */
465
-void MarlinUI::init() {
466
-  inbound_count = 0;
467
-  LCD_SERIAL.begin(500000);
457
+    #if ENABLED(SDSUPPORT)
458
+      // The way last printing status works is simple:
459
+      // The UI needs to see at least one TQ which is not 100%
460
+      // and then when the print is complete, one which is.
461
+      static uint8_t last_percent_done = 100;
462
+
463
+      // If there was a print in progress, we need to emit the final
464
+      // print status as {TQ:100}. Reset last percent done so a new print will
465
+      // issue a percent of 0.
466
+      const uint8_t percent_done = IS_SD_PRINTING() ? card.percentDone() : last_printing_status ? 100 : 0;
467
+      if (percent_done != last_percent_done) {
468
+        char message_buffer[10];
469
+        sprintf_P(message_buffer, PSTR("{TQ:%03i}"), percent_done);
470
+        write_to_lcd(message_buffer);
471
+        last_percent_done = percent_done;
472
+        last_printing_status = IS_SD_PRINTING();
473
+      }
474
+    #endif
475
+  }
468
 
476
 
469
-  // Signal init
470
-  write_to_lcd_P(PSTR("{SYS:STARTED}\r\n"));
477
+  void onPrinterKilled(PGM_P const msg) {}
478
+  void onMediaInserted() {};
479
+  void onMediaError() {};
480
+  void onMediaRemoved() {};
481
+  void onPlayTone(const uint16_t frequency, const uint16_t duration) {}
482
+  void onPrintTimerStarted() {}
483
+  void onPrintTimerPaused() {}
484
+  void onPrintTimerStopped() {}
485
+  void onFilamentRunout() {}
486
+  void onUserConfirmRequired(const char * const msg) {}
487
+  void onStatusChanged(const char * const msg) {
488
+    write_to_lcd_P(PSTR("{E:"));
489
+    write_to_lcd(msg);
490
+    write_to_lcd_P("}");
491
+  }
492
+  void onFactoryReset() {}
471
 
493
 
472
-  // send a version that says "unsupported"
473
-  write_to_lcd_P(PSTR("{VER:99}\r\n"));
494
+  void onStoreSettings(char *buff) {
495
+    // This is called when saving to EEPROM (i.e. M500). If the ExtUI needs
496
+    // permanent data to be stored, it can write up to eeprom_data_size bytes
497
+    // into buff.
474
 
498
 
475
-  // No idea why it does this twice.
476
-  write_to_lcd_P(PSTR("{SYS:STARTED}\r\n"));
477
-  update_usb_status(true);
478
-}
499
+    // Example:
500
+    //  static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
501
+    //  memcpy(buff, &myDataStruct, sizeof(myDataStruct));
502
+  }
479
 
503
 
480
-/**
481
- * Set an alert.
482
- */
483
-void MarlinUI::set_alert_status_P(PGM_P const message) {
484
-  write_to_lcd_P(PSTR("{E:"));
485
-  write_to_lcd_P(message);
486
-  write_to_lcd_P("}");
504
+  void onLoadSettings(const char *buff) {
505
+    // This is called while loading settings from EEPROM. If the ExtUI
506
+    // needs to retrieve data, it should copy up to eeprom_data_size bytes
507
+    // from buff
508
+
509
+    // Example:
510
+    //  static_assert(sizeof(myDataStruct) <= ExtUI::eeprom_data_size);
511
+    //  memcpy(&myDataStruct, buff, sizeof(myDataStruct));
512
+  }
513
+
514
+  void onConfigurationStoreWritten(bool success) {
515
+    // This is called after the entire EEPROM has been written,
516
+    // whether successful or not.
517
+  }
518
+
519
+  void onConfigurationStoreRead(bool success) {
520
+    // This is called after the entire EEPROM has been read,
521
+    // whether successful or not.
522
+  }
487
 }
523
 }
488
 
524
 
489
 #endif // MALYAN_LCD
525
 #endif // MALYAN_LCD

+ 4
- 9
Marlin/src/lcd/menu/menu_backlash.cpp Visa fil

30
 
30
 
31
 #include "menu.h"
31
 #include "menu.h"
32
 
32
 
33
-extern float backlash_distance_mm[XYZ];
34
-extern uint8_t backlash_correction;
35
-
36
-#ifdef BACKLASH_SMOOTHING_MM
37
-  extern float backlash_smoothing_mm;
38
-#endif
33
+#include "../../feature/backlash.h"
39
 
34
 
40
 void menu_backlash() {
35
 void menu_backlash() {
41
   START_MENU();
36
   START_MENU();
42
   MENU_BACK(MSG_MAIN);
37
   MENU_BACK(MSG_MAIN);
43
 
38
 
44
-  MENU_MULTIPLIER_ITEM_EDIT(percent, MSG_BACKLASH_CORRECTION, &backlash_correction, all_off, all_on);
39
+  MENU_MULTIPLIER_ITEM_EDIT(percent, MSG_BACKLASH_CORRECTION, &backlash.correction, all_off, all_on);
45
 
40
 
46
-  #define EDIT_BACKLASH_DISTANCE(N) MENU_MULTIPLIER_ITEM_EDIT(float43, MSG_##N, &backlash_distance_mm[_AXIS(N)], 0.0f, 9.9f);
41
+  #define EDIT_BACKLASH_DISTANCE(N) MENU_MULTIPLIER_ITEM_EDIT(float43, MSG_##N, &backlash.distance_mm[_AXIS(N)], 0.0f, 9.9f);
47
   EDIT_BACKLASH_DISTANCE(A);
42
   EDIT_BACKLASH_DISTANCE(A);
48
   EDIT_BACKLASH_DISTANCE(B);
43
   EDIT_BACKLASH_DISTANCE(B);
49
   EDIT_BACKLASH_DISTANCE(C);
44
   EDIT_BACKLASH_DISTANCE(C);
50
 
45
 
51
   #ifdef BACKLASH_SMOOTHING_MM
46
   #ifdef BACKLASH_SMOOTHING_MM
52
-    MENU_MULTIPLIER_ITEM_EDIT(float43, MSG_BACKLASH_SMOOTHING, &backlash_smoothing_mm, 0.0f, 9.9f);
47
+    MENU_MULTIPLIER_ITEM_EDIT(float43, MSG_BACKLASH_SMOOTHING, &backlash.smoothing_mm, 0.0f, 9.9f);
53
   #endif
48
   #endif
54
 
49
 
55
   END_MENU();
50
   END_MENU();

+ 1
- 1
Marlin/src/lcd/ultralcd.cpp Visa fil

23
 #include "../inc/MarlinConfigPre.h"
23
 #include "../inc/MarlinConfigPre.h"
24
 
24
 
25
 // These displays all share the MarlinUI class
25
 // These displays all share the MarlinUI class
26
-#if HAS_SPI_LCD || EITHER(MALYAN_LCD, EXTENSIBLE_UI)
26
+#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI)
27
   #include "ultralcd.h"
27
   #include "ultralcd.h"
28
   #include "fontutils.h"
28
   #include "fontutils.h"
29
   MarlinUI ui;
29
   MarlinUI ui;

+ 173
- 9
Marlin/src/module/configuration_store.cpp Visa fil

37
  */
37
  */
38
 
38
 
39
 // Change EEPROM version if the structure changes
39
 // Change EEPROM version if the structure changes
40
-#define EEPROM_VERSION "V65"
40
+#define EEPROM_VERSION "V66"
41
 #define EEPROM_OFFSET 100
41
 #define EEPROM_OFFSET 100
42
 
42
 
43
 // Check the integrity of data offsets.
43
 // Check the integrity of data offsets.
90
 
90
 
91
 #include "../feature/pause.h"
91
 #include "../feature/pause.h"
92
 
92
 
93
+#if ENABLED(BACKLASH_COMPENSATION)
94
+  #include "../feature/backlash.h"
95
+#endif
96
+
93
 #if HAS_FILAMENT_SENSOR
97
 #if HAS_FILAMENT_SENSOR
94
   #include "../feature/runout.h"
98
   #include "../feature/runout.h"
95
 #endif
99
 #endif
96
 
100
 
101
+#include "../lcd/extensible_ui/ui_api.h"
102
+
97
 #if ENABLED(EXTRA_LIN_ADVANCE_K)
103
 #if ENABLED(EXTRA_LIN_ADVANCE_K)
98
 extern float saved_extruder_advance_K[EXTRUDERS];
104
 extern float saved_extruder_advance_K[EXTRUDERS];
99
 #endif
105
 #endif
149
   // FILAMENT_RUNOUT_SENSOR
155
   // FILAMENT_RUNOUT_SENSOR
150
   //
156
   //
151
   bool runout_sensor_enabled;                           // M412 S
157
   bool runout_sensor_enabled;                           // M412 S
158
+  float runout_distance_mm;                             // M412 D
152
 
159
 
153
   //
160
   //
154
   // ENABLE_LEVELING_FADE_HEIGHT
161
   // ENABLE_LEVELING_FADE_HEIGHT
298
     toolchange_settings_t toolchange_settings;          // M217 S P R
305
     toolchange_settings_t toolchange_settings;          // M217 S P R
299
   #endif
306
   #endif
300
 
307
 
308
+  //
309
+  // BACKLASH_COMPENSATION
310
+  //
311
+  float backlash_distance_mm[XYZ];                      // M425 X Y Z
312
+  uint8_t backlash_correction;                          // M425 F
313
+  float backlash_smoothing_mm;                          // M425 S
314
+
315
+  //
316
+  // EXTENSIBLE_UI
317
+  //
318
+  #if ENABLED(EXTENSIBLE_UI)
319
+    // This is a significant hardware change; don't reserve space when not present
320
+    uint8_t extui_data[ExtUI::eeprom_data_size];
321
+  #endif
322
+
301
 } SettingsData;
323
 } SettingsData;
302
 
324
 
303
 //static_assert(sizeof(SettingsData) <= E2END + 1, "EEPROM too small to contain SettingsData!");
325
 //static_assert(sizeof(SettingsData) <= E2END + 1, "EEPROM too small to contain SettingsData!");
372
     report_current_position();
394
     report_current_position();
373
 }
395
 }
374
 
396
 
397
+#if ENABLED(PRINTCOUNTER) && ENABLED(EEPROM_SETTINGS)
398
+  #include "printcounter.h"
399
+
400
+  static_assert(
401
+    !WITHIN(STATS_EEPROM_ADDRESS, EEPROM_OFFSET, EEPROM_OFFSET + sizeof(SettingsData)) &&
402
+    !WITHIN(STATS_EEPROM_ADDRESS + sizeof(printStatistics), EEPROM_OFFSET, EEPROM_OFFSET + sizeof(SettingsData)),
403
+    "STATS_EEPROM_ADDRESS collides with EEPROM settings storage."
404
+  );
405
+#endif
406
+
375
 #if ENABLED(SD_FIRMWARE_UPDATE)
407
 #if ENABLED(SD_FIRMWARE_UPDATE)
376
 
408
 
377
   #if ENABLED(EEPROM_SETTINGS)
409
   #if ENABLED(EEPROM_SETTINGS)
528
     //
560
     //
529
     {
561
     {
530
       #if HAS_FILAMENT_SENSOR
562
       #if HAS_FILAMENT_SENSOR
531
-        EEPROM_WRITE(runout.enabled);
563
+        const bool &runout_sensor_enabled = runout.enabled;
532
       #else
564
       #else
533
-        const bool runout_sensor_enabled = true;
534
-        EEPROM_WRITE(runout_sensor_enabled);
565
+        const bool runout_sensor_enabled = false;
535
       #endif
566
       #endif
567
+      #if HAS_FILAMENT_SENSOR && defined(FILAMENT_RUNOUT_DISTANCE_MM)
568
+        const float &runout_distance_mm = runout.runout_distance();
569
+      #else
570
+        const float runout_distance_mm = 0;
571
+      #endif
572
+      _FIELD_TEST(runout_sensor_enabled);
573
+      EEPROM_WRITE(runout_sensor_enabled);
574
+      EEPROM_WRITE(runout_distance_mm);
536
     }
575
     }
537
 
576
 
538
     //
577
     //
1119
     #endif
1158
     #endif
1120
 
1159
 
1121
     //
1160
     //
1161
+    // Backlash Compensation
1162
+    //
1163
+    {
1164
+      #if ENABLED(BACKLASH_COMPENSATION)
1165
+        const float   (&backlash_distance_mm)[XYZ] = backlash.distance_mm;
1166
+        const uint8_t &backlash_correction         = backlash.correction;
1167
+      #else
1168
+        const float    backlash_distance_mm[XYZ]   = { 0 };
1169
+        const uint8_t  backlash_correction         = 0;
1170
+      #endif
1171
+      #ifdef BACKLASH_SMOOTHING_MM
1172
+        const float   &backlash_smoothing_mm       = backlash.smoothing_mm;
1173
+      #else
1174
+        const float    backlash_smoothing_mm       = 3;
1175
+      #endif
1176
+      _FIELD_TEST(backlash_distance_mm);
1177
+      EEPROM_WRITE(backlash_distance_mm[X_AXIS]);
1178
+      EEPROM_WRITE(backlash_distance_mm[Y_AXIS]);
1179
+      EEPROM_WRITE(backlash_distance_mm[Z_AXIS]);
1180
+      EEPROM_WRITE(backlash_correction);
1181
+      EEPROM_WRITE(backlash_smoothing_mm);
1182
+    }
1183
+
1184
+    //
1185
+    // Extensible UI User Data
1186
+    //
1187
+    #if ENABLED(EXTENSIBLE_UI)
1188
+      {
1189
+        char extui_data[ExtUI::eeprom_data_size] = { 0 };
1190
+        ExtUI::onStoreSettings(extui_data);
1191
+        _FIELD_TEST(extui_data);
1192
+        EEPROM_WRITE(extui_data);
1193
+      }
1194
+    #endif
1195
+
1196
+    //
1122
     // Validate CRC and Data Size
1197
     // Validate CRC and Data Size
1123
     //
1198
     //
1124
     if (!eeprom_error) {
1199
     if (!eeprom_error) {
1148
     #endif
1223
     #endif
1149
 
1224
 
1150
     #if ENABLED(EXTENSIBLE_UI)
1225
     #if ENABLED(EXTENSIBLE_UI)
1151
-      if (!eeprom_error) ExtUI::onStoreSettings();
1226
+      ExtUI::onConfigurationStoreWritten(!eeprom_error);
1152
     #endif
1227
     #endif
1153
 
1228
 
1154
     return !eeprom_error;
1229
     return !eeprom_error;
1264
       // Filament Runout Sensor
1339
       // Filament Runout Sensor
1265
       //
1340
       //
1266
       {
1341
       {
1267
-        _FIELD_TEST(runout_sensor_enabled);
1268
         #if HAS_FILAMENT_SENSOR
1342
         #if HAS_FILAMENT_SENSOR
1269
-          EEPROM_READ(runout.enabled);
1343
+          bool &runout_sensor_enabled = runout.enabled;
1270
         #else
1344
         #else
1271
           bool runout_sensor_enabled;
1345
           bool runout_sensor_enabled;
1272
-          EEPROM_READ(runout_sensor_enabled);
1346
+        #endif
1347
+        _FIELD_TEST(runout_sensor_enabled);
1348
+        EEPROM_READ(runout_sensor_enabled);
1349
+
1350
+        float runout_distance_mm;
1351
+        EEPROM_READ(runout_distance_mm);
1352
+        #if HAS_FILAMENT_SENSOR && defined(FILAMENT_RUNOUT_DISTANCE_MM)
1353
+          runout.set_runout_distance(runout_distance_mm);
1273
         #endif
1354
         #endif
1274
       }
1355
       }
1275
 
1356
 
1851
         EEPROM_READ(toolchange_settings);
1932
         EEPROM_READ(toolchange_settings);
1852
       #endif
1933
       #endif
1853
 
1934
 
1935
+      //
1936
+      // Backlash Compensation
1937
+      //
1938
+      {
1939
+        #if ENABLED(BACKLASH_COMPENSATION)
1940
+          float   (&backlash_distance_mm)[XYZ] = backlash.distance_mm;
1941
+          uint8_t &backlash_correction         = backlash.correction;
1942
+        #else
1943
+          float   backlash_distance_mm[XYZ];
1944
+          uint8_t backlash_correction;
1945
+        #endif
1946
+        #ifdef BACKLASH_SMOOTHING_MM
1947
+          float &backlash_smoothing_mm = backlash.smoothing_mm;
1948
+        #else
1949
+          float  backlash_smoothing_mm;
1950
+        #endif
1951
+        _FIELD_TEST(backlash_distance_mm);
1952
+        EEPROM_READ(backlash_distance_mm[X_AXIS]);
1953
+        EEPROM_READ(backlash_distance_mm[Y_AXIS]);
1954
+        EEPROM_READ(backlash_distance_mm[Z_AXIS]);
1955
+        EEPROM_READ(backlash_correction);
1956
+        EEPROM_READ(backlash_smoothing_mm);
1957
+      }
1958
+
1959
+      //
1960
+      // Extensible UI User Data
1961
+      //
1962
+      #if ENABLED(EXTENSIBLE_UI)
1963
+        // This is a significant hardware change; don't reserve EEPROM space when not present
1964
+        {
1965
+          const char extui_data[ExtUI::eeprom_data_size] = { 0 };
1966
+          _FIELD_TEST(extui_data);
1967
+          EEPROM_READ(extui_data);
1968
+          if(!validating)
1969
+            ExtUI::onLoadSettings(extui_data);
1970
+        }
1971
+      #endif
1972
+
1854
       eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET));
1973
       eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET));
1855
       if (eeprom_error) {
1974
       if (eeprom_error) {
1856
         DEBUG_ECHO_START();
1975
         DEBUG_ECHO_START();
1921
     if (validate()) {
2040
     if (validate()) {
1922
       const bool success = _load();
2041
       const bool success = _load();
1923
       #if ENABLED(EXTENSIBLE_UI)
2042
       #if ENABLED(EXTENSIBLE_UI)
1924
-        if (success) ExtUI::onLoadSettings();
2043
+        ExtUI::onConfigurationStoreRead(success);
1925
       #endif
2044
       #endif
1926
       return success;
2045
       return success;
1927
     }
2046
     }
2090
   #if HAS_FILAMENT_SENSOR
2209
   #if HAS_FILAMENT_SENSOR
2091
     runout.enabled = true;
2210
     runout.enabled = true;
2092
     runout.reset();
2211
     runout.reset();
2212
+    #ifdef FILAMENT_RUNOUT_DISTANCE_MM
2213
+      runout.set_runout_distance(FILAMENT_RUNOUT_DISTANCE_MM);
2214
+    #endif
2093
   #endif
2215
   #endif
2094
 
2216
 
2095
   //
2217
   //
2108
     toolchange_settings.z_raise = TOOLCHANGE_ZRAISE;
2230
     toolchange_settings.z_raise = TOOLCHANGE_ZRAISE;
2109
   #endif
2231
   #endif
2110
 
2232
 
2233
+  #if ENABLED(BACKLASH_GCODE)
2234
+    backlash.correction = (BACKLASH_CORRECTION) * 255;
2235
+    #ifdef BACKLASH_DISTANCE_MM
2236
+      constexpr float tmp[XYZ] = BACKLASH_DISTANCE_MM;
2237
+      backlash.distance_mm[X_AXIS] = tmp[X_AXIS];
2238
+      backlash.distance_mm[Y_AXIS] = tmp[Y_AXIS];
2239
+      backlash.distance_mm[Z_AXIS] = tmp[Z_AXIS];
2240
+    #endif
2241
+    #ifdef BACKLASH_SMOOTHING_MM
2242
+      backlash.smoothing_mm = BACKLASH_SMOOTHING_MM;
2243
+    #endif
2244
+  #endif
2245
+
2246
+  #if ENABLED(EXTENSIBLE_UI)
2247
+    ExtUI::onFactoryReset();
2248
+  #endif
2249
+
2111
   //
2250
   //
2112
   // Magnetic Parking Extruder
2251
   // Magnetic Parking Extruder
2113
   //
2252
   //
3200
       CONFIG_ECHO_START();
3339
       CONFIG_ECHO_START();
3201
       M217_report(true);
3340
       M217_report(true);
3202
     #endif
3341
     #endif
3342
+
3343
+    #if ENABLED(BACKLASH_GCODE)
3344
+      CONFIG_ECHO_HEADING("Backlash compensation:");
3345
+      CONFIG_ECHO_START();
3346
+      SERIAL_ECHOLNPAIR(
3347
+        "  M425 F", backlash.get_correction(),
3348
+        " X", LINEAR_UNIT(backlash.distance_mm[X_AXIS]),
3349
+        " Y", LINEAR_UNIT(backlash.distance_mm[Y_AXIS]),
3350
+        " Z", LINEAR_UNIT(backlash.distance_mm[Z_AXIS])
3351
+        #ifdef BACKLASH_SMOOTHING_MM
3352
+          , " S", LINEAR_UNIT(backlash.smoothing_mm)
3353
+        #endif
3354
+      );
3355
+    #endif
3356
+
3357
+    #if HAS_FILAMENT_SENSOR
3358
+      CONFIG_ECHO_HEADING("Filament runout sensor:");
3359
+      CONFIG_ECHO_START();
3360
+      SERIAL_ECHOLNPAIR(
3361
+        "  M412 S", int(runout.enabled)
3362
+        #ifdef FILAMENT_RUNOUT_DISTANCE_MM
3363
+          , " D", LINEAR_UNIT(runout.runout_distance())
3364
+        #endif
3365
+      );
3366
+    #endif
3203
   }
3367
   }
3204
 
3368
 
3205
 #endif // !DISABLE_M503
3369
 #endif // !DISABLE_M503

+ 5
- 89
Marlin/src/module/planner.cpp Visa fil

92
   #include "../feature/power.h"
92
   #include "../feature/power.h"
93
 #endif
93
 #endif
94
 
94
 
95
+#if ENABLED(BACKLASH_COMPENSATION)
96
+  #include "../feature/backlash.h"
97
+#endif
98
+
95
 // Delay for delivery of first block to the stepper ISR, if the queue contains 2 or
99
 // Delay for delivery of first block to the stepper ISR, if the queue contains 2 or
96
 // fewer movements. The delay is measured in milliseconds, and must be less than 250ms
100
 // fewer movements. The delay is measured in milliseconds, and must be less than 250ms
97
 #define BLOCK_DELAY_FOR_1ST_MOVE 100
101
 #define BLOCK_DELAY_FOR_1ST_MOVE 100
1561
 }
1565
 }
1562
 
1566
 
1563
 /**
1567
 /**
1564
- * The following implements axis backlash correction. To minimize seams
1565
- * on the printed part, the backlash correction only adds steps to the
1566
- * current segment (instead of creating a new segment, which causes
1567
- * discontinuities and print artifacts).
1568
- *
1569
- * When BACKLASH_SMOOTHING_MM is enabled and non-zero, the backlash
1570
- * correction is spread over multiple segments, smoothing out print
1571
- * artifacts even more.
1572
- */
1573
-#if ENABLED(BACKLASH_COMPENSATION)
1574
-  #if ENABLED(BACKLASH_GCODE)
1575
-    extern float backlash_distance_mm[];
1576
-    extern uint8_t backlash_correction;
1577
-    #ifdef BACKLASH_SMOOTHING_MM
1578
-      extern float backlash_smoothing_mm;
1579
-    #endif
1580
-  #else
1581
-    constexpr float backlash_distance_mm[XYZ] = BACKLASH_DISTANCE_MM,
1582
-    constexpr uint8_t backlash_correction = BACKLASH_CORRECTION * 255;
1583
-    #ifdef BACKLASH_SMOOTHING_MM
1584
-      constexpr float backlash_smoothing_mm = BACKLASH_SMOOTHING_MM;
1585
-    #endif
1586
-  #endif
1587
-
1588
-  void Planner::add_backlash_correction_steps(const int32_t da, const int32_t db, const int32_t dc, const uint8_t dm, block_t * const block) {
1589
-    static uint8_t last_direction_bits;
1590
-    uint8_t changed_dir = last_direction_bits ^ dm;
1591
-    // Ignore direction change if no steps are taken in that direction
1592
-    if (da == 0) CBI(changed_dir, X_AXIS);
1593
-    if (db == 0) CBI(changed_dir, Y_AXIS);
1594
-    if (dc == 0) CBI(changed_dir, Z_AXIS);
1595
-    last_direction_bits ^= changed_dir;
1596
-
1597
-    if (backlash_correction == 0) return;
1598
-
1599
-    #ifdef BACKLASH_SMOOTHING_MM
1600
-      // The segment proportion is a value greater than 0.0 indicating how much residual_error
1601
-      // is corrected for in this segment. The contribution is based on segment length and the
1602
-      // smoothing distance. Since the computation of this proportion involves a floating point
1603
-      // division, defer computation until needed.
1604
-      float segment_proportion = 0;
1605
-
1606
-      // Residual error carried forward across multiple segments, so correction can be applied
1607
-      // to segments where there is no direction change.
1608
-      static int32_t residual_error[XYZ] = { 0 };
1609
-    #else
1610
-      // No leftover residual error from segment to segment
1611
-      int32_t residual_error[XYZ] = { 0 };
1612
-      // No direction change, no correction.
1613
-      if (!changed_dir) return;
1614
-    #endif
1615
-
1616
-    const float f_corr = float(backlash_correction) / 255.0f;
1617
-
1618
-    LOOP_XYZ(axis) {
1619
-      if (backlash_distance_mm[axis]) {
1620
-        const bool reversing = TEST(dm,axis);
1621
-
1622
-        // When an axis changes direction, add axis backlash to the residual error
1623
-        if (TEST(changed_dir, axis))
1624
-          residual_error[axis] += (reversing ? -f_corr : f_corr) * backlash_distance_mm[axis] * planner.settings.axis_steps_per_mm[axis];
1625
-
1626
-        // Decide how much of the residual error to correct in this segment
1627
-        int32_t error_correction = residual_error[axis];
1628
-        #ifdef BACKLASH_SMOOTHING_MM
1629
-          if (error_correction && backlash_smoothing_mm != 0) {
1630
-            // Take up a portion of the residual_error in this segment, but only when
1631
-            // the current segment travels in the same direction as the correction
1632
-            if (reversing == (error_correction < 0)) {
1633
-              if (segment_proportion == 0)
1634
-                segment_proportion = MIN(1.0f, block->millimeters / backlash_smoothing_mm);
1635
-              error_correction = ceil(segment_proportion * error_correction);
1636
-            }
1637
-            else
1638
-              error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps
1639
-          }
1640
-        #endif
1641
-        // Making a correction reduces the residual error and modifies delta_mm
1642
-        if (error_correction) {
1643
-          block->steps[axis] += ABS(error_correction);
1644
-          residual_error[axis] -= error_correction;
1645
-        }
1646
-      }
1647
-    }
1648
-  }
1649
-#endif // BACKLASH_COMPENSATION
1650
-
1651
-/**
1652
  * Planner::_buffer_steps
1568
  * Planner::_buffer_steps
1653
  *
1569
  *
1654
  * Add a new linear movement to the planner queue (in terms of steps).
1570
  * Add a new linear movement to the planner queue (in terms of steps).
1919
      * should *never* remove steps!
1835
      * should *never* remove steps!
1920
      */
1836
      */
1921
     #if ENABLED(BACKLASH_COMPENSATION)
1837
     #if ENABLED(BACKLASH_COMPENSATION)
1922
-      add_backlash_correction_steps(da, db, dc, dm, block);
1838
+      backlash.add_correction_steps(da, db, dc, dm, block);
1923
     #endif
1839
     #endif
1924
   }
1840
   }
1925
 
1841
 

+ 0
- 4
Marlin/src/module/planner.h Visa fil

338
       volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs
338
       volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs
339
     #endif
339
     #endif
340
 
340
 
341
-    #if ENABLED(BACKLASH_COMPENSATION)
342
-      static void add_backlash_correction_steps(const int32_t da, const int32_t db, const int32_t dc, const uint8_t dm, block_t * const block);
343
-    #endif
344
-
345
   public:
341
   public:
346
 
342
 
347
     /**
343
     /**

+ 8
- 0
Marlin/src/module/printcounter.cpp Visa fil

29
 
29
 
30
 #else // PRINTCOUNTER
30
 #else // PRINTCOUNTER
31
 
31
 
32
+#if ENABLED(EXTENSIBLE_UI)
33
+  #include "../lcd/extensible_ui/ui_api.h"
34
+#endif
35
+
32
 #include "printcounter.h"
36
 #include "printcounter.h"
33
 #include "../Marlin.h"
37
 #include "../Marlin.h"
34
 #include "../HAL/shared/persistent_store_api.h"
38
 #include "../HAL/shared/persistent_store_api.h"
169
   persistentStore.access_start();
173
   persistentStore.access_start();
170
   persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
174
   persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
171
   persistentStore.access_finish();
175
   persistentStore.access_finish();
176
+
177
+  #if ENABLED(EXTENSIBLE_UI)
178
+    ExtUI::onConfigurationStoreWritten(true);
179
+  #endif
172
 }
180
 }
173
 
181
 
174
 #if HAS_SERVICE_INTERVALS
182
 #if HAS_SERVICE_INTERVALS

+ 5
- 25
Marlin/src/module/probe.cpp Visa fil

54
   #include "planner.h"
54
   #include "planner.h"
55
 #endif
55
 #endif
56
 
56
 
57
+#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
58
+  #include "../feature/backlash.h"
59
+#endif
60
+
57
 float zprobe_zoffset; // Initialized by settings.load()
61
 float zprobe_zoffset; // Initialized by settings.load()
58
 
62
 
59
 #if ENABLED(BLTOUCH)
63
 #if ENABLED(BLTOUCH)
463
   }
467
   }
464
 #endif
468
 #endif
465
 
469
 
466
-#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
467
-  #if USES_Z_MIN_PROBE_ENDSTOP
468
-    #define TEST_PROBE_PIN (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
469
-  #else
470
-    #define TEST_PROBE_PIN (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
471
-  #endif
472
-
473
-  extern float backlash_measured_mm[];
474
-  extern uint8_t backlash_measured_num[];
475
-
476
-  /* Measure Z backlash by raising nozzle in increments until probe deactivates */
477
-  static void measure_backlash_with_probe() {
478
-    if (backlash_measured_num[Z_AXIS] == 255) return;
479
-
480
-    float start_height = current_position[Z_AXIS];
481
-    while (current_position[Z_AXIS] < (start_height + BACKLASH_MEASUREMENT_LIMIT) && TEST_PROBE_PIN)
482
-      do_blocking_move_to_z(current_position[Z_AXIS] + BACKLASH_MEASUREMENT_RESOLUTION, MMM_TO_MMS(BACKLASH_MEASUREMENT_FEEDRATE));
483
-
484
-    // The backlash from all probe points is averaged, so count the number of measurements
485
-    backlash_measured_mm[Z_AXIS] += current_position[Z_AXIS] - start_height;
486
-    backlash_measured_num[Z_AXIS]++;
487
-  }
488
-#endif
489
-
490
 /**
470
 /**
491
  * @brief Used by run_z_probe to do a single Z probe move.
471
  * @brief Used by run_z_probe to do a single Z probe move.
492
  *
472
  *
643
       }
623
       }
644
 
624
 
645
       #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
625
       #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
646
-        measure_backlash_with_probe();
626
+        backlash.measure_with_probe();
647
       #endif
627
       #endif
648
 
628
 
649
   #if MULTIPLE_PROBING > 2
629
   #if MULTIPLE_PROBING > 2

+ 2
- 2
Marlin/src/module/stepper.cpp Visa fil

113
   #include "../feature/mixing.h"
113
   #include "../feature/mixing.h"
114
 #endif
114
 #endif
115
 
115
 
116
-#if FILAMENT_RUNOUT_DISTANCE_MM > 0
116
+#ifdef FILAMENT_RUNOUT_DISTANCE_MM
117
   #include "../feature/runout.h"
117
   #include "../feature/runout.h"
118
 #endif
118
 #endif
119
 
119
 
1537
 
1537
 
1538
     // If current block is finished, reset pointer
1538
     // If current block is finished, reset pointer
1539
     if (step_events_completed >= step_event_count) {
1539
     if (step_events_completed >= step_event_count) {
1540
-      #if FILAMENT_RUNOUT_DISTANCE_MM > 0
1540
+      #ifdef FILAMENT_RUNOUT_DISTANCE_MM
1541
         runout.block_completed(current_block);
1541
         runout.block_completed(current_block);
1542
       #endif
1542
       #endif
1543
       axis_did_move = 0;
1543
       axis_did_move = 0;

Laddar…
Avbryt
Spara