Ver Fonte

Add n_arc_correction and enhanced small angle sin/cos approximation.

FormerLurker há 3 anos atrás
pai
commit
6fc8155cbe

+ 72 - 71
Firmware/ConfigurationStore.cpp

@@ -34,8 +34,8 @@ static bool EEPROM_writeData(uint8_t* pos, uint8_t* value, uint8_t size, const c
 #ifdef DEBUG_EEPROM_WRITE
 	printf_P(PSTR("EEPROM_WRITE_VAR addr=0x%04x size=0x%02x name=%s\n"), pos, size, name);
 #endif //DEBUG_EEPROM_WRITE
-	while (size--)
-	{
+  while (size--)
+  {
 
         eeprom_update_byte(pos, *value);
         if (eeprom_read_byte(pos) != *value) {
@@ -43,9 +43,9 @@ static bool EEPROM_writeData(uint8_t* pos, uint8_t* value, uint8_t size, const c
             return false;
         }
 
-		pos++;
-		value++;
-	}
+    pos++;
+    value++;
+  }
     return true;
 }
 
@@ -89,8 +89,8 @@ void Config_StoreSettings()
 void Config_PrintSettings(uint8_t level)
 {  // Always have this function, even with EEPROM_SETTINGS disabled, the current values will be shown
 #ifdef TMC2130
-	printf_P(PSTR(
-		"%SSteps per unit:\n%S  M92 X%.2f Y%.2f Z%.2f E%.2f\n"
+  printf_P(PSTR(
+    "%SSteps per unit:\n%S  M92 X%.2f Y%.2f Z%.2f E%.2f\n"
         "%SUStep resolution: \n%S M350 X%d Y%d Z%d E%d\n"
 		"%SMaximum feedrates - normal (mm/s):\n%S  M203 X%.2f Y%.2f Z%.2f E%.2f\n"
 		"%SMaximum feedrates - stealth (mm/s):\n%S  M203 X%.2f Y%.2f Z%.2f E%.2f\n"
@@ -125,54 +125,54 @@ void Config_PrintSettings(uint8_t level)
 		echomagic, echomagic, cs.minimumfeedrate, cs.mintravelfeedrate, cs.minsegmenttime, cs.max_jerk[X_AXIS], cs.max_jerk[Y_AXIS], cs.max_jerk[Z_AXIS], cs.max_jerk[E_AXIS],
 		echomagic, echomagic, cs.add_homing[X_AXIS], cs.add_homing[Y_AXIS], cs.add_homing[Z_AXIS]
 #endif //TMC2130
-	);
+  );
 #ifdef PIDTEMP
-	printf_P(PSTR("%SPID settings:\n%S   M301 P%.2f I%.2f D%.2f\n"),
-		echomagic, echomagic, cs.Kp, unscalePID_i(cs.Ki), unscalePID_d(cs.Kd));
+  printf_P(PSTR("%SPID settings:\n%S   M301 P%.2f I%.2f D%.2f\n"),
+    echomagic, echomagic, cs.Kp, unscalePID_i(cs.Ki), unscalePID_d(cs.Kd));
 #endif
 #ifdef PIDTEMPBED
-	printf_P(PSTR("%SPID heatbed settings:\n%S   M304 P%.2f I%.2f D%.2f\n"),
-		echomagic, echomagic, cs.bedKp, unscalePID_i(cs.bedKi), unscalePID_d(cs.bedKd));
+  printf_P(PSTR("%SPID heatbed settings:\n%S   M304 P%.2f I%.2f D%.2f\n"),
+    echomagic, echomagic, cs.bedKp, unscalePID_i(cs.bedKi), unscalePID_d(cs.bedKd));
 #endif
 #ifdef FWRETRACT
-	printf_P(PSTR(
-		"%SRetract: S=Length (mm) F:Speed (mm/m) Z: ZLift (mm)\n%S   M207 S%.2f F%.2f Z%.2f\n"
-		"%SRecover: S=Extra length (mm) F:Speed (mm/m)\n%S   M208 S%.2f F%.2f\n"
-		"%SAuto-Retract: S=0 to disable, 1 to interpret extrude-only moves as retracts or recoveries\n%S   M209 S%d\n"
-		),
-		echomagic, echomagic, cs.retract_length, cs.retract_feedrate*60, cs.retract_zlift,
-		echomagic, echomagic, cs.retract_recover_length, cs.retract_recover_feedrate*60,
-		echomagic, echomagic, (cs.autoretract_enabled ? 1 : 0)
-	);
+  printf_P(PSTR(
+    "%SRetract: S=Length (mm) F:Speed (mm/m) Z: ZLift (mm)\n%S   M207 S%.2f F%.2f Z%.2f\n"
+    "%SRecover: S=Extra length (mm) F:Speed (mm/m)\n%S   M208 S%.2f F%.2f\n"
+    "%SAuto-Retract: S=0 to disable, 1 to interpret extrude-only moves as retracts or recoveries\n%S   M209 S%d\n"
+    ),
+    echomagic, echomagic, cs.retract_length, cs.retract_feedrate*60, cs.retract_zlift,
+    echomagic, echomagic, cs.retract_recover_length, cs.retract_recover_feedrate*60,
+    echomagic, echomagic, (cs.autoretract_enabled ? 1 : 0)
+  );
 #if EXTRUDERS > 1
-	printf_P(PSTR("%SMulti-extruder settings:\n%S   Swap retract length (mm):    %.2f\n%S   Swap rec. addl. length (mm): %.2f\n"),
-		echomagic, echomagic, retract_length_swap, echomagic, retract_recover_length_swap);
+  printf_P(PSTR("%SMulti-extruder settings:\n%S   Swap retract length (mm):    %.2f\n%S   Swap rec. addl. length (mm): %.2f\n"),
+    echomagic, echomagic, retract_length_swap, echomagic, retract_recover_length_swap);
 #endif
-	if (cs.volumetric_enabled) {
-		printf_P(PSTR("%SFilament settings:\n%S   M200 D%.2f\n"),
-			echomagic, echomagic, cs.filament_size[0]);
+  if (cs.volumetric_enabled) {
+    printf_P(PSTR("%SFilament settings:\n%S   M200 D%.2f\n"),
+      echomagic, echomagic, cs.filament_size[0]);
 #if EXTRUDERS > 1
-		printf_P(PSTR("%S   M200 T1 D%.2f\n"),
-			echomagic, echomagic, cs.filament_size[1]);
+    printf_P(PSTR("%S   M200 T1 D%.2f\n"),
+      echomagic, echomagic, cs.filament_size[1]);
 #if EXTRUDERS > 2
-		printf_P(PSTR("%S   M200 T1 D%.2f\n"),
-			echomagic, echomagic, cs.filament_size[2]);
+    printf_P(PSTR("%S   M200 T1 D%.2f\n"),
+      echomagic, echomagic, cs.filament_size[2]);
 #endif
 #endif
     } else {
         printf_P(PSTR("%SFilament settings: Disabled\n"), echomagic);
     }
 #endif
-	if (level >= 10) {
+  if (level >= 10) {
 #ifdef LIN_ADVANCE
-		printf_P(PSTR("%SLinear advance settings:%S   M900 K%.2f\n"),
+    printf_P(PSTR("%SLinear advance settings:%S   M900 K%.2f\n"),
                  echomagic, echomagic, extruder_advance_K);
 #endif //LIN_ADVANCE
-	}
+  }
     // Arc Interpolation Settings
     printf_P(PSTR(
-        "%SArc Settings: P=Arc segment length max (mm) S=Arc segment length Min (mm), R=Min arc segments, F=Arc segments per second.\n%S  M214 P%.2f S%.2f R%d F%d\n"),
-        echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.min_arc_segments, cs.arc_segments_per_sec);
+        "%SArc Settings: P=Arc segment length max (mm) S=Arc segment length Min (mm), N=Num Segments Per Correction, R=Min arc segments, F=Arc segments per second.\n%S  M214 P%.2f S%.2f N%d R%d F%d\n"),
+        echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.n_arc_correction, cs.min_arc_segments, cs.arc_segments_per_sec);
 }
 #endif
 
@@ -188,7 +188,7 @@ static_assert (false, "zprobe_zoffset was not initialized in printers in field t
         "0.0, if this is not acceptable, increment EEPROM_VERSION to force use default_conf");
 #endif
 
-static_assert (sizeof(M500_conf) == 208, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, "
+static_assert (sizeof(M500_conf) == 209, "sizeof(M500_conf) has changed, ensure that EEPROM_VERSION has been incremented, "
         "or if you added members in the end of struct, ensure that historically uninitialized values will be initialized."
         "If this is caused by change to more then 8bit processor, decide whether make this struct packed to save EEPROM,"
         "leave as it is to keep fast code, or reorder struct members to pack more tightly.");
@@ -260,7 +260,7 @@ static bool is_uninitialized(void* addr, uint8_t len)
 //! @retval false Failed. Default settings has been retrieved, because of older version or corrupted data.
 bool Config_RetrieveSettings()
 {
-	bool previous_settings_retrieved = true;
+  bool previous_settings_retrieved = true;
     char ver[4]=EEPROM_VERSION;
     EEPROM_readData(reinterpret_cast<uint8_t*>(EEPROM_M500_base->version), reinterpret_cast<uint8_t*>(cs.version), sizeof(cs.version), "cs.version"); //read stored version
     //  SERIAL_ECHOLN("Version: [" << ver << "] Stored version: [" << cs.version << "]");
@@ -270,7 +270,7 @@ bool Config_RetrieveSettings()
         EEPROM_readData(reinterpret_cast<uint8_t*>(EEPROM_M500_base), reinterpret_cast<uint8_t*>(&cs), sizeof(cs), "cs");
         calculate_extruder_multipliers();
 
-		//if max_feedrate_silent and max_acceleration_units_per_sq_second_silent were never stored to eeprom, use default values:
+    //if max_feedrate_silent and max_acceleration_units_per_sq_second_silent were never stored to eeprom, use default values:
         for (uint8_t i = 0; i < (sizeof(cs.max_feedrate_silent)/sizeof(cs.max_feedrate_silent[0])); ++i)
         {
             const uint32_t erased = 0xffffffff;
@@ -284,32 +284,33 @@ bool Config_RetrieveSettings()
         // Initialize arc interpolation settings if they are not already (Not sure about this bit, please review)
         if (is_uninitialized(cs.mm_per_arc_segment, sizeof(float))) cs.mm_per_arc_segment = DEFAULT_MM_PER_ARC_SEGMENT;
         if (is_uninitialized(cs.min_mm_per_arc_segment, sizeof(float))) cs.min_mm_per_arc_segment = DEFAULT_MIN_MM_PER_ARC_SEGMENT;
+        if (is_uninitialized(cs.n_arc_correction), sizeof(uint8_t)) cs.n_arc_correction = DEFAULT_N_ARC_CORRECTION;
         if (is_uninitialized(cs.min_arc_segments, sizeof(uint16_t))) cs.min_arc_segments = DEFAULT_MIN_ARC_SEGMENTS;
         if (is_uninitialized(cs.arc_segments_per_sec, sizeof(uint16_t))) cs.arc_segments_per_sec = DEFAULT_ARC_SEGMENTS_PER_SEC;
 
 
 #ifdef TMC2130
-		for (uint8_t j = X_AXIS; j <= Y_AXIS; j++)
-		{
-			if (cs.max_feedrate_normal[j] > NORMAL_MAX_FEEDRATE_XY)
-				cs.max_feedrate_normal[j] = NORMAL_MAX_FEEDRATE_XY;
-			if (cs.max_feedrate_silent[j] > SILENT_MAX_FEEDRATE_XY)
-				cs.max_feedrate_silent[j] = SILENT_MAX_FEEDRATE_XY;
-			if (cs.max_acceleration_units_per_sq_second_normal[j] > NORMAL_MAX_ACCEL_XY)
-				cs.max_acceleration_units_per_sq_second_normal[j] = NORMAL_MAX_ACCEL_XY;
-			if (cs.max_acceleration_units_per_sq_second_silent[j] > SILENT_MAX_ACCEL_XY)
-				cs.max_acceleration_units_per_sq_second_silent[j] = SILENT_MAX_ACCEL_XY;
-		}
+    for (uint8_t j = X_AXIS; j <= Y_AXIS; j++)
+    {
+      if (cs.max_feedrate_normal[j] > NORMAL_MAX_FEEDRATE_XY)
+        cs.max_feedrate_normal[j] = NORMAL_MAX_FEEDRATE_XY;
+      if (cs.max_feedrate_silent[j] > SILENT_MAX_FEEDRATE_XY)
+        cs.max_feedrate_silent[j] = SILENT_MAX_FEEDRATE_XY;
+      if (cs.max_acceleration_units_per_sq_second_normal[j] > NORMAL_MAX_ACCEL_XY)
+        cs.max_acceleration_units_per_sq_second_normal[j] = NORMAL_MAX_ACCEL_XY;
+      if (cs.max_acceleration_units_per_sq_second_silent[j] > SILENT_MAX_ACCEL_XY)
+        cs.max_acceleration_units_per_sq_second_silent[j] = SILENT_MAX_ACCEL_XY;
+    }
         
-		if(cs.axis_ustep_resolution[X_AXIS] == 0xff){ cs.axis_ustep_resolution[X_AXIS] = TMC2130_USTEPS_XY; }
-		if(cs.axis_ustep_resolution[Y_AXIS] == 0xff){ cs.axis_ustep_resolution[Y_AXIS] = TMC2130_USTEPS_XY; }
-		if(cs.axis_ustep_resolution[Z_AXIS] == 0xff){ cs.axis_ustep_resolution[Z_AXIS] = TMC2130_USTEPS_Z; }
-		if(cs.axis_ustep_resolution[E_AXIS] == 0xff){ cs.axis_ustep_resolution[E_AXIS] = TMC2130_USTEPS_E; }
-
-		tmc2130_set_res(X_AXIS, cs.axis_ustep_resolution[X_AXIS]);
-		tmc2130_set_res(Y_AXIS, cs.axis_ustep_resolution[Y_AXIS]);
-		tmc2130_set_res(Z_AXIS, cs.axis_ustep_resolution[Z_AXIS]);
-		tmc2130_set_res(E_AXIS, cs.axis_ustep_resolution[E_AXIS]);
+    if(cs.axis_ustep_resolution[X_AXIS] == 0xff){ cs.axis_ustep_resolution[X_AXIS] = TMC2130_USTEPS_XY; }
+    if(cs.axis_ustep_resolution[Y_AXIS] == 0xff){ cs.axis_ustep_resolution[Y_AXIS] = TMC2130_USTEPS_XY; }
+    if(cs.axis_ustep_resolution[Z_AXIS] == 0xff){ cs.axis_ustep_resolution[Z_AXIS] = TMC2130_USTEPS_Z; }
+    if(cs.axis_ustep_resolution[E_AXIS] == 0xff){ cs.axis_ustep_resolution[E_AXIS] = TMC2130_USTEPS_E; }
+
+    tmc2130_set_res(X_AXIS, cs.axis_ustep_resolution[X_AXIS]);
+    tmc2130_set_res(Y_AXIS, cs.axis_ustep_resolution[Y_AXIS]);
+    tmc2130_set_res(Z_AXIS, cs.axis_ustep_resolution[Z_AXIS]);
+    tmc2130_set_res(E_AXIS, cs.axis_ustep_resolution[E_AXIS]);
 #endif //TMC2130
 
         if(is_uninitialized(&cs.travel_acceleration, sizeof(cs.travel_acceleration)))
@@ -317,27 +318,27 @@ bool Config_RetrieveSettings()
 
 		reset_acceleration_rates();
 
-		// Call updatePID (similar to when we have processed M301)
-		updatePID();
+    // Call updatePID (similar to when we have processed M301)
+    updatePID();
         SERIAL_ECHO_START;
         SERIAL_ECHOLNPGM("Stored settings retrieved");
     }
     else
     {
         Config_ResetDefault();
-		//Return false to inform user that eeprom version was changed and firmware is using default hardcoded settings now.
-		//In case that storing to eeprom was not used yet, do not inform user that hardcoded settings are used.
-		if (eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[0]))) != 0xFF ||
-			eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[1]))) != 0xFF ||
-			eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[2]))) != 0xFF)
-		{
-			previous_settings_retrieved = false;
-		}
+    //Return false to inform user that eeprom version was changed and firmware is using default hardcoded settings now.
+    //In case that storing to eeprom was not used yet, do not inform user that hardcoded settings are used.
+    if (eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[0]))) != 0xFF ||
+      eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[1]))) != 0xFF ||
+      eeprom_read_byte(reinterpret_cast<uint8_t*>(&(EEPROM_M500_base->version[2]))) != 0xFF)
+    {
+      previous_settings_retrieved = false;
+    }
     }
     #ifdef EEPROM_CHITCHAT
       Config_PrintSettings();
     #endif
-	return previous_settings_retrieved;
+  return previous_settings_retrieved;
 }
 #endif
 
@@ -345,14 +346,14 @@ void Config_ResetDefault()
 {
     memcpy_P(&cs,&default_conf, sizeof(cs));
 
-	// steps per sq second need to be updated to agree with the units per sq second
+  // steps per sq second need to be updated to agree with the units per sq second
     reset_acceleration_rates();
     
 #ifdef PIDTEMP
     updatePID();
 #endif//PIDTEMP
 
-	calculate_extruder_multipliers();
+  calculate_extruder_multipliers();
 
 SERIAL_ECHO_START;
 SERIAL_ECHOLNPGM("Hardcoded Default Settings Loaded");

+ 3 - 2
Firmware/ConfigurationStore.h

@@ -42,8 +42,9 @@ typedef struct
     // Arc Interpolation Settings, configurable via M214
     float mm_per_arc_segment;
     float min_mm_per_arc_segment;
-    uint16_t min_arc_segments; // If less than or equal to zero, this is disabled
-    uint16_t arc_segments_per_sec; // If less than or equal to zero, this is disabled
+    uint8_t n_arc_correction; // If equal to zero, this is disabled
+    uint16_t min_arc_segments; // If equal to zero, this is disabled
+    uint16_t arc_segments_per_sec; // If equal to zero, this is disabled
 } M500_conf;
 
 extern M500_conf cs;

+ 14 - 1
Firmware/Marlin_main.cpp

@@ -7509,11 +7509,12 @@ Sigma_Exit:
 
     #### Usage
 
-        M214 [P] [S] [R] [F]
+        M214 [P] [S] [N] [R] [F]
 
     #### Parameters
     - `P` - A float representing the max and default millimeters per arc segment.  Must be greater than 0.
     - `S` - A float representing the minimum allowable millimeters per arc segment.  Set to 0 to disable
+    - `N` - An int representing the number of arcs to draw before correcting the small angle approximation.  Set to 1 or 0 to disable.
     - `R` - An int representing the minimum number of segments per arcs of any radius,
             except when the results in segment lengths greater than or less than the minimum
             and maximum segment length.  Set to 0 to disable.
@@ -7525,6 +7526,7 @@ Sigma_Exit:
         // Extract N
         float p = cs.mm_per_arc_segment;
         float s = cs.min_mm_per_arc_segment;
+        uint8_t n = cs.n_arc_correction;
         uint16_t r = cs.min_arc_segments;
         uint16_t f = cs.arc_segments_per_sec;
 
@@ -7546,6 +7548,16 @@ Sigma_Exit:
                 break;
             }
         }
+        // Extract N
+        if (code_seen('N'))
+        {
+
+            n = code_value();
+            if (n < 0)
+            {
+                break;
+            }
+        }
         // Extract R
         if (code_seen('R'))
         {
@@ -7567,6 +7579,7 @@ Sigma_Exit:
         }
         cs.mm_per_arc_segment = p;
         cs.min_mm_per_arc_segment = s;
+        cs.n_arc_correction = n;
         cs.min_arc_segments = r;
         cs.arc_segments_per_sec = f;
     }break;

+ 31 - 6
Firmware/motion_control.cpp

@@ -39,6 +39,9 @@ void mc_arc(float* position, float* target, float* offset, float feed_rate, floa
     float rt_y = target[Y_AXIS] - center_axis_y;
     // 20200419 - Add a variable that will be used to hold the arc segment length
     float mm_per_arc_segment = cs.mm_per_arc_segment;
+    // 20210109 - Add a variable to hold the n_arc_correction value
+    bool correction_enabled = cs.n_arc_correction > 1;
+    uint8_t n_arc_correction = cs.n_arc_correction;
 
     // CCW angle between position and target from circle center. Only one atan2() trig computation required.
     float angular_travel_total = atan2(r_axis_x * rt_y - r_axis_y * rt_x, r_axis_x * rt_x + r_axis_y * rt_y);
@@ -126,16 +129,38 @@ void mc_arc(float* position, float* target, float* offset, float feed_rate, floa
     {
         // Initialize the extruder axis
 
-        float cos_T = cos(theta_per_segment);
-        float sin_T = sin(theta_per_segment);
+        float cos_T;
+        float sin_T;
+
+        if (correction_enabled > 1){
+            float sq_theta_per_segment = theta_per_segment * theta_per_segment;
+            // Small angle approximation
+            sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6,
+            cos_T = 1 - 0.5f * sq_theta_per_segment; 
+        }
+        else {
+            cos_T = cos(theta_per_segment);
+            sin_T = sin(theta_per_segment);
+        }
+
         float r_axisi;
         uint16_t i;
 
         for (i = 1; i < segments; i++) { // Increment (segments-1)
-            r_axisi = r_axis_x * sin_T + r_axis_y * cos_T;
-            r_axis_x = r_axis_x * cos_T - r_axis_y * sin_T;
-            r_axis_y = r_axisi;
-
+            if (correction_enabled && --n_arc_correction == 0) {
+                // Calculate the actual position for r_axis_x and r_axis_y
+                const float cos_Ti = cos(i * theta_per_segment), sin_Ti = sin(i * theta_per_segment);
+                r_axis_x = -offset[X_AXIS] * cos_Ti + offset[Y_AXIS] * sin_Ti;
+                r_axis_y = -offset[X_AXIS] * sin_Ti - offset[Y_AXIS] * cos_Ti;
+                // reset n_arc_correction
+                n_arc_correction = cs.n_arc_correction;
+            }
+            else {
+                r_axisi = r_axis_x * sin_T + r_axis_y * cos_T;
+                r_axis_x = r_axis_x * cos_T - r_axis_y * sin_T;
+                r_axis_y = r_axisi;
+            }
+            
             // Update arc_target location
             position[X_AXIS] = center_axis_x + r_axis_x;
             position[Y_AXIS] = center_axis_y + r_axis_y;

+ 10 - 6
Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h

@@ -526,11 +526,15 @@
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+/*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+    or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+    calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h

@@ -530,11 +530,15 @@
 //#define MICROMETER_LOGGING //related to D-codes D80 and D81, currently works on MK2.5 only (MK3 board pin definitions missing)
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h

@@ -533,11 +533,15 @@
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h

@@ -534,11 +534,15 @@
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -672,11 +672,15 @@
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h

@@ -684,11 +684,15 @@
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/obsolete/1_75mm_MK2-RAMBo10a-E3Dv6full.h

@@ -450,11 +450,15 @@ THERMISTORS SETTINGS
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H

+ 10 - 6
Firmware/variants/obsolete/1_75mm_MK2-RAMBo13a-E3Dv6full.h

@@ -439,11 +439,15 @@ THERMISTORS SETTINGS
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 // Default Arc Interpolation Settings (Now configurable via M214)
-#define DEFAULT_MM_PER_ARC_SEGMENT 1.0f // REQUIRED - The enforced maximum length of an arc segment
-#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f /* OPTIONAL - the enforced minimum length of an interpolated segment.  Must be smaller than
-    MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0 or ARC_SEGMENTS_PER_SEC > 0 */
-    // If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum calculated segment length is used.
-#define DEFAULT_MIN_ARC_SEGMENTS 20 // OPTIONAL - The enforced minimum segments in a full circle of the same radius.
-#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // OPTIONAL - Use feedrate to choose segment length.
+#define DEFAULT_N_ARC_CORRECTION       25 // Number of interpolated segments between corrections.
+/* A value of 1 or less for N_ARC_CORRECTION will trigger the use of Sin and Cos for every arc, which will improve accuracy at the
+   cost of performance*/
+#define DEFAULT_MM_PER_ARC_SEGMENT     1.0f // REQUIRED - The enforced maximum length of an arc segment
+#define DEFAULT_MIN_MM_PER_ARC_SEGMENT 0.5f //the enforced minimum length of an interpolated segment
+   /*  MIN_MM_PER_ARC_SEGMENT Must be smaller than MM_PER_ARC_SEGMENT.  Only has an effect if MIN_ARC_SEGMENTS > 0
+       or ARC_SEGMENTS_PER_SEC > 0 .  If both MIN_ARC_SEGMENTS and ARC_SEGMENTS_PER_SEC is defined, the minimum
+       calculated segment length is used. */
+#define DEFAULT_MIN_ARC_SEGMENTS 20 // The enforced minimum segments in a full circle of the same radius.  Set to 0 to disable
+#define DEFAULT_ARC_SEGMENTS_PER_SEC 0 // Use feedrate to choose segment length. Set to 0 to disable
 
 #endif //__CONFIGURATION_PRUSA_H