Selaa lähdekoodia

Implement delta auto-calibration and delta_height

LVD-AC 7 vuotta sitten
vanhempi
commit
8821963873
5 muutettua tiedostoa jossa 438 lisäystä ja 20 poistoa
  1. 386
    8
      Marlin/Marlin_main.cpp
  2. 1
    1
      Marlin/SanityCheck.h
  3. 31
    7
      Marlin/configuration_store.cpp
  4. 6
    0
      Marlin/language_en.h
  5. 14
    4
      Marlin/ultralcd.cpp

+ 386
- 8
Marlin/Marlin_main.cpp Näytä tiedosto

@@ -61,6 +61,7 @@
61 61
  * G30 - Single Z probe, probes bed at X Y location (defaults to current XY location)
62 62
  * G31 - Dock sled (Z_PROBE_SLED only)
63 63
  * G32 - Undock sled (Z_PROBE_SLED only)
64
+ * G33 - Delta '4-point' auto calibration iteration
64 65
  * G38 - Probe target - similar to G28 except it uses the Z_MIN_PROBE for all three axes
65 66
  * G90 - Use Absolute Coordinates
66 67
  * G91 - Use Relative Coordinates
@@ -1443,7 +1444,7 @@ bool get_target_extruder_from_command(int code) {
1443 1444
 
1444 1445
 #endif // NO_WORKSPACE_OFFSETS
1445 1446
 
1446
-#if DISABLED(NO_WORKSPACE_OFFSETS)
1447
+#if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
1447 1448
   /**
1448 1449
    * Change the home offset for an axis, update the current
1449 1450
    * position and the software endstops to retain the same
@@ -1457,7 +1458,7 @@ bool get_target_extruder_from_command(int code) {
1457 1458
     home_offset[axis] = v;
1458 1459
     update_software_endstops(axis);
1459 1460
   }
1460
-#endif // NO_WORKSPACE_OFFSETS
1461
+#endif // !NO_WORKSPACE_OFFSETS && !DELTA
1461 1462
 
1462 1463
 /**
1463 1464
  * Set an axis' current position to its home position (after homing).
@@ -2299,7 +2300,7 @@ static void clean_up_after_endstop_or_probe_move() {
2299 2300
       SERIAL_PROTOCOLPGM(" Y: ");
2300 2301
       SERIAL_PROTOCOL_F(y, 3);
2301 2302
       SERIAL_PROTOCOLPGM(" Z: ");
2302
-      SERIAL_PROTOCOL_F(FIXFLOAT(measured_z), 3);
2303
+      SERIAL_PROTOCOL_F(measured_z, 3);
2303 2304
       SERIAL_EOL;
2304 2305
     }
2305 2306
 
@@ -4901,8 +4902,366 @@ inline void gcode_G28() {
4901 4902
 
4902 4903
   #endif // Z_PROBE_SLED
4903 4904
 
4905
+  #if ENABLED(DELTA_AUTO_CALIBRATION)
4906
+    /**
4907
+     * G33: Delta '4-point' auto calibration iteration
4908
+     *
4909
+     * Usage: G33 <Cn> <Vn>
4910
+     *
4911
+     *  C  (default) = Calibrate endstops, height and delta radius
4912
+     *
4913
+     *  -2, 1-4: n x n probe points, default 3 x 3
4914
+     *
4915
+     *    1: probe center
4916
+     *       set height only - useful when z_offset is changed
4917
+     *    2: probe center and towers
4918
+     *       solve one '4 point' calibration
4919
+     *   -2: probe center and opposite the towers
4920
+     *       solve one '4 point' calibration
4921
+     *    3: probe 3 center points, towers and opposite-towers
4922
+     *       averages between 2 '4 point' calibrations
4923
+     *    4: probe 4 center points, towers, opposite-towers and itermediate points
4924
+     *       averages between 4 '4 point' calibrations
4925
+     *
4926
+     *  V  Verbose level (0-3, default 1)
4927
+     *
4928
+     *    0: Dry-run mode: no calibration
4929
+     *    1: Settings
4930
+     *    2: Setting + probe results
4931
+     *    3: Expert mode: setting + iteration factors (see Configuration_adv.h)
4932
+     *       This prematurely stops the iteration process when factors are found
4933
+     */
4934
+    inline void gcode_G33() {
4935
+
4936
+      stepper.synchronize();
4937
+
4938
+      #if PLANNER_LEVELING
4939
+        set_bed_leveling_enabled(false);
4940
+      #endif
4941
+
4942
+      const int8_t pp = code_seen('C') ? code_value_int() : DELTA_CALIBRATION_DEFAULT_POINTS,
4943
+                   probe_points = (WITHIN(pp, 1, 4) || pp == -2) ? pp : DELTA_CALIBRATION_DEFAULT_POINTS;
4944
+
4945
+      int8_t verbose_level = code_seen('V') ? code_value_byte() : 1;
4946
+
4947
+      #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
4948
+        #define _MAX_M33_V 3
4949
+        if (verbose_level == 3 && probe_points == 1) verbose_level--; // needs at least 4 points
4950
+      #else
4951
+        #define _MAX_M33_V 2
4952
+        if (verbose_level > 2)
4953
+          SERIAL_PROTOCOLLNPGM("Enable DELTA_CALIBRATE_EXPERT_MODE in Configuration_adv.h");
4954
+      #endif
4955
+
4956
+      if (!WITHIN(verbose_level, 0, _MAX_M33_V)) verbose_level = 1;
4957
+
4958
+      float zero_std_dev = verbose_level ? 999.0 : 0.0; // 0.0 in dry-run mode : forced end
4959
+
4960
+      gcode_G28();
4961
+
4962
+      float e_old[XYZ],
4963
+            dr_old = delta_radius,
4964
+            zh_old = home_offset[Z_AXIS];
4965
+      COPY(e_old,endstop_adj);
4966
+      #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
4967
+        // expert variables
4968
+        float h_f_old = 1.00, r_f_old = 0.00,
4969
+              h_diff_min = 1.00, r_diff_max = 0.10;
4970
+      #endif
4971
+
4972
+      // print settings
4973
+
4974
+      SERIAL_PROTOCOLLNPGM("G33 Auto Calibrate");
4975
+      SERIAL_PROTOCOLPGM("Checking... AC");
4976
+      if (verbose_level == 0) SERIAL_PROTOCOLPGM(" (DRY-RUN)");
4977
+      #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
4978
+        if (verbose_level == 3) SERIAL_PROTOCOLPGM(" (EXPERT)");
4979
+      #endif
4980
+      SERIAL_EOL;
4981
+      LCD_MESSAGEPGM("Checking... AC");
4982
+
4983
+      SERIAL_PROTOCOLPAIR("Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
4984
+      if (abs(probe_points) > 1) {
4985
+        SERIAL_PROTOCOLPGM("    Ex:");
4986
+        if (endstop_adj[A_AXIS] >= 0) SERIAL_CHAR('+');
4987
+        SERIAL_PROTOCOL_F(endstop_adj[A_AXIS], 2);
4988
+        SERIAL_PROTOCOLPGM("  Ey:");
4989
+        if (endstop_adj[B_AXIS] >= 0) SERIAL_CHAR('+');
4990
+        SERIAL_PROTOCOL_F(endstop_adj[B_AXIS], 2);
4991
+        SERIAL_PROTOCOLPGM("  Ez:");
4992
+        if (endstop_adj[C_AXIS] >= 0) SERIAL_CHAR('+');
4993
+        SERIAL_PROTOCOL_F(endstop_adj[C_AXIS], 2);
4994
+        SERIAL_PROTOCOLPAIR("    Radius:", delta_radius);
4995
+      }
4996
+      SERIAL_EOL;
4997
+
4998
+      #if ENABLED(Z_PROBE_SLED)
4999
+        DEPLOY_PROBE();
5000
+      #endif
5001
+
5002
+      float test_precision;
5003
+      int8_t iterations = 0;
5004
+
5005
+      do { // start iterations
5006
+
5007
+        setup_for_endstop_or_probe_move();
5008
+
5009
+        test_precision =
5010
+          #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
5011
+            // Expert mode : forced end at std_dev < 0.1
5012
+            (verbose_level == 3 && zero_std_dev < 0.1) ? 0.0 :
5013
+          #endif
5014
+          zero_std_dev
5015
+        ;
5016
+
5017
+        float z_at_pt[13] = { 0 };
5018
+
5019
+        iterations++;
5020
+
5021
+        // probe the points
5022
+
5023
+        int16_t center_points = 0;
5024
+
5025
+        if (probe_points != 3) {
5026
+          z_at_pt[0] += probe_pt(0.0, 0.0 , true, 1);
5027
+          center_points = 1;
5028
+        }
5029
+
5030
+        int16_t step_axis = 4;
5031
+        if (probe_points >= 3) {
5032
+          for (int8_t axis = 9; axis > 0; axis -= step_axis) { // uint8_t starts endless loop
5033
+            z_at_pt[0] += probe_pt(
5034
+              0.1 * cos(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS),
5035
+              0.1 * sin(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS), true, 1);
5036
+          }
5037
+          center_points += 3;
5038
+          z_at_pt[0] /= center_points;
5039
+        }
5040
+
5041
+        float S1 = z_at_pt[0], S2 = sq(S1);
5042
+
5043
+        int16_t N = 1, start = (probe_points == -2) ? 3 : 1;
5044
+        step_axis = (abs(probe_points) == 2) ? 4 : (probe_points == 3) ? 2 : 1;
5045
+
5046
+        if (probe_points != 1) {
5047
+          for (uint8_t axis = start; axis < 13; axis += step_axis)
5048
+            z_at_pt[axis] += probe_pt(
5049
+              cos(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS),
5050
+              sin(RADIANS(180 + 30 * axis)) * (DELTA_CALIBRATION_RADIUS), true, 1
5051
+            );
5052
+
5053
+          if (probe_points == 4) step_axis = 2;
5054
+        }
5055
+
5056
+        for (uint8_t axis = start; axis < 13; axis += step_axis) {
5057
+          if (probe_points == 4)
5058
+            z_at_pt[axis] = (z_at_pt[axis] + (z_at_pt[axis + 1] + z_at_pt[(axis + 10) % 12 + 1]) / 2.0) / 2.0;
5059
+
5060
+          S1 += z_at_pt[axis];
5061
+          S2 += sq(z_at_pt[axis]);
5062
+          N++;
5063
+        }
5064
+        zero_std_dev = round(sqrt(S2 / N) * 1000.0) / 1000.0 + 0.00001; // deviation from zero plane
5065
+
5066
+        // Solve matrices
5067
+
5068
+        if (zero_std_dev < test_precision) {
5069
+          COPY(e_old, endstop_adj);
5070
+          dr_old = delta_radius;
5071
+          zh_old = home_offset[Z_AXIS];
5072
+
5073
+          float e_delta[XYZ] = { 0.0 }, r_delta = 0.0;
5074
+
5075
+          #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
5076
+            float h_f_new = 0.0, r_f_new = 0.0 , t_f_new = 0.0,
5077
+                  h_diff = 0.00, r_diff = 0.00;
5078
+          #endif
5079
+
5080
+          #define ZP(N,I) ((N) * z_at_pt[I])
5081
+          #define Z1000(I) ZP(1.00, I)
5082
+          #define Z1050(I) ZP(H_FACTOR, I)
5083
+          #define Z0700(I) ZP((H_FACTOR) * 2.0 / 3.00, I)
5084
+          #define Z0350(I) ZP((H_FACTOR) / 3.00, I)
5085
+          #define Z0175(I) ZP((H_FACTOR) / 6.00, I)
5086
+          #define Z2250(I) ZP(R_FACTOR, I)
5087
+          #define Z0750(I) ZP((R_FACTOR) / 3.00, I)
5088
+          #define Z0375(I) ZP((R_FACTOR) / 6.00, I)
5089
+
5090
+          switch (probe_points) {
5091
+            case 1:
5092
+              LOOP_XYZ(i) e_delta[i] = Z1000(0);
5093
+              r_delta = 0.00;
5094
+              break;
5095
+
5096
+            case 2:
5097
+              e_delta[X_AXIS] = Z1050(0) + Z0700(1) - Z0350(5) - Z0350(9);
5098
+              e_delta[Y_AXIS] = Z1050(0) - Z0350(1) + Z0700(5) - Z0350(9);
5099
+              e_delta[Z_AXIS] = Z1050(0) - Z0350(1) - Z0350(5) + Z0700(9);
5100
+              r_delta         = Z2250(0) - Z0750(1) - Z0750(5) - Z0750(9);
5101
+              break;
5102
+
5103
+            case -2:
5104
+              e_delta[X_AXIS] = Z1050(0) - Z0700(7) + Z0350(11) + Z0350(3);
5105
+              e_delta[Y_AXIS] = Z1050(0) + Z0350(7) - Z0700(11) + Z0350(3);
5106
+              e_delta[Z_AXIS] = Z1050(0) + Z0350(7) + Z0350(11) - Z0700(3);
5107
+              r_delta         = Z2250(0) - Z0750(7) - Z0750(11) - Z0750(3);
5108
+              break;
5109
+
5110
+            default:
5111
+              e_delta[X_AXIS] = Z1050(0) + Z0350(1) - Z0175(5) - Z0175(9) - Z0350(7) + Z0175(11) + Z0175(3);
5112
+              e_delta[Y_AXIS] = Z1050(0) - Z0175(1) + Z0350(5) - Z0175(9) + Z0175(7) - Z0350(11) + Z0175(3);
5113
+              e_delta[Z_AXIS] = Z1050(0) - Z0175(1) - Z0175(5) + Z0350(9) + Z0175(7) + Z0175(11) - Z0350(3);
5114
+              r_delta         = Z2250(0) - Z0375(1) - Z0375(5) - Z0375(9) - Z0375(7) - Z0375(11) - Z0375(3);
5115
+              break;
5116
+          }
5117
+
5118
+          #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
5119
+            // Calculate h & r factors
5120
+            if (verbose_level == 3) {
5121
+              LOOP_XYZ(axis) h_f_new += e_delta[axis] / 3;
5122
+              r_f_new = r_delta;
5123
+              h_diff = (1.0 / H_FACTOR) * (h_f_old - h_f_new) / h_f_old;
5124
+              if (h_diff < h_diff_min && h_diff > 0.9) h_diff_min = h_diff;
5125
+              if (r_f_old != 0)
5126
+                r_diff = (   0.0301 * sq(R_FACTOR) * R_FACTOR
5127
+                           + 0.311  * sq(R_FACTOR)
5128
+                           + 1.1493 * R_FACTOR
5129
+                           + 1.7952
5130
+                         ) * (r_f_old - r_f_new) / r_f_old;
5131
+              if (r_diff > r_diff_max && r_diff < 0.4444) r_diff_max = r_diff;
5132
+              SERIAL_EOL;
5133
+
5134
+              h_f_old = h_f_new;
5135
+              r_f_old = r_f_new;
5136
+            }
5137
+          #endif // DELTA_CALIBRATE_EXPERT_MODE
5138
+
5139
+          // Adjust delta_height and endstops by the max amount
5140
+          LOOP_XYZ(axis) endstop_adj[axis] += e_delta[axis];
5141
+          delta_radius += r_delta;
5142
+
5143
+          const float z_temp = MAX3(endstop_adj[0], endstop_adj[1], endstop_adj[2]);
5144
+          home_offset[Z_AXIS] -= z_temp;
5145
+          LOOP_XYZ(i) endstop_adj[i] -= z_temp;
5146
+
5147
+          recalc_delta_settings(delta_radius, delta_diagonal_rod);
5148
+        }
5149
+        else { // !iterate
5150
+          // step one back
5151
+          COPY(endstop_adj, e_old);
5152
+          delta_radius = dr_old;
5153
+          home_offset[Z_AXIS] = zh_old;
5154
+
5155
+          recalc_delta_settings(delta_radius, delta_diagonal_rod);
5156
+        }
5157
+
5158
+        // print report
5159
+
5160
+        #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
5161
+          if (verbose_level == 3) {
5162
+            const float r_factor =   22.902 * sq(r_diff_max) * r_diff_max
5163
+                                   - 44.988 * sq(r_diff_max)
5164
+                                   + 31.697 * r_diff_max
5165
+                                   - 9.4439;
5166
+            SERIAL_PROTOCOLPAIR("h_factor:", 1.0 / h_diff_min);
5167
+            SERIAL_PROTOCOLPAIR("              r_factor:", r_factor);
5168
+            SERIAL_EOL;
5169
+          }
5170
+        #endif
5171
+        if (verbose_level == 2) {
5172
+          SERIAL_PROTOCOLPGM(".     c:");
5173
+          if (z_at_pt[0] > 0) SERIAL_CHAR('+');
5174
+          SERIAL_PROTOCOL_F(z_at_pt[0], 2);
5175
+          if (probe_points > 1) {
5176
+            SERIAL_PROTOCOLPGM("     x:");
5177
+            if (z_at_pt[1] >= 0) SERIAL_CHAR('+');
5178
+            SERIAL_PROTOCOL_F(z_at_pt[1], 2);
5179
+            SERIAL_PROTOCOLPGM("   y:");
5180
+            if (z_at_pt[5] >= 0) SERIAL_CHAR('+');
5181
+            SERIAL_PROTOCOL_F(z_at_pt[5], 2);
5182
+            SERIAL_PROTOCOLPGM("   z:");
5183
+            if (z_at_pt[9] >= 0) SERIAL_CHAR('+');
5184
+            SERIAL_PROTOCOL_F(z_at_pt[9], 2);
5185
+          }
5186
+          if (probe_points > 0) SERIAL_EOL;
5187
+          if (probe_points > 2 || probe_points == -2) {
5188
+            if (probe_points > 2) SERIAL_PROTOCOLPGM(".            ");
5189
+            SERIAL_PROTOCOLPGM("    yz:");
5190
+            if (z_at_pt[7] >= 0) SERIAL_CHAR('+');
5191
+            SERIAL_PROTOCOL_F(z_at_pt[7], 2);
5192
+            SERIAL_PROTOCOLPGM("  zx:");
5193
+            if (z_at_pt[11] >= 0) SERIAL_CHAR('+');
5194
+            SERIAL_PROTOCOL_F(z_at_pt[11], 2);
5195
+            SERIAL_PROTOCOLPGM("  xy:");
5196
+            if (z_at_pt[3] >= 0) SERIAL_CHAR('+');
5197
+            SERIAL_PROTOCOL_F(z_at_pt[3], 2);
5198
+            SERIAL_EOL;
5199
+          }
5200
+        }
5201
+        if (test_precision != 0.0) {            // !forced end
5202
+          if (zero_std_dev >= test_precision) {
5203
+            SERIAL_PROTOCOLPGM("Calibration OK");
5204
+            SERIAL_PROTOCOLLNPGM("                                   rolling back 1");
5205
+            LCD_MESSAGEPGM("Calibration OK");
5206
+            SERIAL_EOL;
5207
+          }
5208
+          else {                                // !end iterations
5209
+            char mess[15] = "No convergence";
5210
+            if (iterations < 31)
5211
+              sprintf_P(mess, PSTR("Iteration : %02i"), (int)iterations);
5212
+            SERIAL_PROTOCOL(mess);
5213
+            SERIAL_PROTOCOLPGM("                                   std dev:");
5214
+            SERIAL_PROTOCOL_F(zero_std_dev, 3);
5215
+            SERIAL_EOL;
5216
+            lcd_setstatus(mess);
5217
+          }
5218
+          SERIAL_PROTOCOLPAIR("Height:", DELTA_HEIGHT + home_offset[Z_AXIS]);
5219
+          if (abs(probe_points) > 1) {
5220
+            SERIAL_PROTOCOLPGM("    Ex:");
5221
+            if (endstop_adj[A_AXIS] >= 0) SERIAL_CHAR('+');
5222
+            SERIAL_PROTOCOL_F(endstop_adj[A_AXIS], 2);
5223
+            SERIAL_PROTOCOLPGM("  Ey:");
5224
+            if (endstop_adj[B_AXIS] >= 0) SERIAL_CHAR('+');
5225
+            SERIAL_PROTOCOL_F(endstop_adj[B_AXIS], 2);
5226
+            SERIAL_PROTOCOLPGM("  Ez:");
5227
+            if (endstop_adj[C_AXIS] >= 0) SERIAL_CHAR('+');
5228
+            SERIAL_PROTOCOL_F(endstop_adj[C_AXIS], 2);
5229
+            SERIAL_PROTOCOLPAIR("    Radius:", delta_radius);
5230
+          }
5231
+          SERIAL_EOL;
5232
+          if (zero_std_dev >= test_precision)
5233
+            SERIAL_PROTOCOLLNPGM("Save with M500");
5234
+        }
5235
+        else {                                  // forced end
5236
+          #if ENABLED(DELTA_CALIBRATE_EXPERT_MODE)
5237
+            if (verbose_level == 3)
5238
+              SERIAL_PROTOCOLLNPGM("Copy to Configuration_adv.h");
5239
+            else
5240
+          #endif
5241
+            {
5242
+              SERIAL_PROTOCOLPGM("End DRY-RUN                                      std dev:");
5243
+              SERIAL_PROTOCOL_F(zero_std_dev, 3);
5244
+              SERIAL_EOL;
5245
+            }
5246
+        }
5247
+
5248
+        clean_up_after_endstop_or_probe_move();
5249
+        stepper.synchronize();
5250
+
5251
+        gcode_G28();
5252
+
5253
+      } while (zero_std_dev < test_precision && iterations < 31);
5254
+
5255
+      #if ENABLED(Z_PROBE_SLED)
5256
+        RETRACT_PROBE();
5257
+      #endif
5258
+    }
5259
+
5260
+  #endif // DELTA_AUTO_CALIBRATION
5261
+
4904 5262
 #endif // HAS_BED_PROBE
4905 5263
 
5264
+
4906 5265
 #if ENABLED(G38_PROBE_TARGET)
4907 5266
 
4908 5267
   static bool G38_run_probe() {
@@ -5631,7 +5990,7 @@ inline void gcode_M42() {
5631 5990
 
5632 5991
     if (axis_unhomed_error(true, true, true)) return;
5633 5992
 
5634
-    int8_t verbose_level = code_seen('V') ? code_value_byte() : 1;
5993
+    const int8_t verbose_level = code_seen('V') ? code_value_byte() : 1;
5635 5994
     if (!WITHIN(verbose_level, 0, 4)) {
5636 5995
       SERIAL_PROTOCOLLNPGM("?Verbose Level not plausible (0-4).");
5637 5996
       return;
@@ -7023,7 +7382,7 @@ inline void gcode_M205() {
7023 7382
   if (code_seen('E')) planner.max_jerk[E_AXIS] = code_value_axis_units(E_AXIS);
7024 7383
 }
7025 7384
 
7026
-#if DISABLED(NO_WORKSPACE_OFFSETS)
7385
+#if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
7027 7386
 
7028 7387
   /**
7029 7388
    * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y
@@ -7048,6 +7407,7 @@ inline void gcode_M205() {
7048 7407
   /**
7049 7408
    * M665: Set delta configurations
7050 7409
    *
7410
+   *    H = diagonal rod // AC-version
7051 7411
    *    L = diagonal rod
7052 7412
    *    R = delta radius
7053 7413
    *    S = segments per second
@@ -7056,6 +7416,12 @@ inline void gcode_M205() {
7056 7416
    *    C = Gamma (Tower 3) diagonal rod trim
7057 7417
    */
7058 7418
   inline void gcode_M665() {
7419
+    if (code_seen('H')) {
7420
+      home_offset[Z_AXIS] = code_value_linear_units() - DELTA_HEIGHT;
7421
+      current_position[Z_AXIS] += code_value_linear_units() - DELTA_HEIGHT - home_offset[Z_AXIS];
7422
+      home_offset[Z_AXIS] = code_value_linear_units() - DELTA_HEIGHT;
7423
+      update_software_endstops(Z_AXIS);
7424
+    }
7059 7425
     if (code_seen('L')) delta_diagonal_rod = code_value_linear_units();
7060 7426
     if (code_seen('R')) delta_radius = code_value_linear_units();
7061 7427
     if (code_seen('S')) delta_segments_per_second = code_value_float();
@@ -7914,7 +8280,7 @@ void quickstop_stepper() {
7914 8280
 
7915 8281
 #endif
7916 8282
 
7917
-#if DISABLED(NO_WORKSPACE_OFFSETS)
8283
+#if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
7918 8284
 
7919 8285
   /**
7920 8286
    * M428: Set home_offset based on the distance between the
@@ -9203,6 +9569,15 @@ void process_next_command() {
9203 9569
               break;
9204 9570
 
9205 9571
         #endif // Z_PROBE_SLED
9572
+
9573
+        #if ENABLED(DELTA_AUTO_CALIBRATION)
9574
+
9575
+          case 33: // G33: Delta Auto Calibrate
9576
+            gcode_G33();
9577
+            break;
9578
+
9579
+        #endif // DELTA_AUTO_CALIBRATION
9580
+
9206 9581
       #endif // HAS_BED_PROBE
9207 9582
 
9208 9583
       #if ENABLED(G38_PROBE_TARGET)
@@ -9520,7 +9895,7 @@ void process_next_command() {
9520 9895
         gcode_M205();
9521 9896
         break;
9522 9897
 
9523
-      #if DISABLED(NO_WORKSPACE_OFFSETS)
9898
+      #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
9524 9899
         case 206: // M206: Set home offsets
9525 9900
           gcode_M206();
9526 9901
           break;
@@ -9688,7 +10063,7 @@ void process_next_command() {
9688 10063
           break;
9689 10064
       #endif
9690 10065
 
9691
-      #if DISABLED(NO_WORKSPACE_OFFSETS)
10066
+      #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
9692 10067
         case 428: // M428: Apply current_position to home_offset
9693 10068
           gcode_M428();
9694 10069
           break;
@@ -11054,6 +11429,9 @@ void disable_all_steppers() {
11054 11429
       #if ENABLED(E3_IS_TMC2130)
11055 11430
         automatic_current_control(stepperE3);
11056 11431
       #endif
11432
+      #if ENABLED(E4_IS_TMC2130)
11433
+        automatic_current_control(stepperE4);
11434
+      #endif
11057 11435
     }
11058 11436
   }
11059 11437
 

+ 1
- 1
Marlin/SanityCheck.h Näytä tiedosto

@@ -395,7 +395,7 @@
395 395
  * Delta Auto calibration
396 396
  */
397 397
 #if ENABLED(DELTA_AUTO_CALIBRATION) && ENABLED(NO_WORKSPACE_OFFSETS)
398
-  #error "To use DELTA_AUTO_CALIBRATION you must disable NO_WORKSPACE_OFFSETS."
398
+  #error "DELTA_AUTO_CALIBRATION is incompatible with NO_WORKSPACE_OFFSETS."
399 399
 #endif
400 400
 
401 401
 /**

+ 31
- 7
Marlin/configuration_store.cpp Näytä tiedosto

@@ -47,7 +47,7 @@
47 47
  *  100  Version                                    (char x4)
48 48
  *  104  EEPROM Checksum                            (uint16_t)
49 49
  *
50
- *  106            E_STEPPERS (uint8_t)
50
+ *  106            E_STEPPERS                       (uint8_t)
51 51
  *  107  M92 XYZE  planner.axis_steps_per_mm        (float x4 ... x8)
52 52
  *  123  M203 XYZE planner.max_feedrate_mm_s        (float x4 ... x8)
53 53
  *  139  M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4 ... x8)
@@ -300,9 +300,17 @@ void MarlinSettings::postprocess() {
300 300
     EEPROM_WRITE(planner.min_segment_time);
301 301
     EEPROM_WRITE(planner.max_jerk);
302 302
     #if ENABLED(NO_WORKSPACE_OFFSETS)
303
-      float home_offset[XYZ] = { 0 };
303
+      const float home_offset[XYZ] = { 0 };
304
+    #endif
305
+    #if ENABLED(DELTA)
306
+      dummy = 0.0;
307
+      EEPROM_WRITE(dummy);
308
+      EEPROM_WRITE(dummy);
309
+      dummy = DELTA_HEIGHT + home_offset[Z_AXIS];
310
+      EEPROM_WRITE(dummy);
311
+    #else
312
+      EEPROM_WRITE(home_offset);
304 313
     #endif
305
-    EEPROM_WRITE(home_offset);
306 314
 
307 315
     #if HOTENDS > 1
308 316
       // Skip hotend 0 which must be 0
@@ -488,7 +496,7 @@ void MarlinSettings::postprocess() {
488 496
       EEPROM_WRITE(dummy);
489 497
     }
490 498
 
491
-    // Save TCM2130 Configuration, and placeholder values
499
+    // Save TMC2130 Configuration, and placeholder values
492 500
     uint16_t val;
493 501
     #if ENABLED(HAVE_TMC2130)
494 502
       #if ENABLED(X_IS_TMC2130)
@@ -551,6 +559,12 @@ void MarlinSettings::postprocess() {
551 559
         val = 0;
552 560
       #endif
553 561
       EEPROM_WRITE(val);
562
+      #if ENABLED(E4_IS_TMC2130)
563
+        val = stepperE4.getCurrent();
564
+      #else
565
+        val = 0;
566
+      #endif
567
+      EEPROM_WRITE(val);
554 568
     #else
555 569
       val = 0;
556 570
       for (uint8_t q = 0; q < 11; ++q) EEPROM_WRITE(val);
@@ -644,6 +658,12 @@ void MarlinSettings::postprocess() {
644 658
       #endif
645 659
       EEPROM_READ(home_offset);
646 660
 
661
+      #if ENABLED(DELTA)
662
+        home_offset[X_AXIS] = 0.0;
663
+        home_offset[Y_AXIS] = 0.0;
664
+        home_offset[Z_AXIS] -= DELTA_HEIGHT;
665
+      #endif
666
+
647 667
       #if HOTENDS > 1
648 668
         // Skip hotend 0 which must be 0
649 669
         for (uint8_t e = 1; e < HOTENDS; e++)
@@ -1019,6 +1039,9 @@ void MarlinSettings::reset() {
1019 1039
     delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
1020 1040
     COPY(delta_diagonal_rod_trim, drt);
1021 1041
     COPY(delta_tower_angle_trim, dta);
1042
+    #if ENABLED(DELTA)
1043
+      home_offset[Z_AXIS] = 0;
1044
+    #endif
1022 1045
   #elif ENABLED(Z_DUAL_ENDSTOPS)
1023 1046
     float z_endstop_adj =
1024 1047
       #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT
@@ -1143,7 +1166,7 @@ void MarlinSettings::reset() {
1143 1166
 
1144 1167
   /**
1145 1168
    * M503 - Report current settings in RAM
1146
-   *   
1169
+   *
1147 1170
    * Unless specifically disabled, M503 is available even without EEPROM
1148 1171
    */
1149 1172
   void MarlinSettings::report(bool forReplay) {
@@ -1231,7 +1254,7 @@ void MarlinSettings::reset() {
1231 1254
     SERIAL_ECHOPAIR(" E", planner.max_jerk[E_AXIS]);
1232 1255
     SERIAL_EOL;
1233 1256
 
1234
-    #if DISABLED(NO_WORKSPACE_OFFSETS)
1257
+    #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
1235 1258
       CONFIG_ECHO_START;
1236 1259
       if (!forReplay) {
1237 1260
         SERIAL_ECHOLNPGM("Home offset (mm)");
@@ -1346,11 +1369,12 @@ void MarlinSettings::reset() {
1346 1369
       SERIAL_EOL;
1347 1370
       CONFIG_ECHO_START;
1348 1371
       if (!forReplay) {
1349
-        SERIAL_ECHOLNPGM("Delta settings: L=diagonal rod, R=radius, S=segments-per-second, ABC=diagonal rod trim, IJK=tower angle trim");
1372
+        SERIAL_ECHOLNPGM("Delta settings: L=diagonal_rod, R=radius, H=height, S=segments_per_second, ABC=diagonal_rod_trim_tower_[123]");
1350 1373
         CONFIG_ECHO_START;
1351 1374
       }
1352 1375
       SERIAL_ECHOPAIR("  M665 L", delta_diagonal_rod);
1353 1376
       SERIAL_ECHOPAIR(" R", delta_radius);
1377
+      SERIAL_ECHOPAIR(" H", DELTA_HEIGHT + home_offset[Z_AXIS]);
1354 1378
       SERIAL_ECHOPAIR(" S", delta_segments_per_second);
1355 1379
       SERIAL_ECHOPAIR(" A", delta_diagonal_rod_trim[A_AXIS]);
1356 1380
       SERIAL_ECHOPAIR(" B", delta_diagonal_rod_trim[B_AXIS]);

+ 6
- 0
Marlin/language_en.h Näytä tiedosto

@@ -498,6 +498,12 @@
498 498
 #ifndef MSG_DELTA_CALIBRATE_CENTER
499 499
   #define MSG_DELTA_CALIBRATE_CENTER          _UxGT("Calibrate Center")
500 500
 #endif
501
+#ifndef MSG_DELTA_AUTO_CALIBRATE
502
+  #define MSG_DELTA_AUTO_CALIBRATE            _UxGT("Auto Calibration")
503
+#endif
504
+#ifndef MSG_DELTA_HEIGHT_CALIBRATE
505
+  #define MSG_DELTA_HEIGHT_CALIBRATE          _UxGT("Set Delta Height")
506
+#endif
501 507
 #ifndef MSG_INFO_MENU
502 508
   #define MSG_INFO_MENU                       _UxGT("About Printer")
503 509
 #endif

+ 14
- 4
Marlin/ultralcd.cpp Näytä tiedosto

@@ -817,7 +817,7 @@ void kill_screen(const char* lcd_msg) {
817 817
    *
818 818
    */
819 819
 
820
-  #if DISABLED(NO_WORKSPACE_OFFSETS)
820
+  #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
821 821
     /**
822 822
      * Set the home offset based on the current_position
823 823
      */
@@ -1672,7 +1672,7 @@ void kill_screen(const char* lcd_msg) {
1672 1672
 
1673 1673
     #endif
1674 1674
 
1675
-    #if DISABLED(NO_WORKSPACE_OFFSETS)
1675
+    #if DISABLED(NO_WORKSPACE_OFFSETS) && DISABLED(DELTA)
1676 1676
       //
1677 1677
       // Set Home Offsets
1678 1678
       //
@@ -1770,14 +1770,20 @@ void kill_screen(const char* lcd_msg) {
1770 1770
       lcd_goto_screen(_lcd_calibrate_homing);
1771 1771
     }
1772 1772
 
1773
+    #if ENABLED(DELTA_AUTO_CALIBRATION)
1774
+      #define _DELTA_TOWER_MOVE_RADIUS DELTA_CALIBRATION_RADIUS
1775
+    #else
1776
+      #define _DELTA_TOWER_MOVE_RADIUS DELTA_PRINTABLE_RADIUS
1777
+    #endif
1778
+
1773 1779
     // Move directly to the tower position with uninterpolated moves
1774 1780
     // If we used interpolated moves it would cause this to become re-entrant
1775 1781
     void _goto_tower_pos(const float &a) {
1776 1782
       current_position[Z_AXIS] = max(Z_HOMING_HEIGHT, Z_CLEARANCE_BETWEEN_PROBES) + (DELTA_PRINTABLE_RADIUS) / 5;
1777 1783
       line_to_current(Z_AXIS);
1778 1784
 
1779
-      current_position[X_AXIS] = a < 0 ? X_HOME_POS : sin(a) * -(DELTA_PRINTABLE_RADIUS);
1780
-      current_position[Y_AXIS] = a < 0 ? Y_HOME_POS : cos(a) *  (DELTA_PRINTABLE_RADIUS);
1785
+      current_position[X_AXIS] = a < 0 ? LOGICAL_X_POSITION(X_HOME_POS) : sin(a) * -(_DELTA_TOWER_MOVE_RADIUS);
1786
+      current_position[Y_AXIS] = a < 0 ? LOGICAL_Y_POSITION(Y_HOME_POS) : cos(a) *  (_DELTA_TOWER_MOVE_RADIUS);
1781 1787
       line_to_current(Z_AXIS);
1782 1788
 
1783 1789
       current_position[Z_AXIS] = 4.0;
@@ -1797,6 +1803,10 @@ void kill_screen(const char* lcd_msg) {
1797 1803
     void lcd_delta_calibrate_menu() {
1798 1804
       START_MENU();
1799 1805
       MENU_BACK(MSG_MAIN);
1806
+      #if ENABLED(DELTA_AUTO_CALIBRATION)
1807
+        MENU_ITEM(gcode, MSG_DELTA_AUTO_CALIBRATE, PSTR("G33 C"));
1808
+        MENU_ITEM(gcode, MSG_DELTA_HEIGHT_CALIBRATE, PSTR("G33 C1"));
1809
+      #endif
1800 1810
       MENU_ITEM(submenu, MSG_AUTO_HOME, _lcd_delta_calibrate_home);
1801 1811
       if (axis_homed[Z_AXIS]) {
1802 1812
         MENU_ITEM(submenu, MSG_DELTA_CALIBRATE_X, _goto_tower_x);

Loading…
Peruuta
Tallenna