Browse Source

Merge pull request #4319 from thinkyhead/rc_feedrates_to_mess_with_you

Wrangle feed rate variables
Scott Lahteine 9 years ago
parent
commit
f242aea032

+ 12
- 2
Marlin/Marlin.h View File

297
   #define CRITICAL_SECTION_END    SREG = _sreg;
297
   #define CRITICAL_SECTION_END    SREG = _sreg;
298
 #endif
298
 #endif
299
 
299
 
300
+/**
301
+ * Feedrate scaling and conversion
302
+ */
303
+extern int feedrate_percentage;
304
+
305
+#define MMM_TO_MMS(MM_M) ((MM_M)/60.0)
306
+#define MMS_TO_MMM(MM_S) ((MM_S)*60.0)
307
+#define MMM_SCALED(MM_M) ((MM_M)*feedrate_percentage/100.0)
308
+#define MMS_SCALED(MM_S) MMM_SCALED(MM_S)
309
+#define MMM_TO_MMS_SCALED(MM_M) (MMS_SCALED(MMM_TO_MMS(MM_M)))
310
+
300
 extern bool axis_relative_modes[];
311
 extern bool axis_relative_modes[];
301
-extern int feedrate_multiplier;
302
 extern bool volumetric_enabled;
312
 extern bool volumetric_enabled;
303
 extern int extruder_multiplier[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
313
 extern int extruder_multiplier[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
304
 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.
314
 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.
386
   extern bool autoretract_enabled;
396
   extern bool autoretract_enabled;
387
   extern bool retracted[EXTRUDERS]; // extruder[n].retracted
397
   extern bool retracted[EXTRUDERS]; // extruder[n].retracted
388
   extern float retract_length, retract_length_swap, retract_feedrate_mm_s, retract_zlift;
398
   extern float retract_length, retract_length_swap, retract_feedrate_mm_s, retract_zlift;
389
-  extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate;
399
+  extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate_mm_s;
390
 #endif
400
 #endif
391
 
401
 
392
 // Print job timer
402
 // Print job timer

+ 112
- 109
Marlin/Marlin_main.cpp View File

280
 
280
 
281
 uint8_t marlin_debug_flags = DEBUG_NONE;
281
 uint8_t marlin_debug_flags = DEBUG_NONE;
282
 
282
 
283
-static float feedrate = 1500.0, saved_feedrate;
284
 float current_position[NUM_AXIS] = { 0.0 };
283
 float current_position[NUM_AXIS] = { 0.0 };
285
 static float destination[NUM_AXIS] = { 0.0 };
284
 static float destination[NUM_AXIS] = { 0.0 };
286
 bool axis_known_position[3] = { false };
285
 bool axis_known_position[3] = { false };
302
   TempUnit input_temp_units = TEMPUNIT_C;
301
   TempUnit input_temp_units = TEMPUNIT_C;
303
 #endif
302
 #endif
304
 
303
 
305
-const float homing_feedrate[] = HOMING_FEEDRATE;
304
+/**
305
+ * Feed rates are often configured with mm/m
306
+ * but the planner and stepper like mm/s units.
307
+ */
308
+const float homing_feedrate_mm_m[] = HOMING_FEEDRATE;
309
+static float feedrate_mm_m = 1500.0, saved_feedrate_mm_m;
310
+int feedrate_percentage = 100, saved_feedrate_percentage;
306
 
311
 
307
 bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
312
 bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
308
-int feedrate_multiplier = 100; //100->1 200->2
309
-int saved_feedrate_multiplier;
310
 int extruder_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100);
313
 int extruder_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100);
311
 bool volumetric_enabled = false;
314
 bool volumetric_enabled = false;
312
 float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(DEFAULT_NOMINAL_FILAMENT_DIA);
315
 float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(DEFAULT_NOMINAL_FILAMENT_DIA);
382
   float zprobe_zoffset = Z_PROBE_OFFSET_FROM_EXTRUDER;
385
   float zprobe_zoffset = Z_PROBE_OFFSET_FROM_EXTRUDER;
383
 #endif
386
 #endif
384
 
387
 
385
-#define PLANNER_XY_FEEDRATE() (min(planner.max_feedrate[X_AXIS], planner.max_feedrate[Y_AXIS]))
388
+#define PLANNER_XY_FEEDRATE() (min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]))
386
 
389
 
387
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
390
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
388
-  int xy_probe_speed = XY_PROBE_SPEED;
391
+  int xy_probe_feedrate_mm_m = XY_PROBE_SPEED;
389
   bool bed_leveling_in_progress = false;
392
   bool bed_leveling_in_progress = false;
390
-  #define XY_PROBE_FEEDRATE xy_probe_speed
393
+  #define XY_PROBE_FEEDRATE_MM_M xy_probe_feedrate_mm_m
391
 #elif defined(XY_PROBE_SPEED)
394
 #elif defined(XY_PROBE_SPEED)
392
-  #define XY_PROBE_FEEDRATE XY_PROBE_SPEED
395
+  #define XY_PROBE_FEEDRATE_MM_M XY_PROBE_SPEED
393
 #else
396
 #else
394
-  #define XY_PROBE_FEEDRATE (PLANNER_XY_FEEDRATE() * 60)
397
+  #define XY_PROBE_FEEDRATE_MM_M MMS_TO_MMM(PLANNER_XY_FEEDRATE())
395
 #endif
398
 #endif
396
 
399
 
397
 #if ENABLED(Z_DUAL_ENDSTOPS) && DISABLED(DELTA)
400
 #if ENABLED(Z_DUAL_ENDSTOPS) && DISABLED(DELTA)
430
   float retract_zlift = RETRACT_ZLIFT;
433
   float retract_zlift = RETRACT_ZLIFT;
431
   float retract_recover_length = RETRACT_RECOVER_LENGTH;
434
   float retract_recover_length = RETRACT_RECOVER_LENGTH;
432
   float retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
435
   float retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
433
-  float retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE;
436
+  float retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
434
 
437
 
435
 #endif // FWRETRACT
438
 #endif // FWRETRACT
436
 
439
 
1599
     SERIAL_ECHO_START;
1602
     SERIAL_ECHO_START;
1600
     SERIAL_ECHOLNPGM("Warning: Homing Bump Divisor < 1");
1603
     SERIAL_ECHOLNPGM("Warning: Homing Bump Divisor < 1");
1601
   }
1604
   }
1602
-  feedrate = homing_feedrate[axis] / hbd;
1605
+  feedrate_mm_m = homing_feedrate_mm_m[axis] / hbd;
1603
 }
1606
 }
1604
 //
1607
 //
1605
 // line_to_current_position
1608
 // line_to_current_position
1607
 // (or from wherever it has been told it is located).
1610
 // (or from wherever it has been told it is located).
1608
 //
1611
 //
1609
 inline void line_to_current_position() {
1612
 inline void line_to_current_position() {
1610
-  planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate / 60, active_extruder);
1613
+  planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(feedrate_mm_m), active_extruder);
1611
 }
1614
 }
1612
 inline void line_to_z(float zPosition) {
1615
 inline void line_to_z(float zPosition) {
1613
-  planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate / 60, active_extruder);
1616
+  planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], MMM_TO_MMS(feedrate_mm_m), active_extruder);
1614
 }
1617
 }
1615
 //
1618
 //
1616
 // line_to_destination
1619
 // line_to_destination
1617
 // Move the planner, not necessarily synced with current_position
1620
 // Move the planner, not necessarily synced with current_position
1618
 //
1621
 //
1619
-inline void line_to_destination(float mm_m) {
1620
-  planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], mm_m / 60, active_extruder);
1622
+inline void line_to_destination(float fr_mm_m) {
1623
+  planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], MMM_TO_MMS(fr_mm_m), active_extruder);
1621
 }
1624
 }
1622
-inline void line_to_destination() { line_to_destination(feedrate); }
1625
+inline void line_to_destination() { line_to_destination(feedrate_mm_m); }
1623
 
1626
 
1624
 /**
1627
 /**
1625
  * sync_plan_position
1628
  * sync_plan_position
1647
     #endif
1650
     #endif
1648
     refresh_cmd_timeout();
1651
     refresh_cmd_timeout();
1649
     calculate_delta(destination);
1652
     calculate_delta(destination);
1650
-    planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate / 60) * (feedrate_multiplier / 100.0), active_extruder);
1653
+    planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], MMM_TO_MMS_SCALED(feedrate_mm_m), active_extruder);
1651
     set_current_to_destination();
1654
     set_current_to_destination();
1652
   }
1655
   }
1653
 #endif
1656
 #endif
1656
  *  Plan a move to (X, Y, Z) and set the current_position
1659
  *  Plan a move to (X, Y, Z) and set the current_position
1657
  *  The final current_position may not be the one that was requested
1660
  *  The final current_position may not be the one that was requested
1658
  */
1661
  */
1659
-static void do_blocking_move_to(float x, float y, float z, float feed_rate = 0.0) {
1660
-  float old_feedrate = feedrate;
1662
+static void do_blocking_move_to(float x, float y, float z, float fr_mm_m = 0.0) {
1663
+  float old_feedrate_mm_m = feedrate_mm_m;
1661
 
1664
 
1662
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1665
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1663
     if (DEBUGGING(LEVELING)) print_xyz(PSTR("do_blocking_move_to"), NULL, x, y, z);
1666
     if (DEBUGGING(LEVELING)) print_xyz(PSTR("do_blocking_move_to"), NULL, x, y, z);
1665
 
1668
 
1666
   #if ENABLED(DELTA)
1669
   #if ENABLED(DELTA)
1667
 
1670
 
1668
-    feedrate = (feed_rate != 0.0) ? feed_rate : XY_PROBE_FEEDRATE;
1671
+    feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : XY_PROBE_FEEDRATE_MM_M;
1669
 
1672
 
1670
     destination[X_AXIS] = x;
1673
     destination[X_AXIS] = x;
1671
     destination[Y_AXIS] = y;
1674
     destination[Y_AXIS] = y;
1680
 
1683
 
1681
     // If Z needs to raise, do it before moving XY
1684
     // If Z needs to raise, do it before moving XY
1682
     if (current_position[Z_AXIS] < z) {
1685
     if (current_position[Z_AXIS] < z) {
1683
-      feedrate = (feed_rate != 0.0) ? feed_rate : homing_feedrate[Z_AXIS];
1686
+      feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : homing_feedrate_mm_m[Z_AXIS];
1684
       current_position[Z_AXIS] = z;
1687
       current_position[Z_AXIS] = z;
1685
       line_to_current_position();
1688
       line_to_current_position();
1686
     }
1689
     }
1687
 
1690
 
1688
-    feedrate = (feed_rate != 0.0) ? feed_rate : XY_PROBE_FEEDRATE;
1691
+    feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : XY_PROBE_FEEDRATE_MM_M;
1689
     current_position[X_AXIS] = x;
1692
     current_position[X_AXIS] = x;
1690
     current_position[Y_AXIS] = y;
1693
     current_position[Y_AXIS] = y;
1691
     line_to_current_position();
1694
     line_to_current_position();
1692
 
1695
 
1693
     // If Z needs to lower, do it after moving XY
1696
     // If Z needs to lower, do it after moving XY
1694
     if (current_position[Z_AXIS] > z) {
1697
     if (current_position[Z_AXIS] > z) {
1695
-      feedrate = (feed_rate != 0.0) ? feed_rate : homing_feedrate[Z_AXIS];
1698
+      feedrate_mm_m = (fr_mm_m != 0.0) ? fr_mm_m : homing_feedrate_mm_m[Z_AXIS];
1696
       current_position[Z_AXIS] = z;
1699
       current_position[Z_AXIS] = z;
1697
       line_to_current_position();
1700
       line_to_current_position();
1698
     }
1701
     }
1701
 
1704
 
1702
   stepper.synchronize();
1705
   stepper.synchronize();
1703
 
1706
 
1704
-  feedrate = old_feedrate;
1707
+  feedrate_mm_m = old_feedrate_mm_m;
1705
 }
1708
 }
1706
 
1709
 
1707
-inline void do_blocking_move_to_x(float x, float feed_rate = 0.0) {
1708
-  do_blocking_move_to(x, current_position[Y_AXIS], current_position[Z_AXIS], feed_rate);
1710
+inline void do_blocking_move_to_x(float x, float fr_mm_m = 0.0) {
1711
+  do_blocking_move_to(x, current_position[Y_AXIS], current_position[Z_AXIS], fr_mm_m);
1709
 }
1712
 }
1710
 
1713
 
1711
 inline void do_blocking_move_to_y(float y) {
1714
 inline void do_blocking_move_to_y(float y) {
1712
   do_blocking_move_to(current_position[X_AXIS], y, current_position[Z_AXIS]);
1715
   do_blocking_move_to(current_position[X_AXIS], y, current_position[Z_AXIS]);
1713
 }
1716
 }
1714
 
1717
 
1715
-inline void do_blocking_move_to_xy(float x, float y, float feed_rate = 0.0) {
1716
-  do_blocking_move_to(x, y, current_position[Z_AXIS], feed_rate);
1718
+inline void do_blocking_move_to_xy(float x, float y, float fr_mm_m = 0.0) {
1719
+  do_blocking_move_to(x, y, current_position[Z_AXIS], fr_mm_m);
1717
 }
1720
 }
1718
 
1721
 
1719
-inline void do_blocking_move_to_z(float z, float feed_rate = 0.0) {
1720
-  do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z, feed_rate);
1722
+inline void do_blocking_move_to_z(float z, float fr_mm_m = 0.0) {
1723
+  do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z, fr_mm_m);
1721
 }
1724
 }
1722
 
1725
 
1723
 //
1726
 //
1733
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1736
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1734
     if (DEBUGGING(LEVELING)) DEBUG_POS("setup_for_endstop_or_probe_move", current_position);
1737
     if (DEBUGGING(LEVELING)) DEBUG_POS("setup_for_endstop_or_probe_move", current_position);
1735
   #endif
1738
   #endif
1736
-  saved_feedrate = feedrate;
1737
-  saved_feedrate_multiplier = feedrate_multiplier;
1738
-  feedrate_multiplier = 100;
1739
+  saved_feedrate_mm_m = feedrate_mm_m;
1740
+  saved_feedrate_percentage = feedrate_percentage;
1741
+  feedrate_percentage = 100;
1739
   refresh_cmd_timeout();
1742
   refresh_cmd_timeout();
1740
 }
1743
 }
1741
 
1744
 
1743
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1746
   #if ENABLED(DEBUG_LEVELING_FEATURE)
1744
     if (DEBUGGING(LEVELING)) DEBUG_POS("clean_up_after_endstop_or_probe_move", current_position);
1747
     if (DEBUGGING(LEVELING)) DEBUG_POS("clean_up_after_endstop_or_probe_move", current_position);
1745
   #endif
1748
   #endif
1746
-  feedrate = saved_feedrate;
1747
-  feedrate_multiplier = saved_feedrate_multiplier;
1749
+  feedrate_mm_m = saved_feedrate_mm_m;
1750
+  feedrate_percentage = saved_feedrate_percentage;
1748
   refresh_cmd_timeout();
1751
   refresh_cmd_timeout();
1749
 }
1752
 }
1750
 
1753
 
2003
       if (DEBUGGING(LEVELING)) {
2006
       if (DEBUGGING(LEVELING)) {
2004
         DEBUG_POS("set_probe_deployed", current_position);
2007
         DEBUG_POS("set_probe_deployed", current_position);
2005
         SERIAL_ECHOPAIR("deploy: ", deploy);
2008
         SERIAL_ECHOPAIR("deploy: ", deploy);
2009
+        SERIAL_EOL;
2006
       }
2010
       }
2007
     #endif
2011
     #endif
2008
 
2012
 
2062
   // at the height where the probe triggered.
2066
   // at the height where the probe triggered.
2063
   static float run_z_probe() {
2067
   static float run_z_probe() {
2064
 
2068
 
2065
-    float old_feedrate = feedrate;
2069
+    float old_feedrate_mm_m = feedrate_mm_m;
2066
 
2070
 
2067
     // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding
2071
     // Prevent stepper_inactive_time from running out and EXTRUDER_RUNOUT_PREVENT from extruding
2068
     refresh_cmd_timeout();
2072
     refresh_cmd_timeout();
2077
       #endif
2081
       #endif
2078
 
2082
 
2079
       // move down slowly until you find the bed
2083
       // move down slowly until you find the bed
2080
-      feedrate = homing_feedrate[Z_AXIS] / 4;
2084
+      feedrate_mm_m = homing_feedrate_mm_m[Z_AXIS] / 4;
2081
       destination[Z_AXIS] = -10;
2085
       destination[Z_AXIS] = -10;
2082
       prepare_move_to_destination_raw(); // this will also set_current_to_destination
2086
       prepare_move_to_destination_raw(); // this will also set_current_to_destination
2083
       stepper.synchronize();
2087
       stepper.synchronize();
2101
         planner.bed_level_matrix.set_to_identity();
2105
         planner.bed_level_matrix.set_to_identity();
2102
       #endif
2106
       #endif
2103
 
2107
 
2104
-      feedrate = homing_feedrate[Z_AXIS];
2108
+      feedrate_mm_m = homing_feedrate_mm_m[Z_AXIS];
2105
 
2109
 
2106
       // Move down until the Z probe (or endstop?) is triggered
2110
       // Move down until the Z probe (or endstop?) is triggered
2107
       float zPosition = -(Z_MAX_LENGTH + 10);
2111
       float zPosition = -(Z_MAX_LENGTH + 10);
2140
 
2144
 
2141
     SYNC_PLAN_POSITION_KINEMATIC();
2145
     SYNC_PLAN_POSITION_KINEMATIC();
2142
 
2146
 
2143
-    feedrate = old_feedrate;
2147
+    feedrate_mm_m = old_feedrate_mm_m;
2144
 
2148
 
2145
     return current_position[Z_AXIS];
2149
     return current_position[Z_AXIS];
2146
   }
2150
   }
2165
       }
2169
       }
2166
     #endif
2170
     #endif
2167
 
2171
 
2168
-    float old_feedrate = feedrate;
2172
+    float old_feedrate_mm_m = feedrate_mm_m;
2169
 
2173
 
2170
     // Ensure a minimum height before moving the probe
2174
     // Ensure a minimum height before moving the probe
2171
     do_probe_raise(Z_RAISE_BETWEEN_PROBINGS);
2175
     do_probe_raise(Z_RAISE_BETWEEN_PROBINGS);
2178
         SERIAL_ECHOLNPGM(")");
2182
         SERIAL_ECHOLNPGM(")");
2179
       }
2183
       }
2180
     #endif
2184
     #endif
2181
-    feedrate = XY_PROBE_FEEDRATE;
2185
+    feedrate_mm_m = XY_PROBE_FEEDRATE_MM_M;
2182
     do_blocking_move_to_xy(x - (X_PROBE_OFFSET_FROM_EXTRUDER), y - (Y_PROBE_OFFSET_FROM_EXTRUDER));
2186
     do_blocking_move_to_xy(x - (X_PROBE_OFFSET_FROM_EXTRUDER), y - (Y_PROBE_OFFSET_FROM_EXTRUDER));
2183
 
2187
 
2184
     #if ENABLED(DEBUG_LEVELING_FEATURE)
2188
     #if ENABLED(DEBUG_LEVELING_FEATURE)
2215
       if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt");
2219
       if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt");
2216
     #endif
2220
     #endif
2217
 
2221
 
2218
-    feedrate = old_feedrate;
2222
+    feedrate_mm_m = old_feedrate_mm_m;
2219
 
2223
 
2220
     return measured_z;
2224
     return measured_z;
2221
   }
2225
   }
2416
 
2420
 
2417
   // Move towards the endstop until an endstop is triggered
2421
   // Move towards the endstop until an endstop is triggered
2418
   destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
2422
   destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
2419
-  feedrate = homing_feedrate[axis];
2423
+  feedrate_mm_m = homing_feedrate_mm_m[axis];
2420
   line_to_destination();
2424
   line_to_destination();
2421
   stepper.synchronize();
2425
   stepper.synchronize();
2422
 
2426
 
2456
       sync_plan_position();
2460
       sync_plan_position();
2457
 
2461
 
2458
       // Move to the adjusted endstop height
2462
       // Move to the adjusted endstop height
2459
-      feedrate = homing_feedrate[axis];
2463
+      feedrate_mm_m = homing_feedrate_mm_m[axis];
2460
       destination[Z_AXIS] = adj;
2464
       destination[Z_AXIS] = adj;
2461
       line_to_destination();
2465
       line_to_destination();
2462
       stepper.synchronize();
2466
       stepper.synchronize();
2520
 
2524
 
2521
     if (retracting == retracted[active_extruder]) return;
2525
     if (retracting == retracted[active_extruder]) return;
2522
 
2526
 
2523
-    float old_feedrate = feedrate;
2527
+    float old_feedrate_mm_m = feedrate_mm_m;
2524
 
2528
 
2525
     set_destination_to_current();
2529
     set_destination_to_current();
2526
 
2530
 
2527
     if (retracting) {
2531
     if (retracting) {
2528
 
2532
 
2529
-      feedrate = retract_feedrate_mm_s * 60;
2533
+      feedrate_mm_m = MMS_TO_MMM(retract_feedrate_mm_s);
2530
       current_position[E_AXIS] += (swapping ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder];
2534
       current_position[E_AXIS] += (swapping ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder];
2531
       sync_plan_position_e();
2535
       sync_plan_position_e();
2532
       prepare_move_to_destination();
2536
       prepare_move_to_destination();
2544
         SYNC_PLAN_POSITION_KINEMATIC();
2548
         SYNC_PLAN_POSITION_KINEMATIC();
2545
       }
2549
       }
2546
 
2550
 
2547
-      feedrate = retract_recover_feedrate * 60;
2551
+      feedrate_mm_m = MMM_TO_MMS(retract_recover_feedrate_mm_s);
2548
       float move_e = swapping ? retract_length_swap + retract_recover_length_swap : retract_length + retract_recover_length;
2552
       float move_e = swapping ? retract_length_swap + retract_recover_length_swap : retract_length + retract_recover_length;
2549
       current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder];
2553
       current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder];
2550
       sync_plan_position_e();
2554
       sync_plan_position_e();
2551
       prepare_move_to_destination();
2555
       prepare_move_to_destination();
2552
     }
2556
     }
2553
 
2557
 
2554
-    feedrate = old_feedrate;
2558
+    feedrate_mm_m = old_feedrate_mm_m;
2555
     retracted[active_extruder] = retracting;
2559
     retracted[active_extruder] = retracting;
2556
 
2560
 
2557
   } // retract()
2561
   } // retract()
2613
   }
2617
   }
2614
 
2618
 
2615
   if (code_seen('F') && code_value_linear_units() > 0.0)
2619
   if (code_seen('F') && code_value_linear_units() > 0.0)
2616
-    feedrate = code_value_linear_units();
2620
+    feedrate_mm_m = code_value_linear_units();
2617
 
2621
 
2618
   #if ENABLED(PRINTCOUNTER)
2622
   #if ENABLED(PRINTCOUNTER)
2619
-    if(!DEBUGGING(DRYRUN))
2623
+    if (!DEBUGGING(DRYRUN))
2620
       print_job_timer.incFilamentUsed(destination[E_AXIS] - current_position[E_AXIS]);
2624
       print_job_timer.incFilamentUsed(destination[E_AXIS] - current_position[E_AXIS]);
2621
   #endif
2625
   #endif
2622
 
2626
 
2846
 
2850
 
2847
     destination[X_AXIS] = 1.5 * mlx * x_axis_home_dir;
2851
     destination[X_AXIS] = 1.5 * mlx * x_axis_home_dir;
2848
     destination[Y_AXIS] = 1.5 * mly * home_dir(Y_AXIS);
2852
     destination[Y_AXIS] = 1.5 * mly * home_dir(Y_AXIS);
2849
-    feedrate = min(homing_feedrate[X_AXIS], homing_feedrate[Y_AXIS]) * sqrt(mlratio * mlratio + 1);
2853
+    feedrate_mm_m = min(homing_feedrate_mm_m[X_AXIS], homing_feedrate_mm_m[Y_AXIS]) * sqrt(sq(mlratio) + 1);
2850
     line_to_destination();
2854
     line_to_destination();
2851
     stepper.synchronize();
2855
     stepper.synchronize();
2852
     endstops.hit_on_purpose(); // clear endstop hit flags
2856
     endstops.hit_on_purpose(); // clear endstop hit flags
2943
 
2947
 
2944
     // Move all carriages up together until the first endstop is hit.
2948
     // Move all carriages up together until the first endstop is hit.
2945
     for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * (Z_MAX_LENGTH);
2949
     for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * (Z_MAX_LENGTH);
2946
-    feedrate = 1.732 * homing_feedrate[X_AXIS];
2950
+    feedrate_mm_m = 1.732 * homing_feedrate_mm_m[X_AXIS];
2947
     line_to_destination();
2951
     line_to_destination();
2948
     stepper.synchronize();
2952
     stepper.synchronize();
2949
     endstops.hit_on_purpose(); // clear endstop hit flags
2953
     endstops.hit_on_purpose(); // clear endstop hit flags
3164
         #if ENABLED(MESH_G28_REST_ORIGIN)
3168
         #if ENABLED(MESH_G28_REST_ORIGIN)
3165
           current_position[Z_AXIS] = 0.0;
3169
           current_position[Z_AXIS] = 0.0;
3166
           set_destination_to_current();
3170
           set_destination_to_current();
3167
-          feedrate = homing_feedrate[Z_AXIS];
3171
+          feedrate_mm_m = homing_feedrate_mm_m[Z_AXIS];
3168
           line_to_destination();
3172
           line_to_destination();
3169
           stepper.synchronize();
3173
           stepper.synchronize();
3170
           #if ENABLED(DEBUG_LEVELING_FEATURE)
3174
           #if ENABLED(DEBUG_LEVELING_FEATURE)
3224
   enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset, MeshReset };
3228
   enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset, MeshReset };
3225
 
3229
 
3226
   inline void _mbl_goto_xy(float x, float y) {
3230
   inline void _mbl_goto_xy(float x, float y) {
3227
-    float old_feedrate = feedrate;
3228
-    feedrate = homing_feedrate[X_AXIS];
3231
+    float old_feedrate_mm_m = feedrate_mm_m;
3232
+    feedrate_mm_m = homing_feedrate_mm_m[X_AXIS];
3229
 
3233
 
3230
     current_position[Z_AXIS] = MESH_HOME_SEARCH_Z
3234
     current_position[Z_AXIS] = MESH_HOME_SEARCH_Z
3231
       #if Z_RAISE_BETWEEN_PROBINGS > MIN_Z_HEIGHT_FOR_HOMING
3235
       #if Z_RAISE_BETWEEN_PROBINGS > MIN_Z_HEIGHT_FOR_HOMING
3245
       line_to_current_position();
3249
       line_to_current_position();
3246
     #endif
3250
     #endif
3247
 
3251
 
3248
-    feedrate = old_feedrate;
3252
+    feedrate_mm_m = old_feedrate_mm_m;
3249
     stepper.synchronize();
3253
     stepper.synchronize();
3250
   }
3254
   }
3251
 
3255
 
3492
         }
3496
         }
3493
       #endif
3497
       #endif
3494
 
3498
 
3495
-      xy_probe_speed = code_seen('S') ? (int)code_value_linear_units() : XY_PROBE_SPEED;
3499
+      xy_probe_feedrate_mm_m = code_seen('S') ? (int)code_value_linear_units() : XY_PROBE_SPEED;
3496
 
3500
 
3497
       int left_probe_bed_position = code_seen('L') ? (int)code_value_axis_units(X_AXIS) : LEFT_PROBE_BED_POSITION,
3501
       int left_probe_bed_position = code_seen('L') ? (int)code_value_axis_units(X_AXIS) : LEFT_PROBE_BED_POSITION,
3498
           right_probe_bed_position = code_seen('R') ? (int)code_value_axis_units(X_AXIS) : RIGHT_PROBE_BED_POSITION,
3502
           right_probe_bed_position = code_seen('R') ? (int)code_value_axis_units(X_AXIS) : RIGHT_PROBE_BED_POSITION,
3594
          * so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
3598
          * so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
3595
          */
3599
          */
3596
 
3600
 
3597
-        int abl2 = auto_bed_leveling_grid_points * auto_bed_leveling_grid_points;
3601
+        int abl2 = sq(auto_bed_leveling_grid_points);
3598
 
3602
 
3599
         double eqnAMatrix[abl2 * 3], // "A" matrix of the linear system of equations
3603
         double eqnAMatrix[abl2 * 3], // "A" matrix of the linear system of equations
3600
                eqnBVector[abl2],     // "B" vector of Z points
3604
                eqnBVector[abl2],     // "B" vector of Z points
3627
 
3631
 
3628
           #if ENABLED(DELTA)
3632
           #if ENABLED(DELTA)
3629
             // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.
3633
             // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.
3630
-            float distance_from_center = sqrt(xProbe * xProbe + yProbe * yProbe);
3634
+            float distance_from_center = HYPOT(xProbe, yProbe);
3631
             if (distance_from_center > DELTA_PROBEABLE_RADIUS) continue;
3635
             if (distance_from_center > DELTA_PROBEABLE_RADIUS) continue;
3632
           #endif //DELTA
3636
           #endif //DELTA
3633
 
3637
 
4250
         return;
4254
         return;
4251
       }
4255
       }
4252
     #else
4256
     #else
4253
-      if (sqrt(X_probe_location * X_probe_location + Y_probe_location * Y_probe_location) > DELTA_PROBEABLE_RADIUS) {
4257
+      if (HYPOT(X_probe_location, Y_probe_location) > DELTA_PROBEABLE_RADIUS) {
4254
         SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius.");
4258
         SERIAL_PROTOCOLLNPGM("? (X,Y) location outside of probeable radius.");
4255
         return;
4259
         return;
4256
       }
4260
       }
4340
           #else
4344
           #else
4341
             // If we have gone out too far, we can do a simple fix and scale the numbers
4345
             // If we have gone out too far, we can do a simple fix and scale the numbers
4342
             // back in closer to the origin.
4346
             // back in closer to the origin.
4343
-            while (sqrt(X_current * X_current + Y_current * Y_current) > DELTA_PROBEABLE_RADIUS) {
4347
+            while (HYPOT(X_current, Y_current) > DELTA_PROBEABLE_RADIUS) {
4344
               X_current /= 1.25;
4348
               X_current /= 1.25;
4345
               Y_current /= 1.25;
4349
               Y_current /= 1.25;
4346
               if (verbose_level > 3) {
4350
               if (verbose_level > 3) {
4376
        * data points we have so far
4380
        * data points we have so far
4377
        */
4381
        */
4378
       sum = 0.0;
4382
       sum = 0.0;
4379
-      for (uint8_t j = 0; j <= n; j++) {
4380
-        float ss = sample_set[j] - mean;
4381
-        sum += ss * ss;
4382
-      }
4383
+      for (uint8_t j = 0; j <= n; j++)
4384
+        sum += sq(sample_set[j] - mean);
4385
+
4383
       sigma = sqrt(sum / (n + 1));
4386
       sigma = sqrt(sum / (n + 1));
4384
       if (verbose_level > 0) {
4387
       if (verbose_level > 0) {
4385
         if (verbose_level > 1) {
4388
         if (verbose_level > 1) {
5163
         if (value < 20.0) {
5166
         if (value < 20.0) {
5164
           float factor = planner.axis_steps_per_mm[i] / value; // increase e constants if M92 E14 is given for netfab.
5167
           float factor = planner.axis_steps_per_mm[i] / value; // increase e constants if M92 E14 is given for netfab.
5165
           planner.max_e_jerk *= factor;
5168
           planner.max_e_jerk *= factor;
5166
-          planner.max_feedrate[i] *= factor;
5169
+          planner.max_feedrate_mm_s[i] *= factor;
5167
           planner.max_acceleration_steps_per_s2[i] *= factor;
5170
           planner.max_acceleration_steps_per_s2[i] *= factor;
5168
         }
5171
         }
5169
         planner.axis_steps_per_mm[i] = value;
5172
         planner.axis_steps_per_mm[i] = value;
5372
 inline void gcode_M203() {
5375
 inline void gcode_M203() {
5373
   for (int8_t i = 0; i < NUM_AXIS; i++)
5376
   for (int8_t i = 0; i < NUM_AXIS; i++)
5374
     if (code_seen(axis_codes[i]))
5377
     if (code_seen(axis_codes[i]))
5375
-      planner.max_feedrate[i] = code_value_axis_units(i);
5378
+      planner.max_feedrate_mm_s[i] = code_value_axis_units(i);
5376
 }
5379
 }
5377
 
5380
 
5378
 /**
5381
 /**
5418
  *    E = Max E Jerk (units/sec^2)
5421
  *    E = Max E Jerk (units/sec^2)
5419
  */
5422
  */
5420
 inline void gcode_M205() {
5423
 inline void gcode_M205() {
5421
-  if (code_seen('S')) planner.min_feedrate = code_value_linear_units();
5422
-  if (code_seen('T')) planner.min_travel_feedrate = code_value_linear_units();
5424
+  if (code_seen('S')) planner.min_feedrate_mm_s = code_value_linear_units();
5425
+  if (code_seen('T')) planner.min_travel_feedrate_mm_s = code_value_linear_units();
5423
   if (code_seen('B')) planner.min_segment_time = code_value_millis();
5426
   if (code_seen('B')) planner.min_segment_time = code_value_millis();
5424
   if (code_seen('X')) planner.max_xy_jerk = code_value_linear_units();
5427
   if (code_seen('X')) planner.max_xy_jerk = code_value_linear_units();
5425
   if (code_seen('Z')) planner.max_z_jerk = code_value_axis_units(Z_AXIS);
5428
   if (code_seen('Z')) planner.max_z_jerk = code_value_axis_units(Z_AXIS);
5517
    */
5520
    */
5518
   inline void gcode_M207() {
5521
   inline void gcode_M207() {
5519
     if (code_seen('S')) retract_length = code_value_axis_units(E_AXIS);
5522
     if (code_seen('S')) retract_length = code_value_axis_units(E_AXIS);
5520
-    if (code_seen('F')) retract_feedrate_mm_s = code_value_axis_units(E_AXIS) / 60;
5523
+    if (code_seen('F')) retract_feedrate_mm_s = MMM_TO_MMS(code_value_axis_units(E_AXIS));
5521
     if (code_seen('Z')) retract_zlift = code_value_axis_units(Z_AXIS);
5524
     if (code_seen('Z')) retract_zlift = code_value_axis_units(Z_AXIS);
5522
     #if EXTRUDERS > 1
5525
     #if EXTRUDERS > 1
5523
       if (code_seen('W')) retract_length_swap = code_value_axis_units(E_AXIS);
5526
       if (code_seen('W')) retract_length_swap = code_value_axis_units(E_AXIS);
5529
    *
5532
    *
5530
    *   S[+units]    retract_recover_length (in addition to M207 S*)
5533
    *   S[+units]    retract_recover_length (in addition to M207 S*)
5531
    *   W[+units]    retract_recover_length_swap (multi-extruder)
5534
    *   W[+units]    retract_recover_length_swap (multi-extruder)
5532
-   *   F[units/min] retract_recover_feedrate
5535
+   *   F[units/min] retract_recover_feedrate_mm_s
5533
    */
5536
    */
5534
   inline void gcode_M208() {
5537
   inline void gcode_M208() {
5535
     if (code_seen('S')) retract_recover_length = code_value_axis_units(E_AXIS);
5538
     if (code_seen('S')) retract_recover_length = code_value_axis_units(E_AXIS);
5536
-    if (code_seen('F')) retract_recover_feedrate = code_value_axis_units(E_AXIS) / 60;
5539
+    if (code_seen('F')) retract_recover_feedrate_mm_s = MMM_TO_MMS(code_value_axis_units(E_AXIS));
5537
     #if EXTRUDERS > 1
5540
     #if EXTRUDERS > 1
5538
       if (code_seen('W')) retract_recover_length_swap = code_value_axis_units(E_AXIS);
5541
       if (code_seen('W')) retract_recover_length_swap = code_value_axis_units(E_AXIS);
5539
     #endif
5542
     #endif
5604
  * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
5607
  * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
5605
  */
5608
  */
5606
 inline void gcode_M220() {
5609
 inline void gcode_M220() {
5607
-  if (code_seen('S')) feedrate_multiplier = code_value_int();
5610
+  if (code_seen('S')) feedrate_percentage = code_value_int();
5608
 }
5611
 }
5609
 
5612
 
5610
 /**
5613
 /**
6308
 
6311
 
6309
     // Define runplan for move axes
6312
     // Define runplan for move axes
6310
     #if ENABLED(DELTA)
6313
     #if ENABLED(DELTA)
6311
-      #define RUNPLAN(RATE) calculate_delta(destination); \
6312
-                            planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], RATE, active_extruder);
6314
+      #define RUNPLAN(RATE_MM_S) calculate_delta(destination); \
6315
+                                 planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], RATE_MM_S, active_extruder);
6313
     #else
6316
     #else
6314
-      #define RUNPLAN(RATE) line_to_destination(RATE * 60);
6317
+      #define RUNPLAN(RATE_MM_S) line_to_destination(MMS_TO_MMM(RATE_MM_S));
6315
     #endif
6318
     #endif
6316
 
6319
 
6317
     KEEPALIVE_STATE(IN_HANDLER);
6320
     KEEPALIVE_STATE(IN_HANDLER);
6726
         return;
6729
         return;
6727
       }
6730
       }
6728
 
6731
 
6729
-      float old_feedrate = feedrate;
6732
+      float old_feedrate_mm_m = feedrate_mm_m;
6730
 
6733
 
6731
       if (code_seen('F')) {
6734
       if (code_seen('F')) {
6732
-        float next_feedrate = code_value_axis_units(X_AXIS);
6733
-        if (next_feedrate > 0.0) old_feedrate = feedrate = next_feedrate;
6735
+        float next_feedrate_mm_m = code_value_axis_units(X_AXIS);
6736
+        if (next_feedrate_mm_m > 0.0) old_feedrate_mm_m = feedrate_mm_m = next_feedrate_mm_m;
6734
       }
6737
       }
6735
       else
6738
       else
6736
-        feedrate = XY_PROBE_FEEDRATE;
6739
+        feedrate_mm_m = XY_PROBE_FEEDRATE_MM_M;
6737
 
6740
 
6738
       if (tmp_extruder != active_extruder) {
6741
       if (tmp_extruder != active_extruder) {
6739
         bool no_move = code_seen('S') && code_value_bool();
6742
         bool no_move = code_seen('S') && code_value_bool();
6776
                 current_position[Y_AXIS],
6779
                 current_position[Y_AXIS],
6777
                 current_position[Z_AXIS] + (i == 2 ? 0 : TOOLCHANGE_PARK_ZLIFT),
6780
                 current_position[Z_AXIS] + (i == 2 ? 0 : TOOLCHANGE_PARK_ZLIFT),
6778
                 current_position[E_AXIS],
6781
                 current_position[E_AXIS],
6779
-                planner.max_feedrate[i == 1 ? X_AXIS : Z_AXIS],
6782
+                planner.max_feedrate_mm_s[i == 1 ? X_AXIS : Z_AXIS],
6780
                 active_extruder
6783
                 active_extruder
6781
               );
6784
               );
6782
             stepper.synchronize();
6785
             stepper.synchronize();
6839
               current_position[Y_AXIS],
6842
               current_position[Y_AXIS],
6840
               current_position[Z_AXIS] + z_raise,
6843
               current_position[Z_AXIS] + z_raise,
6841
               current_position[E_AXIS],
6844
               current_position[E_AXIS],
6842
-              planner.max_feedrate[Z_AXIS],
6845
+              planner.max_feedrate_mm_s[Z_AXIS],
6843
               active_extruder
6846
               active_extruder
6844
             );
6847
             );
6845
             stepper.synchronize();
6848
             stepper.synchronize();
6854
                 current_position[Y_AXIS],
6857
                 current_position[Y_AXIS],
6855
                 current_position[Z_AXIS] + z_diff,
6858
                 current_position[Z_AXIS] + z_diff,
6856
                 current_position[E_AXIS],
6859
                 current_position[E_AXIS],
6857
-                planner.max_feedrate[Z_AXIS],
6860
+                planner.max_feedrate_mm_s[Z_AXIS],
6858
                 active_extruder
6861
                 active_extruder
6859
               );
6862
               );
6860
               stepper.synchronize();
6863
               stepper.synchronize();
6985
         enable_solenoid_on_active_extruder();
6988
         enable_solenoid_on_active_extruder();
6986
       #endif // EXT_SOLENOID
6989
       #endif // EXT_SOLENOID
6987
 
6990
 
6988
-      feedrate = old_feedrate;
6991
+      feedrate_mm_m = old_feedrate_mm_m;
6989
 
6992
 
6990
     #else // HOTENDS <= 1
6993
     #else // HOTENDS <= 1
6991
 
6994
 
7838
 #if ENABLED(MESH_BED_LEVELING)
7841
 #if ENABLED(MESH_BED_LEVELING)
7839
 
7842
 
7840
 // This function is used to split lines on mesh borders so each segment is only part of one mesh area
7843
 // This function is used to split lines on mesh borders so each segment is only part of one mesh area
7841
-void mesh_buffer_line(float x, float y, float z, const float e, float feed_rate, const uint8_t& extruder, uint8_t x_splits = 0xff, uint8_t y_splits = 0xff) {
7844
+void mesh_buffer_line(float x, float y, float z, const float e, float fr_mm_s, const uint8_t& extruder, uint8_t x_splits = 0xff, uint8_t y_splits = 0xff) {
7842
   if (!mbl.active()) {
7845
   if (!mbl.active()) {
7843
-    planner.buffer_line(x, y, z, e, feed_rate, extruder);
7846
+    planner.buffer_line(x, y, z, e, fr_mm_s, extruder);
7844
     set_current_to_destination();
7847
     set_current_to_destination();
7845
     return;
7848
     return;
7846
   }
7849
   }
7854
   NOMORE(cy,  MESH_NUM_Y_POINTS - 2);
7857
   NOMORE(cy,  MESH_NUM_Y_POINTS - 2);
7855
   if (pcx == cx && pcy == cy) {
7858
   if (pcx == cx && pcy == cy) {
7856
     // Start and end on same mesh square
7859
     // Start and end on same mesh square
7857
-    planner.buffer_line(x, y, z, e, feed_rate, extruder);
7860
+    planner.buffer_line(x, y, z, e, fr_mm_s, extruder);
7858
     set_current_to_destination();
7861
     set_current_to_destination();
7859
     return;
7862
     return;
7860
   }
7863
   }
7893
   }
7896
   }
7894
   else {
7897
   else {
7895
     // Already split on a border
7898
     // Already split on a border
7896
-    planner.buffer_line(x, y, z, e, feed_rate, extruder);
7899
+    planner.buffer_line(x, y, z, e, fr_mm_s, extruder);
7897
     set_current_to_destination();
7900
     set_current_to_destination();
7898
     return;
7901
     return;
7899
   }
7902
   }
7902
   destination[Y_AXIS] = ny;
7905
   destination[Y_AXIS] = ny;
7903
   destination[Z_AXIS] = nz;
7906
   destination[Z_AXIS] = nz;
7904
   destination[E_AXIS] = ne;
7907
   destination[E_AXIS] = ne;
7905
-  mesh_buffer_line(nx, ny, nz, ne, feed_rate, extruder, x_splits, y_splits);
7908
+  mesh_buffer_line(nx, ny, nz, ne, fr_mm_s, extruder, x_splits, y_splits);
7906
   destination[X_AXIS] = x;
7909
   destination[X_AXIS] = x;
7907
   destination[Y_AXIS] = y;
7910
   destination[Y_AXIS] = y;
7908
   destination[Z_AXIS] = z;
7911
   destination[Z_AXIS] = z;
7909
   destination[E_AXIS] = e;
7912
   destination[E_AXIS] = e;
7910
-  mesh_buffer_line(x, y, z, e, feed_rate, extruder, x_splits, y_splits);
7913
+  mesh_buffer_line(x, y, z, e, fr_mm_s, extruder, x_splits, y_splits);
7911
 }
7914
 }
7912
 #endif  // MESH_BED_LEVELING
7915
 #endif  // MESH_BED_LEVELING
7913
 
7916
 
7920
     float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
7923
     float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
7921
     if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
7924
     if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
7922
     if (cartesian_mm < 0.000001) return false;
7925
     if (cartesian_mm < 0.000001) return false;
7923
-    float _feedrate = feedrate * feedrate_multiplier / 6000.0;
7924
-    float seconds = cartesian_mm / _feedrate;
7926
+    float _feedrate_mm_s = MMM_TO_MMS_SCALED(feedrate_mm_m);
7927
+    float seconds = cartesian_mm / _feedrate_mm_s;
7925
     int steps = max(1, int(delta_segments_per_second * seconds));
7928
     int steps = max(1, int(delta_segments_per_second * seconds));
7926
     float inv_steps = 1.0/steps;
7929
     float inv_steps = 1.0/steps;
7927
 
7930
 
7945
       //DEBUG_POS("prepare_delta_move_to", target);
7948
       //DEBUG_POS("prepare_delta_move_to", target);
7946
       //DEBUG_POS("prepare_delta_move_to", delta);
7949
       //DEBUG_POS("prepare_delta_move_to", delta);
7947
 
7950
 
7948
-      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], _feedrate, active_extruder);
7951
+      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], _feedrate_mm_s, active_extruder);
7949
     }
7952
     }
7950
     return true;
7953
     return true;
7951
   }
7954
   }
7964
         // move duplicate extruder into correct duplication position.
7967
         // move duplicate extruder into correct duplication position.
7965
         planner.set_position_mm(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
7968
         planner.set_position_mm(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
7966
         planner.buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset,
7969
         planner.buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset,
7967
-                         current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate[X_AXIS], 1);
7970
+                         current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[X_AXIS], 1);
7968
         SYNC_PLAN_POSITION_KINEMATIC();
7971
         SYNC_PLAN_POSITION_KINEMATIC();
7969
         stepper.synchronize();
7972
         stepper.synchronize();
7970
         extruder_duplication_enabled = true;
7973
         extruder_duplication_enabled = true;
7984
         }
7987
         }
7985
         delayed_move_time = 0;
7988
         delayed_move_time = 0;
7986
         // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
7989
         // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
7987
-        planner.buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate[Z_AXIS], active_extruder);
7990
+        planner.buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
7988
         planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], PLANNER_XY_FEEDRATE(), active_extruder);
7991
         planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], PLANNER_XY_FEEDRATE(), active_extruder);
7989
-        planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate[Z_AXIS], active_extruder);
7992
+        planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
7990
         active_extruder_parked = false;
7993
         active_extruder_parked = false;
7991
       }
7994
       }
7992
     }
7995
     }
7998
 #if DISABLED(DELTA) && DISABLED(SCARA)
8001
 #if DISABLED(DELTA) && DISABLED(SCARA)
7999
 
8002
 
8000
   inline bool prepare_move_to_destination_cartesian() {
8003
   inline bool prepare_move_to_destination_cartesian() {
8001
-    // Do not use feedrate_multiplier for E or Z only moves
8004
+    // Do not use feedrate_percentage for E or Z only moves
8002
     if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) {
8005
     if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) {
8003
       line_to_destination();
8006
       line_to_destination();
8004
     }
8007
     }
8005
     else {
8008
     else {
8006
       #if ENABLED(MESH_BED_LEVELING)
8009
       #if ENABLED(MESH_BED_LEVELING)
8007
-        mesh_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate / 60) * (feedrate_multiplier / 100.0), active_extruder);
8010
+        mesh_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], MMM_TO_MMS_SCALED(feedrate_mm_m), active_extruder);
8008
         return false;
8011
         return false;
8009
       #else
8012
       #else
8010
-        line_to_destination(feedrate * feedrate_multiplier / 100.0);
8013
+        line_to_destination(MMM_SCALED(feedrate_mm_m));
8011
       #endif
8014
       #endif
8012
     }
8015
     }
8013
     return true;
8016
     return true;
8082
     uint8_t clockwise       // Clockwise?
8085
     uint8_t clockwise       // Clockwise?
8083
   ) {
8086
   ) {
8084
 
8087
 
8085
-    float radius = hypot(offset[X_AXIS], offset[Y_AXIS]),
8088
+    float radius = HYPOT(offset[X_AXIS], offset[Y_AXIS]),
8086
           center_X = current_position[X_AXIS] + offset[X_AXIS],
8089
           center_X = current_position[X_AXIS] + offset[X_AXIS],
8087
           center_Y = current_position[Y_AXIS] + offset[Y_AXIS],
8090
           center_Y = current_position[Y_AXIS] + offset[Y_AXIS],
8088
           linear_travel = target[Z_AXIS] - current_position[Z_AXIS],
8091
           linear_travel = target[Z_AXIS] - current_position[Z_AXIS],
8101
     if (angular_travel == 0 && current_position[X_AXIS] == target[X_AXIS] && current_position[Y_AXIS] == target[Y_AXIS])
8104
     if (angular_travel == 0 && current_position[X_AXIS] == target[X_AXIS] && current_position[Y_AXIS] == target[Y_AXIS])
8102
       angular_travel += RADIANS(360);
8105
       angular_travel += RADIANS(360);
8103
 
8106
 
8104
-    float mm_of_travel = hypot(angular_travel * radius, fabs(linear_travel));
8107
+    float mm_of_travel = HYPOT(angular_travel * radius, fabs(linear_travel));
8105
     if (mm_of_travel < 0.001) return;
8108
     if (mm_of_travel < 0.001) return;
8106
     uint16_t segments = floor(mm_of_travel / (MM_PER_ARC_SEGMENT));
8109
     uint16_t segments = floor(mm_of_travel / (MM_PER_ARC_SEGMENT));
8107
     if (segments == 0) segments = 1;
8110
     if (segments == 0) segments = 1;
8137
      * This is important when there are successive arc motions.
8140
      * This is important when there are successive arc motions.
8138
      */
8141
      */
8139
     // Vector rotation matrix values
8142
     // Vector rotation matrix values
8140
-    float cos_T = 1 - 0.5 * theta_per_segment * theta_per_segment; // Small angle approximation
8143
+    float cos_T = 1 - 0.5 * sq(theta_per_segment); // Small angle approximation
8141
     float sin_T = theta_per_segment;
8144
     float sin_T = theta_per_segment;
8142
 
8145
 
8143
     float arc_target[NUM_AXIS];
8146
     float arc_target[NUM_AXIS];
8151
     // Initialize the extruder axis
8154
     // Initialize the extruder axis
8152
     arc_target[E_AXIS] = current_position[E_AXIS];
8155
     arc_target[E_AXIS] = current_position[E_AXIS];
8153
 
8156
 
8154
-    float feed_rate = feedrate * feedrate_multiplier / 60 / 100.0;
8157
+    float fr_mm_s = MMM_TO_MMS_SCALED(feedrate_mm_m);
8155
 
8158
 
8156
     millis_t next_idle_ms = millis() + 200UL;
8159
     millis_t next_idle_ms = millis() + 200UL;
8157
 
8160
 
8195
         #if ENABLED(AUTO_BED_LEVELING_FEATURE)
8198
         #if ENABLED(AUTO_BED_LEVELING_FEATURE)
8196
           adjust_delta(arc_target);
8199
           adjust_delta(arc_target);
8197
         #endif
8200
         #endif
8198
-        planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], arc_target[E_AXIS], feed_rate, active_extruder);
8201
+        planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], arc_target[E_AXIS], fr_mm_s, active_extruder);
8199
       #else
8202
       #else
8200
-        planner.buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], feed_rate, active_extruder);
8203
+        planner.buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], fr_mm_s, active_extruder);
8201
       #endif
8204
       #endif
8202
     }
8205
     }
8203
 
8206
 
8207
       #if ENABLED(AUTO_BED_LEVELING_FEATURE)
8210
       #if ENABLED(AUTO_BED_LEVELING_FEATURE)
8208
         adjust_delta(target);
8211
         adjust_delta(target);
8209
       #endif
8212
       #endif
8210
-      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], feed_rate, active_extruder);
8213
+      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], fr_mm_s, active_extruder);
8211
     #else
8214
     #else
8212
-      planner.buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate, active_extruder);
8215
+      planner.buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], fr_mm_s, active_extruder);
8213
     #endif
8216
     #endif
8214
 
8217
 
8215
     // As far as the parser is concerned, the position is now == target. In reality the
8218
     // As far as the parser is concerned, the position is now == target. In reality the
8222
 #if ENABLED(BEZIER_CURVE_SUPPORT)
8225
 #if ENABLED(BEZIER_CURVE_SUPPORT)
8223
 
8226
 
8224
   void plan_cubic_move(const float offset[4]) {
8227
   void plan_cubic_move(const float offset[4]) {
8225
-    cubic_b_spline(current_position, destination, offset, feedrate * feedrate_multiplier / 60 / 100.0, active_extruder);
8228
+    cubic_b_spline(current_position, destination, offset, MMM_TO_MMS_SCALED(feedrate_mm_m), active_extruder);
8226
 
8229
 
8227
     // As far as the parser is concerned, the position is now == target. In reality the
8230
     // As far as the parser is concerned, the position is now == target. In reality the
8228
     // motion control system might still be processing the action and the real tool position
8231
     // motion control system might still be processing the action and the real tool position
8548
       float oldepos = current_position[E_AXIS], oldedes = destination[E_AXIS];
8551
       float oldepos = current_position[E_AXIS], oldedes = destination[E_AXIS];
8549
       planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS],
8552
       planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS],
8550
                        destination[E_AXIS] + (EXTRUDER_RUNOUT_EXTRUDE) * (EXTRUDER_RUNOUT_ESTEPS) / planner.axis_steps_per_mm[E_AXIS],
8553
                        destination[E_AXIS] + (EXTRUDER_RUNOUT_EXTRUDE) * (EXTRUDER_RUNOUT_ESTEPS) / planner.axis_steps_per_mm[E_AXIS],
8551
-                       (EXTRUDER_RUNOUT_SPEED) / 60. * (EXTRUDER_RUNOUT_ESTEPS) / planner.axis_steps_per_mm[E_AXIS], active_extruder);
8554
+                       MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED) * (EXTRUDER_RUNOUT_ESTEPS) / planner.axis_steps_per_mm[E_AXIS], active_extruder);
8552
       current_position[E_AXIS] = oldepos;
8555
       current_position[E_AXIS] = oldepos;
8553
       destination[E_AXIS] = oldedes;
8556
       destination[E_AXIS] = oldedes;
8554
       planner.set_e_position_mm(oldepos);
8557
       planner.set_e_position_mm(oldepos);

+ 24
- 24
Marlin/configuration_store.cpp View File

49
  *  104  EEPROM Checksum (uint16_t)
49
  *  104  EEPROM Checksum (uint16_t)
50
  *
50
  *
51
  *  106  M92 XYZE  planner.axis_steps_per_mm (float x4)
51
  *  106  M92 XYZE  planner.axis_steps_per_mm (float x4)
52
- *  122  M203 XYZE planner.max_feedrate (float x4)
52
+ *  122  M203 XYZE planner.max_feedrate_mm_s (float x4)
53
  *  138  M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4)
53
  *  138  M201 XYZE planner.max_acceleration_mm_per_s2 (uint32_t x4)
54
  *  154  M204 P    planner.acceleration (float)
54
  *  154  M204 P    planner.acceleration (float)
55
  *  158  M204 R    planner.retract_acceleration (float)
55
  *  158  M204 R    planner.retract_acceleration (float)
56
  *  162  M204 T    planner.travel_acceleration (float)
56
  *  162  M204 T    planner.travel_acceleration (float)
57
- *  166  M205 S    planner.min_feedrate (float)
58
- *  170  M205 T    planner.min_travel_feedrate (float)
57
+ *  166  M205 S    planner.min_feedrate_mm_s (float)
58
+ *  170  M205 T    planner.min_travel_feedrate_mm_s (float)
59
  *  174  M205 B    planner.min_segment_time (ulong)
59
  *  174  M205 B    planner.min_segment_time (ulong)
60
  *  178  M205 X    planner.max_xy_jerk (float)
60
  *  178  M205 X    planner.max_xy_jerk (float)
61
  *  182  M205 Z    planner.max_z_jerk (float)
61
  *  182  M205 Z    planner.max_z_jerk (float)
116
  *  406  M207 Z    retract_zlift (float)
116
  *  406  M207 Z    retract_zlift (float)
117
  *  410  M208 S    retract_recover_length (float)
117
  *  410  M208 S    retract_recover_length (float)
118
  *  414  M208 W    retract_recover_length_swap (float)
118
  *  414  M208 W    retract_recover_length_swap (float)
119
- *  418  M208 F    retract_recover_feedrate (float)
119
+ *  418  M208 F    retract_recover_feedrate_mm_s (float)
120
  *
120
  *
121
  * Volumetric Extrusion:
121
  * Volumetric Extrusion:
122
  *  422  M200 D    volumetric_enabled (bool)
122
  *  422  M200 D    volumetric_enabled (bool)
202
   eeprom_checksum = 0; // clear before first "real data"
202
   eeprom_checksum = 0; // clear before first "real data"
203
 
203
 
204
   EEPROM_WRITE_VAR(i, planner.axis_steps_per_mm);
204
   EEPROM_WRITE_VAR(i, planner.axis_steps_per_mm);
205
-  EEPROM_WRITE_VAR(i, planner.max_feedrate);
205
+  EEPROM_WRITE_VAR(i, planner.max_feedrate_mm_s);
206
   EEPROM_WRITE_VAR(i, planner.max_acceleration_mm_per_s2);
206
   EEPROM_WRITE_VAR(i, planner.max_acceleration_mm_per_s2);
207
   EEPROM_WRITE_VAR(i, planner.acceleration);
207
   EEPROM_WRITE_VAR(i, planner.acceleration);
208
   EEPROM_WRITE_VAR(i, planner.retract_acceleration);
208
   EEPROM_WRITE_VAR(i, planner.retract_acceleration);
209
   EEPROM_WRITE_VAR(i, planner.travel_acceleration);
209
   EEPROM_WRITE_VAR(i, planner.travel_acceleration);
210
-  EEPROM_WRITE_VAR(i, planner.min_feedrate);
211
-  EEPROM_WRITE_VAR(i, planner.min_travel_feedrate);
210
+  EEPROM_WRITE_VAR(i, planner.min_feedrate_mm_s);
211
+  EEPROM_WRITE_VAR(i, planner.min_travel_feedrate_mm_s);
212
   EEPROM_WRITE_VAR(i, planner.min_segment_time);
212
   EEPROM_WRITE_VAR(i, planner.min_segment_time);
213
   EEPROM_WRITE_VAR(i, planner.max_xy_jerk);
213
   EEPROM_WRITE_VAR(i, planner.max_xy_jerk);
214
   EEPROM_WRITE_VAR(i, planner.max_z_jerk);
214
   EEPROM_WRITE_VAR(i, planner.max_z_jerk);
343
       dummy = 0.0f;
343
       dummy = 0.0f;
344
       EEPROM_WRITE_VAR(i, dummy);
344
       EEPROM_WRITE_VAR(i, dummy);
345
     #endif
345
     #endif
346
-    EEPROM_WRITE_VAR(i, retract_recover_feedrate);
346
+    EEPROM_WRITE_VAR(i, retract_recover_feedrate_mm_s);
347
   #endif // FWRETRACT
347
   #endif // FWRETRACT
348
 
348
 
349
   EEPROM_WRITE_VAR(i, volumetric_enabled);
349
   EEPROM_WRITE_VAR(i, volumetric_enabled);
389
 
389
 
390
     // version number match
390
     // version number match
391
     EEPROM_READ_VAR(i, planner.axis_steps_per_mm);
391
     EEPROM_READ_VAR(i, planner.axis_steps_per_mm);
392
-    EEPROM_READ_VAR(i, planner.max_feedrate);
392
+    EEPROM_READ_VAR(i, planner.max_feedrate_mm_s);
393
     EEPROM_READ_VAR(i, planner.max_acceleration_mm_per_s2);
393
     EEPROM_READ_VAR(i, planner.max_acceleration_mm_per_s2);
394
 
394
 
395
     EEPROM_READ_VAR(i, planner.acceleration);
395
     EEPROM_READ_VAR(i, planner.acceleration);
396
     EEPROM_READ_VAR(i, planner.retract_acceleration);
396
     EEPROM_READ_VAR(i, planner.retract_acceleration);
397
     EEPROM_READ_VAR(i, planner.travel_acceleration);
397
     EEPROM_READ_VAR(i, planner.travel_acceleration);
398
-    EEPROM_READ_VAR(i, planner.min_feedrate);
399
-    EEPROM_READ_VAR(i, planner.min_travel_feedrate);
398
+    EEPROM_READ_VAR(i, planner.min_feedrate_mm_s);
399
+    EEPROM_READ_VAR(i, planner.min_travel_feedrate_mm_s);
400
     EEPROM_READ_VAR(i, planner.min_segment_time);
400
     EEPROM_READ_VAR(i, planner.min_segment_time);
401
     EEPROM_READ_VAR(i, planner.max_xy_jerk);
401
     EEPROM_READ_VAR(i, planner.max_xy_jerk);
402
     EEPROM_READ_VAR(i, planner.max_z_jerk);
402
     EEPROM_READ_VAR(i, planner.max_z_jerk);
525
       #else
525
       #else
526
         EEPROM_READ_VAR(i, dummy);
526
         EEPROM_READ_VAR(i, dummy);
527
       #endif
527
       #endif
528
-      EEPROM_READ_VAR(i, retract_recover_feedrate);
528
+      EEPROM_READ_VAR(i, retract_recover_feedrate_mm_s);
529
     #endif // FWRETRACT
529
     #endif // FWRETRACT
530
 
530
 
531
     EEPROM_READ_VAR(i, volumetric_enabled);
531
     EEPROM_READ_VAR(i, volumetric_enabled);
565
   long tmp3[] = DEFAULT_MAX_ACCELERATION;
565
   long tmp3[] = DEFAULT_MAX_ACCELERATION;
566
   for (uint8_t i = 0; i < NUM_AXIS; i++) {
566
   for (uint8_t i = 0; i < NUM_AXIS; i++) {
567
     planner.axis_steps_per_mm[i] = tmp1[i];
567
     planner.axis_steps_per_mm[i] = tmp1[i];
568
-    planner.max_feedrate[i] = tmp2[i];
568
+    planner.max_feedrate_mm_s[i] = tmp2[i];
569
     planner.max_acceleration_mm_per_s2[i] = tmp3[i];
569
     planner.max_acceleration_mm_per_s2[i] = tmp3[i];
570
     #if ENABLED(SCARA)
570
     #if ENABLED(SCARA)
571
       if (i < COUNT(axis_scaling))
571
       if (i < COUNT(axis_scaling))
576
   planner.acceleration = DEFAULT_ACCELERATION;
576
   planner.acceleration = DEFAULT_ACCELERATION;
577
   planner.retract_acceleration = DEFAULT_RETRACT_ACCELERATION;
577
   planner.retract_acceleration = DEFAULT_RETRACT_ACCELERATION;
578
   planner.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION;
578
   planner.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION;
579
-  planner.min_feedrate = DEFAULT_MINIMUMFEEDRATE;
579
+  planner.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE;
580
   planner.min_segment_time = DEFAULT_MINSEGMENTTIME;
580
   planner.min_segment_time = DEFAULT_MINSEGMENTTIME;
581
-  planner.min_travel_feedrate = DEFAULT_MINTRAVELFEEDRATE;
581
+  planner.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE;
582
   planner.max_xy_jerk = DEFAULT_XYJERK;
582
   planner.max_xy_jerk = DEFAULT_XYJERK;
583
   planner.max_z_jerk = DEFAULT_ZJERK;
583
   planner.max_z_jerk = DEFAULT_ZJERK;
584
   planner.max_e_jerk = DEFAULT_EJERK;
584
   planner.max_e_jerk = DEFAULT_EJERK;
654
     #if EXTRUDERS > 1
654
     #if EXTRUDERS > 1
655
       retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
655
       retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP;
656
     #endif
656
     #endif
657
-    retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE;
657
+    retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
658
   #endif
658
   #endif
659
 
659
 
660
   volumetric_enabled = false;
660
   volumetric_enabled = false;
715
     SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):");
715
     SERIAL_ECHOLNPGM("Maximum feedrates (mm/s):");
716
     CONFIG_ECHO_START;
716
     CONFIG_ECHO_START;
717
   }
717
   }
718
-  SERIAL_ECHOPAIR("  M203 X", planner.max_feedrate[X_AXIS]);
719
-  SERIAL_ECHOPAIR(" Y", planner.max_feedrate[Y_AXIS]);
720
-  SERIAL_ECHOPAIR(" Z", planner.max_feedrate[Z_AXIS]);
721
-  SERIAL_ECHOPAIR(" E", planner.max_feedrate[E_AXIS]);
718
+  SERIAL_ECHOPAIR("  M203 X", planner.max_feedrate_mm_s[X_AXIS]);
719
+  SERIAL_ECHOPAIR(" Y", planner.max_feedrate_mm_s[Y_AXIS]);
720
+  SERIAL_ECHOPAIR(" Z", planner.max_feedrate_mm_s[Z_AXIS]);
721
+  SERIAL_ECHOPAIR(" E", planner.max_feedrate_mm_s[E_AXIS]);
722
   SERIAL_EOL;
722
   SERIAL_EOL;
723
 
723
 
724
   CONFIG_ECHO_START;
724
   CONFIG_ECHO_START;
746
     SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s),  Z=maximum Z jerk (mm/s),  E=maximum E jerk (mm/s)");
746
     SERIAL_ECHOLNPGM("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum XY jerk (mm/s),  Z=maximum Z jerk (mm/s),  E=maximum E jerk (mm/s)");
747
     CONFIG_ECHO_START;
747
     CONFIG_ECHO_START;
748
   }
748
   }
749
-  SERIAL_ECHOPAIR("  M205 S", planner.min_feedrate);
750
-  SERIAL_ECHOPAIR(" T", planner.min_travel_feedrate);
749
+  SERIAL_ECHOPAIR("  M205 S", planner.min_feedrate_mm_s);
750
+  SERIAL_ECHOPAIR(" T", planner.min_travel_feedrate_mm_s);
751
   SERIAL_ECHOPAIR(" B", planner.min_segment_time);
751
   SERIAL_ECHOPAIR(" B", planner.min_segment_time);
752
   SERIAL_ECHOPAIR(" X", planner.max_xy_jerk);
752
   SERIAL_ECHOPAIR(" X", planner.max_xy_jerk);
753
   SERIAL_ECHOPAIR(" Z", planner.max_z_jerk);
753
   SERIAL_ECHOPAIR(" Z", planner.max_z_jerk);
903
     #if EXTRUDERS > 1
903
     #if EXTRUDERS > 1
904
       SERIAL_ECHOPAIR(" W", retract_length_swap);
904
       SERIAL_ECHOPAIR(" W", retract_length_swap);
905
     #endif
905
     #endif
906
-    SERIAL_ECHOPAIR(" F", retract_feedrate_mm_s * 60);
906
+    SERIAL_ECHOPAIR(" F", MMS_TO_MMM(retract_feedrate_mm_s));
907
     SERIAL_ECHOPAIR(" Z", retract_zlift);
907
     SERIAL_ECHOPAIR(" Z", retract_zlift);
908
     SERIAL_EOL;
908
     SERIAL_EOL;
909
     CONFIG_ECHO_START;
909
     CONFIG_ECHO_START;
915
     #if EXTRUDERS > 1
915
     #if EXTRUDERS > 1
916
       SERIAL_ECHOPAIR(" W", retract_recover_length_swap);
916
       SERIAL_ECHOPAIR(" W", retract_recover_length_swap);
917
     #endif
917
     #endif
918
-    SERIAL_ECHOPAIR(" F", retract_recover_feedrate * 60);
918
+    SERIAL_ECHOPAIR(" F", MMS_TO_MMM(retract_recover_feedrate_mm_s));
919
     SERIAL_EOL;
919
     SERIAL_EOL;
920
     CONFIG_ECHO_START;
920
     CONFIG_ECHO_START;
921
     if (!forReplay) {
921
     if (!forReplay) {

+ 1
- 1
Marlin/dogm_lcd_implementation.h View File

450
 
450
 
451
   lcd_setFont(FONT_STATUSMENU);
451
   lcd_setFont(FONT_STATUSMENU);
452
   u8g.setPrintPos(12, 49);
452
   u8g.setPrintPos(12, 49);
453
-  lcd_print(itostr3(feedrate_multiplier));
453
+  lcd_print(itostr3(feedrate_percentage));
454
   lcd_print('%');
454
   lcd_print('%');
455
 
455
 
456
   // Status line
456
   // Status line

+ 1
- 0
Marlin/macros.h View File

36
 // Macros for maths shortcuts
36
 // Macros for maths shortcuts
37
 #define RADIANS(d) ((d)*M_PI/180.0)
37
 #define RADIANS(d) ((d)*M_PI/180.0)
38
 #define DEGREES(r) ((r)*180.0/M_PI)
38
 #define DEGREES(r) ((r)*180.0/M_PI)
39
+#define HYPOT(x,y) sqrt(sq(x)+sq(y))
39
 
40
 
40
 // Macros to contrain values
41
 // Macros to contrain values
41
 #define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
42
 #define NOLESS(v,n) do{ if (v < n) v = n; }while(0)

+ 19
- 19
Marlin/planner.cpp View File

80
 volatile uint8_t Planner::block_buffer_head = 0;           // Index of the next block to be pushed
80
 volatile uint8_t Planner::block_buffer_head = 0;           // Index of the next block to be pushed
81
 volatile uint8_t Planner::block_buffer_tail = 0;
81
 volatile uint8_t Planner::block_buffer_tail = 0;
82
 
82
 
83
-float Planner::max_feedrate[NUM_AXIS]; // Max speeds in mm per second
83
+float Planner::max_feedrate_mm_s[NUM_AXIS]; // Max speeds in mm per second
84
 float Planner::axis_steps_per_mm[NUM_AXIS];
84
 float Planner::axis_steps_per_mm[NUM_AXIS];
85
 unsigned long Planner::max_acceleration_steps_per_s2[NUM_AXIS];
85
 unsigned long Planner::max_acceleration_steps_per_s2[NUM_AXIS];
86
 unsigned long Planner::max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software
86
 unsigned long Planner::max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software
87
 
87
 
88
 millis_t Planner::min_segment_time;
88
 millis_t Planner::min_segment_time;
89
-float Planner::min_feedrate;
89
+float Planner::min_feedrate_mm_s;
90
 float Planner::acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
90
 float Planner::acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
91
 float Planner::retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
91
 float Planner::retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
92
 float Planner::travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
92
 float Planner::travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
93
 float Planner::max_xy_jerk;          // The largest speed change requiring no acceleration
93
 float Planner::max_xy_jerk;          // The largest speed change requiring no acceleration
94
 float Planner::max_z_jerk;
94
 float Planner::max_z_jerk;
95
 float Planner::max_e_jerk;
95
 float Planner::max_e_jerk;
96
-float Planner::min_travel_feedrate;
96
+float Planner::min_travel_feedrate_mm_s;
97
 
97
 
98
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
98
 #if ENABLED(AUTO_BED_LEVELING_FEATURE)
99
   matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level
99
   matrix_3x3 Planner::bed_level_matrix; // Transform to compensate for bed level
171
   }
171
   }
172
 
172
 
173
   #if ENABLED(ADVANCE)
173
   #if ENABLED(ADVANCE)
174
-    volatile long initial_advance = block->advance * entry_factor * entry_factor;
175
-    volatile long final_advance = block->advance * exit_factor * exit_factor;
174
+    volatile long initial_advance = block->advance * sq(entry_factor);
175
+    volatile long final_advance = block->advance * sq(exit_factor);
176
   #endif // ADVANCE
176
   #endif // ADVANCE
177
 
177
 
178
   // block->accelerate_until = accelerate_steps;
178
   // block->accelerate_until = accelerate_steps;
527
  * Add a new linear movement to the buffer.
527
  * Add a new linear movement to the buffer.
528
  *
528
  *
529
  *  x,y,z,e   - target position in mm
529
  *  x,y,z,e   - target position in mm
530
- *  feed_rate - (target) speed of the move
530
+ *  fr_mm_s   - (target) speed of the move
531
  *  extruder  - target extruder
531
  *  extruder  - target extruder
532
  */
532
  */
533
 
533
 
534
 #if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING)
534
 #if ENABLED(AUTO_BED_LEVELING_FEATURE) || ENABLED(MESH_BED_LEVELING)
535
-  void Planner::buffer_line(float x, float y, float z, const float& e, float feed_rate, const uint8_t extruder)
535
+  void Planner::buffer_line(float x, float y, float z, const float& e, float fr_mm_s, const uint8_t extruder)
536
 #else
536
 #else
537
-  void Planner::buffer_line(const float& x, const float& y, const float& z, const float& e, float feed_rate, const uint8_t extruder)
537
+  void Planner::buffer_line(const float& x, const float& y, const float& z, const float& e, float fr_mm_s, const uint8_t extruder)
538
 #endif  // AUTO_BED_LEVELING_FEATURE
538
 #endif  // AUTO_BED_LEVELING_FEATURE
539
 {
539
 {
540
   // Calculate the buffer head after we push this byte
540
   // Calculate the buffer head after we push this byte
768
   }
768
   }
769
 
769
 
770
   if (block->steps[E_AXIS])
770
   if (block->steps[E_AXIS])
771
-    NOLESS(feed_rate, min_feedrate);
771
+    NOLESS(fr_mm_s, min_feedrate_mm_s);
772
   else
772
   else
773
-    NOLESS(feed_rate, min_travel_feedrate);
773
+    NOLESS(fr_mm_s, min_travel_feedrate_mm_s);
774
 
774
 
775
   /**
775
   /**
776
    * This part of the code calculates the total length of the movement.
776
    * This part of the code calculates the total length of the movement.
815
   else {
815
   else {
816
     block->millimeters = sqrt(
816
     block->millimeters = sqrt(
817
       #if ENABLED(COREXY)
817
       #if ENABLED(COREXY)
818
-        square(delta_mm[X_HEAD]) + square(delta_mm[Y_HEAD]) + square(delta_mm[Z_AXIS])
818
+        sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_AXIS])
819
       #elif ENABLED(COREXZ)
819
       #elif ENABLED(COREXZ)
820
-        square(delta_mm[X_HEAD]) + square(delta_mm[Y_AXIS]) + square(delta_mm[Z_HEAD])
820
+        sq(delta_mm[X_HEAD]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_HEAD])
821
       #elif ENABLED(COREYZ)
821
       #elif ENABLED(COREYZ)
822
-        square(delta_mm[X_AXIS]) + square(delta_mm[Y_HEAD]) + square(delta_mm[Z_HEAD])
822
+        sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_HEAD]) + sq(delta_mm[Z_HEAD])
823
       #else
823
       #else
824
-        square(delta_mm[X_AXIS]) + square(delta_mm[Y_AXIS]) + square(delta_mm[Z_AXIS])
824
+        sq(delta_mm[X_AXIS]) + sq(delta_mm[Y_AXIS]) + sq(delta_mm[Z_AXIS])
825
       #endif
825
       #endif
826
     );
826
     );
827
   }
827
   }
828
   float inverse_millimeters = 1.0 / block->millimeters;  // Inverse millimeters to remove multiple divides
828
   float inverse_millimeters = 1.0 / block->millimeters;  // Inverse millimeters to remove multiple divides
829
 
829
 
830
   // Calculate moves/second for this move. No divide by zero due to previous checks.
830
   // Calculate moves/second for this move. No divide by zero due to previous checks.
831
-  float inverse_second = feed_rate * inverse_millimeters;
831
+  float inverse_second = fr_mm_s * inverse_millimeters;
832
 
832
 
833
   int moves_queued = movesplanned();
833
   int moves_queued = movesplanned();
834
 
834
 
836
   #if ENABLED(OLD_SLOWDOWN) || ENABLED(SLOWDOWN)
836
   #if ENABLED(OLD_SLOWDOWN) || ENABLED(SLOWDOWN)
837
     bool mq = moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE) / 2;
837
     bool mq = moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE) / 2;
838
     #if ENABLED(OLD_SLOWDOWN)
838
     #if ENABLED(OLD_SLOWDOWN)
839
-      if (mq) feed_rate *= 2.0 * moves_queued / (BLOCK_BUFFER_SIZE);
839
+      if (mq) fr_mm_s *= 2.0 * moves_queued / (BLOCK_BUFFER_SIZE);
840
     #endif
840
     #endif
841
     #if ENABLED(SLOWDOWN)
841
     #if ENABLED(SLOWDOWN)
842
       //  segment time im micro seconds
842
       //  segment time im micro seconds
895
   float speed_factor = 1.0; //factor <=1 do decrease speed
895
   float speed_factor = 1.0; //factor <=1 do decrease speed
896
   for (int i = 0; i < NUM_AXIS; i++) {
896
   for (int i = 0; i < NUM_AXIS; i++) {
897
     current_speed[i] = delta_mm[i] * inverse_second;
897
     current_speed[i] = delta_mm[i] * inverse_second;
898
-    float cs = fabs(current_speed[i]), mf = max_feedrate[i];
898
+    float cs = fabs(current_speed[i]), mf = max_feedrate_mm_s[i];
899
     if (cs > mf) speed_factor = min(speed_factor, mf / cs);
899
     if (cs > mf) speed_factor = min(speed_factor, mf / cs);
900
   }
900
   }
901
 
901
 
1030
           dsy = current_speed[Y_AXIS] - previous_speed[Y_AXIS],
1030
           dsy = current_speed[Y_AXIS] - previous_speed[Y_AXIS],
1031
           dsz = fabs(csz - previous_speed[Z_AXIS]),
1031
           dsz = fabs(csz - previous_speed[Z_AXIS]),
1032
           dse = fabs(cse - previous_speed[E_AXIS]),
1032
           dse = fabs(cse - previous_speed[E_AXIS]),
1033
-          jerk = sqrt(dsx * dsx + dsy * dsy);
1033
+          jerk = HYPOT(dsx, dsy);
1034
 
1034
 
1035
     //    if ((fabs(previous_speed[X_AXIS]) > 0.0001) || (fabs(previous_speed[Y_AXIS]) > 0.0001)) {
1035
     //    if ((fabs(previous_speed[X_AXIS]) > 0.0001) || (fabs(previous_speed[Y_AXIS]) > 0.0001)) {
1036
     vmax_junction = block->nominal_speed;
1036
     vmax_junction = block->nominal_speed;
1086
     }
1086
     }
1087
     else {
1087
     else {
1088
       long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_steps_per_s2);
1088
       long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_steps_per_s2);
1089
-      float advance = ((STEPS_PER_CUBIC_MM_E) * (EXTRUDER_ADVANCE_K)) * (cse * cse * (EXTRUSION_AREA) * (EXTRUSION_AREA)) * 256;
1089
+      float advance = ((STEPS_PER_CUBIC_MM_E) * (EXTRUDER_ADVANCE_K)) * HYPOT(cse, EXTRUSION_AREA) * 256;
1090
       block->advance = advance;
1090
       block->advance = advance;
1091
       block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
1091
       block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
1092
     }
1092
     }

+ 9
- 9
Marlin/planner.h View File

119
     static volatile uint8_t block_buffer_head;           // Index of the next block to be pushed
119
     static volatile uint8_t block_buffer_head;           // Index of the next block to be pushed
120
     static volatile uint8_t block_buffer_tail;
120
     static volatile uint8_t block_buffer_tail;
121
 
121
 
122
-    static float max_feedrate[NUM_AXIS]; // Max speeds in mm per second
122
+    static float max_feedrate_mm_s[NUM_AXIS]; // Max speeds in mm per second
123
     static float axis_steps_per_mm[NUM_AXIS];
123
     static float axis_steps_per_mm[NUM_AXIS];
124
     static unsigned long max_acceleration_steps_per_s2[NUM_AXIS];
124
     static unsigned long max_acceleration_steps_per_s2[NUM_AXIS];
125
     static unsigned long max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software
125
     static unsigned long max_acceleration_mm_per_s2[NUM_AXIS]; // Use M201 to override by software
126
 
126
 
127
     static millis_t min_segment_time;
127
     static millis_t min_segment_time;
128
-    static float min_feedrate;
128
+    static float min_feedrate_mm_s;
129
     static float acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
129
     static float acceleration;         // Normal acceleration mm/s^2  DEFAULT ACCELERATION for all printing moves. M204 SXXXX
130
     static float retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
130
     static float retract_acceleration; // Retract acceleration mm/s^2 filament pull-back and push-forward while standing still in the other axes M204 TXXXX
131
     static float travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
131
     static float travel_acceleration;  // Travel acceleration mm/s^2  DEFAULT ACCELERATION for all NON printing moves. M204 MXXXX
132
     static float max_xy_jerk;          // The largest speed change requiring no acceleration
132
     static float max_xy_jerk;          // The largest speed change requiring no acceleration
133
     static float max_z_jerk;
133
     static float max_z_jerk;
134
     static float max_e_jerk;
134
     static float max_e_jerk;
135
-    static float min_travel_feedrate;
135
+    static float min_travel_feedrate_mm_s;
136
 
136
 
137
     #if ENABLED(AUTO_BED_LEVELING_FEATURE)
137
     #if ENABLED(AUTO_BED_LEVELING_FEATURE)
138
       static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level
138
       static matrix_3x3 bed_level_matrix; // Transform to compensate for bed level
211
        * Add a new linear movement to the buffer.
211
        * Add a new linear movement to the buffer.
212
        *
212
        *
213
        *  x,y,z,e   - target position in mm
213
        *  x,y,z,e   - target position in mm
214
-       *  feed_rate - (target) speed of the move
214
+       *  fr_mm_s   - (target) speed of the move (mm/s)
215
        *  extruder  - target extruder
215
        *  extruder  - target extruder
216
        */
216
        */
217
-      static void buffer_line(float x, float y, float z, const float& e, float feed_rate, const uint8_t extruder);
217
+      static void buffer_line(float x, float y, float z, const float& e, float fr_mm_s, const uint8_t extruder);
218
 
218
 
219
       /**
219
       /**
220
        * Set the planner.position and individual stepper positions.
220
        * Set the planner.position and individual stepper positions.
229
 
229
 
230
     #else
230
     #else
231
 
231
 
232
-      static void buffer_line(const float& x, const float& y, const float& z, const float& e, float feed_rate, const uint8_t extruder);
232
+      static void buffer_line(const float& x, const float& y, const float& z, const float& e, float fr_mm_s, const uint8_t extruder);
233
       static void set_position_mm(const float& x, const float& y, const float& z, const float& e);
233
       static void set_position_mm(const float& x, const float& y, const float& z, const float& e);
234
 
234
 
235
     #endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING
235
     #endif // AUTO_BED_LEVELING_FEATURE || MESH_BED_LEVELING
290
      */
290
      */
291
     static float estimate_acceleration_distance(float initial_rate, float target_rate, float accel) {
291
     static float estimate_acceleration_distance(float initial_rate, float target_rate, float accel) {
292
       if (accel == 0) return 0; // accel was 0, set acceleration distance to 0
292
       if (accel == 0) return 0; // accel was 0, set acceleration distance to 0
293
-      return (target_rate * target_rate - initial_rate * initial_rate) / (accel * 2);
293
+      return (sq(target_rate) - sq(initial_rate)) / (accel * 2);
294
     }
294
     }
295
 
295
 
296
     /**
296
     /**
303
      */
303
      */
304
     static float intersection_distance(float initial_rate, float final_rate, float accel, float distance) {
304
     static float intersection_distance(float initial_rate, float final_rate, float accel, float distance) {
305
       if (accel == 0) return 0; // accel was 0, set intersection distance to 0
305
       if (accel == 0) return 0; // accel was 0, set intersection distance to 0
306
-      return (accel * 2 * distance - initial_rate * initial_rate + final_rate * final_rate) / (accel * 4);
306
+      return (accel * 2 * distance - sq(initial_rate) + sq(final_rate)) / (accel * 4);
307
     }
307
     }
308
 
308
 
309
     /**
309
     /**
312
      * 'distance'.
312
      * 'distance'.
313
      */
313
      */
314
     static float max_allowable_speed(float accel, float target_velocity, float distance) {
314
     static float max_allowable_speed(float accel, float target_velocity, float distance) {
315
-      return sqrt(target_velocity * target_velocity - 2 * accel * distance);
315
+      return sqrt(sq(target_velocity) - 2 * accel * distance);
316
     }
316
     }
317
 
317
 
318
     static void calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor);
318
     static void calculate_trapezoid_for_block(block_t* block, float entry_factor, float exit_factor);

+ 3
- 3
Marlin/planner_bezier.cpp View File

105
  * the mitigation offered by MIN_STEP and the small computational
105
  * the mitigation offered by MIN_STEP and the small computational
106
  * power available on Arduino, I think it is not wise to implement it.
106
  * power available on Arduino, I think it is not wise to implement it.
107
  */
107
  */
108
-void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float feed_rate, uint8_t extruder) {
108
+void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS], const float offset[4], float fr_mm_s, uint8_t extruder) {
109
   // Absolute first and second control points are recovered.
109
   // Absolute first and second control points are recovered.
110
   float first0 = position[X_AXIS] + offset[0];
110
   float first0 = position[X_AXIS] + offset[0];
111
   float first1 = position[Y_AXIS] + offset[1];
111
   float first1 = position[Y_AXIS] + offset[1];
193
       #if ENABLED(AUTO_BED_LEVELING_FEATURE)
193
       #if ENABLED(AUTO_BED_LEVELING_FEATURE)
194
         adjust_delta(bez_target);
194
         adjust_delta(bez_target);
195
       #endif
195
       #endif
196
-      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], bez_target[E_AXIS], feed_rate, extruder);
196
+      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], bez_target[E_AXIS], fr_mm_s, extruder);
197
     #else
197
     #else
198
-      planner.buffer_line(bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS], feed_rate, extruder);
198
+      planner.buffer_line(bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS], fr_mm_s, extruder);
199
     #endif
199
     #endif
200
   }
200
   }
201
 }
201
 }

+ 1
- 1
Marlin/planner_bezier.h View File

36
               const float position[NUM_AXIS], // current position
36
               const float position[NUM_AXIS], // current position
37
               const float target[NUM_AXIS],   // target position
37
               const float target[NUM_AXIS],   // target position
38
               const float offset[4],          // a pair of offsets
38
               const float offset[4],          // a pair of offsets
39
-              float feed_rate,
39
+              float fr_mm_s,
40
               uint8_t extruder
40
               uint8_t extruder
41
             );
41
             );
42
 
42
 

+ 30
- 30
Marlin/ultralcd.cpp View File

104
   #if HAS_POWER_SWITCH
104
   #if HAS_POWER_SWITCH
105
     extern bool powersupply;
105
     extern bool powersupply;
106
   #endif
106
   #endif
107
-  const float manual_feedrate[] = MANUAL_FEEDRATE;
107
+  const float manual_feedrate_mm_m[] = MANUAL_FEEDRATE;
108
   static void lcd_main_menu();
108
   static void lcd_main_menu();
109
   static void lcd_tune_menu();
109
   static void lcd_tune_menu();
110
   static void lcd_prepare_menu();
110
   static void lcd_prepare_menu();
254
    *     lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause)
254
    *     lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause)
255
    *     menu_action_function(lcd_sdcard_pause)
255
    *     menu_action_function(lcd_sdcard_pause)
256
    *
256
    *
257
-   *   MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999)
258
-   *   MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
259
-   *     lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
260
-   *     menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
257
+   *   MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999)
258
+   *   MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_percentage, 10, 999)
259
+   *     lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedrate_percentage, 10, 999)
260
+   *     menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999)
261
    *
261
    *
262
    */
262
    */
263
   #define _MENU_ITEM_PART_1(TYPE, LABEL, ARGS...) \
263
   #define _MENU_ITEM_PART_1(TYPE, LABEL, ARGS...) \
523
     }
523
     }
524
 
524
 
525
     #if ENABLED(ULTIPANEL_FEEDMULTIPLY)
525
     #if ENABLED(ULTIPANEL_FEEDMULTIPLY)
526
-      int new_frm = feedrate_multiplier + (int32_t)encoderPosition;
526
+      int new_frm = feedrate_percentage + (int32_t)encoderPosition;
527
       // Dead zone at 100% feedrate
527
       // Dead zone at 100% feedrate
528
-      if ((feedrate_multiplier < 100 && new_frm > 100) || (feedrate_multiplier > 100 && new_frm < 100)) {
529
-        feedrate_multiplier = 100;
528
+      if ((feedrate_percentage < 100 && new_frm > 100) || (feedrate_percentage > 100 && new_frm < 100)) {
529
+        feedrate_percentage = 100;
530
         encoderPosition = 0;
530
         encoderPosition = 0;
531
       }
531
       }
532
-      else if (feedrate_multiplier == 100) {
532
+      else if (feedrate_percentage == 100) {
533
         if ((int32_t)encoderPosition > ENCODER_FEEDRATE_DEADZONE) {
533
         if ((int32_t)encoderPosition > ENCODER_FEEDRATE_DEADZONE) {
534
-          feedrate_multiplier += (int32_t)encoderPosition - (ENCODER_FEEDRATE_DEADZONE);
534
+          feedrate_percentage += (int32_t)encoderPosition - (ENCODER_FEEDRATE_DEADZONE);
535
           encoderPosition = 0;
535
           encoderPosition = 0;
536
         }
536
         }
537
         else if ((int32_t)encoderPosition < -(ENCODER_FEEDRATE_DEADZONE)) {
537
         else if ((int32_t)encoderPosition < -(ENCODER_FEEDRATE_DEADZONE)) {
538
-          feedrate_multiplier += (int32_t)encoderPosition + ENCODER_FEEDRATE_DEADZONE;
538
+          feedrate_percentage += (int32_t)encoderPosition + ENCODER_FEEDRATE_DEADZONE;
539
           encoderPosition = 0;
539
           encoderPosition = 0;
540
         }
540
         }
541
       }
541
       }
542
       else {
542
       else {
543
-        feedrate_multiplier = new_frm;
543
+        feedrate_percentage = new_frm;
544
         encoderPosition = 0;
544
         encoderPosition = 0;
545
       }
545
       }
546
     #endif // ULTIPANEL_FEEDMULTIPLY
546
     #endif // ULTIPANEL_FEEDMULTIPLY
547
 
547
 
548
-    feedrate_multiplier = constrain(feedrate_multiplier, 10, 999);
548
+    feedrate_percentage = constrain(feedrate_percentage, 10, 999);
549
 
549
 
550
   #endif //ULTIPANEL
550
   #endif //ULTIPANEL
551
 }
551
 }
573
   inline void line_to_current(AxisEnum axis) {
573
   inline void line_to_current(AxisEnum axis) {
574
     #if ENABLED(DELTA)
574
     #if ENABLED(DELTA)
575
       calculate_delta(current_position);
575
       calculate_delta(current_position);
576
-      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder);
576
+      planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[axis]), active_extruder);
577
     #else // !DELTA
577
     #else // !DELTA
578
-      planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[axis]/60, active_extruder);
578
+      planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[axis]), active_extruder);
579
     #endif // !DELTA
579
     #endif // !DELTA
580
   }
580
   }
581
 
581
 
757
     //
757
     //
758
     // Speed:
758
     // Speed:
759
     //
759
     //
760
-    MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999);
760
+    MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999);
761
 
761
 
762
     // Manual bed leveling, Bed Z:
762
     // Manual bed leveling, Bed Z:
763
     #if ENABLED(MANUAL_BED_LEVELING)
763
     #if ENABLED(MANUAL_BED_LEVELING)
1020
       line_to_current(Z_AXIS);
1020
       line_to_current(Z_AXIS);
1021
       current_position[X_AXIS] = x + home_offset[X_AXIS];
1021
       current_position[X_AXIS] = x + home_offset[X_AXIS];
1022
       current_position[Y_AXIS] = y + home_offset[Y_AXIS];
1022
       current_position[Y_AXIS] = y + home_offset[Y_AXIS];
1023
-      line_to_current(manual_feedrate[X_AXIS] <= manual_feedrate[Y_AXIS] ? X_AXIS : Y_AXIS);
1023
+      line_to_current(manual_feedrate_mm_m[X_AXIS] <= manual_feedrate_mm_m[Y_AXIS] ? X_AXIS : Y_AXIS);
1024
       #if MIN_Z_HEIGHT_FOR_HOMING > 0
1024
       #if MIN_Z_HEIGHT_FOR_HOMING > 0
1025
         current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; // How do condition and action match?
1025
         current_position[Z_AXIS] = MESH_HOME_SEARCH_Z; // How do condition and action match?
1026
         line_to_current(Z_AXIS);
1026
         line_to_current(Z_AXIS);
1310
     if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) {
1310
     if (manual_move_axis != (int8_t)NO_AXIS && ELAPSED(millis(), manual_move_start_time) && !planner.is_full()) {
1311
       #if ENABLED(DELTA)
1311
       #if ENABLED(DELTA)
1312
         calculate_delta(current_position);
1312
         calculate_delta(current_position);
1313
-        planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], manual_feedrate[manual_move_axis]/60, manual_move_e_index);
1313
+        planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index);
1314
       #else
1314
       #else
1315
-        planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], manual_feedrate[manual_move_axis]/60, manual_move_e_index);
1315
+        planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_e_index);
1316
       #endif
1316
       #endif
1317
       manual_move_axis = (int8_t)NO_AXIS;
1317
       manual_move_axis = (int8_t)NO_AXIS;
1318
     }
1318
     }
1356
   }
1356
   }
1357
   #if ENABLED(DELTA)
1357
   #if ENABLED(DELTA)
1358
     static float delta_clip_radius_2 =  (DELTA_PRINTABLE_RADIUS) * (DELTA_PRINTABLE_RADIUS);
1358
     static float delta_clip_radius_2 =  (DELTA_PRINTABLE_RADIUS) * (DELTA_PRINTABLE_RADIUS);
1359
-    static int delta_clip( float a ) { return sqrt(delta_clip_radius_2 - a*a); }
1359
+    static int delta_clip( float a ) { return sqrt(delta_clip_radius_2 - sq(a)); }
1360
     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)); }
1360
     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)); }
1361
     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)); }
1361
     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)); }
1362
   #else
1362
   #else
1800
       MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &planner.max_z_jerk, 0.1, 990);
1800
       MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &planner.max_z_jerk, 0.1, 990);
1801
     #endif
1801
     #endif
1802
     MENU_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_e_jerk, 1, 990);
1802
     MENU_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_e_jerk, 1, 990);
1803
-    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_X, &planner.max_feedrate[X_AXIS], 1, 999);
1804
-    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Y, &planner.max_feedrate[Y_AXIS], 1, 999);
1805
-    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Z, &planner.max_feedrate[Z_AXIS], 1, 999);
1806
-    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate[E_AXIS], 1, 999);
1807
-    MENU_ITEM_EDIT(float3, MSG_VMIN, &planner.min_feedrate, 0, 999);
1808
-    MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &planner.min_travel_feedrate, 0, 999);
1803
+    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_X, &planner.max_feedrate_mm_s[X_AXIS], 1, 999);
1804
+    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Y, &planner.max_feedrate_mm_s[Y_AXIS], 1, 999);
1805
+    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_Z, &planner.max_feedrate_mm_s[Z_AXIS], 1, 999);
1806
+    MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate_mm_s[E_AXIS], 1, 999);
1807
+    MENU_ITEM_EDIT(float3, MSG_VMIN, &planner.min_feedrate_mm_s, 0, 999);
1808
+    MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &planner.min_travel_feedrate_mm_s, 0, 999);
1809
     MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &planner.max_acceleration_mm_per_s2[X_AXIS], 100, 99000, _reset_acceleration_rates);
1809
     MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &planner.max_acceleration_mm_per_s2[X_AXIS], 100, 99000, _reset_acceleration_rates);
1810
     MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &planner.max_acceleration_mm_per_s2[Y_AXIS], 100, 99000, _reset_acceleration_rates);
1810
     MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &planner.max_acceleration_mm_per_s2[Y_AXIS], 100, 99000, _reset_acceleration_rates);
1811
     MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &planner.max_acceleration_mm_per_s2[Z_AXIS], 10, 99000, _reset_acceleration_rates);
1811
     MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &planner.max_acceleration_mm_per_s2[Z_AXIS], 10, 99000, _reset_acceleration_rates);
1905
       #if EXTRUDERS > 1
1905
       #if EXTRUDERS > 1
1906
         MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &retract_recover_length_swap, 0, 100);
1906
         MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &retract_recover_length_swap, 0, 100);
1907
       #endif
1907
       #endif
1908
-      MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate, 1, 999);
1908
+      MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate_mm_s, 1, 999);
1909
       END_MENU();
1909
       END_MENU();
1910
     }
1910
     }
1911
   #endif // FWRETRACT
1911
   #endif // FWRETRACT
2257
    *   static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, screenFunc_t callback); // edit int with callback
2257
    *   static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, screenFunc_t callback); // edit int with callback
2258
    *
2258
    *
2259
    * You can then use one of the menu macros to present the edit interface:
2259
    * You can then use one of the menu macros to present the edit interface:
2260
-   *   MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999)
2260
+   *   MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_percentage, 10, 999)
2261
    *
2261
    *
2262
    * This expands into a more primitive menu item:
2262
    * This expands into a more primitive menu item:
2263
-   *   MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
2263
+   *   MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_percentage, 10, 999)
2264
    *
2264
    *
2265
    *
2265
    *
2266
    * Also: MENU_MULTIPLIER_ITEM_EDIT, MENU_ITEM_EDIT_CALLBACK, and MENU_MULTIPLIER_ITEM_EDIT_CALLBACK
2266
    * Also: MENU_MULTIPLIER_ITEM_EDIT, MENU_ITEM_EDIT_CALLBACK, and MENU_MULTIPLIER_ITEM_EDIT_CALLBACK
2267
    *
2267
    *
2268
-   *       menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
2268
+   *       menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999)
2269
    */
2269
    */
2270
   #define menu_edit_type(_type, _name, _strFunc, scale) \
2270
   #define menu_edit_type(_type, _name, _strFunc, scale) \
2271
     bool _menu_edit_ ## _name () { \
2271
     bool _menu_edit_ ## _name () { \

+ 1
- 1
Marlin/ultralcd_implementation_hitachi_HD44780.h View File

742
 
742
 
743
     lcd.setCursor(0, 2);
743
     lcd.setCursor(0, 2);
744
     lcd.print(LCD_STR_FEEDRATE[0]);
744
     lcd.print(LCD_STR_FEEDRATE[0]);
745
-    lcd.print(itostr3(feedrate_multiplier));
745
+    lcd.print(itostr3(feedrate_percentage));
746
     lcd.print('%');
746
     lcd.print('%');
747
 
747
 
748
     #if LCD_WIDTH > 19 && ENABLED(SDSUPPORT)
748
     #if LCD_WIDTH > 19 && ENABLED(SDSUPPORT)

Loading…
Cancel
Save