Partial LA15 support
This commit is contained in:
parent
098c0979ba
commit
eeea2725cb
5 changed files with 99 additions and 98 deletions
|
@ -165,8 +165,8 @@ void Config_PrintSettings(uint8_t level)
|
||||||
#endif
|
#endif
|
||||||
if (level >= 10) {
|
if (level >= 10) {
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
printf_P(PSTR("%SLinear advance settings:\n M900 K%.2f E/D = %.2f\n"),
|
printf_P(PSTR("%SLinear advance settings:\n M900 K%.2f\n"),
|
||||||
echomagic, extruder_advance_k, advance_ed_ratio);
|
echomagic, extruder_advance_K);
|
||||||
#endif //LIN_ADVANCE
|
#endif //LIN_ADVANCE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,43 +276,26 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of linear pressure control
|
* Linear Pressure Control v1.5
|
||||||
*
|
*
|
||||||
* Assumption: advance = k * (delta velocity)
|
* Assumption: advance [steps] = k * (delta velocity [steps/s])
|
||||||
* K=0 means advance disabled.
|
* K=0 means advance disabled.
|
||||||
* See Marlin documentation for calibration instructions.
|
*
|
||||||
*/
|
* NOTE: K values for LIN_ADVANCE 1.5 differ from earlier versions!
|
||||||
|
*
|
||||||
|
* Set K around 0.22 for 3mm PLA Direct Drive with ~6.5cm between the drive gear and heatbreak.
|
||||||
|
* Larger K values will be needed for flexible filament and greater distances.
|
||||||
|
* If this algorithm produces a higher speed offset than the extruder can handle (compared to E jerk)
|
||||||
|
* print acceleration will be reduced during the affected moves to keep within the limit.
|
||||||
|
*
|
||||||
|
* See http://marlinfw.org/docs/features/lin_advance.html for full instructions.
|
||||||
|
* Mention @Sebastianv650 on GitHub to alert the author of any issues.
|
||||||
|
*/
|
||||||
#define LIN_ADVANCE
|
#define LIN_ADVANCE
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
#define LIN_ADVANCE_K 0 //Try around 45 for PLA, around 25 for ABS.
|
#define LIN_ADVANCE_K 0 // Unit: mm compression per 1mm/s extruder speed
|
||||||
|
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
|
||||||
/**
|
|
||||||
* Some Slicers produce Gcode with randomly jumping extrusion widths occasionally.
|
|
||||||
* For example within a 0.4mm perimeter it may produce a single segment of 0.05mm width.
|
|
||||||
* While this is harmless for normal printing (the fluid nature of the filament will
|
|
||||||
* close this very, very tiny gap), it throws off the LIN_ADVANCE pressure adaption.
|
|
||||||
*
|
|
||||||
* For this case LIN_ADVANCE_E_D_RATIO can be used to set the extrusion:distance ratio
|
|
||||||
* to a fixed value. Note that using a fixed ratio will lead to wrong nozzle pressures
|
|
||||||
* if the slicer is using variable widths or layer heights within one print!
|
|
||||||
*
|
|
||||||
* This option sets the default E:D ratio at startup. Use `M900` to override this value.
|
|
||||||
*
|
|
||||||
* Example: `M900 W0.4 H0.2 D1.75`, where:
|
|
||||||
* - W is the extrusion width in mm
|
|
||||||
* - H is the layer height in mm
|
|
||||||
* - D is the filament diameter in mm
|
|
||||||
*
|
|
||||||
* Example: `M900 R0.0458` to set the ratio directly.
|
|
||||||
*
|
|
||||||
* Set to 0 to auto-detect the ratio based on given Gcode G1 print moves.
|
|
||||||
*
|
|
||||||
* Slic3r (including Prusa Slic3r) produces Gcode compatible with the automatic mode.
|
|
||||||
* Cura (as of this writing) may produce Gcode incompatible with the automatic mode.
|
|
||||||
*/
|
|
||||||
#define LIN_ADVANCE_E_D_RATIO 0 // The calculated ratio (or 0) according to the formula W * H / ((D / 2) ^ 2 * PI)
|
|
||||||
// Example: 0.4 * 0.2 / ((1.75 / 2) ^ 2 * PI) = 0.033260135
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Arc interpretation settings:
|
// Arc interpretation settings:
|
||||||
|
|
|
@ -2073,35 +2073,23 @@ static float probe_pt(float x, float y, float z_before) {
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
/**
|
/**
|
||||||
* M900: Set and/or Get advance K factor and WH/D ratio
|
* M900: Set and/or Get advance K factor
|
||||||
*
|
*
|
||||||
* K<factor> Set advance K factor
|
* K<factor> Set advance K factor
|
||||||
* R<ratio> Set ratio directly (overrides WH/D)
|
|
||||||
* W<width> H<height> D<diam> Set ratio from WH/D
|
|
||||||
*/
|
*/
|
||||||
inline void gcode_M900() {
|
inline void gcode_M900() {
|
||||||
st_synchronize();
|
st_synchronize();
|
||||||
|
|
||||||
const float newK = code_seen('K') ? code_value_float() : -1;
|
const float newK = code_seen('K') ? code_value_float() : -1;
|
||||||
if (newK >= 0) extruder_advance_k = newK;
|
if (newK >= 0 && newK < 10)
|
||||||
|
extruder_advance_K = newK;
|
||||||
float newR = code_seen('R') ? code_value_float() : -1;
|
else
|
||||||
if (newR < 0) {
|
SERIAL_ECHOLNPGM("K out of allowed range!");
|
||||||
const float newD = code_seen('D') ? code_value_float() : -1,
|
|
||||||
newW = code_seen('W') ? code_value_float() : -1,
|
|
||||||
newH = code_seen('H') ? code_value_float() : -1;
|
|
||||||
if (newD >= 0 && newW >= 0 && newH >= 0)
|
|
||||||
newR = newD ? (newW * newH) / (sq(newD * 0.5) * M_PI) : 0;
|
|
||||||
}
|
|
||||||
if (newR >= 0) advance_ed_ratio = newR;
|
|
||||||
|
|
||||||
SERIAL_ECHO_START;
|
SERIAL_ECHO_START;
|
||||||
SERIAL_ECHOPGM("Advance K=");
|
SERIAL_ECHOPGM("Advance K=");
|
||||||
SERIAL_ECHOLN(extruder_advance_k);
|
SERIAL_ECHOLN(extruder_advance_K);
|
||||||
SERIAL_ECHOPGM(" E/D=");
|
}
|
||||||
const float ratio = advance_ed_ratio;
|
|
||||||
if (ratio) SERIAL_ECHOLN(ratio); else SERIAL_ECHOLNPGM("Auto");
|
|
||||||
}
|
|
||||||
#endif // LIN_ADVANCE
|
#endif // LIN_ADVANCE
|
||||||
|
|
||||||
bool check_commands() {
|
bool check_commands() {
|
||||||
|
|
|
@ -126,8 +126,7 @@ float extrude_min_temp=EXTRUDE_MINTEMP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
float extruder_advance_k = LIN_ADVANCE_K,
|
float extruder_advance_K = LIN_ADVANCE_K,
|
||||||
advance_ed_ratio = LIN_ADVANCE_E_D_RATIO,
|
|
||||||
position_float[NUM_AXIS] = { 0 };
|
position_float[NUM_AXIS] = { 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -402,6 +401,13 @@ void planner_recalculate(const float &safe_final_speed)
|
||||||
if ((prev->flag | current->flag) & BLOCK_FLAG_RECALCULATE) {
|
if ((prev->flag | current->flag) & BLOCK_FLAG_RECALCULATE) {
|
||||||
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
||||||
calculate_trapezoid_for_block(prev, prev->entry_speed, current->entry_speed);
|
calculate_trapezoid_for_block(prev, prev->entry_speed, current->entry_speed);
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
if (current->use_advance_lead) {
|
||||||
|
const float comp = current->e_D_ratio * extruder_advance_K * axis_steps_per_unit[E_AXIS];
|
||||||
|
current->max_adv_steps = current->nominal_speed * comp;
|
||||||
|
current->final_adv_steps = next->entry_speed * comp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Reset current only to ensure next trapezoid is computed.
|
// Reset current only to ensure next trapezoid is computed.
|
||||||
prev->flag &= ~BLOCK_FLAG_RECALCULATE;
|
prev->flag &= ~BLOCK_FLAG_RECALCULATE;
|
||||||
}
|
}
|
||||||
|
@ -415,6 +421,13 @@ void planner_recalculate(const float &safe_final_speed)
|
||||||
// Last/newest block in buffer. Exit speed is set with safe_final_speed. Always recalculated.
|
// Last/newest block in buffer. Exit speed is set with safe_final_speed. Always recalculated.
|
||||||
current = block_buffer + prev_block_index(block_buffer_head);
|
current = block_buffer + prev_block_index(block_buffer_head);
|
||||||
calculate_trapezoid_for_block(current, current->entry_speed, safe_final_speed);
|
calculate_trapezoid_for_block(current, current->entry_speed, safe_final_speed);
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
if (current->use_advance_lead) {
|
||||||
|
const float comp = current->e_D_ratio * extruder_advance_K * axis_steps_per_unit[E_AXIS];
|
||||||
|
current->max_adv_steps = current->nominal_speed * comp;
|
||||||
|
current->final_adv_steps = safe_final_speed * comp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
current->flag &= ~BLOCK_FLAG_RECALCULATE;
|
current->flag &= ~BLOCK_FLAG_RECALCULATE;
|
||||||
|
|
||||||
// SERIAL_ECHOLNPGM("planner_recalculate - 4");
|
// SERIAL_ECHOLNPGM("planner_recalculate - 4");
|
||||||
|
@ -748,11 +761,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
|
||||||
#endif // ENABLE_MESH_BED_LEVELING
|
#endif // ENABLE_MESH_BED_LEVELING
|
||||||
target[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
|
target[E_AXIS] = lround(e*cs.axis_steps_per_unit[E_AXIS]);
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
|
||||||
const float mm_D_float = sqrt(sq(x - position_float[X_AXIS]) + sq(y - position_float[Y_AXIS]));
|
|
||||||
float de_float = e - position_float[E_AXIS];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PREVENT_DANGEROUS_EXTRUDE
|
#ifdef PREVENT_DANGEROUS_EXTRUDE
|
||||||
if(target[E_AXIS]!=position[E_AXIS])
|
if(target[E_AXIS]!=position[E_AXIS])
|
||||||
{
|
{
|
||||||
|
@ -761,7 +769,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
|
||||||
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
|
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
position_float[E_AXIS] = e;
|
position_float[E_AXIS] = e;
|
||||||
de_float = 0;
|
|
||||||
#endif
|
#endif
|
||||||
SERIAL_ECHO_START;
|
SERIAL_ECHO_START;
|
||||||
SERIAL_ECHOLNRPGM(_n(" cold extrusion prevented"));////MSG_ERR_COLD_EXTRUDE_STOP
|
SERIAL_ECHOLNRPGM(_n(" cold extrusion prevented"));////MSG_ERR_COLD_EXTRUDE_STOP
|
||||||
|
@ -773,7 +780,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
|
||||||
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
|
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
position_float[E_AXIS] = e;
|
position_float[E_AXIS] = e;
|
||||||
de_float = 0;
|
|
||||||
#endif
|
#endif
|
||||||
SERIAL_ECHO_START;
|
SERIAL_ECHO_START;
|
||||||
SERIAL_ECHOLNRPGM(_n(" too long extrusion prevented"));////MSG_ERR_LONG_EXTRUDE_STOP
|
SERIAL_ECHOLNRPGM(_n(" too long extrusion prevented"));////MSG_ERR_LONG_EXTRUDE_STOP
|
||||||
|
@ -1001,10 +1007,50 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||||
if(block->steps_x.wide == 0 && block->steps_y.wide == 0 && block->steps_z.wide == 0)
|
if(block->steps_x.wide == 0 && block->steps_y.wide == 0 && block->steps_z.wide == 0)
|
||||||
{
|
{
|
||||||
block->acceleration_st = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
|
block->acceleration_st = ceil(cs.retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
block->use_advance_lead = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
block->acceleration_st = ceil(cs.acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
|
block->acceleration_st = ceil(cs.acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
|
||||||
|
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Use LIN_ADVANCE for blocks if all these are true:
|
||||||
|
*
|
||||||
|
* block->steps_e : This is a print move, because we checked for X, Y, Z steps before.
|
||||||
|
*
|
||||||
|
* extruder_advance_K : There is an advance factor set.
|
||||||
|
*
|
||||||
|
* delta_mm[E_AXIS] > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
|
||||||
|
*/
|
||||||
|
block->use_advance_lead = block->steps_e
|
||||||
|
&& extruder_advance_K
|
||||||
|
&& delta_mm[E_AXIS] > 0;
|
||||||
|
|
||||||
|
if (block->use_advance_lead) {
|
||||||
|
block->e_D_ratio = (e - position_float[E_AXIS]) /
|
||||||
|
sqrt(sq(x - position_float[X_AXIS])
|
||||||
|
+ sq(y - position_float[Y_AXIS])
|
||||||
|
+ sq(z - position_float[Z_AXIS]));
|
||||||
|
|
||||||
|
// Check for unusual high e_D ratio to detect if a retract move was combined with the last print move due to min. steps per segment. Never execute this with advance!
|
||||||
|
// This assumes no one will use a retract length of 0mm < retr_length < ~0.2mm and no one will print 100mm wide lines using 3mm filament or 35mm wide lines using 1.75mm filament.
|
||||||
|
if (block->e_D_ratio > 3.0)
|
||||||
|
block->use_advance_lead = false;
|
||||||
|
else {
|
||||||
|
const uint32_t max_accel_steps_per_s2 = max_jerk[E_AXIS] / (extruder_advance_K * block->e_D_ratio) * steps_per_mm;
|
||||||
|
#ifdef LA_DEBUG
|
||||||
|
if (block->acceleration_st > max_accel_steps_per_s2)
|
||||||
|
SERIAL_ECHOLNPGM("Acceleration limited.");
|
||||||
|
#endif
|
||||||
|
NOMORE(block->acceleration_st, max_accel_steps_per_s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Limit acceleration per axis
|
// Limit acceleration per axis
|
||||||
//FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.
|
//FIXME Vojtech: One shall rather limit a projection of the acceleration vector instead of using the limit.
|
||||||
if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
|
if(((float)block->acceleration_st * (float)block->steps_x.wide / (float)block->step_event_count.wide) > axis_steps_per_sqr_second[X_AXIS])
|
||||||
|
@ -1037,6 +1083,18 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||||
|
|
||||||
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0)));
|
||||||
|
|
||||||
|
#ifdef LIN_ADVANCE
|
||||||
|
if (block->use_advance_lead) {
|
||||||
|
block->advance_speed = ((F_CPU) * 0.125) / (extruder_advance_K * block->e_D_ratio * block->acceleration * axis_steps_per_unit[E_AXIS]);
|
||||||
|
#ifdef LA_DEBUG
|
||||||
|
if (extruder_advance_K * block->e_D_ratio * block->acceleration * 2 < block->nominal_speed * block->e_D_ratio)
|
||||||
|
SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed.");
|
||||||
|
if (block->advance_speed < 200)
|
||||||
|
SERIAL_ECHOLNPGM("eISR running at > 10kHz.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Start with a safe speed.
|
// Start with a safe speed.
|
||||||
// Safe speed is the speed, from which the machine may halt to stop immediately.
|
// Safe speed is the speed, from which the machine may halt to stop immediately.
|
||||||
float safe_speed = block->nominal_speed;
|
float safe_speed = block->nominal_speed;
|
||||||
|
@ -1153,37 +1211,6 @@ Having the real displacement of the head, we can calculate the total movement le
|
||||||
previous_nominal_speed = block->nominal_speed;
|
previous_nominal_speed = block->nominal_speed;
|
||||||
previous_safe_speed = safe_speed;
|
previous_safe_speed = safe_speed;
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
|
||||||
|
|
||||||
//
|
|
||||||
// Use LIN_ADVANCE for blocks if all these are true:
|
|
||||||
//
|
|
||||||
// esteps : We have E steps todo (a printing move)
|
|
||||||
//
|
|
||||||
// block->steps[X_AXIS] || block->steps[Y_AXIS] : We have a movement in XY direction (i.e., not retract / prime).
|
|
||||||
//
|
|
||||||
// extruder_advance_k : There is an advance factor set.
|
|
||||||
//
|
|
||||||
// block->steps[E_AXIS] != block->step_event_count : A problem occurs if the move before a retract is too small.
|
|
||||||
// In that case, the retract and move will be executed together.
|
|
||||||
// This leads to too many advance steps due to a huge e_acceleration.
|
|
||||||
// The math is good, but we must avoid retract moves with advance!
|
|
||||||
// de_float > 0.0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves)
|
|
||||||
//
|
|
||||||
block->use_advance_lead = block->steps_e.wide
|
|
||||||
&& (block->steps_x.wide || block->steps_y.wide)
|
|
||||||
&& extruder_advance_k
|
|
||||||
&& (uint32_t)block->steps_e.wide != block->step_event_count.wide
|
|
||||||
&& de_float > 0.0;
|
|
||||||
if (block->use_advance_lead)
|
|
||||||
block->abs_adv_steps_multiplier8 = lround(
|
|
||||||
extruder_advance_k
|
|
||||||
* ((advance_ed_ratio < 0.000001) ? de_float / mm_D_float : advance_ed_ratio) // Use the fixed ratio, if set
|
|
||||||
* (block->nominal_speed / (float)block->nominal_rate)
|
|
||||||
* cs.axis_steps_per_unit[E_AXIS] * 256.0
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated.
|
// Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated.
|
||||||
block->speed_factor = block->nominal_rate / block->nominal_speed;
|
block->speed_factor = block->nominal_rate / block->nominal_speed;
|
||||||
calculate_trapezoid_for_block(block, block->entry_speed, safe_speed);
|
calculate_trapezoid_for_block(block, block->entry_speed, safe_speed);
|
||||||
|
|
|
@ -113,14 +113,17 @@ typedef struct {
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
bool use_advance_lead;
|
bool use_advance_lead;
|
||||||
unsigned long abs_adv_steps_multiplier8; // Factorised by 2^8 to avoid float
|
uint16_t advance_speed, // Timer value for extruder speed offset
|
||||||
|
max_adv_steps, // max. advance steps to get cruising speed pressure (not always nominal_speed!)
|
||||||
|
final_adv_steps; // advance steps due to exit speed
|
||||||
|
float e_D_ratio;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint16_t sdlen;
|
uint16_t sdlen;
|
||||||
} block_t;
|
} block_t;
|
||||||
|
|
||||||
#ifdef LIN_ADVANCE
|
#ifdef LIN_ADVANCE
|
||||||
extern float extruder_advance_k, advance_ed_ratio;
|
extern float extruder_advance_K;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_AUTO_BED_LEVELING
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue