|
@@ -23,8 +23,9 @@
|
|
|
|
|
|
#define MMU_TODELAY 100
|
|
#define MMU_TODELAY 100
|
|
#define MMU_TIMEOUT 10
|
|
#define MMU_TIMEOUT 10
|
|
-#define MMU_CMD_TIMEOUT 300000ul //5min timeout for mmu commands (except P0)
|
|
|
|
|
|
+#define MMU_CMD_TIMEOUT 45000ul //5min timeout for mmu commands (except P0)
|
|
#define MMU_P0_TIMEOUT 3000ul //timeout for P0 command: 3seconds
|
|
#define MMU_P0_TIMEOUT 3000ul //timeout for P0 command: 3seconds
|
|
|
|
+#define MMU_MAX_RESEND_ATTEMPTS 2
|
|
|
|
|
|
#ifdef MMU_HWRESET
|
|
#ifdef MMU_HWRESET
|
|
#define MMU_RST_PIN 76
|
|
#define MMU_RST_PIN 76
|
|
@@ -139,6 +140,7 @@ bool check_for_idler_sensor()
|
|
//mmu main loop - state machine processing
|
|
//mmu main loop - state machine processing
|
|
void mmu_loop(void)
|
|
void mmu_loop(void)
|
|
{
|
|
{
|
|
|
|
+ static uint8_t mmu_attempt_nr = 0;
|
|
int filament = 0;
|
|
int filament = 0;
|
|
// printf_P(PSTR("MMU loop, state=%d\n"), mmu_state);
|
|
// printf_P(PSTR("MMU loop, state=%d\n"), mmu_state);
|
|
switch (mmu_state)
|
|
switch (mmu_state)
|
|
@@ -352,6 +354,7 @@ void mmu_loop(void)
|
|
#ifdef MMU_DEBUG
|
|
#ifdef MMU_DEBUG
|
|
printf_P(PSTR("MMU => 'ok'\n"));
|
|
printf_P(PSTR("MMU => 'ok'\n"));
|
|
#endif //MMU_DEBUG
|
|
#endif //MMU_DEBUG
|
|
|
|
+ mmu_attempt_nr = 0;
|
|
mmu_last_cmd = 0;
|
|
mmu_last_cmd = 0;
|
|
mmu_ready = true;
|
|
mmu_ready = true;
|
|
mmu_state = 1;
|
|
mmu_state = 1;
|
|
@@ -360,11 +363,17 @@ void mmu_loop(void)
|
|
{ //resend request after timeout (5 min)
|
|
{ //resend request after timeout (5 min)
|
|
if (mmu_last_cmd)
|
|
if (mmu_last_cmd)
|
|
{
|
|
{
|
|
|
|
+ if (mmu_attempt_nr++ < MMU_MAX_RESEND_ATTEMPTS) {
|
|
#ifdef MMU_DEBUG
|
|
#ifdef MMU_DEBUG
|
|
- printf_P(PSTR("MMU retry\n"));
|
|
|
|
|
|
+ printf_P(PSTR("MMU retry attempt nr. %d\n"), mmu_attempt_nr - 1);
|
|
#endif //MMU_DEBUG
|
|
#endif //MMU_DEBUG
|
|
- mmu_cmd = mmu_last_cmd;
|
|
|
|
-// mmu_last_cmd = 0; //resend just once
|
|
|
|
|
|
+ mmu_cmd = mmu_last_cmd;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ mmu_cmd = 0;
|
|
|
|
+ mmu_last_cmd = 0; //check
|
|
|
|
+ mmu_attempt_nr = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
mmu_state = 1;
|
|
mmu_state = 1;
|
|
}
|
|
}
|
|
@@ -372,7 +381,7 @@ void mmu_loop(void)
|
|
case 4:
|
|
case 4:
|
|
if (mmu_rx_ok() > 0)
|
|
if (mmu_rx_ok() > 0)
|
|
{
|
|
{
|
|
- fscanf_P(uart2io, PSTR("%d"), &mmu_power_failures); //scan finda from buffer
|
|
|
|
|
|
+ fscanf_P(uart2io, PSTR("%d"), &mmu_power_failures); //scan power failures
|
|
#ifdef MMU_DEBUG
|
|
#ifdef MMU_DEBUG
|
|
printf_P(PSTR("MMU => 'ok'\n"));
|
|
printf_P(PSTR("MMU => 'ok'\n"));
|
|
#endif //MMU_DEBUG
|
|
#endif //MMU_DEBUG
|
|
@@ -424,10 +433,11 @@ void mmu_command(uint8_t cmd)
|
|
}
|
|
}
|
|
|
|
|
|
void mmu_load_step() {
|
|
void mmu_load_step() {
|
|
- current_position[E_AXIS] = current_position[E_AXIS] + MMU_LOAD_FEEDRATE * 0.1;
|
|
|
|
- plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ current_position[E_AXIS] = current_position[E_AXIS] + MMU_LOAD_FEEDRATE * 0.1;
|
|
|
|
+ plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], MMU_LOAD_FEEDRATE, active_extruder);
|
|
|
|
+ st_synchronize();
|
|
}
|
|
}
|
|
|
|
+
|
|
bool mmu_get_response(uint8_t move)
|
|
bool mmu_get_response(uint8_t move)
|
|
{
|
|
{
|
|
mmu_loading_flag = false;
|
|
mmu_loading_flag = false;
|
|
@@ -445,13 +455,23 @@ bool mmu_get_response(uint8_t move)
|
|
{
|
|
{
|
|
// mmu_loop();
|
|
// mmu_loop();
|
|
|
|
|
|
- if (mmu_state != 3)
|
|
|
|
|
|
+ if ((mmu_state != 3) && (mmu_last_cmd == 0))
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+ //Do load steps only if temperature is higher then min. temp for safe extrusion.
|
|
|
|
+ //Otherwise "cold extrusion prevented" would be send to serial line periodically
|
|
|
|
+ if (degHotend(active_extruder) < EXTRUDE_MINTEMP) {
|
|
|
|
+ disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
|
|
|
+ delay_keep_alive(100);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
switch (move) {
|
|
switch (move) {
|
|
case MMU_LOAD_MOVE:
|
|
case MMU_LOAD_MOVE:
|
|
mmu_loading_flag = true;
|
|
mmu_loading_flag = true;
|
|
mmu_load_step();
|
|
mmu_load_step();
|
|
|
|
+ //don't rely on "ok" signal from mmu unit; if filament detected by idler sensor during loading stop loading movements to prevent infinite loading
|
|
|
|
+ if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
|
|
break;
|
|
break;
|
|
case MMU_UNLOAD_MOVE:
|
|
case MMU_UNLOAD_MOVE:
|
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
|
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
|
|
@@ -467,7 +487,6 @@ bool mmu_get_response(uint8_t move)
|
|
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
|
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
|
move = MMU_NO_MOVE;
|
|
move = MMU_NO_MOVE;
|
|
}
|
|
}
|
|
-
|
|
|
|
break;
|
|
break;
|
|
case MMU_TCODE_MOVE: //first do unload and then continue with infinite loading movements
|
|
case MMU_TCODE_MOVE: //first do unload and then continue with infinite loading movements
|
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first
|
|
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first
|
|
@@ -491,6 +510,7 @@ bool mmu_get_response(uint8_t move)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ printf_P(PSTR("mmu_get_response() returning: %d\n"), mmu_ready);
|
|
bool ret = mmu_ready;
|
|
bool ret = mmu_ready;
|
|
mmu_ready = false;
|
|
mmu_ready = false;
|
|
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
|
|
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
|
|
@@ -527,6 +547,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
|
float x_position_bckp = current_position[X_AXIS];
|
|
float x_position_bckp = current_position[X_AXIS];
|
|
float y_position_bckp = current_position[Y_AXIS];
|
|
float y_position_bckp = current_position[Y_AXIS];
|
|
uint8_t screen = 0; //used for showing multiscreen messages
|
|
uint8_t screen = 0; //used for showing multiscreen messages
|
|
|
|
+
|
|
while(!response)
|
|
while(!response)
|
|
{
|
|
{
|
|
response = mmu_get_response(move); //wait for "ok" from mmu
|
|
response = mmu_get_response(move); //wait for "ok" from mmu
|
|
@@ -563,6 +584,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
|
//set nozzle target temperature to 0
|
|
//set nozzle target temperature to 0
|
|
setAllTargetHotends(0);
|
|
setAllTargetHotends(0);
|
|
}
|
|
}
|
|
|
|
+ disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
|
|
}
|
|
}
|
|
|
|
|
|
//first three lines are used for printing multiscreen message; last line contains measured and target nozzle temperature
|
|
//first three lines are used for printing multiscreen message; last line contains measured and target nozzle temperature
|
|
@@ -577,19 +599,21 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
|
|
}
|
|
}
|
|
|
|
|
|
lcd_set_degree();
|
|
lcd_set_degree();
|
|
- lcd_set_cursor(0, 4); //line 4
|
|
|
|
- //Print the hotend temperature (9 chars total) and fill rest of the line with space
|
|
|
|
- int chars = lcd_printf_P(_N("%c%3d/%d%c"), LCD_STR_THERMOMETER[0],(int)(degHotend(active_extruder) + 0.5), (int)(degTargetHotend(active_extruder) + 0.5), LCD_STR_DEGREE[0]);
|
|
|
|
- lcd_space(9 - chars);
|
|
|
|
|
|
|
|
|
|
|
|
//5 seconds delay
|
|
//5 seconds delay
|
|
- for (uint8_t i = 0; i < 50; i++) {
|
|
|
|
|
|
+ for (uint8_t i = 0; i < 5; i++) {
|
|
if (lcd_clicked()) {
|
|
if (lcd_clicked()) {
|
|
setTargetHotend(hotend_temp_bckp, active_extruder);
|
|
setTargetHotend(hotend_temp_bckp, active_extruder);
|
|
|
|
+ /// mmu_cmd = mmu_last_cmd;
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
- delay_keep_alive(100);
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Print the hotend temperature (9 chars total) and fill rest of the line with space
|
|
|
|
+ lcd_set_cursor(0, 4); //line 4
|
|
|
|
+ int chars = lcd_printf_P(_N("%c%3d/%d%c"), LCD_STR_THERMOMETER[0],(int)(degHotend(active_extruder) + 0.5), (int)(degTargetHotend(active_extruder) + 0.5), LCD_STR_DEGREE[0]);
|
|
|
|
+ lcd_space(9 - chars);
|
|
|
|
+ delay_keep_alive(1000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (mmu_print_saved) {
|
|
else if (mmu_print_saved) {
|
|
@@ -1332,6 +1356,7 @@ void mmu_continue_loading()
|
|
//set nozzle target temperature to 0
|
|
//set nozzle target temperature to 0
|
|
setAllTargetHotends(0);
|
|
setAllTargetHotends(0);
|
|
lcd_show_fullscreen_message_and_wait_P(_i("MMU load failed, fix the issue and press the knob."));
|
|
lcd_show_fullscreen_message_and_wait_P(_i("MMU load failed, fix the issue and press the knob."));
|
|
|
|
+
|
|
mmu_fil_loaded = false; //so we can retry same T-code again
|
|
mmu_fil_loaded = false; //so we can retry same T-code again
|
|
restore_print_from_ram_and_continue(0);
|
|
restore_print_from_ram_and_continue(0);
|
|
}
|
|
}
|