Rewritten FILAMENT_CHANGE_ENABLE feature

This commit is contained in:
Petr Zahradnik
2016-04-28 18:57:21 +02:00
committed by Scott Lahteine
parent 4a8e191cec
commit 43ff0ce35f
24 changed files with 745 additions and 250 deletions

View File

@ -294,6 +294,7 @@ static char command_queue[BUFSIZE][MAX_CMD_SIZE];
#endif
const float homing_feedrate[] = HOMING_FEEDRATE;
bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
int feedrate_multiplier = 100; //100->1 200->2
int saved_feedrate_multiplier;
@ -490,6 +491,10 @@ static uint8_t target_extruder;
static bool filament_ran_out = false;
#endif
#if ENABLED(FILAMENT_CHANGE_FEATURE)
FilamentChangeMenuResponse filament_change_menu_response;
#endif
static bool send_ok[BUFSIZE];
#if HAS_SERVOS
@ -1564,9 +1569,8 @@ inline void line_to_z(float zPosition) {
inline void line_to_destination(float mm_m) {
planner.buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], mm_m / 60, active_extruder);
}
inline void line_to_destination() {
line_to_destination(feedrate);
}
inline void line_to_destination() { line_to_destination(feedrate); }
/**
* sync_plan_position
* Set planner / stepper positions to the cartesian current_position.
@ -3123,7 +3127,7 @@ inline void gcode_G28() {
enum MeshLevelingState { MeshReport, MeshStart, MeshNext, MeshSet, MeshSetZOffset, MeshReset };
inline void _mbl_goto_xy(float x, float y) {
saved_feedrate = feedrate;
float old_feedrate = feedrate;
feedrate = homing_feedrate[X_AXIS];
current_position[Z_AXIS] = MESH_HOME_SEARCH_Z
@ -3144,7 +3148,7 @@ inline void gcode_G28() {
line_to_current_position();
#endif
feedrate = saved_feedrate;
feedrate = old_feedrate;
stepper.synchronize();
}
@ -6131,7 +6135,7 @@ inline void gcode_M503() {
#endif // HAS_BED_PROBE
#if ENABLED(FILAMENTCHANGEENABLE)
#if ENABLED(FILAMENT_CHANGE_FEATURE)
/**
* M600: Pause for filament change
@ -6153,129 +6157,160 @@ inline void gcode_M503() {
return;
}
float lastpos[NUM_AXIS];
#if ENABLED(DELTA)
float fr60 = feedrate / 60;
#endif
// Show initial message and wait for synchronize steppers
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_INIT);
stepper.synchronize();
for (int i = 0; i < NUM_AXIS; i++)
float lastpos[NUM_AXIS];
// Save current position of all axes
for (uint8_t i = 0; i < NUM_AXIS; i++)
lastpos[i] = destination[i] = current_position[i];
// Define runplan for move axes
#if ENABLED(DELTA)
#define RUNPLAN calculate_delta(destination); \
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], fr60, active_extruder);
#define RUNPLAN(RATE) calculate_delta(destination); \
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], RATE, active_extruder);
#else
#define RUNPLAN line_to_destination();
#define RUNPLAN(RATE) line_to_destination(RATE * 60);
#endif
//retract by E
KEEPALIVE_STATE(IN_HANDLER);
// Initial retract before move to filament change position
if (code_seen('E')) destination[E_AXIS] += code_value_axis_units(E_AXIS);
#ifdef FILAMENTCHANGE_FIRSTRETRACT
else destination[E_AXIS] += FILAMENTCHANGE_FIRSTRETRACT;
#if defined(FILAMENT_CHANGE_RETRACT_LENGTH) && FILAMENT_CHANGE_RETRACT_LENGTH > 0
else destination[E_AXIS] -= FILAMENT_CHANGE_RETRACT_LENGTH;
#endif
RUNPLAN;
RUNPLAN(FILAMENT_CHANGE_RETRACT_FEEDRATE);
//lift Z
if (code_seen('Z')) destination[Z_AXIS] += code_value_axis_units(Z_AXIS);
#ifdef FILAMENTCHANGE_ZADD
else destination[Z_AXIS] += FILAMENTCHANGE_ZADD;
#endif
// Lift Z axis
float z_lift = code_seen('Z') ? code_value_axis_units(Z_AXIS) :
#if defined(FILAMENT_CHANGE_Z_ADD) && FILAMENT_CHANGE_Z_ADD > 0
FILAMENT_CHANGE_Z_ADD
#else
0
#endif
;
RUNPLAN;
if (z_lift > 0) {
destination[Z_AXIS] += z_lift;
NOMORE(destination[Z_AXIS], Z_MAX_POS);
RUNPLAN(FILAMENT_CHANGE_Z_FEEDRATE);
}
//move xy
// Move XY axes to filament exchange position
if (code_seen('X')) destination[X_AXIS] = code_value_axis_units(X_AXIS);
#ifdef FILAMENTCHANGE_XPOS
else destination[X_AXIS] = FILAMENTCHANGE_XPOS;
#ifdef FILAMENT_CHANGE_X_POS
else destination[X_AXIS] = FILAMENT_CHANGE_X_POS;
#endif
if (code_seen('Y')) destination[Y_AXIS] = code_value_axis_units(Y_AXIS);
#ifdef FILAMENTCHANGE_YPOS
else destination[Y_AXIS] = FILAMENTCHANGE_YPOS;
#ifdef FILAMENT_CHANGE_Y_POS
else destination[Y_AXIS] = FILAMENT_CHANGE_Y_POS;
#endif
RUNPLAN;
RUNPLAN(FILAMENT_CHANGE_XY_FEEDRATE);
if (code_seen('L')) destination[E_AXIS] += code_value_axis_units(E_AXIS);
#ifdef FILAMENTCHANGE_FINALRETRACT
else destination[E_AXIS] += FILAMENTCHANGE_FINALRETRACT;
#endif
RUNPLAN;
//finish moves
stepper.synchronize();
//disable extruder steppers so filament can be removed
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_UNLOAD);
// Unload filament
if (code_seen('L')) destination[E_AXIS] += code_value_axis_units(E_AXIS);
#if defined(FILAMENT_CHANGE_UNLOAD_LENGTH) && FILAMENT_CHANGE_UNLOAD_LENGTH > 0
else destination[E_AXIS] -= FILAMENT_CHANGE_UNLOAD_LENGTH;
#endif
RUNPLAN(FILAMENT_CHANGE_UNLOAD_FEEDRATE);
// Synchronize steppers and then disable extruders steppers for manual filament changing
stepper.synchronize();
disable_e0();
disable_e1();
disable_e2();
disable_e3();
delay(100);
LCD_ALERTMESSAGEPGM(MSG_FILAMENTCHANGE);
#if DISABLED(AUTO_FILAMENT_CHANGE)
millis_t next_tick = 0;
#endif
KEEPALIVE_STATE(PAUSED_FOR_USER);
millis_t next_tick = 0;
// Wait for filament insert by user and press button
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_INSERT);
while (!lcd_clicked()) {
#if DISABLED(AUTO_FILAMENT_CHANGE)
#if HAS_BUZZER
millis_t ms = millis();
if (ELAPSED(ms, next_tick)) {
lcd_quick_feedback();
next_tick = ms + 2500UL; // feedback every 2.5s while waiting
if (ms >= next_tick) {
buzzer.tone(300, 2000);
next_tick = ms + 2500; // Beep every 2.5s while waiting
}
idle(true);
#else
current_position[E_AXIS] += AUTO_FILAMENT_CHANGE_LENGTH;
destination[E_AXIS] = current_position[E_AXIS];
line_to_destination(AUTO_FILAMENT_CHANGE_FEEDRATE);
stepper.synchronize();
#endif
} // while(!lcd_clicked)
KEEPALIVE_STATE(IN_HANDLER);
lcd_quick_feedback(); // click sound feedback
idle(true);
}
delay(100);
while (lcd_clicked()) idle(true);
delay(100);
#if ENABLED(AUTO_FILAMENT_CHANGE)
current_position[E_AXIS] = 0;
stepper.synchronize();
#endif
// Show load message
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_LOAD);
//return to normal
// Load filament
if (code_seen('L')) destination[E_AXIS] -= code_value_axis_units(E_AXIS);
#ifdef FILAMENTCHANGE_FINALRETRACT
else destination[E_AXIS] -= FILAMENTCHANGE_FINALRETRACT;
#if defined(FILAMENT_CHANGE_LOAD_LENGTH) && FILAMENT_CHANGE_LOAD_LENGTH > 0
else destination[E_AXIS] += FILAMENT_CHANGE_LOAD_LENGTH;
#endif
current_position[E_AXIS] = destination[E_AXIS]; //the long retract of L is compensated by manual filament feeding
sync_plan_position_e();
RUNPLAN(FILAMENT_CHANGE_LOAD_FEEDRATE);
stepper.synchronize();
RUNPLAN; //should do nothing
#if defined(FILAMENT_CHANGE_EXTRUDE_LENGTH) && FILAMENT_CHANGE_EXTRUDE_LENGTH > 0
do {
// Extrude filament to get into hotend
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_EXTRUDE);
destination[E_AXIS] += FILAMENT_CHANGE_EXTRUDE_LENGTH;
RUNPLAN(FILAMENT_CHANGE_EXTRUDE_FEEDRATE);
stepper.synchronize();
// Ask user if more filament should be extruded
KEEPALIVE_STATE(PAUSED_FOR_USER);
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_OPTION);
while (filament_change_menu_response == FILAMENT_CHANGE_RESPONSE_WAIT_FOR) idle(true);
KEEPALIVE_STATE(IN_HANDLER);
} while (filament_change_menu_response != FILAMENT_CHANGE_RESPONSE_RESUME_PRINT);
#endif
lcd_reset_alert_level();
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_RESUME);
KEEPALIVE_STATE(IN_HANDLER);
// Set extruder to saved position
current_position[E_AXIS] = lastpos[E_AXIS];
destination[E_AXIS] = lastpos[E_AXIS];
planner.set_e_position_mm(current_position[E_AXIS]);
#if ENABLED(DELTA)
// Move XYZ to starting position, then E
calculate_delta(lastpos);
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], fr60, active_extruder);
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], lastpos[E_AXIS], fr60, active_extruder);
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], FILAMENT_CHANGE_XY_FEEDRATE, active_extruder);
planner.buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], lastpos[E_AXIS], FILAMENT_CHANGE_XY_FEEDRATE, active_extruder);
#else
// Move XY to starting position, then Z, then E
destination[X_AXIS] = lastpos[X_AXIS];
destination[Y_AXIS] = lastpos[Y_AXIS];
line_to_destination();
RUNPLAN(FILAMENT_CHANGE_XY_FEEDRATE);
destination[Z_AXIS] = lastpos[Z_AXIS];
line_to_destination();
destination[E_AXIS] = lastpos[E_AXIS];
line_to_destination();
RUNPLAN(FILAMENT_CHANGE_Z_FEEDRATE);
#endif
stepper.synchronize();
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
filament_ran_out = false;
#endif
// Show status screen
lcd_filament_change_show_message(FILAMENT_CHANGE_MESSAGE_STATUS);
}
#endif // FILAMENTCHANGEENABLE
#endif // FILAMENT_CHANGE_FEATURE
#if ENABLED(DUAL_X_CARRIAGE)
@ -6464,11 +6499,11 @@ inline void gcode_T(uint8_t tmp_extruder) {
#if HOTENDS > 1
float stored_feedrate = feedrate;
float old_feedrate = feedrate;
if (code_seen('F')) {
float next_feedrate = code_value_axis_units(X_AXIS);
if (next_feedrate > 0.0) stored_feedrate = feedrate = next_feedrate;
if (next_feedrate > 0.0) old_feedrate = feedrate = next_feedrate;
}
else
feedrate = XY_PROBE_FEEDRATE;
@ -6624,7 +6659,7 @@ inline void gcode_T(uint8_t tmp_extruder) {
enable_solenoid_on_active_extruder();
#endif // EXT_SOLENOID
feedrate = stored_feedrate;
feedrate = old_feedrate;
#else // !HOTENDS > 1
@ -7232,11 +7267,11 @@ void process_next_command() {
break;
#endif // HAS_BED_PROBE
#if ENABLED(FILAMENTCHANGEENABLE)
#if ENABLED(FILAMENT_CHANGE_FEATURE)
case 600: //Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
gcode_M600();
break;
#endif // FILAMENTCHANGEENABLE
#endif // FILAMENT_CHANGE_FEATURE
#if ENABLED(DUAL_X_CARRIAGE)
case 605:
@ -7993,14 +8028,14 @@ void disable_all_steppers() {
* Standard idle routine keeps the machine alive
*/
void idle(
#if ENABLED(FILAMENTCHANGEENABLE)
#if ENABLED(FILAMENT_CHANGE_FEATURE)
bool no_stepper_sleep/*=false*/
#endif
) {
lcd_update();
host_keepalive();
manage_inactivity(
#if ENABLED(FILAMENTCHANGEENABLE)
#if ENABLED(FILAMENT_CHANGE_FEATURE)
no_stepper_sleep
#endif
);