瀏覽代碼

Merge pull request #4667 from thinkyhead/rc_M211_sw_endstop_switch

M211: Enable/Disable Software Endstops
Scott Lahteine 8 年之前
父節點
當前提交
27b80b1dd1
共有 9 個文件被更改,包括 154 次插入107 次删除
  1. 25
    22
      Marlin/Marlin.h
  2. 93
    67
      Marlin/Marlin_main.cpp
  3. 3
    0
      Marlin/language.h
  4. 3
    0
      Marlin/macros.h
  5. 1
    1
      Marlin/planner.cpp
  6. 1
    1
      Marlin/stepper.cpp
  7. 1
    1
      Marlin/stepper.h
  8. 1
    1
      Marlin/temperature.cpp
  9. 26
    14
      Marlin/ultralcd.cpp

+ 25
- 22
Marlin/Marlin.h 查看文件

103
 
103
 
104
 // Things to write to serial from Program memory. Saves 400 to 2k of RAM.
104
 // Things to write to serial from Program memory. Saves 400 to 2k of RAM.
105
 FORCE_INLINE void serialprintPGM(const char* str) {
105
 FORCE_INLINE void serialprintPGM(const char* str) {
106
-  char ch;
107
-  while ((ch = pgm_read_byte(str))) {
108
-    MYSERIAL.write(ch);
109
-    str++;
110
-  }
106
+  while (char ch = pgm_read_byte(str++)) MYSERIAL.write(ch);
111
 }
107
 }
112
 
108
 
113
 void idle(
109
 void idle(
245
 void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
241
 void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
246
 void clear_command_queue();
242
 void clear_command_queue();
247
 
243
 
248
-void clamp_to_software_endstops(float target[3]);
249
-
250
 extern millis_t previous_cmd_ms;
244
 extern millis_t previous_cmd_ms;
251
 inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
245
 inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
252
 
246
 
268
 extern int flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder
262
 extern int flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder
269
 extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
263
 extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
270
 extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
264
 extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
271
-extern bool axis_known_position[3]; // axis[n].is_known
272
-extern bool axis_homed[3]; // axis[n].is_homed
265
+extern bool axis_known_position[XYZ]; // axis[n].is_known
266
+extern bool axis_homed[XYZ]; // axis[n].is_homed
273
 extern volatile bool wait_for_heatup;
267
 extern volatile bool wait_for_heatup;
274
 
268
 
275
 extern float current_position[NUM_AXIS];
269
 extern float current_position[NUM_AXIS];
276
-extern float position_shift[3];
277
-extern float home_offset[3];
278
-extern float sw_endstop_min[3];
279
-extern float sw_endstop_max[3];
270
+extern float position_shift[XYZ];
271
+extern float home_offset[XYZ];
272
+
273
+// Software Endstops
274
+void update_software_endstops(AxisEnum axis);
275
+#if ENABLED(min_software_endstops) || ENABLED(max_software_endstops)
276
+  extern bool soft_endstops_enabled;
277
+  void clamp_to_software_endstops(float target[XYZ]);
278
+#else
279
+  #define soft_endstops_enabled false
280
+  #define clamp_to_software_endstops(x) NOOP
281
+#endif
282
+extern float soft_endstop_min[XYZ];
283
+extern float soft_endstop_max[XYZ];
280
 
284
 
281
 #define LOGICAL_POSITION(POS, AXIS) (POS + home_offset[AXIS] + position_shift[AXIS])
285
 #define LOGICAL_POSITION(POS, AXIS) (POS + home_offset[AXIS] + position_shift[AXIS])
282
 #define RAW_POSITION(POS, AXIS)     (POS - home_offset[AXIS] - position_shift[AXIS])
286
 #define RAW_POSITION(POS, AXIS)     (POS - home_offset[AXIS] - position_shift[AXIS])
295
 float code_value_temp_diff();
299
 float code_value_temp_diff();
296
 
300
 
297
 #if ENABLED(DELTA)
301
 #if ENABLED(DELTA)
298
-  extern float delta[3];
299
-  extern float endstop_adj[3]; // axis[n].endstop_adj
302
+  extern float delta[ABC];
303
+  extern float endstop_adj[ABC]; // axis[n].endstop_adj
300
   extern float delta_radius;
304
   extern float delta_radius;
301
   extern float delta_diagonal_rod;
305
   extern float delta_diagonal_rod;
302
   extern float delta_segments_per_second;
306
   extern float delta_segments_per_second;
303
   extern float delta_diagonal_rod_trim_tower_1;
307
   extern float delta_diagonal_rod_trim_tower_1;
304
   extern float delta_diagonal_rod_trim_tower_2;
308
   extern float delta_diagonal_rod_trim_tower_2;
305
   extern float delta_diagonal_rod_trim_tower_3;
309
   extern float delta_diagonal_rod_trim_tower_3;
306
-  void inverse_kinematics(const float cartesian[3]);
310
+  void inverse_kinematics(const float cartesian[XYZ]);
307
   void recalc_delta_settings(float radius, float diagonal_rod);
311
   void recalc_delta_settings(float radius, float diagonal_rod);
308
   #if ENABLED(AUTO_BED_LEVELING_FEATURE)
312
   #if ENABLED(AUTO_BED_LEVELING_FEATURE)
309
     extern int delta_grid_spacing[2];
313
     extern int delta_grid_spacing[2];
310
-    void adjust_delta(float cartesian[3]);
314
+    void adjust_delta(float cartesian[XYZ]);
311
   #endif
315
   #endif
312
 #elif ENABLED(SCARA)
316
 #elif ENABLED(SCARA)
313
-  extern float delta[3];
314
-  extern float axis_scaling[3];  // Build size scaling
315
-  void inverse_kinematics(const float cartesian[3]);
316
-  void forward_kinematics_SCARA(float f_scara[3]);
317
+  extern float delta[ABC];
318
+  extern float axis_scaling[ABC];  // Build size scaling
319
+  void inverse_kinematics(const float cartesian[XYZ]);
320
+  void forward_kinematics_SCARA(float f_scara[ABC]);
317
 #endif
321
 #endif
318
 
322
 
319
 #if ENABLED(Z_DUAL_ENDSTOPS)
323
 #if ENABLED(Z_DUAL_ENDSTOPS)
379
   extern float mixing_factor[MIXING_STEPPERS];
383
   extern float mixing_factor[MIXING_STEPPERS];
380
 #endif
384
 #endif
381
 
385
 
382
-void update_software_endstops(AxisEnum axis);
383
 void calculate_volumetric_multipliers();
386
 void calculate_volumetric_multipliers();
384
 
387
 
385
 // Buzzer
388
 // Buzzer

+ 93
- 67
Marlin/Marlin_main.cpp 查看文件

205
  * M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>
205
  * M208 - Set Recover (unretract) Additional (!) Length: S<length> and Feedrate: F<units/min>
206
  * M209 - Turn Automatic Retract Detection on/off: S<bool> (For slicers that don't support G10/11).
206
  * M209 - Turn Automatic Retract Detection on/off: S<bool> (For slicers that don't support G10/11).
207
           Every normal extrude-only move will be classified as retract depending on the direction.
207
           Every normal extrude-only move will be classified as retract depending on the direction.
208
+ * M211 - Enable, Disable, and/or Report software endstops: [S<bool>]
208
  * M218 - Set a tool offset: T<index> X<offset> Y<offset>
209
  * M218 - Set a tool offset: T<index> X<offset> Y<offset>
209
  * M220 - Set Feedrate Percentage: S<percent> ("FR" on your LCD)
210
  * M220 - Set Feedrate Percentage: S<percent> ("FR" on your LCD)
210
  * M221 - Set Flow Percentage: S<percent>
211
  * M221 - Set Flow Percentage: S<percent>
285
 
286
 
286
 float current_position[NUM_AXIS] = { 0.0 };
287
 float current_position[NUM_AXIS] = { 0.0 };
287
 static float destination[NUM_AXIS] = { 0.0 };
288
 static float destination[NUM_AXIS] = { 0.0 };
288
-bool axis_known_position[3] = { false };
289
-bool axis_homed[3] = { false };
289
+bool axis_known_position[XYZ] = { false };
290
+bool axis_homed[XYZ] = { false };
290
 
291
 
291
 static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
292
 static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
292
 
293
 
326
 float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0);
327
 float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0);
327
 
328
 
328
 // The distance that XYZ has been offset by G92. Reset by G28.
329
 // The distance that XYZ has been offset by G92. Reset by G28.
329
-float position_shift[3] = { 0 };
330
+float position_shift[XYZ] = { 0 };
330
 
331
 
331
 // This offset is added to the configured home position.
332
 // This offset is added to the configured home position.
332
 // Set by M206, M428, or menu item. Saved to EEPROM.
333
 // Set by M206, M428, or menu item. Saved to EEPROM.
333
-float home_offset[3] = { 0 };
334
+float home_offset[XYZ] = { 0 };
334
 
335
 
335
-// Software Endstops. Default to configured limits.
336
-float sw_endstop_min[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
337
-float sw_endstop_max[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
336
+// Software Endstops are based on the configured limits.
337
+#if ENABLED(min_software_endstops) || ENABLED(max_software_endstops)
338
+  bool soft_endstops_enabled = true;
339
+#endif
340
+float soft_endstop_min[XYZ] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS },
341
+      soft_endstop_max[XYZ] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
338
 
342
 
339
 #if FAN_COUNT > 0
343
 #if FAN_COUNT > 0
340
   int fanSpeeds[FAN_COUNT] = { 0 };
344
   int fanSpeeds[FAN_COUNT] = { 0 };
458
   #define TOWER_2 Y_AXIS
462
   #define TOWER_2 Y_AXIS
459
   #define TOWER_3 Z_AXIS
463
   #define TOWER_3 Z_AXIS
460
 
464
 
461
-  float delta[3];
462
-  float cartesian_position[3] = { 0 };
465
+  float delta[ABC];
466
+  float cartesian_position[XYZ] = { 0 };
463
   #define SIN_60 0.8660254037844386
467
   #define SIN_60 0.8660254037844386
464
   #define COS_60 0.5
468
   #define COS_60 0.5
465
-  float endstop_adj[3] = { 0 };
469
+  float endstop_adj[ABC] = { 0 };
466
   // these are the default values, can be overriden with M665
470
   // these are the default values, can be overriden with M665
467
   float delta_radius = DELTA_RADIUS;
471
   float delta_radius = DELTA_RADIUS;
468
   float delta_tower1_x = -SIN_60 * (delta_radius + DELTA_RADIUS_TRIM_TOWER_1); // front left tower
472
   float delta_tower1_x = -SIN_60 * (delta_radius + DELTA_RADIUS_TRIM_TOWER_1); // front left tower
491
 
495
 
492
 #if ENABLED(SCARA)
496
 #if ENABLED(SCARA)
493
   float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND;
497
   float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND;
494
-  float delta[3];
495
-  float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
498
+  float delta[ABC];
499
+  float axis_scaling[ABC] = { 1, 1, 1 };    // Build size scaling, default to 1
496
 #endif
500
 #endif
497
 
501
 
498
 #if ENABLED(FILAMENT_WIDTH_SENSOR)
502
 #if ENABLED(FILAMENT_WIDTH_SENSOR)
1411
 DEFINE_PGM_READ_ANY(signed char, byte);
1415
 DEFINE_PGM_READ_ANY(signed char, byte);
1412
 
1416
 
1413
 #define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \
1417
 #define XYZ_CONSTS_FROM_CONFIG(type, array, CONFIG) \
1414
-  static const PROGMEM type array##_P[3] =        \
1418
+  static const PROGMEM type array##_P[XYZ] =        \
1415
       { X_##CONFIG, Y_##CONFIG, Z_##CONFIG };     \
1419
       { X_##CONFIG, Y_##CONFIG, Z_##CONFIG };     \
1416
   static inline type array(int axis)          \
1420
   static inline type array(int axis)          \
1417
   { return pgm_read_any(&array##_P[axis]); }
1421
   { return pgm_read_any(&array##_P[axis]); }
1477
     if (axis == X_AXIS) {
1481
     if (axis == X_AXIS) {
1478
       float dual_max_x = max(hotend_offset[X_AXIS][1], X2_MAX_POS);
1482
       float dual_max_x = max(hotend_offset[X_AXIS][1], X2_MAX_POS);
1479
       if (active_extruder != 0) {
1483
       if (active_extruder != 0) {
1480
-        sw_endstop_min[X_AXIS] = X2_MIN_POS + offs;
1481
-        sw_endstop_max[X_AXIS] = dual_max_x + offs;
1484
+        soft_endstop_min[X_AXIS] = X2_MIN_POS + offs;
1485
+        soft_endstop_max[X_AXIS] = dual_max_x + offs;
1482
         return;
1486
         return;
1483
       }
1487
       }
1484
       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
1488
       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
1485
-        sw_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs;
1486
-        sw_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs;
1489
+        soft_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs;
1490
+        soft_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs;
1487
         return;
1491
         return;
1488
       }
1492
       }
1489
     }
1493
     }
1490
     else
1494
     else
1491
   #endif
1495
   #endif
1492
   {
1496
   {
1493
-    sw_endstop_min[axis] = base_min_pos(axis) + offs;
1494
-    sw_endstop_max[axis] = base_max_pos(axis) + offs;
1497
+    soft_endstop_min[axis] = base_min_pos(axis) + offs;
1498
+    soft_endstop_max[axis] = base_max_pos(axis) + offs;
1495
   }
1499
   }
1496
 
1500
 
1497
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1501
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1499
       SERIAL_ECHOPAIR("For ", axis_codes[axis]);
1503
       SERIAL_ECHOPAIR("For ", axis_codes[axis]);
1500
       SERIAL_ECHOPAIR(" axis:\n home_offset = ", home_offset[axis]);
1504
       SERIAL_ECHOPAIR(" axis:\n home_offset = ", home_offset[axis]);
1501
       SERIAL_ECHOPAIR("\n position_shift = ", position_shift[axis]);
1505
       SERIAL_ECHOPAIR("\n position_shift = ", position_shift[axis]);
1502
-      SERIAL_ECHOPAIR("\n sw_endstop_min = ", sw_endstop_min[axis]);
1503
-      SERIAL_ECHOPAIR("\n sw_endstop_max = ", sw_endstop_max[axis]);
1506
+      SERIAL_ECHOPAIR("\n soft_endstop_min = ", soft_endstop_min[axis]);
1507
+      SERIAL_ECHOPAIR("\n soft_endstop_max = ", soft_endstop_max[axis]);
1504
       SERIAL_EOL;
1508
       SERIAL_EOL;
1505
     }
1509
     }
1506
   #endif
1510
   #endif
1507
 
1511
 
1508
   #if ENABLED(DELTA)
1512
   #if ENABLED(DELTA)
1509
-    if (axis == Z_AXIS) {
1510
-      delta_clip_start_height = sw_endstop_max[axis] - delta_safe_distance_from_top();
1511
-    }
1513
+    if (axis == Z_AXIS)
1514
+      delta_clip_start_height = soft_endstop_max[axis] - delta_safe_distance_from_top();
1512
   #endif
1515
   #endif
1513
 
1516
 
1514
 }
1517
 }
1552
 
1555
 
1553
     if (axis == X_AXIS || axis == Y_AXIS) {
1556
     if (axis == X_AXIS || axis == Y_AXIS) {
1554
 
1557
 
1555
-      float homeposition[3];
1558
+      float homeposition[XYZ];
1556
       LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos(i), i);
1559
       LOOP_XYZ(i) homeposition[i] = LOGICAL_POSITION(base_home_pos(i), i);
1557
 
1560
 
1558
       // SERIAL_ECHOPGM("homeposition[x]= "); SERIAL_ECHO(homeposition[0]);
1561
       // SERIAL_ECHOPGM("homeposition[x]= "); SERIAL_ECHO(homeposition[0]);
1574
        * SCARA home positions are based on configuration since the actual
1577
        * SCARA home positions are based on configuration since the actual
1575
        * limits are determined by the inverse kinematic transform.
1578
        * limits are determined by the inverse kinematic transform.
1576
        */
1579
        */
1577
-      sw_endstop_min[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis));
1578
-      sw_endstop_max[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis));
1580
+      soft_endstop_min[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis));
1581
+      soft_endstop_max[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis));
1579
     }
1582
     }
1580
     else
1583
     else
1581
   #endif
1584
   #endif
3323
     switch (state) {
3326
     switch (state) {
3324
       case MeshReport:
3327
       case MeshReport:
3325
         if (mbl.has_mesh()) {
3328
         if (mbl.has_mesh()) {
3326
-          SERIAL_PROTOCOLPAIR("State: ", mbl.active() ? "On" : "Off");
3329
+          SERIAL_PROTOCOLPAIR("State: ", mbl.active() ? MSG_ON : MSG_OFF);
3327
           SERIAL_PROTOCOLLNPGM("\nNum X,Y: " STRINGIFY(MESH_NUM_X_POINTS) "," STRINGIFY(MESH_NUM_Y_POINTS));
3330
           SERIAL_PROTOCOLLNPGM("\nNum X,Y: " STRINGIFY(MESH_NUM_X_POINTS) "," STRINGIFY(MESH_NUM_Y_POINTS));
3328
           SERIAL_PROTOCOLLNPGM("Z search height: " STRINGIFY(MESH_HOME_SEARCH_Z));
3331
           SERIAL_PROTOCOLLNPGM("Z search height: " STRINGIFY(MESH_HOME_SEARCH_Z));
3329
           SERIAL_PROTOCOLPGM("Z offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5);
3332
           SERIAL_PROTOCOLPGM("Z offset: "); SERIAL_PROTOCOL_F(mbl.z_offset, 5);
5554
    */
5557
    */
5555
   inline void gcode_M209() {
5558
   inline void gcode_M209() {
5556
     if (code_seen('S')) {
5559
     if (code_seen('S')) {
5557
-      int t = code_value_int();
5558
-      switch (t) {
5559
-        case 0:
5560
-          autoretract_enabled = false;
5561
-          break;
5562
-        case 1:
5563
-          autoretract_enabled = true;
5564
-          break;
5565
-        default:
5566
-          unknown_command_error();
5567
-          return;
5568
-      }
5560
+      autoretract_enabled = code_value_bool();
5569
       for (int i = 0; i < EXTRUDERS; i++) retracted[i] = false;
5561
       for (int i = 0; i < EXTRUDERS; i++) retracted[i] = false;
5570
     }
5562
     }
5571
   }
5563
   }
5572
 
5564
 
5573
 #endif // FWRETRACT
5565
 #endif // FWRETRACT
5574
 
5566
 
5567
+/**
5568
+ * M211: Enable, Disable, and/or Report software endstops
5569
+ *
5570
+ * Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report
5571
+ */
5572
+inline void gcode_M211() {
5573
+  SERIAL_ECHO_START;
5574
+  #if ENABLED(min_software_endstops) || ENABLED(max_software_endstops)
5575
+    if (code_seen('S')) soft_endstops_enabled = code_value_bool();
5576
+  #endif
5577
+  #if ENABLED(min_software_endstops) || ENABLED(max_software_endstops)
5578
+    SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS ": ");
5579
+    serialprintPGM(soft_endstops_enabled ? PSTR(MSG_ON) : PSTR(MSG_OFF));
5580
+  #else
5581
+    SERIAL_ECHOPGM(MSG_SOFT_ENDSTOPS ": " MSG_OFF);
5582
+  #endif
5583
+  SERIAL_ECHOPGM("  " MSG_SOFT_MIN ": ");
5584
+  SERIAL_ECHOPAIR(    MSG_X, soft_endstop_min[X_AXIS]);
5585
+  SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_min[Y_AXIS]);
5586
+  SERIAL_ECHOPAIR(" " MSG_Z, soft_endstop_min[Z_AXIS]);
5587
+  SERIAL_ECHOPGM("  " MSG_SOFT_MAX ": ");
5588
+  SERIAL_ECHOPAIR(    MSG_X, soft_endstop_max[X_AXIS]);
5589
+  SERIAL_ECHOPAIR(" " MSG_Y, soft_endstop_max[Y_AXIS]);
5590
+  SERIAL_ECHOPAIR(" " MSG_Z, soft_endstop_max[Z_AXIS]);
5591
+  SERIAL_EOL;
5592
+}
5593
+
5575
 #if HOTENDS > 1
5594
 #if HOTENDS > 1
5576
 
5595
 
5577
   /**
5596
   /**
6175
   bool err = false;
6194
   bool err = false;
6176
   LOOP_XYZ(i) {
6195
   LOOP_XYZ(i) {
6177
     if (axis_homed[i]) {
6196
     if (axis_homed[i]) {
6178
-      float base = (current_position[i] > (sw_endstop_min[i] + sw_endstop_max[i]) * 0.5) ? base_home_pos(i) : 0,
6197
+      float base = (current_position[i] > (soft_endstop_min[i] + soft_endstop_max[i]) * 0.5) ? base_home_pos(i) : 0,
6179
             diff = current_position[i] - LOGICAL_POSITION(base, i);
6198
             diff = current_position[i] - LOGICAL_POSITION(base, i);
6180
       if (diff > -20 && diff < 20) {
6199
       if (diff > -20 && diff < 20) {
6181
         set_home_offset((AxisEnum)i, home_offset[i] - diff);
6200
         set_home_offset((AxisEnum)i, home_offset[i] - diff);
6499
     stepper.synchronize();
6518
     stepper.synchronize();
6500
     extruder_duplication_enabled = code_seen('S') && code_value_int() == 2;
6519
     extruder_duplication_enabled = code_seen('S') && code_value_int() == 2;
6501
     SERIAL_ECHO_START;
6520
     SERIAL_ECHO_START;
6502
-    SERIAL_ECHOPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF);
6503
-    SERIAL_EOL;
6521
+    SERIAL_ECHOLNPAIR(MSG_DUPLICATION_MODE, extruder_duplication_enabled ? MSG_ON : MSG_OFF);
6504
   }
6522
   }
6505
 
6523
 
6506
 #endif // M605
6524
 #endif // M605
7495
           break;
7513
           break;
7496
       #endif // FWRETRACT
7514
       #endif // FWRETRACT
7497
 
7515
 
7516
+      case 211: // M211 - Enable, Disable, and/or Report software endstops
7517
+        gcode_M211();
7518
+        break;
7519
+
7498
       #if HOTENDS > 1
7520
       #if HOTENDS > 1
7499
         case 218: // M218 - Set a tool offset: T<index> X<offset> Y<offset>
7521
         case 218: // M218 - Set a tool offset: T<index> X<offset> Y<offset>
7500
           gcode_M218();
7522
           gcode_M218();
7749
   SERIAL_EOL;
7771
   SERIAL_EOL;
7750
 }
7772
 }
7751
 
7773
 
7752
-void clamp_to_software_endstops(float target[3]) {
7753
-  if (min_software_endstops) {
7754
-    NOLESS(target[X_AXIS], sw_endstop_min[X_AXIS]);
7755
-    NOLESS(target[Y_AXIS], sw_endstop_min[Y_AXIS]);
7756
-    NOLESS(target[Z_AXIS], sw_endstop_min[Z_AXIS]);
7757
-  }
7758
-  if (max_software_endstops) {
7759
-    NOMORE(target[X_AXIS], sw_endstop_max[X_AXIS]);
7760
-    NOMORE(target[Y_AXIS], sw_endstop_max[Y_AXIS]);
7761
-    NOMORE(target[Z_AXIS], sw_endstop_max[Z_AXIS]);
7774
+#if ENABLED(min_software_endstops) || ENABLED(max_software_endstops)
7775
+
7776
+  void clamp_to_software_endstops(float target[XYZ]) {
7777
+    #if ENABLED(min_software_endstops)
7778
+      NOLESS(target[X_AXIS], soft_endstop_min[X_AXIS]);
7779
+      NOLESS(target[Y_AXIS], soft_endstop_min[Y_AXIS]);
7780
+      NOLESS(target[Z_AXIS], soft_endstop_min[Z_AXIS]);
7781
+    #endif
7782
+    #if ENABLED(max_software_endstops)
7783
+      NOMORE(target[X_AXIS], soft_endstop_max[X_AXIS]);
7784
+      NOMORE(target[Y_AXIS], soft_endstop_max[Y_AXIS]);
7785
+      NOMORE(target[Z_AXIS], soft_endstop_max[Z_AXIS]);
7786
+    #endif
7762
   }
7787
   }
7763
-}
7788
+
7789
+#endif
7764
 
7790
 
7765
 #if ENABLED(DELTA)
7791
 #if ENABLED(DELTA)
7766
 
7792
 
7776
     delta_diagonal_rod_2_tower_3 = sq(diagonal_rod + delta_diagonal_rod_trim_tower_3);
7802
     delta_diagonal_rod_2_tower_3 = sq(diagonal_rod + delta_diagonal_rod_trim_tower_3);
7777
   }
7803
   }
7778
 
7804
 
7779
-  void inverse_kinematics(const float in_cartesian[3]) {
7805
+  void inverse_kinematics(const float in_cartesian[XYZ]) {
7780
 
7806
 
7781
-    const float cartesian[3] = {
7807
+    const float cartesian[XYZ] = {
7782
       RAW_X_POSITION(in_cartesian[X_AXIS]),
7808
       RAW_X_POSITION(in_cartesian[X_AXIS]),
7783
       RAW_Y_POSITION(in_cartesian[Y_AXIS]),
7809
       RAW_Y_POSITION(in_cartesian[Y_AXIS]),
7784
       RAW_Z_POSITION(in_cartesian[Z_AXIS])
7810
       RAW_Z_POSITION(in_cartesian[Z_AXIS])
7808
   }
7834
   }
7809
 
7835
 
7810
   float delta_safe_distance_from_top() {
7836
   float delta_safe_distance_from_top() {
7811
-    float cartesian[3] = {
7837
+    float cartesian[XYZ] = {
7812
       LOGICAL_X_POSITION(0),
7838
       LOGICAL_X_POSITION(0),
7813
       LOGICAL_Y_POSITION(0),
7839
       LOGICAL_Y_POSITION(0),
7814
       LOGICAL_Z_POSITION(0)
7840
       LOGICAL_Z_POSITION(0)
7889
     cartesian_position[Z_AXIS] = z1             + ex[2]*Xnew + ey[2]*Ynew - ez[2]*Znew;
7915
     cartesian_position[Z_AXIS] = z1             + ex[2]*Xnew + ey[2]*Ynew - ez[2]*Znew;
7890
   };
7916
   };
7891
 
7917
 
7892
-  void forward_kinematics_DELTA(float point[3]) {
7893
-    forward_kinematics_DELTA(point[X_AXIS], point[Y_AXIS], point[Z_AXIS]);
7918
+  void forward_kinematics_DELTA(float point[ABC]) {
7919
+    forward_kinematics_DELTA(point[A_AXIS], point[B_AXIS], point[C_AXIS]);
7894
   }
7920
   }
7895
 
7921
 
7896
   void set_cartesian_from_steppers() {
7922
   void set_cartesian_from_steppers() {
7897
-    forward_kinematics_DELTA(stepper.get_axis_position_mm(X_AXIS),
7898
-                             stepper.get_axis_position_mm(Y_AXIS),
7899
-                             stepper.get_axis_position_mm(Z_AXIS));
7923
+    forward_kinematics_DELTA(stepper.get_axis_position_mm(A_AXIS),
7924
+                             stepper.get_axis_position_mm(B_AXIS),
7925
+                             stepper.get_axis_position_mm(C_AXIS));
7900
   }
7926
   }
7901
 
7927
 
7902
   #if ENABLED(AUTO_BED_LEVELING_FEATURE)
7928
   #if ENABLED(AUTO_BED_LEVELING_FEATURE)
7903
 
7929
 
7904
     // Adjust print surface height by linear interpolation over the bed_level array.
7930
     // Adjust print surface height by linear interpolation over the bed_level array.
7905
-    void adjust_delta(float cartesian[3]) {
7931
+    void adjust_delta(float cartesian[XYZ]) {
7906
       if (delta_grid_spacing[X_AXIS] == 0 || delta_grid_spacing[Y_AXIS] == 0) return; // G29 not done!
7932
       if (delta_grid_spacing[X_AXIS] == 0 || delta_grid_spacing[Y_AXIS] == 0) return; // G29 not done!
7907
 
7933
 
7908
       int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2;
7934
       int half = (AUTO_BED_LEVELING_GRID_POINTS - 1) / 2;
8375
 
8401
 
8376
 #if ENABLED(SCARA)
8402
 #if ENABLED(SCARA)
8377
 
8403
 
8378
-  void forward_kinematics_SCARA(float f_scara[3]) {
8379
-    // Perform forward kinematics, and place results in delta[3]
8404
+  void forward_kinematics_SCARA(float f_scara[ABC]) {
8405
+    // Perform forward kinematics, and place results in delta[]
8380
     // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
8406
     // The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
8381
 
8407
 
8382
     float x_sin, x_cos, y_sin, y_cos;
8408
     float x_sin, x_cos, y_sin, y_cos;
8401
     //SERIAL_ECHOPGM(" delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
8427
     //SERIAL_ECHOPGM(" delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
8402
   }
8428
   }
8403
 
8429
 
8404
-  void inverse_kinematics(const float cartesian[3]) {
8430
+  void inverse_kinematics(const float cartesian[XYZ]) {
8405
     // Inverse kinematics.
8431
     // Inverse kinematics.
8406
-    // Perform SCARA IK and place results in delta[3].
8432
+    // Perform SCARA IK and place results in delta[].
8407
     // The maths and first version were done by QHARLEY.
8433
     // The maths and first version were done by QHARLEY.
8408
     // Integrated, tweaked by Joachim Cerny in June 2014.
8434
     // Integrated, tweaked by Joachim Cerny in June 2014.
8409
 
8435
 

+ 3
- 0
Marlin/language.h 查看文件

157
 #define MSG_ENDSTOP_OPEN                    "open"
157
 #define MSG_ENDSTOP_OPEN                    "open"
158
 #define MSG_HOTEND_OFFSET                   "Hotend offsets:"
158
 #define MSG_HOTEND_OFFSET                   "Hotend offsets:"
159
 #define MSG_DUPLICATION_MODE                "Duplication mode: "
159
 #define MSG_DUPLICATION_MODE                "Duplication mode: "
160
+#define MSG_SOFT_ENDSTOPS                   "Soft endstops"
161
+#define MSG_SOFT_MIN                        "Min"
162
+#define MSG_SOFT_MAX                        "Max"
160
 
163
 
161
 #define MSG_SD_CANT_OPEN_SUBDIR             "Cannot open subdir "
164
 #define MSG_SD_CANT_OPEN_SUBDIR             "Cannot open subdir "
162
 #define MSG_SD_INIT_FAIL                    "SD init fail"
165
 #define MSG_SD_INIT_FAIL                    "SD init fail"

+ 3
- 0
Marlin/macros.h 查看文件

24
 #define MACROS_H
24
 #define MACROS_H
25
 
25
 
26
 #define NUM_AXIS 4
26
 #define NUM_AXIS 4
27
+#define XYZE 4
28
+#define ABC  3
29
+#define XYZ  3
27
 
30
 
28
 #define FORCE_INLINE __attribute__((always_inline)) inline
31
 #define FORCE_INLINE __attribute__((always_inline)) inline
29
 
32
 

+ 1
- 1
Marlin/planner.cpp 查看文件

968
     float junction_deviation = 0.1;
968
     float junction_deviation = 0.1;
969
 
969
 
970
     // Compute path unit vector
970
     // Compute path unit vector
971
-    double unit_vec[3];
971
+    double unit_vec[XYZ];
972
 
972
 
973
     unit_vec[X_AXIS] = delta_mm[X_AXIS] * inverse_millimeters;
973
     unit_vec[X_AXIS] = delta_mm[X_AXIS] * inverse_millimeters;
974
     unit_vec[Y_AXIS] = delta_mm[Y_AXIS] * inverse_millimeters;
974
     unit_vec[Y_AXIS] = delta_mm[Y_AXIS] * inverse_millimeters;

+ 1
- 1
Marlin/stepper.cpp 查看文件

122
 uint8_t Stepper::step_loops, Stepper::step_loops_nominal;
122
 uint8_t Stepper::step_loops, Stepper::step_loops_nominal;
123
 unsigned short Stepper::OCR1A_nominal;
123
 unsigned short Stepper::OCR1A_nominal;
124
 
124
 
125
-volatile long Stepper::endstops_trigsteps[3];
125
+volatile long Stepper::endstops_trigsteps[XYZ];
126
 
126
 
127
 #if ENABLED(X_DUAL_STEPPER_DRIVERS)
127
 #if ENABLED(X_DUAL_STEPPER_DRIVERS)
128
   #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0)
128
   #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0)

+ 1
- 1
Marlin/stepper.h 查看文件

128
     static uint8_t step_loops, step_loops_nominal;
128
     static uint8_t step_loops, step_loops_nominal;
129
     static unsigned short OCR1A_nominal;
129
     static unsigned short OCR1A_nominal;
130
 
130
 
131
-    static volatile long endstops_trigsteps[3];
131
+    static volatile long endstops_trigsteps[XYZ];
132
     static volatile long endstops_stepsTotal, endstops_stepsDone;
132
     static volatile long endstops_stepsTotal, endstops_stepsDone;
133
 
133
 
134
     #if HAS_MOTOR_CURRENT_PWM
134
     #if HAS_MOTOR_CURRENT_PWM

+ 1
- 1
Marlin/temperature.cpp 查看文件

95
 #endif
95
 #endif
96
 
96
 
97
 #if ENABLED(BABYSTEPPING)
97
 #if ENABLED(BABYSTEPPING)
98
-  volatile int Temperature::babystepsTodo[3] = { 0 };
98
+  volatile int Temperature::babystepsTodo[XYZ] = { 0 };
99
 #endif
99
 #endif
100
 
100
 
101
 #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0
101
 #if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0

+ 26
- 14
Marlin/ultralcd.cpp 查看文件

1327
    *
1327
    *
1328
    */
1328
    */
1329
 
1329
 
1330
-  static void _lcd_move_xyz(const char* name, AxisEnum axis, float min, float max) {
1330
+  static void _lcd_move_xyz(const char* name, AxisEnum axis) {
1331
     if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; }
1331
     if (LCD_CLICKED) { lcd_goto_previous_menu(true); return; }
1332
     ENCODER_DIRECTION_NORMAL();
1332
     ENCODER_DIRECTION_NORMAL();
1333
     if (encoderPosition) {
1333
     if (encoderPosition) {
1334
       refresh_cmd_timeout();
1334
       refresh_cmd_timeout();
1335
+
1336
+      // Limit to software endstops, if enabled
1337
+      float min = (soft_endstops_enabled && min_software_endstops) ? soft_endstop_min[axis] : current_position[axis] - 1000,
1338
+            max = (soft_endstops_enabled && max_software_endstops) ? soft_endstop_max[axis] : current_position[axis] + 1000;
1339
+
1340
+      // Get the new position
1335
       current_position[axis] += float((int32_t)encoderPosition) * move_menu_scale;
1341
       current_position[axis] += float((int32_t)encoderPosition) * move_menu_scale;
1336
-      if (min_software_endstops) NOLESS(current_position[axis], min);
1337
-      if (max_software_endstops) NOMORE(current_position[axis], max);
1338
-      encoderPosition = 0;
1342
+
1343
+      // Delta limits XY based on the current offset from center
1344
+      // This assumes the center is 0,0
1345
+      #if ENABLED(DELTA)
1346
+        if (axis != Z_AXIS) {
1347
+          max = sqrt(sq(DELTA_PRINTABLE_RADIUS) - sq(current_position[Y_AXIS - axis]));
1348
+          min = -max;
1349
+        }
1350
+      #endif
1351
+
1352
+      // Limit only when trying to move towards the limit
1353
+      if ((int32_t)encoderPosition < 0) NOLESS(current_position[axis], min);
1354
+      if ((int32_t)encoderPosition > 0) NOMORE(current_position[axis], max);
1355
+
1339
       manual_move_to_current(axis);
1356
       manual_move_to_current(axis);
1357
+
1358
+      encoderPosition = 0;
1340
       lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
1359
       lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
1341
     }
1360
     }
1342
     if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr41sign(current_position[axis]));
1361
     if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr41sign(current_position[axis]));
1343
   }
1362
   }
1344
-  #if ENABLED(DELTA)
1345
-    static float delta_clip_radius_2 =  (DELTA_PRINTABLE_RADIUS) * (DELTA_PRINTABLE_RADIUS);
1346
-    static int delta_clip( float a ) { return sqrt(delta_clip_radius_2 - sq(a)); }
1347
-    static void lcd_move_x() { int clip = delta_clip(current_position[Y_AXIS]); _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS, max(sw_endstop_min[X_AXIS], -clip), min(sw_endstop_max[X_AXIS], clip)); }
1348
-    static void lcd_move_y() { int clip = delta_clip(current_position[X_AXIS]); _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS, max(sw_endstop_min[Y_AXIS], -clip), min(sw_endstop_max[Y_AXIS], clip)); }
1349
-  #else
1350
-    static void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS, sw_endstop_min[X_AXIS], sw_endstop_max[X_AXIS]); }
1351
-    static void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS, sw_endstop_min[Y_AXIS], sw_endstop_max[Y_AXIS]); }
1352
-  #endif
1353
-  static void lcd_move_z() { _lcd_move_xyz(PSTR(MSG_MOVE_Z), Z_AXIS, sw_endstop_min[Z_AXIS], sw_endstop_max[Z_AXIS]); }
1363
+  static void lcd_move_x() { _lcd_move_xyz(PSTR(MSG_MOVE_X), X_AXIS); }
1364
+  static void lcd_move_y() { _lcd_move_xyz(PSTR(MSG_MOVE_Y), Y_AXIS); }
1365
+  static void lcd_move_z() { _lcd_move_xyz(PSTR(MSG_MOVE_Z), Z_AXIS); }
1354
   static void _lcd_move_e(
1366
   static void _lcd_move_e(
1355
     #if E_MANUAL > 1
1367
     #if E_MANUAL > 1
1356
       int8_t eindex=-1
1368
       int8_t eindex=-1

Loading…
取消
儲存