Merge branch 'MK3' into auto_deplete_2

This commit is contained in:
Marek Bel 2019-01-07 21:39:46 +01:00
commit 2db42c8577
13 changed files with 441 additions and 83 deletions

View file

@ -130,6 +130,7 @@
#include "sound.h"
#include "cmdqueue.h"
#include "io_atmega2560.h"
// Macros for bit masks
#define BIT(b) (1<<(b))
@ -642,6 +643,8 @@ void failstats_reset_print()
eeprom_update_byte((uint8_t *)EEPROM_CRASH_COUNT_Y, 0);
eeprom_update_byte((uint8_t *)EEPROM_FERROR_COUNT, 0);
eeprom_update_byte((uint8_t *)EEPROM_POWER_COUNT, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
}
@ -688,6 +691,12 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
eeprom_update_word((uint16_t *)EEPROM_FERROR_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_POWER_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
lcd_menu_statistics();
break;
@ -714,6 +723,11 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
eeprom_update_word((uint16_t *)EEPROM_FERROR_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_POWER_COUNT_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
#ifdef FILAMENT_SENSOR
fsensor_enable();
fsensor_autoload_set(true);
@ -1388,6 +1402,12 @@ void setup()
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_X_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_CRASH_COUNT_Y_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) == 0xffff) eeprom_write_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_FAIL_TOT, 0);
if (eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) == 0xffff) eeprom_update_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_FAIL, 0);
if (eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) == 0xff) eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
#ifdef SNMM
if (eeprom_read_dword((uint32_t*)EEPROM_BOWDEN_LENGTH) == 0x0ffffffff) { //bowden length used for SNMM
int _z = BOWDEN_LENGTH;
@ -6893,16 +6913,20 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
if (mmu_enabled)
{
tmp_extruder = choose_menu_P(_T(MSG_CHOOSE_FILAMENT), _T(MSG_FILAMENT));
if ((tmp_extruder == mmu_extruder) && mmu_fil_loaded) {
printf_P(PSTR("Duplicit T-code ignored.\n"));
return; //dont execute the same T-code twice in a row
}
st_synchronize();
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true);
manage_response(true, true, MMU_TCODE_MOVE);
}
}
else if (*(strchr_pointer + index) == 'c') { //load to from bondtech gears to nozzle (nozzle should be preheated)
if (mmu_enabled)
{
st_synchronize();
mmu_command(MMU_CMD_C0);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
mmu_load_to_nozzle();
}
@ -6931,11 +6955,15 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
if (mmu_enabled)
{
if ((tmp_extruder == mmu_extruder) && mmu_fil_loaded) {
printf_P(PSTR("Duplicit T-code ignored.\n"));
return; //dont execute the same T-code twice in a row
}
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true);
mmu_command(MMU_CMD_C0);
mmu_extruder = tmp_extruder; //filament change is finished
manage_response(true, true, MMU_TCODE_MOVE);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
if (load_to_nozzle)// for single material usage with mmu
{

View file

@ -148,6 +148,12 @@
#define EEPROM_FSENS_OQ_MEASS_ENABLED (EEPROM_AUTO_DEPLETE - 1) //bool
#define EEPROM_MMU_FAIL_TOT (EEPROM_FSENS_OQ_MEASS_ENABLED - 2) //uint16_t
#define EEPROM_MMU_FAIL (EEPROM_MMU_FAIL_TOT - 1) //uint8_t
#define EEPROM_MMU_LOAD_FAIL_TOT (EEPROM_MMU_FAIL - 2) //uint16_t
#define EEPROM_MMU_LOAD_FAIL (EEPROM_MMU_LOAD_FAIL_TOT - 1) //uint8_t
// !!!!!
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
// !!!!!

View file

@ -13,6 +13,7 @@
#include "sound.h"
#include "printers.h"
#include <avr/pgmspace.h>
#include "io_atmega2560.h"
#include "AutoDeplete.h"
#ifdef TMC2130
@ -23,25 +24,31 @@
#define MMU_TODELAY 100
#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_MAX_RESEND_ATTEMPTS 2
#ifdef MMU_HWRESET
#define MMU_RST_PIN 76
#endif //MMU_HWRESET
bool mmu_enabled = false;
bool mmu_ready = false;
bool mmu_fil_loaded = false; //if true: blocks execution of duplicit T-codes
static int8_t mmu_state = 0;
uint8_t mmu_cmd = 0;
uint8_t mmu_extruder = 0;
//idler ir sensor
uint8_t mmu_idl_sens = 0;
bool mmu_idler_sensor_detected = false;
bool mmu_loading_flag = false;
uint8_t mmu_extruder = MMU_FILAMENT_UNKNOWN;
//! This variable probably has no meaning and is planed to be removed
uint8_t tmp_extruder = 0;
uint8_t tmp_extruder = MMU_FILAMENT_UNKNOWN;
int8_t mmu_finda = -1;
@ -53,6 +60,7 @@ uint32_t mmu_last_request = 0;
uint32_t mmu_last_response = 0;
uint8_t mmu_last_cmd = 0;
uint16_t mmu_power_failures = 0;
//clear rx buffer
@ -109,11 +117,31 @@ void mmu_init(void)
_delay_ms(10); //wait 10ms for sure
mmu_reset(); //reset mmu (HW or SW), do not wait for response
mmu_state = -1;
PIN_INP(MMU_IDLER_SENSOR_PIN); //input mode
PIN_SET(MMU_IDLER_SENSOR_PIN); //pullup
}
//returns true if idler IR sensor was detected, otherwise returns false
bool check_for_idler_sensor()
{
bool detected = false;
//if MMU_IDLER_SENSOR_PIN input is low and pat9125sensor is not present we detected idler sensor
if ((PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) && fsensor_not_responding)
{
detected = true;
//printf_P(PSTR("Idler IR sensor detected\n"));
}
else
{
//printf_P(PSTR("Idler IR sensor not detected\n"));
}
return detected;
}
//mmu main loop - state machine processing
void mmu_loop(void)
{
static uint8_t mmu_attempt_nr = 0;
int filament = 0;
// printf_P(PSTR("MMU loop, state=%d\n"), mmu_state);
switch (mmu_state)
@ -161,9 +189,9 @@ void mmu_loop(void)
if ((PRINTER_TYPE == PRINTER_MK3) || (PRINTER_TYPE == PRINTER_MK3_SNMM))
{
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = -4;
}
@ -181,9 +209,9 @@ void mmu_loop(void)
case -5:
if (mmu_rx_ok() > 0)
{
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = -4;
}
@ -192,11 +220,13 @@ void mmu_loop(void)
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
puts_P(PSTR("MMU - ENABLED"));
mmu_enabled = true;
//if we have filament loaded into the nozzle, we can decide if printer has idler sensor right now; otherwise we will will wait till start of T-code so it will be detected on beginning of second T-code
if(check_for_idler_sensor()) mmu_idler_sensor_detected = true;
mmu_state = 1;
}
return;
@ -211,6 +241,8 @@ void mmu_loop(void)
#endif //MMU_DEBUG
mmu_printf_P(PSTR("T%d\n"), filament);
mmu_state = 3; // wait for response
mmu_fil_loaded = true;
if(mmu_idler_sensor_detected) mmu_idl_sens = 1; //if idler sensor detected, use it for T-code
}
else if ((mmu_cmd >= MMU_CMD_L0) && (mmu_cmd <= MMU_CMD_L4))
{
@ -228,6 +260,7 @@ void mmu_loop(void)
#endif //MMU_DEBUG
mmu_puts_P(PSTR("C0\n")); //send 'continue loading'
mmu_state = 3;
if(mmu_idler_sensor_detected) mmu_idl_sens = 1; //if idler sensor detected use it for C0 code
}
else if (mmu_cmd == MMU_CMD_U0)
{
@ -235,6 +268,7 @@ void mmu_loop(void)
printf_P(PSTR("MMU <= 'U0'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("U0\n")); //send 'unload current filament'
mmu_fil_loaded = false;
mmu_state = 3;
}
else if ((mmu_cmd >= MMU_CMD_E0) && (mmu_cmd <= MMU_CMD_E4))
@ -244,6 +278,7 @@ void mmu_loop(void)
printf_P(PSTR("MMU <= 'E%d'\n"), filament);
#endif //MMU_DEBUG
mmu_printf_P(PSTR("E%d\n"), filament); //send eject filament
mmu_fil_loaded = false;
mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_R0)
@ -254,14 +289,23 @@ void mmu_loop(void)
mmu_puts_P(PSTR("R0\n")); //send recover after eject
mmu_state = 3; // wait for response
}
else if (mmu_cmd == MMU_CMD_S3)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'S3'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("S3\n")); //send power failures request
mmu_state = 4; // power failures response
}
mmu_last_cmd = mmu_cmd;
mmu_cmd = 0;
}
else if ((mmu_last_response + 300) < millis()) //request every 300ms
{
#ifdef MMU_DEBUG
if(check_for_idler_sensor()) mmu_idler_sensor_detected = true;
#if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
puts_P(PSTR("MMU <= 'P0'"));
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
mmu_puts_P(PSTR("P0\n")); //send 'read finda' request
mmu_state = 2;
}
@ -270,9 +314,9 @@ void mmu_loop(void)
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
#ifdef MMU_DEBUG
#if defined MMU_DEBUG && MMU_FINDA_DEBUG
printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
#endif //MMU_DEBUG
#endif //MMU_DEBUG && MMU_FINDA_DEBUG
//printf_P(PSTR("Eact: %d\n"), int(e_active()));
if (!mmu_finda && CHECK_FINDA && fsensor_enabled) {
fsensor_stop_and_save_print();
@ -297,10 +341,57 @@ void mmu_loop(void)
}
return;
case 3: //response to mmu commands
if (mmu_idler_sensor_detected) {
if (mmu_idl_sens)
{
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0 && mmu_loading_flag)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU <= 'A'\n"));
#endif //MMU_DEBUG
mmu_puts_P(PSTR("A\n")); //send 'abort' request
mmu_idl_sens = 0;
//printf_P(PSTR("MMU IDLER_SENSOR = 0 - ABORT\n"));
}
//else
//printf_P(PSTR("MMU IDLER_SENSOR = 1 - WAIT\n"));
}
}
if (mmu_rx_ok() > 0)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU => 'ok'\n"));
#endif //MMU_DEBUG
mmu_attempt_nr = 0;
mmu_last_cmd = 0;
mmu_ready = true;
mmu_state = 1;
}
else if ((mmu_last_request + MMU_CMD_TIMEOUT) < millis())
{ //resend request after timeout (5 min)
if (mmu_last_cmd)
{
if (mmu_attempt_nr++ < MMU_MAX_RESEND_ATTEMPTS) {
#ifdef MMU_DEBUG
printf_P(PSTR("MMU retry attempt nr. %d\n"), mmu_attempt_nr - 1);
#endif //MMU_DEBUG
mmu_cmd = mmu_last_cmd;
}
else {
mmu_cmd = 0;
mmu_last_cmd = 0; //check
mmu_attempt_nr = 0;
}
}
mmu_state = 1;
}
return;
case 4:
if (mmu_rx_ok() > 0)
{
fscanf_P(uart2io, PSTR("%d"), &mmu_power_failures); //scan power failures
#ifdef MMU_DEBUG
printf_P(PSTR("MMU => 'ok'\n"));
#endif //MMU_DEBUG
mmu_last_cmd = 0;
mmu_ready = true;
@ -308,17 +399,8 @@ void mmu_loop(void)
}
else if ((mmu_last_request + MMU_CMD_TIMEOUT) < millis())
{ //resend request after timeout (5 min)
if (mmu_last_cmd)
{
#ifdef MMU_DEBUG
printf_P(PSTR("MMU retry\n"));
#endif //MMU_DEBUG
mmu_cmd = mmu_last_cmd;
// mmu_last_cmd = 0; //resend just once
}
mmu_state = 1;
}
return;
}
}
@ -368,22 +450,85 @@ void mmu_command(uint8_t cmd)
mmu_ready = false;
}
bool mmu_get_response(void)
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();
}
bool mmu_get_response(uint8_t move)
{
// printf_P(PSTR("mmu_get_response - begin\n"));
mmu_loading_flag = false;
if (!mmu_idler_sensor_detected) move = MMU_NO_MOVE;
printf_P(PSTR("mmu_get_response - begin move:%d\n"), move);
KEEPALIVE_STATE(IN_PROCESS);
while (mmu_cmd != 0)
{
// mmu_loop();
delay_keep_alive(100);
}
while (!mmu_ready)
{
// mmu_loop();
if (mmu_state != 3)
if ((mmu_state != 3) && (mmu_last_cmd == 0))
break;
delay_keep_alive(100);
//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) {
case MMU_LOAD_MOVE:
mmu_loading_flag = true;
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;
case MMU_UNLOAD_MOVE:
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading
{
printf_P(PSTR("Unload 1\n"));
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
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();
}
else //filament was unloaded from idler, no additional movements needed
{
printf_P(PSTR("Unloading finished 1\n"));
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
move = MMU_NO_MOVE;
}
break;
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
{
printf_P(PSTR("Unload 2\n"));
current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001;
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();
}
else //delay to allow mmu unit to pull out filament from bondtech gears and then start with infinite loading
{
printf_P(PSTR("Unloading finished 2\n"));
disable_e0(); //turn off E-stepper to prevent overheating and alow filament pull-out if necessary
delay_keep_alive(MMU_LOAD_TIME_MS);
move = MMU_LOAD_MOVE;
}
break;
case MMU_NO_MOVE:
default:
delay_keep_alive(100);
break;
}
}
printf_P(PSTR("mmu_get_response() returning: %d\n"), mmu_ready);
bool ret = mmu_ready;
mmu_ready = false;
// printf_P(PSTR("mmu_get_response - end %d\n"), ret?1:0);
@ -410,7 +555,7 @@ bool mmu_get_response(void)
}
void manage_response(bool move_axes, bool turn_off_nozzle)
void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move)
{
bool response = false;
mmu_print_saved = false;
@ -420,11 +565,18 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
float x_position_bckp = current_position[X_AXIS];
float y_position_bckp = current_position[Y_AXIS];
uint8_t screen = 0; //used for showing multiscreen messages
while(!response)
{
response = mmu_get_response(); //wait for "ok" from mmu
response = mmu_get_response(move); //wait for "ok" from mmu
if (!response) { //no "ok" was received in reserved time frame, user will fix the issue on mmu unit
if (!mmu_print_saved) { //first occurence, we are saving current position, park print head in certain position and disable nozzle heater
uint8_t mmu_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL);
uint16_t mmu_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT);
if(mmu_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_FAIL, mmu_fail + 1);
if(mmu_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_FAIL_TOT, mmu_fail_tot + 1);
if (lcd_update_enabled) {
lcd_update_was_enabled = true;
lcd_update_enable(false);
@ -454,6 +606,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
//set nozzle target temperature to 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
@ -468,19 +621,21 @@ void manage_response(bool move_axes, bool turn_off_nozzle)
}
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
for (uint8_t i = 0; i < 50; i++) {
for (uint8_t i = 0; i < 5; i++) {
if (lcd_clicked()) {
setTargetHotend(hotend_temp_bckp, active_extruder);
/// mmu_cmd = mmu_last_cmd;
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) {
@ -537,7 +692,14 @@ void mmu_load_to_nozzle()
bool saved_e_relative_mode = axis_relative_modes[E_AXIS];
if (!saved_e_relative_mode) axis_relative_modes[E_AXIS] = true;
current_position[E_AXIS] += 7.2f;
if (mmu_idler_sensor_detected)
{
current_position[E_AXIS] += 3.0f;
}
else
{
current_position[E_AXIS] += 7.2f;
}
float feedrate = 562;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate / 60, active_extruder);
st_synchronize();
@ -617,9 +779,10 @@ void mmu_M600_load_filament(bool automatic)
// mmu_printf_P(PSTR("T%d\n"), tmp_extruder);
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(false, true);
mmu_command(MMU_CMD_C0);
manage_response(false, true, MMU_LOAD_MOVE);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
mmu_load_to_nozzle();
load_filament_final_feed();
st_synchronize();
@ -821,13 +984,14 @@ void extr_unload()
lcd_clear();
lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_UNLOADING_FILAMENT));
lcd_print(" ");
lcd_print(mmu_extruder + 1);
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) lcd_print(" ");
else lcd_print(mmu_extruder + 1);
filament_ramming();
mmu_command(MMU_CMD_U0);
// get response
manage_response(false, true);
manage_response(false, true, MMU_UNLOAD_MOVE);
lcd_update_enable(true);
#else //SNMM
@ -1123,8 +1287,8 @@ void lcd_mmu_load_to_nozzle(uint8_t filament_nr)
lcd_print(" ");
lcd_print(tmp_extruder + 1);
mmu_command(MMU_CMD_T0 + tmp_extruder);
manage_response(true, true);
mmu_command(MMU_CMD_C0);
manage_response(true, true, MMU_TCODE_MOVE);
mmu_continue_loading();
mmu_extruder = tmp_extruder; //filament change is finished
mmu_load_to_nozzle();
load_filament_final_feed();
@ -1160,7 +1324,7 @@ void mmu_eject_filament(uint8_t filament, bool recover)
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2500 / 60, active_extruder);
st_synchronize();
mmu_command(MMU_CMD_E0 + filament);
manage_response(false, false);
manage_response(false, false, MMU_UNLOAD_MOVE);
if (recover)
{
lcd_show_fullscreen_message_and_wait_P(_i("Please remove filament and then press the knob."));
@ -1180,3 +1344,46 @@ void mmu_eject_filament(uint8_t filament, bool recover)
puts_P(PSTR("Filament nr out of range!"));
}
}
void mmu_continue_loading()
{
if (mmu_idler_sensor_detected) {
for (uint8_t i = 0; i < MMU_IDLER_SENSOR_ATTEMPTS_NR; i++) {
if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) return;
#ifdef MMU_DEBUG
printf_P(PSTR("Additional load attempt nr. %d\n"), i);
#endif // MMU_DEBUG
mmu_command(MMU_CMD_C0);
manage_response(true, true, MMU_LOAD_MOVE);
}
if (PIN_GET(MMU_IDLER_SENSOR_PIN) != 0) {
uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL);
uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT);
if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1);
if(mmu_load_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, mmu_load_fail_tot + 1);
char cmd[3];
//pause print, show error message and then repeat last T-code
stop_and_save_print_to_ram(0, 0);
//lift z
current_position[Z_AXIS] += Z_PAUSE_LIFT;
if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 15, active_extruder);
st_synchronize();
//Move XY to side
current_position[X_AXIS] = X_PAUSE_POS;
current_position[Y_AXIS] = Y_PAUSE_POS;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder);
st_synchronize();
//set nozzle target temperature to 0
setAllTargetHotends(0);
lcd_setstatuspgm(_i("MMU load failed "));////MSG_RECOVERING_PRINT c=20 r=1
mmu_fil_loaded = false; //so we can retry same T-code again
}
}
else { //mmu_idler_sensor_detected == false
mmu_command(MMU_CMD_C0);
}
}

View file

@ -4,16 +4,30 @@
extern bool mmu_enabled;
extern bool mmu_fil_loaded;
extern uint8_t mmu_extruder;
extern uint8_t tmp_extruder;
extern int8_t mmu_finda;
extern bool mmu_idler_sensor_detected;
extern bool mmu_loading_flag;
extern int16_t mmu_version;
extern int16_t mmu_buildnr;
extern uint16_t mmu_power_failures;
#define MMU_FILAMENT_UNKNOWN 255
#define MMU_NO_MOVE 0
#define MMU_UNLOAD_MOVE 1
#define MMU_LOAD_MOVE 2
#define MMU_TCODE_MOVE 3
#define MMU_LOAD_FEEDRATE 19.02f //mm/s
#define MMU_LOAD_TIME_MS 2000 //should be fine tuned to load time for shortest allowed PTFE tubing and maximum loading speed
#define MMU_CMD_NONE 0
#define MMU_CMD_T0 0x10
@ -34,7 +48,7 @@ extern int16_t mmu_buildnr;
#define MMU_CMD_E3 0x53
#define MMU_CMD_E4 0x54
#define MMU_CMD_R0 0x60
#define MMU_CMD_S3 0x73
extern int mmu_puts_P(const char* str);
@ -42,6 +56,7 @@ extern int mmu_printf_P(const char* format, ...);
extern int8_t mmu_rx_ok(void);
extern bool check_for_idler_sensor();
extern void mmu_init(void);
@ -54,9 +69,9 @@ extern int8_t mmu_set_filament_type(uint8_t extruder, uint8_t filament);
extern void mmu_command(uint8_t cmd);
extern bool mmu_get_response(void);
extern bool mmu_get_response(uint8_t move = 0);
extern void manage_response(bool move_axes, bool turn_off_nozzle);
extern void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move = 0);
extern void mmu_load_to_nozzle();
@ -103,3 +118,4 @@ extern void mmu_eject_fil_1();
extern void mmu_eject_fil_2();
extern void mmu_eject_fil_3();
extern void mmu_eject_fil_4();
extern void mmu_continue_loading();

View file

@ -121,6 +121,7 @@
#define TACH_0 79 // !!! changed from 81 (EINY03)
#define TACH_1 80
#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
// Support for an 8 bit logic analyzer, for example the Saleae.
// Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

View file

@ -102,7 +102,7 @@
#define SDCARDDETECT 72
#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
// Support for an 8 bit logic analyzer, for example the Saleae.
// Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

View file

@ -102,7 +102,7 @@
#define SDCARDDETECT 15
#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
// Support for an 8 bit logic analyzer, for example the Saleae.
// Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

View file

@ -38,7 +38,7 @@
#include "mmu.h"
#include "static_assert.h"
#include "io_atmega2560.h"
extern bool fans_check_enabled;
@ -136,6 +136,11 @@ static void lcd_menu_extruder_info();
static void lcd_menu_xyz_y_min();
static void lcd_menu_xyz_skew();
static void lcd_menu_xyz_offset();
static void lcd_menu_fails_stats_mmu();
static void lcd_menu_fails_stats_mmu_print();
static void lcd_menu_fails_stats_mmu_total();
static void lcd_menu_show_sensors_state();
#if defined(TMC2130) || defined(FILAMENT_SENSOR)
static void lcd_menu_fails_stats();
#endif //TMC2130 or FILAMENT_SENSOR
@ -195,6 +200,9 @@ static void menu_action_sddirectory(const char* filename);
#define ENCODER_FEEDRATE_DEADZONE 10
#define STATE_NA 255
#define STATE_OFF 0
#define STATE_ON 1
/*
#define MENU_ITEM(type, label, args...) do { \
@ -537,10 +545,15 @@ void lcdui_print_percent_done(void)
void lcdui_print_extruder(void)
{
int chars = 0;
if (mmu_extruder == tmp_extruder)
chars = lcd_printf_P(_N(" F%u"), mmu_extruder+1);
if (mmu_extruder == tmp_extruder) {
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) chars = lcd_printf_P(_N(" F?"));
else chars = lcd_printf_P(_N(" F%u"), mmu_extruder + 1);
}
else
chars = lcd_printf_P(_N(" %u>%u"), mmu_extruder+1, tmp_extruder+1);
{
if (mmu_extruder == MMU_FILAMENT_UNKNOWN) chars = lcd_printf_P(_N(" ?>%u"), tmp_extruder + 1);
else chars = lcd_printf_P(_N(" %u>%u"), mmu_extruder + 1, tmp_extruder + 1);
}
lcd_space(5 - chars);
}
@ -1914,6 +1927,48 @@ static void lcd_menu_extruder_info()
menu_back_if_clicked();
}
static void lcd_menu_fails_stats_mmu()
{
MENU_BEGIN();
MENU_ITEM_BACK_P(_T(MSG_MAIN));
MENU_ITEM_SUBMENU_P(_i("Last print"), lcd_menu_fails_stats_mmu_print);
MENU_ITEM_SUBMENU_P(_i("Total"), lcd_menu_fails_stats_mmu_total);
MENU_END();
}
static void lcd_menu_fails_stats_mmu_print()
{
//01234567890123456789
//Last print failures
// MMU fails 000
// MMU load fails 000
//
//////////////////////
lcd_timeoutToStatus.stop(); //infinite timeout
uint8_t fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL);
uint16_t load_fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL);
// lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Power failures %-3d" ESC_H(1,2) "Filam. runouts %-3d" ESC_H(1,3) "Crash X %-3d Y %-3d"), power, filam, crashX, crashY);
lcd_printf_P(PSTR(ESC_H(0,0) "%S" ESC_H(1,1) "%S %-3d" ESC_H(1,2) "%S %-3d" ESC_H(1,3)), _i("Last print failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails);
menu_back_if_clicked_fb();
}
static void lcd_menu_fails_stats_mmu_total()
{
//01234567890123456789
//Last print failures
// MMU fails 000
// MMU load fails 000
//
//////////////////////
mmu_command(MMU_CMD_S3);
lcd_timeoutToStatus.stop(); //infinite timeout
uint8_t fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL_TOT);
uint16_t load_fails = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL_TOT);
// lcd_printf_P(PSTR(ESC_H(0,0) "Last print failures" ESC_H(1,1) "Power failures %-3d" ESC_H(1,2) "Filam. runouts %-3d" ESC_H(1,3) "Crash X %-3d Y %-3d"), power, filam, crashX, crashY);
lcd_printf_P(PSTR(ESC_H(0,0) "%S" ESC_H(1,1) "%S %-3d" ESC_H(1,2) "%S %-3d" ESC_H(1,3) "%S %-3d"), _i("Total failures"), _i("MMU fails"), fails, _i("MMU load fails"), load_fails, _i("MMU power fails"), mmu_power_failures);
menu_back_if_clicked_fb();
}
#if defined(TMC2130) && defined(FILAMENT_SENSOR)
static void lcd_menu_fails_stats_total()
{
@ -1950,6 +2005,7 @@ static void lcd_menu_fails_stats_print()
lcd_printf_P(PSTR(ESC_H(0,0) "%S" ESC_H(1,1) "%S %-3d" ESC_H(1,2) "%S %-3d" ESC_H(1,3) "%S X %-3d Y %-3d"), _i("Last print failures"), _i("Power failures"), power, _i("Filam. runouts"), filam, _i("Crash"), crashX, crashY);
menu_back_if_clicked_fb();
}
/**
* @brief Open fail statistics menu
*
@ -1965,6 +2021,7 @@ static void lcd_menu_fails_stats()
MENU_ITEM_SUBMENU_P(_i("Total"), lcd_menu_fails_stats_total);
MENU_END();
}
#elif defined(FILAMENT_SENSOR)
/**
* @brief Print last print and total filament run outs
@ -2180,16 +2237,17 @@ static void lcd_support_menu()
#ifndef MK1BP
MENU_ITEM_BACK_P(STR_SEPARATOR);
MENU_ITEM_SUBMENU_P(_i("XYZ cal. details"), lcd_menu_xyz_y_min);////MSG_XYZ_DETAILS c=19 r=1
MENU_ITEM_SUBMENU_P(_i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=18 r=1
MENU_ITEM_SUBMENU_P(_i("Show sensors"), lcd_menu_show_sensors_state);////MSG_INFO_SENSORS c=18 r=1
#ifdef TMC2130
MENU_ITEM_SUBMENU_P(_i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=18 r=1
#endif //TMC2130
MENU_ITEM_SUBMENU_P(_i("Temperatures"), lcd_menu_temperatures);////MSG_MENU_TEMPERATURES c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Temperatures"), lcd_menu_temperatures);////MSG_MENU_TEMPERATURES c=18 r=1
#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=15 r=1
MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=18 r=1
#endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
#ifdef DEBUG_BUILD
@ -3571,28 +3629,60 @@ void lcd_diag_show_end_stops()
lcd_return_to_status();
}
#ifdef TMC2130
static void lcd_show_pinda_state()
static void lcd_print_state(uint8_t state)
{
lcd_set_cursor(0, 0);
lcd_puts_P((PSTR("P.I.N.D.A. state")));
lcd_set_cursor(0, 2);
lcd_puts_P(READ(Z_MIN_PIN)?(PSTR("Z1 (LED off)")):(PSTR("Z0 (LED on) "))); // !!! both strings must have same length (due to dynamic refreshing)
switch (state) {
case STATE_ON:
lcd_puts_P(_i("On "));
break;
case STATE_OFF:
lcd_puts_P(_i("Off"));
break;
default:
lcd_puts_P(_i("N/A"));
break;
}
}
static void menu_show_pinda_state()
static void lcd_show_sensors_state()
{
lcd_timeoutToStatus.stop();
lcd_show_pinda_state();
if(LCD_CLICKED)
{
lcd_timeoutToStatus.start();
menu_back();
}
//0: N/A; 1: OFF; 2: ON
uint8_t chars = 0;
uint8_t pinda_state = STATE_NA;
uint8_t finda_state = STATE_NA;
uint8_t idler_state = STATE_NA;
pinda_state = READ(Z_MIN_PIN);
if (mmu_enabled) {
finda_state = mmu_finda;
}
if (mmu_idler_sensor_detected) {
idler_state = !PIN_GET(MMU_IDLER_SENSOR_PIN);
}
lcd_puts_at_P(0, 0, _i("Sensor state"));
lcd_puts_at_P(1, 1, _i("PINDA:"));
lcd_set_cursor(LCD_WIDTH - 4, 1);
lcd_print_state(pinda_state);
lcd_puts_at_P(1, 2, _i("FINDA:"));
lcd_set_cursor(LCD_WIDTH - 4, 2);
lcd_print_state(finda_state);
lcd_puts_at_P(1, 3, _i("IR:"));
lcd_set_cursor(LCD_WIDTH - 4, 3);
lcd_print_state(idler_state);
}
#endif // defined TMC2130
static void lcd_menu_show_sensors_state()
{
lcd_timeoutToStatus.stop();
lcd_show_sensors_state();
if(LCD_CLICKED)
{
lcd_timeoutToStatus.start();
menu_back();
}
}
void prusa_statistics(int _message, uint8_t _fil_nr) {
#ifdef DEBUG_DISABLE_PRUSA_STATISTICS
@ -4949,9 +5039,7 @@ static void lcd_calibration_menu()
MENU_ITEM_SUBMENU_P(_i("Bed level correct"), lcd_adjust_bed);////MSG_BED_CORRECTION_MENU c=0 r=0
MENU_ITEM_SUBMENU_P(_i("PID calibration"), pid_extruder);////MSG_PID_EXTRUDER c=17 r=1
#ifdef TMC2130
MENU_ITEM_SUBMENU_P(_i("Show pinda state"), menu_show_pinda_state);
#else
#ifndef TMC2130
MENU_ITEM_SUBMENU_P(_i("Show end stops"), menu_show_end_stops);////MSG_SHOW_END_STOPS c=17 r=1
#endif
#ifndef MK1BP
@ -5858,7 +5946,9 @@ static void lcd_main_menu()
#if defined(TMC2130) || defined(FILAMENT_SENSOR)
MENU_ITEM_SUBMENU_P(_i("Fail stats"), lcd_menu_fails_stats);
#endif
if (mmu_enabled) {
MENU_ITEM_SUBMENU_P(_i("Fail stats MMU"), lcd_menu_fails_stats_mmu);
}
MENU_ITEM_SUBMENU_P(_i("Support"), lcd_support_menu);////MSG_SUPPORT c=0 r=0
#ifdef LCD_TEST
MENU_ITEM_SUBMENU_P(_i("W25x20CL init"), lcd_test_menu);////MSG_SUPPORT c=0 r=0

View file

@ -432,4 +432,6 @@ THERMISTORS SETTINGS
//#define SUPPORT_VERBOSITY
#endif
#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
#endif //__CONFIGURATION_PRUSA_H

View file

@ -432,4 +432,6 @@ THERMISTORS SETTINGS
//#define SUPPORT_VERBOSITY
#endif
#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
#endif //__CONFIGURATION_PRUSA_H

View file

@ -487,4 +487,6 @@
#define MMU_REQUIRED_FW_BUILDNR 132
//#define MMU_DEBUG //print communication between MMU2 and printer on serial
#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
#endif //__CONFIGURATION_PRUSA_H

View file

@ -488,4 +488,6 @@
#define MMU_REQUIRED_FW_BUILDNR 132
//#define MMU_DEBUG //print communication between MMU2 and printer on serial
#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
#endif //__CONFIGURATION_PRUSA_H

View file

@ -613,6 +613,8 @@
#define MMU_REQUIRED_FW_BUILDNR 83
#define MMU_HWRESET
//#define MMU_DEBUG //print communication between MMU2 and printer on serial
#define MMU_DEBUG //print communication between MMU2 and printer on serial
#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
#endif //__CONFIGURATION_PRUSA_H