|
@@ -72,6 +72,7 @@
|
|
#include "planner.h"
|
|
#include "planner.h"
|
|
#include "stepper.h"
|
|
#include "stepper.h"
|
|
#include "temperature.h"
|
|
#include "temperature.h"
|
|
|
|
+#include "fancheck.h"
|
|
#include "motion_control.h"
|
|
#include "motion_control.h"
|
|
#include "cardreader.h"
|
|
#include "cardreader.h"
|
|
#include "ConfigurationStore.h"
|
|
#include "ConfigurationStore.h"
|
|
@@ -80,12 +81,14 @@
|
|
#include "math.h"
|
|
#include "math.h"
|
|
#include "util.h"
|
|
#include "util.h"
|
|
#include "Timer.h"
|
|
#include "Timer.h"
|
|
|
|
+#include "Prusa_farm.h"
|
|
|
|
|
|
#include <avr/wdt.h>
|
|
#include <avr/wdt.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <avr/pgmspace.h>
|
|
|
|
|
|
|
|
+#include "Tcodes.h"
|
|
#include "Dcodes.h"
|
|
#include "Dcodes.h"
|
|
-#include "AutoDeplete.h"
|
|
|
|
|
|
+#include "SpoolJoin.h"
|
|
|
|
|
|
#ifndef LA_NOCOMPAT
|
|
#ifndef LA_NOCOMPAT
|
|
#include "la10compat.h"
|
|
#include "la10compat.h"
|
|
@@ -93,12 +96,7 @@
|
|
|
|
|
|
#include "spi.h"
|
|
#include "spi.h"
|
|
|
|
|
|
-#ifdef FILAMENT_SENSOR
|
|
|
|
-#include "fsensor.h"
|
|
|
|
-#ifdef IR_SENSOR
|
|
|
|
-#include "pat9125.h" // for pat9125_probe
|
|
|
|
-#endif
|
|
|
|
-#endif //FILAMENT_SENSOR
|
|
|
|
|
|
+#include "Filament_sensor.h"
|
|
|
|
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
#include "tmc2130.h"
|
|
#include "tmc2130.h"
|
|
@@ -128,7 +126,7 @@
|
|
#include <SPI.h>
|
|
#include <SPI.h>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#include "mmu.h"
|
|
|
|
|
|
+#include "mmu2.h"
|
|
|
|
|
|
#define VERSION_STRING "1.0.2"
|
|
#define VERSION_STRING "1.0.2"
|
|
|
|
|
|
@@ -160,8 +158,6 @@
|
|
CardReader card;
|
|
CardReader card;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-unsigned long PingTime = _millis();
|
|
|
|
-
|
|
|
|
uint8_t mbl_z_probe_nr = 3; //numer of Z measurements for each point in mesh bed leveling calibration
|
|
uint8_t mbl_z_probe_nr = 3; //numer of Z measurements for each point in mesh bed leveling calibration
|
|
|
|
|
|
//used for PINDA temp calibration and pause print
|
|
//used for PINDA temp calibration and pause print
|
|
@@ -193,8 +189,6 @@ int extruder_multiply[EXTRUDERS] = {100
|
|
|
|
|
|
bool homing_flag = false;
|
|
bool homing_flag = false;
|
|
|
|
|
|
-int8_t lcd_change_fil_state = 0;
|
|
|
|
-
|
|
|
|
unsigned long pause_time = 0;
|
|
unsigned long pause_time = 0;
|
|
unsigned long start_pause_print = _millis();
|
|
unsigned long start_pause_print = _millis();
|
|
unsigned long t_fan_rising_edge = _millis();
|
|
unsigned long t_fan_rising_edge = _millis();
|
|
@@ -205,12 +199,6 @@ static LongTimer crashDetTimer;
|
|
|
|
|
|
bool mesh_bed_leveling_flag = false;
|
|
bool mesh_bed_leveling_flag = false;
|
|
|
|
|
|
-#ifdef PRUSA_M28
|
|
|
|
-bool prusa_sd_card_upload = false;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-uint8_t status_number = 0;
|
|
|
|
-
|
|
|
|
unsigned long total_filament_used;
|
|
unsigned long total_filament_used;
|
|
HeatingStatus heating_status;
|
|
HeatingStatus heating_status;
|
|
uint8_t heating_status_counter;
|
|
uint8_t heating_status_counter;
|
|
@@ -254,7 +242,6 @@ float extruder_offset[NUM_EXTRUDER_OFFSETS][EXTRUDERS] = {
|
|
};
|
|
};
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-uint8_t active_extruder = 0;
|
|
|
|
int fanSpeed=0;
|
|
int fanSpeed=0;
|
|
uint8_t newFanSpeed = 0;
|
|
uint8_t newFanSpeed = 0;
|
|
|
|
|
|
@@ -296,20 +283,14 @@ const char errormagic[] PROGMEM = "Error:";
|
|
const char echomagic[] PROGMEM = "echo:";
|
|
const char echomagic[] PROGMEM = "echo:";
|
|
const char G28W0[] PROGMEM = "G28 W0";
|
|
const char G28W0[] PROGMEM = "G28 W0";
|
|
|
|
|
|
-bool no_response = false;
|
|
|
|
-uint8_t important_status;
|
|
|
|
-uint8_t saved_filament_type;
|
|
|
|
-
|
|
|
|
// Define some coordinates outside the clamp limits (making them invalid past the parsing stage) so
|
|
// Define some coordinates outside the clamp limits (making them invalid past the parsing stage) so
|
|
// that they can be used later for various logical checks
|
|
// that they can be used later for various logical checks
|
|
#define X_COORD_INVALID (X_MIN_POS-1)
|
|
#define X_COORD_INVALID (X_MIN_POS-1)
|
|
-#define Y_COORD_INVALID (Y_MIN_POS-1)
|
|
|
|
|
|
|
|
-#define SAVED_TARGET_UNSET X_COORD_INVALID
|
|
|
|
-float saved_target[NUM_AXIS] = {SAVED_TARGET_UNSET, 0, 0, 0};
|
|
|
|
|
|
+#define SAVED_START_POSITION_UNSET X_COORD_INVALID
|
|
|
|
+float saved_start_position[NUM_AXIS] = {SAVED_START_POSITION_UNSET, 0, 0, 0};
|
|
|
|
|
|
-// save/restore printing in case that mmu was not responding
|
|
|
|
-bool mmu_print_saved = false;
|
|
|
|
|
|
+uint16_t saved_segment_idx = 0;
|
|
|
|
|
|
// storing estimated time to end of print counted by slicer
|
|
// storing estimated time to end of print counted by slicer
|
|
uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT;
|
|
uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT;
|
|
@@ -378,10 +359,10 @@ uint8_t saved_printing_type = PRINTING_TYPE_SD;
|
|
static float saved_pos[4] = { X_COORD_INVALID, 0, 0, 0 };
|
|
static float saved_pos[4] = { X_COORD_INVALID, 0, 0, 0 };
|
|
static uint16_t saved_feedrate2 = 0; //!< Default feedrate (truncated from float)
|
|
static uint16_t saved_feedrate2 = 0; //!< Default feedrate (truncated from float)
|
|
static int saved_feedmultiply2 = 0;
|
|
static int saved_feedmultiply2 = 0;
|
|
-static uint8_t saved_active_extruder = 0;
|
|
|
|
-static float saved_extruder_temperature = 0.0; //!< Active extruder temperature
|
|
|
|
|
|
+float saved_extruder_temperature = 0.0; //!< Active extruder temperature
|
|
|
|
+float saved_bed_temperature = 0.0;
|
|
static bool saved_extruder_relative_mode = false;
|
|
static bool saved_extruder_relative_mode = false;
|
|
-static int saved_fanSpeed = 0; //!< Print fan speed
|
|
|
|
|
|
+int saved_fan_speed = 0; //!< Print fan speed
|
|
//! @}
|
|
//! @}
|
|
|
|
|
|
static int saved_feedmultiply_mm = 100;
|
|
static int saved_feedmultiply_mm = 100;
|
|
@@ -443,7 +424,6 @@ AutoReportFeatures autoReportFeatures;
|
|
//=============================Routines======================================
|
|
//=============================Routines======================================
|
|
//===========================================================================
|
|
//===========================================================================
|
|
|
|
|
|
-static void get_arc_coordinates();
|
|
|
|
static bool setTargetedHotend(int code, uint8_t &extruder);
|
|
static bool setTargetedHotend(int code, uint8_t &extruder);
|
|
static void print_time_remaining_init();
|
|
static void print_time_remaining_init();
|
|
static void wait_for_heater(long codenum, uint8_t extruder);
|
|
static void wait_for_heater(long codenum, uint8_t extruder);
|
|
@@ -571,6 +551,17 @@ void servo_init()
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool __attribute__((noinline)) printer_active() {
|
|
|
|
+ return IS_SD_PRINTING
|
|
|
|
+ || usb_timer.running()
|
|
|
|
+ || isPrintPaused
|
|
|
|
+ || (custom_message_type == CustomMsg::TempCal)
|
|
|
|
+ || saved_printing
|
|
|
|
+ || (lcd_commands_type == LcdCommands::Layer1Cal)
|
|
|
|
+ || MMU2::mmu2.MMU_PRINT_SAVED()
|
|
|
|
+ || homing_flag
|
|
|
|
+ || mesh_bed_leveling_flag;
|
|
|
|
+}
|
|
|
|
|
|
bool fans_check_enabled = true;
|
|
bool fans_check_enabled = true;
|
|
|
|
|
|
@@ -635,7 +626,6 @@ void crashdet_detected(uint8_t mask)
|
|
lcd_setstatus(msg);
|
|
lcd_setstatus(msg);
|
|
|
|
|
|
gcode_G28(true, true, false); //home X and Y
|
|
gcode_G28(true, true, false); //home X and Y
|
|
- st_synchronize();
|
|
|
|
|
|
|
|
if (automatic_recovery_after_crash) {
|
|
if (automatic_recovery_after_crash) {
|
|
enquecommand_P(PSTR("CRASH_RECOVER"));
|
|
enquecommand_P(PSTR("CRASH_RECOVER"));
|
|
@@ -653,13 +643,12 @@ void crashdet_detected(uint8_t mask)
|
|
lcd_set_cursor(0, 1);
|
|
lcd_set_cursor(0, 1);
|
|
lcd_puts_P(_T(MSG_RESUME_PRINT));
|
|
lcd_puts_P(_T(MSG_RESUME_PRINT));
|
|
lcd_putc('?');
|
|
lcd_putc('?');
|
|
- bool yesno = lcd_show_yes_no_and_wait(false);
|
|
|
|
- lcd_update_enable(true);
|
|
|
|
- if (yesno)
|
|
|
|
|
|
+ uint8_t yesno = lcd_show_yes_no_and_wait(false);
|
|
|
|
+ if (yesno == LCD_LEFT_BUTTON_CHOICE)
|
|
{
|
|
{
|
|
enquecommand_P(PSTR("CRASH_RECOVER"));
|
|
enquecommand_P(PSTR("CRASH_RECOVER"));
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ else // LCD_MIDDLE_BUTTON_CHOICE
|
|
{
|
|
{
|
|
enquecommand_P(PSTR("CRASH_CANCEL"));
|
|
enquecommand_P(PSTR("CRASH_CANCEL"));
|
|
}
|
|
}
|
|
@@ -694,9 +683,6 @@ void failstats_reset_print()
|
|
eeprom_update_byte((uint8_t *)EEPROM_POWER_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_FAIL, 0);
|
|
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
|
|
eeprom_update_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL, 0);
|
|
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
|
|
|
|
- fsensor_softfail = 0;
|
|
|
|
-#endif
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void softReset()
|
|
void softReset()
|
|
@@ -760,12 +746,15 @@ static void factory_reset(char level)
|
|
// Force the "Follow calibration flow" message at the next boot up.
|
|
// Force the "Follow calibration flow" message at the next boot up.
|
|
calibration_status_store(CALIBRATION_STATUS_Z_CALIBRATION);
|
|
calibration_status_store(CALIBRATION_STATUS_Z_CALIBRATION);
|
|
eeprom_write_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 2); //run wizard
|
|
eeprom_write_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 2); //run wizard
|
|
- farm_mode = false;
|
|
|
|
- eeprom_update_byte((uint8_t*)EEPROM_FARM_MODE, farm_mode);
|
|
|
|
|
|
+ farm_disable();
|
|
|
|
|
|
#ifdef FILAMENT_SENSOR
|
|
#ifdef FILAMENT_SENSOR
|
|
- fsensor_enable();
|
|
|
|
- fsensor_autoload_set(true);
|
|
|
|
|
|
+ fsensor.setEnabled(true);
|
|
|
|
+ fsensor.setAutoLoadEnabled(true, true);
|
|
|
|
+ fsensor.setRunoutEnabled(true, true);
|
|
|
|
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
|
|
+ fsensor.setJamDetectionEnabled(true, true);
|
|
|
|
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
#endif //FILAMENT_SENSOR
|
|
#endif //FILAMENT_SENSOR
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -798,7 +787,7 @@ int uart_putchar(char c, FILE *)
|
|
void lcd_splash()
|
|
void lcd_splash()
|
|
{
|
|
{
|
|
lcd_clear(); // clears display and homes screen
|
|
lcd_clear(); // clears display and homes screen
|
|
- lcd_puts_P(PSTR("\n Original Prusa i3\n Prusa Research"));
|
|
|
|
|
|
+ lcd_printf_P(PSTR("\n Original Prusa i3\n Prusa Research\n%20.20S"), PSTR(FW_VERSION));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -864,24 +853,14 @@ void show_fw_version_warnings() {
|
|
lcd_update_enable(true);
|
|
lcd_update_enable(true);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(FILAMENT_SENSOR) && defined(FSENSOR_PROBING)
|
|
//! @brief try to check if firmware is on right type of printer
|
|
//! @brief try to check if firmware is on right type of printer
|
|
-static void check_if_fw_is_on_right_printer(){
|
|
|
|
-#ifdef FILAMENT_SENSOR
|
|
|
|
- if((PRINTER_TYPE == PRINTER_MK3) || (PRINTER_TYPE == PRINTER_MK3S)){
|
|
|
|
- #ifdef IR_SENSOR
|
|
|
|
- if (pat9125_probe()){
|
|
|
|
- lcd_show_fullscreen_message_and_wait_P(_i("MK3S firmware detected on MK3 printer"));}////MSG_MK3S_FIRMWARE_ON_MK3 c=20 r=4
|
|
|
|
- #endif //IR_SENSOR
|
|
|
|
-
|
|
|
|
- #ifdef PAT9125
|
|
|
|
- //will return 1 only if IR can detect filament in bondtech extruder so this may fail even when we have IR sensor
|
|
|
|
- const uint8_t ir_detected = !READ(IR_SENSOR_PIN);
|
|
|
|
- if (ir_detected){
|
|
|
|
- lcd_show_fullscreen_message_and_wait_P(_i("MK3 firmware detected on MK3S printer"));}////MSG_MK3_FIRMWARE_ON_MK3S c=20 r=4
|
|
|
|
- #endif //PAT9125
|
|
|
|
- }
|
|
|
|
-#endif //FILAMENT_SENSOR
|
|
|
|
|
|
+static void check_if_fw_is_on_right_printer() {
|
|
|
|
+ if (fsensor.probeOtherType()) {
|
|
|
|
+ lcd_show_fullscreen_message_and_wait_P(_i(PRINTER_NAME " firmware detected on " PRINTER_NAME_ALTERNATE " printer"));////c=20 r=4
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+#endif //defined(FILAMENT_SENSOR) && defined(FSENSOR_PROBING)
|
|
|
|
|
|
uint8_t check_printer_version()
|
|
uint8_t check_printer_version()
|
|
{
|
|
{
|
|
@@ -1061,7 +1040,6 @@ void setup()
|
|
{
|
|
{
|
|
timer2_init(); // enables functional millis
|
|
timer2_init(); // enables functional millis
|
|
|
|
|
|
- mmu_init();
|
|
|
|
|
|
|
|
ultralcd_init();
|
|
ultralcd_init();
|
|
|
|
|
|
@@ -1095,25 +1073,7 @@ void setup()
|
|
setup_killpin();
|
|
setup_killpin();
|
|
setup_powerhold();
|
|
setup_powerhold();
|
|
|
|
|
|
- farm_mode = eeprom_read_byte((uint8_t*)EEPROM_FARM_MODE);
|
|
|
|
- if (farm_mode == 0xFF) {
|
|
|
|
- farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode
|
|
|
|
- eeprom_update_byte((uint8_t*)EEPROM_FARM_MODE, farm_mode);
|
|
|
|
- } else if (farm_mode) {
|
|
|
|
- no_response = true; //we need confirmation by recieving PRUSA thx
|
|
|
|
- important_status = 8;
|
|
|
|
- prusa_statistics(8);
|
|
|
|
-#ifdef HAS_SECOND_SERIAL_PORT
|
|
|
|
- selectedSerialPort = 1;
|
|
|
|
-#endif //HAS_SECOND_SERIAL_PORT
|
|
|
|
- MYSERIAL.begin(BAUDRATE);
|
|
|
|
-#ifdef FILAMENT_SENSOR
|
|
|
|
- //disabled filament autoload (PFW360)
|
|
|
|
- fsensor_autoload_set(false);
|
|
|
|
-#endif //FILAMENT_SENSOR
|
|
|
|
- // ~ FanCheck -> on
|
|
|
|
- eeprom_update_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED, true);
|
|
|
|
- }
|
|
|
|
|
|
+ farm_mode_init();
|
|
|
|
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
if( FarmOrUserECool() ){
|
|
if( FarmOrUserECool() ){
|
|
@@ -1152,6 +1112,11 @@ void setup()
|
|
SERIAL_ECHO_START;
|
|
SERIAL_ECHO_START;
|
|
puts_P(PSTR(" " FW_VERSION_FULL));
|
|
puts_P(PSTR(" " FW_VERSION_FULL));
|
|
|
|
|
|
|
|
+ if (eeprom_read_byte((uint8_t *)EEPROM_MMU_ENABLED)) {
|
|
|
|
+ MMU2::mmu2.Start();
|
|
|
|
+ }
|
|
|
|
+ SpoolJoin::spooljoin.initSpoolJoinStatus();
|
|
|
|
+
|
|
//SERIAL_ECHOPAIR("Active sheet before:", static_cast<unsigned long int>(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))));
|
|
//SERIAL_ECHOPAIR("Active sheet before:", static_cast<unsigned long int>(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))));
|
|
|
|
|
|
#ifdef DEBUG_SEC_LANG
|
|
#ifdef DEBUG_SEC_LANG
|
|
@@ -1272,9 +1237,15 @@ void setup()
|
|
else { //printer version was changed so use default settings
|
|
else { //printer version was changed so use default settings
|
|
Config_ResetDefault();
|
|
Config_ResetDefault();
|
|
}
|
|
}
|
|
- SdFatUtil::set_stack_guard(); //writes magic number at the end of static variables to protect against overwriting static memory by stack
|
|
|
|
|
|
|
|
- tp_init(); // Initialize temperature loop
|
|
|
|
|
|
+ // writes a magic number at the end of static variables to monitor against incorrect overwriting
|
|
|
|
+ // of static memory by stack (this needs to be done before soft_pwm_init, since the check is
|
|
|
|
+ // performed inside the soft_pwm_isr)
|
|
|
|
+ SdFatUtil::set_stack_guard();
|
|
|
|
+
|
|
|
|
+ // Initialize pwm/temperature loops
|
|
|
|
+ soft_pwm_init();
|
|
|
|
+ temp_mgr_init();
|
|
|
|
|
|
#ifdef EXTRUDER_ALTFAN_DETECT
|
|
#ifdef EXTRUDER_ALTFAN_DETECT
|
|
SERIAL_ECHORPGM(_n("Extruder fan type: "));
|
|
SERIAL_ECHORPGM(_n("Extruder fan type: "));
|
|
@@ -1359,7 +1330,9 @@ void setup()
|
|
|
|
|
|
setup_photpin();
|
|
setup_photpin();
|
|
|
|
|
|
|
|
+#if 0
|
|
servo_init();
|
|
servo_init();
|
|
|
|
+#endif
|
|
|
|
|
|
// Reset the machine correction matrix.
|
|
// Reset the machine correction matrix.
|
|
// It does not make sense to load the correction matrix until the machine is homed.
|
|
// It does not make sense to load the correction matrix until the machine is homed.
|
|
@@ -1375,7 +1348,7 @@ void setup()
|
|
xflash_err_msg();
|
|
xflash_err_msg();
|
|
|
|
|
|
#ifdef FILAMENT_SENSOR
|
|
#ifdef FILAMENT_SENSOR
|
|
- fsensor_init();
|
|
|
|
|
|
+ fsensor.init();
|
|
#endif //FILAMENT_SENSOR
|
|
#endif //FILAMENT_SENSOR
|
|
|
|
|
|
|
|
|
|
@@ -1389,11 +1362,9 @@ void setup()
|
|
enable_z();
|
|
enable_z();
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- if (farm_mode) {
|
|
|
|
- // The farm monitoring SW may accidentally expect
|
|
|
|
- // 2 messages of "printer started" to consider a printer working.
|
|
|
|
- prusa_statistics(8);
|
|
|
|
- }
|
|
|
|
|
|
+ // The farm monitoring SW may accidentally expect
|
|
|
|
+ // 2 messages of "printer started" to consider a printer working.
|
|
|
|
+ prusa_statistics(8);
|
|
|
|
|
|
// Enable Toshiba FlashAir SD card / WiFi enahanced card.
|
|
// Enable Toshiba FlashAir SD card / WiFi enahanced card.
|
|
card.ToshibaFlashAir_enable(eeprom_read_byte((unsigned char*)EEPROM_TOSHIBA_FLASH_AIR_COMPATIBLITY) == 1);
|
|
card.ToshibaFlashAir_enable(eeprom_read_byte((unsigned char*)EEPROM_TOSHIBA_FLASH_AIR_COMPATIBLITY) == 1);
|
|
@@ -1509,15 +1480,13 @@ void setup()
|
|
setup_fan_interrupt();
|
|
setup_fan_interrupt();
|
|
#endif //DEBUG_DISABLE_FANCHECK
|
|
#endif //DEBUG_DISABLE_FANCHECK
|
|
|
|
|
|
-#ifdef PAT9125
|
|
|
|
- fsensor_setup_interrupt();
|
|
|
|
-#endif //PAT9125
|
|
|
|
-
|
|
|
|
#ifndef DEBUG_DISABLE_STARTMSGS
|
|
#ifndef DEBUG_DISABLE_STARTMSGS
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
|
|
if (!farm_mode) {
|
|
if (!farm_mode) {
|
|
|
|
+#if defined(FILAMENT_SENSOR) && defined(FSENSOR_PROBING)
|
|
check_if_fw_is_on_right_printer();
|
|
check_if_fw_is_on_right_printer();
|
|
|
|
+#endif //defined(FILAMENT_SENSOR) && defined(FSENSOR_PROBING)
|
|
show_fw_version_warnings();
|
|
show_fw_version_warnings();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1613,7 +1582,7 @@ void setup()
|
|
#ifdef UVLO_SUPPORT
|
|
#ifdef UVLO_SUPPORT
|
|
if (eeprom_read_byte((uint8_t*)EEPROM_UVLO) != 0) { //previous print was terminated by UVLO
|
|
if (eeprom_read_byte((uint8_t*)EEPROM_UVLO) != 0) { //previous print was terminated by UVLO
|
|
/*
|
|
/*
|
|
- if (lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false)) recover_print();
|
|
|
|
|
|
+ if (!lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false)) recover_print();
|
|
else {
|
|
else {
|
|
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
|
|
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
|
|
lcd_update_enable(true);
|
|
lcd_update_enable(true);
|
|
@@ -1635,8 +1604,9 @@ void setup()
|
|
#ifdef DEBUG_UVLO_AUTOMATIC_RECOVER
|
|
#ifdef DEBUG_UVLO_AUTOMATIC_RECOVER
|
|
puts_P(_N("Normal recovery!"));
|
|
puts_P(_N("Normal recovery!"));
|
|
#endif
|
|
#endif
|
|
- if ( lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false) ) recover_print(0);
|
|
|
|
- else {
|
|
|
|
|
|
+ if ( lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false) == LCD_LEFT_BUTTON_CHOICE) {
|
|
|
|
+ recover_print(0);
|
|
|
|
+ } else {
|
|
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
|
|
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
|
|
lcd_update_enable(true);
|
|
lcd_update_enable(true);
|
|
lcd_update(2);
|
|
lcd_update(2);
|
|
@@ -1651,7 +1621,6 @@ void setup()
|
|
#endif //UVLO_SUPPORT
|
|
#endif //UVLO_SUPPORT
|
|
|
|
|
|
fCheckModeInit();
|
|
fCheckModeInit();
|
|
- fSetMmuMode(mmu_enabled);
|
|
|
|
KEEPALIVE_STATE(NOT_BUSY);
|
|
KEEPALIVE_STATE(NOT_BUSY);
|
|
#ifdef WATCHDOG
|
|
#ifdef WATCHDOG
|
|
wdt_enable(WDTO_4S);
|
|
wdt_enable(WDTO_4S);
|
|
@@ -1692,89 +1661,12 @@ void stack_error() {
|
|
crash_and_burn(dump_crash_reason::stack_error);
|
|
crash_and_burn(dump_crash_reason::stack_error);
|
|
}
|
|
}
|
|
|
|
|
|
-void pullup_error(bool fromTempISR) {
|
|
|
|
- crash_and_burn(fromTempISR ? dump_crash_reason::bad_pullup_temp_isr : dump_crash_reason::bad_pullup_step_isr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#ifdef PRUSA_M28
|
|
|
|
-void trace();
|
|
|
|
-
|
|
|
|
-#define CHUNK_SIZE 64 // bytes
|
|
|
|
-#define SAFETY_MARGIN 1
|
|
|
|
-char chunk[CHUNK_SIZE+SAFETY_MARGIN];
|
|
|
|
-
|
|
|
|
-void serial_read_stream() {
|
|
|
|
-
|
|
|
|
- setAllTargetHotends(0);
|
|
|
|
- setTargetBed(0);
|
|
|
|
-
|
|
|
|
- lcd_clear();
|
|
|
|
- lcd_puts_P(PSTR(" Upload in progress"));
|
|
|
|
-
|
|
|
|
- // first wait for how many bytes we will receive
|
|
|
|
- uint32_t bytesToReceive;
|
|
|
|
-
|
|
|
|
- // receive the four bytes
|
|
|
|
- char bytesToReceiveBuffer[4];
|
|
|
|
- for (int i=0; i<4; i++) {
|
|
|
|
- int data;
|
|
|
|
- while ((data = MYSERIAL.read()) == -1) {};
|
|
|
|
- bytesToReceiveBuffer[i] = data;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // make it a uint32
|
|
|
|
- memcpy(&bytesToReceive, &bytesToReceiveBuffer, 4);
|
|
|
|
-
|
|
|
|
- // we're ready, notify the sender
|
|
|
|
- MYSERIAL.write('+');
|
|
|
|
-
|
|
|
|
- // lock in the routine
|
|
|
|
- uint32_t receivedBytes = 0;
|
|
|
|
- while (prusa_sd_card_upload) {
|
|
|
|
- int i;
|
|
|
|
- for (i=0; i<CHUNK_SIZE; i++) {
|
|
|
|
- int data;
|
|
|
|
-
|
|
|
|
- // check if we're not done
|
|
|
|
- if (receivedBytes == bytesToReceive) {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // read the next byte
|
|
|
|
- while ((data = MYSERIAL.read()) == -1) {};
|
|
|
|
- receivedBytes++;
|
|
|
|
-
|
|
|
|
- // save it to the chunk
|
|
|
|
- chunk[i] = data;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // write the chunk to SD
|
|
|
|
- card.write_command_no_newline(&chunk[0]);
|
|
|
|
-
|
|
|
|
- // notify the sender we're ready for more data
|
|
|
|
- MYSERIAL.write('+');
|
|
|
|
-
|
|
|
|
- // for safety
|
|
|
|
- manage_heater();
|
|
|
|
-
|
|
|
|
- // check if we're done
|
|
|
|
- if(receivedBytes == bytesToReceive) {
|
|
|
|
- trace(); // beep
|
|
|
|
- card.closefile();
|
|
|
|
- prusa_sd_card_upload = false;
|
|
|
|
- SERIAL_PROTOCOLLNRPGM(MSG_FILE_SAVED);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-#endif //PRUSA_M28
|
|
|
|
-
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* Output autoreport values according to features requested in M155
|
|
* Output autoreport values according to features requested in M155
|
|
*/
|
|
*/
|
|
#if defined(AUTO_REPORT)
|
|
#if defined(AUTO_REPORT)
|
|
-static void host_autoreport()
|
|
|
|
|
|
+void host_autoreport()
|
|
{
|
|
{
|
|
if (autoReportFeatures.TimerExpired())
|
|
if (autoReportFeatures.TimerExpired())
|
|
{
|
|
{
|
|
@@ -1834,7 +1726,17 @@ void host_keepalive() {
|
|
// Before loop(), the setup() function is called by the main() routine.
|
|
// Before loop(), the setup() function is called by the main() routine.
|
|
void loop()
|
|
void loop()
|
|
{
|
|
{
|
|
- KEEPALIVE_STATE(NOT_BUSY);
|
|
|
|
|
|
+ // Reset a previously aborted command, we can now start processing motion again
|
|
|
|
+ planner_aborted = false;
|
|
|
|
+
|
|
|
|
+ if(Stopped) {
|
|
|
|
+ // Currently Stopped (possibly due to an error) and not accepting new serial commands.
|
|
|
|
+ // Signal to the host that we're currently busy waiting for supervision.
|
|
|
|
+ KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
+ } else {
|
|
|
|
+ // Printer is available for processing, reset state
|
|
|
|
+ KEEPALIVE_STATE(NOT_BUSY);
|
|
|
|
+ }
|
|
|
|
|
|
if (isPrintPaused && saved_printing_type == PRINTING_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing.
|
|
if (isPrintPaused && saved_printing_type == PRINTING_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing.
|
|
usb_timer.start();
|
|
usb_timer.start();
|
|
@@ -1843,13 +1745,6 @@ void loop()
|
|
;
|
|
;
|
|
}
|
|
}
|
|
|
|
|
|
-#ifdef FANCHECK
|
|
|
|
- if (fan_check_error && isPrintPaused && !IS_SD_PRINTING) {
|
|
|
|
- KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
- host_keepalive(); //prevent timeouts since usb processing is disabled until print is resumed. This is for a crude way of pausing a print on all hosts.
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
#ifdef PRUSA_M28
|
|
#ifdef PRUSA_M28
|
|
if (prusa_sd_card_upload)
|
|
if (prusa_sd_card_upload)
|
|
{
|
|
{
|
|
@@ -1896,7 +1791,7 @@ void loop()
|
|
// The first character in the block is the block type.
|
|
// The first character in the block is the block type.
|
|
char *ptr = cmdbuffer + bufindr;
|
|
char *ptr = cmdbuffer + bufindr;
|
|
if (*ptr == CMDBUFFER_CURRENT_TYPE_SDCARD) {
|
|
if (*ptr == CMDBUFFER_CURRENT_TYPE_SDCARD) {
|
|
- // To support power panic, move the lenght of the command on the SD card to a planner buffer.
|
|
|
|
|
|
+ // To support power panic, move the length of the command on the SD card to a planner buffer.
|
|
union {
|
|
union {
|
|
struct {
|
|
struct {
|
|
char lo;
|
|
char lo;
|
|
@@ -1940,7 +1835,7 @@ void loop()
|
|
}
|
|
}
|
|
//check heater every n milliseconds
|
|
//check heater every n milliseconds
|
|
manage_heater();
|
|
manage_heater();
|
|
- isPrintPaused ? manage_inactivity(true) : manage_inactivity(false);
|
|
|
|
|
|
+ manage_inactivity(isPrintPaused);
|
|
checkHitEndstops();
|
|
checkHitEndstops();
|
|
lcd_update(0);
|
|
lcd_update(0);
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
@@ -1958,7 +1853,7 @@ void loop()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif //TMC2130
|
|
#endif //TMC2130
|
|
- mmu_loop();
|
|
|
|
|
|
+ MMU2::mmu2.mmu_loop();
|
|
}
|
|
}
|
|
|
|
|
|
#define DEFINE_PGM_READ_ANY(type, reader) \
|
|
#define DEFINE_PGM_READ_ANY(type, reader) \
|
|
@@ -2193,19 +2088,15 @@ bool check_commands() {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-// raise_z_above: slowly raise Z to the requested height
|
|
|
|
-//
|
|
|
|
-// contrarily to a simple move, this function will carefully plan a move
|
|
|
|
-// when the current Z position is unknown. In such cases, stallguard is
|
|
|
|
-// enabled and will prevent prolonged pushing against the Z tops
|
|
|
|
-void raise_z_above(float target, bool plan)
|
|
|
|
|
|
+/// @brief Safely move Z-axis by distance delta (mm)
|
|
|
|
+/// @param delta travel distance in mm
|
|
|
|
+/// @returns The actual travel distance in mm. Endstop may limit the requested move.
|
|
|
|
+float raise_z(float delta)
|
|
{
|
|
{
|
|
- if (current_position[Z_AXIS] >= target)
|
|
|
|
- return;
|
|
|
|
|
|
+ float travel_z = current_position[Z_AXIS];
|
|
|
|
|
|
- // Z needs raising
|
|
|
|
- current_position[Z_AXIS] = target;
|
|
|
|
|
|
+ // Prepare to move Z axis
|
|
|
|
+ current_position[Z_AXIS] += delta;
|
|
|
|
|
|
#if defined(Z_MIN_PIN) && (Z_MIN_PIN > -1) && !defined(DEBUG_DISABLE_ZMINLIMIT)
|
|
#if defined(Z_MIN_PIN) && (Z_MIN_PIN > -1) && !defined(DEBUG_DISABLE_ZMINLIMIT)
|
|
bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
|
bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
|
|
@@ -2216,31 +2107,54 @@ void raise_z_above(float target, bool plan)
|
|
if (axis_known_position[Z_AXIS] || z_min_endstop)
|
|
if (axis_known_position[Z_AXIS] || z_min_endstop)
|
|
{
|
|
{
|
|
// current position is known or very low, it's safe to raise Z
|
|
// current position is known or very low, it's safe to raise Z
|
|
- if(plan) plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS]);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ clamp_to_software_endstops(current_position);
|
|
|
|
+ plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS]);
|
|
|
|
+ st_synchronize();
|
|
|
|
|
|
- // ensure Z is powered in normal mode to overcome initial load
|
|
|
|
- enable_z();
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ // Get the final travel distance
|
|
|
|
+ travel_z = current_position[Z_AXIS] - travel_z;
|
|
|
|
+ } else {
|
|
|
|
+ // ensure Z is powered in normal mode to overcome initial load
|
|
|
|
+ enable_z();
|
|
|
|
+ st_synchronize();
|
|
|
|
|
|
- // rely on crashguard to limit damage
|
|
|
|
- bool z_endstop_enabled = enable_z_endstop(true);
|
|
|
|
|
|
+ // rely on crashguard to limit damage
|
|
|
|
+ bool z_endstop_enabled = enable_z_endstop(true);
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
- tmc2130_home_enter(Z_AXIS_MASK);
|
|
|
|
|
|
+ tmc2130_home_enter(Z_AXIS_MASK);
|
|
#endif //TMC2130
|
|
#endif //TMC2130
|
|
- plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60);
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60);
|
|
|
|
+ st_synchronize();
|
|
|
|
+
|
|
|
|
+ // Get the final travel distance
|
|
|
|
+ travel_z = st_get_position_mm(Z_AXIS) - travel_z;
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
- if (endstop_z_hit_on_purpose())
|
|
|
|
- {
|
|
|
|
- // not necessarily exact, but will avoid further vertical moves
|
|
|
|
- current_position[Z_AXIS] = max_pos[Z_AXIS];
|
|
|
|
- plan_set_position_curposXYZE();
|
|
|
|
- }
|
|
|
|
- tmc2130_home_exit();
|
|
|
|
|
|
+ if (endstop_z_hit_on_purpose())
|
|
|
|
+ {
|
|
|
|
+ // not necessarily exact, but will avoid further vertical moves
|
|
|
|
+ current_position[Z_AXIS] = max_pos[Z_AXIS];
|
|
|
|
+ plan_set_position_curposXYZE();
|
|
|
|
+ }
|
|
|
|
+ tmc2130_home_exit();
|
|
#endif //TMC2130
|
|
#endif //TMC2130
|
|
- enable_z_endstop(z_endstop_enabled);
|
|
|
|
|
|
+ enable_z_endstop(z_endstop_enabled);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return travel_z;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// raise_z_above: slowly raise Z to the requested height
|
|
|
|
+//
|
|
|
|
+// contrarily to a simple move, this function will carefully plan a move
|
|
|
|
+// when the current Z position is unknown. In such cases, stallguard is
|
|
|
|
+// enabled and will prevent prolonged pushing against the Z tops
|
|
|
|
+void raise_z_above(float target)
|
|
|
|
+{
|
|
|
|
+ if (current_position[Z_AXIS] >= target)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ // Use absolute value in case the current position is unknown
|
|
|
|
+ raise_z(fabs(current_position[Z_AXIS] - target));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2263,7 +2177,6 @@ bool calibrate_z_auto()
|
|
// current_position[axis] = 0;
|
|
// current_position[axis] = 0;
|
|
// plan_set_position_curposXYZE();
|
|
// plan_set_position_curposXYZE();
|
|
tmc2130_home_exit();
|
|
tmc2130_home_exit();
|
|
- enable_endstops(false);
|
|
|
|
current_position[Z_AXIS] = 0;
|
|
current_position[Z_AXIS] = 0;
|
|
plan_set_position_curposXYZE();
|
|
plan_set_position_curposXYZE();
|
|
set_destination_to_current();
|
|
set_destination_to_current();
|
|
@@ -2286,7 +2199,7 @@ bool calibrate_z_auto()
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
static void check_Z_crash(void)
|
|
static void check_Z_crash(void)
|
|
{
|
|
{
|
|
- if (READ(Z_TMC2130_DIAG) != 0) { //Z crash
|
|
|
|
|
|
+ if (!READ(Z_TMC2130_DIAG)) { //Z crash
|
|
FORCE_HIGH_POWER_END;
|
|
FORCE_HIGH_POWER_END;
|
|
current_position[Z_AXIS] = 0;
|
|
current_position[Z_AXIS] = 0;
|
|
plan_set_position_curposXYZE();
|
|
plan_set_position_curposXYZE();
|
|
@@ -2496,96 +2409,7 @@ void retract(bool retracting, bool swapretract = false) {
|
|
} //retract
|
|
} //retract
|
|
#endif //FWRETRACT
|
|
#endif //FWRETRACT
|
|
|
|
|
|
-#ifdef PRUSA_M28
|
|
|
|
-void trace() {
|
|
|
|
- Sound_MakeCustom(25,440,true);
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
-void ramming() {
|
|
|
|
-// float tmp[4] = DEFAULT_MAX_FEEDRATE;
|
|
|
|
- if (current_temperature[0] < 230) {
|
|
|
|
- //PLA
|
|
|
|
-
|
|
|
|
- max_feedrate[E_AXIS] = 50;
|
|
|
|
- //current_position[E_AXIS] -= 8;
|
|
|
|
- //plan_buffer_line_curposXYZE(2100 / 60, active_extruder);
|
|
|
|
- //current_position[E_AXIS] += 8;
|
|
|
|
- //plan_buffer_line_curposXYZE(2100 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 5.4;
|
|
|
|
- plan_buffer_line_curposXYZE(2800 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 3.2;
|
|
|
|
- plan_buffer_line_curposXYZE(3000 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 3;
|
|
|
|
- plan_buffer_line_curposXYZE(3400 / 60, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
- max_feedrate[E_AXIS] = 80;
|
|
|
|
- current_position[E_AXIS] -= 82;
|
|
|
|
- plan_buffer_line_curposXYZE(9500 / 60, active_extruder);
|
|
|
|
- max_feedrate[E_AXIS] = 50;//tmp[E_AXIS];
|
|
|
|
- current_position[E_AXIS] -= 20;
|
|
|
|
- plan_buffer_line_curposXYZE(1200 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 5;
|
|
|
|
- plan_buffer_line_curposXYZE(400 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 5;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] -= 10;
|
|
|
|
- st_synchronize();
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 10;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] -= 10;
|
|
|
|
- plan_buffer_line_curposXYZE(800 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 10;
|
|
|
|
- plan_buffer_line_curposXYZE(800 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] -= 10;
|
|
|
|
- plan_buffer_line_curposXYZE(800 / 60, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- //ABS
|
|
|
|
- max_feedrate[E_AXIS] = 50;
|
|
|
|
- //current_position[E_AXIS] -= 8;
|
|
|
|
- //plan_buffer_line_curposXYZE(2100 / 60, active_extruder);
|
|
|
|
- //current_position[E_AXIS] += 8;
|
|
|
|
- //plan_buffer_line_curposXYZE(2100 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 3.1;
|
|
|
|
- plan_buffer_line_curposXYZE(2000 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 3.1;
|
|
|
|
- plan_buffer_line_curposXYZE(2500 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 4;
|
|
|
|
- plan_buffer_line_curposXYZE(3000 / 60, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
- //current_position[X_AXIS] += 23; //delay
|
|
|
|
- //plan_buffer_line_curposXYZE(600/60, active_extruder); //delay
|
|
|
|
- //current_position[X_AXIS] -= 23; //delay
|
|
|
|
- //plan_buffer_line_curposXYZE(600/60, active_extruder); //delay
|
|
|
|
- _delay(4700);
|
|
|
|
- max_feedrate[E_AXIS] = 80;
|
|
|
|
- current_position[E_AXIS] -= 92;
|
|
|
|
- plan_buffer_line_curposXYZE(9900 / 60, active_extruder);
|
|
|
|
- max_feedrate[E_AXIS] = 50;//tmp[E_AXIS];
|
|
|
|
- current_position[E_AXIS] -= 5;
|
|
|
|
- plan_buffer_line_curposXYZE(800 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 5;
|
|
|
|
- plan_buffer_line_curposXYZE(400 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] -= 5;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
- current_position[E_AXIS] += 5;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] -= 5;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] += 5;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- current_position[E_AXIS] -= 5;
|
|
|
|
- plan_buffer_line_curposXYZE(600 / 60, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-*/
|
|
|
|
|
|
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
void force_high_power_mode(bool start_high_power_section) {
|
|
void force_high_power_mode(bool start_high_power_section) {
|
|
@@ -2634,7 +2458,7 @@ void gcode_M105(uint8_t extruder)
|
|
}
|
|
}
|
|
#else
|
|
#else
|
|
SERIAL_ERROR_START;
|
|
SERIAL_ERROR_START;
|
|
- SERIAL_ERRORLNRPGM(_i("No thermistors - no temperature"));////MSG_ERR_NO_THERMISTORS
|
|
|
|
|
|
+ SERIAL_ERRORLNRPGM(_n("No thermistors - no temperature"));////MSG_ERR_NO_THERMISTORS
|
|
#endif
|
|
#endif
|
|
|
|
|
|
SERIAL_PROTOCOLPGM(" @:");
|
|
SERIAL_PROTOCOLPGM(" @:");
|
|
@@ -2729,7 +2553,6 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
|
|
//if we are homing all axes, first move z higher to protect heatbed/steel sheet
|
|
//if we are homing all axes, first move z higher to protect heatbed/steel sheet
|
|
if (home_all_axes) {
|
|
if (home_all_axes) {
|
|
raise_z_above(MESH_HOME_Z_SEARCH);
|
|
raise_z_above(MESH_HOME_Z_SEARCH);
|
|
- st_synchronize();
|
|
|
|
}
|
|
}
|
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
|
plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data)
|
|
plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data)
|
|
@@ -2834,11 +2657,9 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
|
|
if(home_z) {
|
|
if(home_z) {
|
|
#if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
|
|
#if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
|
|
raise_z_above(Z_RAISE_BEFORE_HOMING);
|
|
raise_z_above(Z_RAISE_BEFORE_HOMING);
|
|
- st_synchronize();
|
|
|
|
#endif // defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
|
|
#endif // defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
|
|
#ifdef MESH_BED_LEVELING // If Mesh bed leveling, move X&Y to safe position for home
|
|
#ifdef MESH_BED_LEVELING // If Mesh bed leveling, move X&Y to safe position for home
|
|
raise_z_above(MESH_HOME_Z_SEARCH);
|
|
raise_z_above(MESH_HOME_Z_SEARCH);
|
|
- st_synchronize();
|
|
|
|
if (!axis_known_position[X_AXIS]) homeaxis(X_AXIS);
|
|
if (!axis_known_position[X_AXIS]) homeaxis(X_AXIS);
|
|
if (!axis_known_position[Y_AXIS]) homeaxis(Y_AXIS);
|
|
if (!axis_known_position[Y_AXIS]) homeaxis(Y_AXIS);
|
|
// 1st mesh bed leveling measurement point, corrected.
|
|
// 1st mesh bed leveling measurement point, corrected.
|
|
@@ -2956,7 +2777,7 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- if (farm_mode) { prusa_statistics(20); };
|
|
|
|
|
|
+ prusa_statistics(20);
|
|
|
|
|
|
st_synchronize();
|
|
st_synchronize();
|
|
homing_flag = false;
|
|
homing_flag = false;
|
|
@@ -2982,7 +2803,7 @@ static void gcode_G28(bool home_x_axis, bool home_y_axis, bool home_z_axis)
|
|
static void gcode_G80()
|
|
static void gcode_G80()
|
|
{
|
|
{
|
|
st_synchronize();
|
|
st_synchronize();
|
|
- if (waiting_inside_plan_buffer_line_print_aborted)
|
|
|
|
|
|
+ if (planner_aborted)
|
|
return;
|
|
return;
|
|
|
|
|
|
mesh_bed_leveling_flag = true;
|
|
mesh_bed_leveling_flag = true;
|
|
@@ -3076,7 +2897,7 @@ static void gcode_G80()
|
|
plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE);
|
|
plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE);
|
|
// Wait until the move is finished.
|
|
// Wait until the move is finished.
|
|
st_synchronize();
|
|
st_synchronize();
|
|
- if (waiting_inside_plan_buffer_line_print_aborted)
|
|
|
|
|
|
+ if (planner_aborted)
|
|
{
|
|
{
|
|
custom_message_type = custom_message_type_old;
|
|
custom_message_type = custom_message_type_old;
|
|
custom_message_state = custom_message_state_old;
|
|
custom_message_state = custom_message_state_old;
|
|
@@ -3151,7 +2972,7 @@ static void gcode_G80()
|
|
//printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]);
|
|
//printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]);
|
|
plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE);
|
|
plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE);
|
|
st_synchronize();
|
|
st_synchronize();
|
|
- if (waiting_inside_plan_buffer_line_print_aborted)
|
|
|
|
|
|
+ if (planner_aborted)
|
|
{
|
|
{
|
|
custom_message_type = custom_message_type_old;
|
|
custom_message_type = custom_message_type_old;
|
|
custom_message_state = custom_message_state_old;
|
|
custom_message_state = custom_message_state_old;
|
|
@@ -3238,9 +3059,7 @@ static void gcode_G80()
|
|
#endif // TMC2130
|
|
#endif // TMC2130
|
|
// ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing))
|
|
// ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing))
|
|
bState=enable_z_endstop(false);
|
|
bState=enable_z_endstop(false);
|
|
- current_position[Z_AXIS] -= 1;
|
|
|
|
- plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40);
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ raise_z(-1);
|
|
enable_z_endstop(true);
|
|
enable_z_endstop(true);
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
tmc2130_home_enter(Z_AXIS_MASK);
|
|
tmc2130_home_enter(Z_AXIS_MASK);
|
|
@@ -3441,7 +3260,6 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
|
|
int l_feedmultiply = setup_for_endstop_move();
|
|
int l_feedmultiply = setup_for_endstop_move();
|
|
lcd_display_message_fullscreen_P(_T(MSG_AUTO_HOME));
|
|
lcd_display_message_fullscreen_P(_T(MSG_AUTO_HOME));
|
|
raise_z_above(MESH_HOME_Z_SEARCH);
|
|
raise_z_above(MESH_HOME_Z_SEARCH);
|
|
- st_synchronize();
|
|
|
|
home_xy();
|
|
home_xy();
|
|
|
|
|
|
enable_endstops(false);
|
|
enable_endstops(false);
|
|
@@ -3480,19 +3298,19 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
|
|
{
|
|
{
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
#ifdef STEEL_SHEET
|
|
#ifdef STEEL_SHEET
|
|
- bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false, false);
|
|
|
|
- if(result) lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET));
|
|
|
|
|
|
+ uint8_t result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
|
|
|
|
+ if(result == LCD_LEFT_BUTTON_CHOICE) {
|
|
|
|
+ lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET));
|
|
|
|
+ }
|
|
#endif //STEEL_SHEET
|
|
#endif //STEEL_SHEET
|
|
- lcd_show_fullscreen_message_and_wait_P(_T(MSG_PAPER));
|
|
|
|
|
|
+ lcd_show_fullscreen_message_and_wait_P(_T(MSG_PAPER));
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
lcd_display_message_fullscreen_P(_T(MSG_FIND_BED_OFFSET_AND_SKEW_LINE1));
|
|
lcd_display_message_fullscreen_P(_T(MSG_FIND_BED_OFFSET_AND_SKEW_LINE1));
|
|
lcd_puts_at_P(0,3,_n("1/4"));
|
|
lcd_puts_at_P(0,3,_n("1/4"));
|
|
}
|
|
}
|
|
|
|
|
|
bool endstops_enabled = enable_endstops(false);
|
|
bool endstops_enabled = enable_endstops(false);
|
|
- current_position[Z_AXIS] -= 1; //move 1mm down with disabled endstop
|
|
|
|
- plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40);
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ raise_z(-1);
|
|
|
|
|
|
// Move the print head close to the bed.
|
|
// Move the print head close to the bed.
|
|
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
|
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
|
@@ -3635,221 +3453,254 @@ void gcode_M123()
|
|
}
|
|
}
|
|
#endif //FANCHECK and TACH_0 or TACH_1
|
|
#endif //FANCHECK and TACH_0 or TACH_1
|
|
|
|
|
|
-//! extracted code to compute z_shift for M600 in case of filament change operation
|
|
|
|
-//! requested from fsensors.
|
|
|
|
-//! The function ensures, that the printhead lifts to at least 25mm above the heat bed
|
|
|
|
-//! unlike the previous implementation, which was adding 25mm even when the head was
|
|
|
|
-//! printing at e.g. 24mm height.
|
|
|
|
-//! A safety margin of FILAMENTCHANGE_ZADD is added in all cases to avoid touching
|
|
|
|
-//! the printout.
|
|
|
|
-//! This function is templated to enable fast change of computation data type.
|
|
|
|
-//! @return new z_shift value
|
|
|
|
-template<typename T>
|
|
|
|
-static T gcode_M600_filament_change_z_shift()
|
|
|
|
-{
|
|
|
|
-#ifdef FILAMENTCHANGE_ZADD
|
|
|
|
- static_assert(Z_MAX_POS < (255 - FILAMENTCHANGE_ZADD), "Z-range too high, change the T type from uint8_t to uint16_t");
|
|
|
|
- // avoid floating point arithmetics when not necessary - results in shorter code
|
|
|
|
- T z_shift = T(FILAMENTCHANGE_ZADD); // always move above printout
|
|
|
|
- T ztmp = T( current_position[Z_AXIS] );
|
|
|
|
- if((ztmp + z_shift) < T(MIN_Z_FOR_SWAP)){
|
|
|
|
- z_shift = T(MIN_Z_FOR_SWAP) - ztmp; // make sure to be at least 25mm above the heat bed
|
|
|
|
- }
|
|
|
|
- return z_shift;
|
|
|
|
-#else
|
|
|
|
- return T(0);
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
|
|
+static void mmu_M600_wait_and_beep() {
|
|
|
|
+ // Beep and wait for user to remove old filament and prepare new filament for load
|
|
|
|
+ KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
|
|
-static void gcode_M600(bool automatic, float x_position, float y_position, float z_shift, float e_shift, float /*e_shift_late*/)
|
|
|
|
-{
|
|
|
|
|
|
+ int counterBeep = 0;
|
|
|
|
+ lcd_display_message_fullscreen_P(_i("Remove old filament and press the knob to start loading new filament.")); ////MSG_REMOVE_OLD_FILAMENT c=20 r=5
|
|
|
|
+ bool bFirst = true;
|
|
|
|
+
|
|
|
|
+ while (!lcd_clicked()) {
|
|
|
|
+ manage_heater();
|
|
|
|
+ manage_inactivity(true);
|
|
|
|
+
|
|
|
|
+#if BEEPER > 0
|
|
|
|
+ if (counterBeep == 500) {
|
|
|
|
+ counterBeep = 0;
|
|
|
|
+ }
|
|
|
|
+ SET_OUTPUT(BEEPER);
|
|
|
|
+ if (counterBeep == 0) {
|
|
|
|
+ if ((eSoundMode == e_SOUND_MODE_BLIND) || (eSoundMode == e_SOUND_MODE_LOUD) || ((eSoundMode == e_SOUND_MODE_ONCE) && bFirst)) {
|
|
|
|
+ bFirst = false;
|
|
|
|
+ WRITE(BEEPER, HIGH);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (counterBeep == 20) {
|
|
|
|
+ WRITE(BEEPER, LOW);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ counterBeep++;
|
|
|
|
+#endif // BEEPER > 0
|
|
|
|
+
|
|
|
|
+ delay_keep_alive(4);
|
|
|
|
+ }
|
|
|
|
+ WRITE(BEEPER, LOW);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief Handling of unload when using MMU with M600
|
|
|
|
+ * A fullscreen message showing "Unloading Filament x"
|
|
|
|
+ * should be shown on the LCD and LCD updates should be
|
|
|
|
+ * are disabled in the meantime.
|
|
|
|
+ */
|
|
|
|
+static void mmu_M600_unload_filament() {
|
|
|
|
+ if (MMU2::mmu2.get_current_tool() == (uint8_t)MMU2::FILAMENT_UNKNOWN) return;
|
|
|
|
+
|
|
|
|
+ lcd_update_enable(false);
|
|
|
|
+ lcd_clear();
|
|
|
|
+ lcd_puts_at_P(0, 1, _T(MSG_UNLOADING_FILAMENT));
|
|
|
|
+ lcd_print(' ');
|
|
|
|
+ lcd_print(MMU2::mmu2.get_current_tool() + 1);
|
|
|
|
+
|
|
|
|
+ // unload just current filament for multimaterial printers (used also in M702)
|
|
|
|
+ MMU2::mmu2.unload();
|
|
|
|
+ lcd_update_enable(true);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/// @brief load filament for mmu v2
|
|
|
|
+/// @par nozzle_temp nozzle temperature to load filament
|
|
|
|
+static void mmu_M600_load_filament(bool automatic, float nozzle_temp) {
|
|
|
|
+ uint8_t slot;
|
|
|
|
+ if (automatic) {
|
|
|
|
+ slot = SpoolJoin::spooljoin.nextSlot();
|
|
|
|
+ } else {
|
|
|
|
+ // Only ask for the slot if automatic/SpoolJoin is off
|
|
|
|
+ slot = choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ setTargetHotend(nozzle_temp, active_extruder);
|
|
|
|
+
|
|
|
|
+ MMU2::mmu2.load_filament_to_nozzle(slot);
|
|
|
|
+
|
|
|
|
+ load_filament_final_feed(); // @@TODO verify
|
|
|
|
+ st_synchronize();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void gcode_M600(bool automatic, float x_position, float y_position, float z_shift, float e_shift, float /*e_shift_late*/) {
|
|
st_synchronize();
|
|
st_synchronize();
|
|
float lastpos[4];
|
|
float lastpos[4];
|
|
|
|
|
|
- if (farm_mode)
|
|
|
|
- {
|
|
|
|
prusa_statistics(22);
|
|
prusa_statistics(22);
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+
|
|
//First backup current position and settings
|
|
//First backup current position and settings
|
|
int feedmultiplyBckp = feedmultiply;
|
|
int feedmultiplyBckp = feedmultiply;
|
|
float HotendTempBckp = degTargetHotend(active_extruder);
|
|
float HotendTempBckp = degTargetHotend(active_extruder);
|
|
int fanSpeedBckp = fanSpeed;
|
|
int fanSpeedBckp = fanSpeed;
|
|
|
|
|
|
- lastpos[X_AXIS] = current_position[X_AXIS];
|
|
|
|
- lastpos[Y_AXIS] = current_position[Y_AXIS];
|
|
|
|
- lastpos[Z_AXIS] = current_position[Z_AXIS];
|
|
|
|
- lastpos[E_AXIS] = current_position[E_AXIS];
|
|
|
|
|
|
+ memcpy(lastpos, current_position, sizeof(lastpos));
|
|
|
|
|
|
- //Retract E
|
|
|
|
|
|
+ // Retract E
|
|
current_position[E_AXIS] += e_shift;
|
|
current_position[E_AXIS] += e_shift;
|
|
plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED);
|
|
plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED);
|
|
st_synchronize();
|
|
st_synchronize();
|
|
|
|
|
|
- //Lift Z
|
|
|
|
- current_position[Z_AXIS] += z_shift;
|
|
|
|
- clamp_to_software_endstops(current_position);
|
|
|
|
- plan_buffer_line_curposXYZE(FILAMENTCHANGE_ZFEED);
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ // Raise the Z axis
|
|
|
|
+ raise_z(z_shift);
|
|
|
|
|
|
- //Move XY to side
|
|
|
|
|
|
+ // Move XY to side
|
|
current_position[X_AXIS] = x_position;
|
|
current_position[X_AXIS] = x_position;
|
|
current_position[Y_AXIS] = y_position;
|
|
current_position[Y_AXIS] = y_position;
|
|
plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED);
|
|
plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED);
|
|
st_synchronize();
|
|
st_synchronize();
|
|
|
|
|
|
- //Beep, manage nozzle heater and wait for user to start unload filament
|
|
|
|
- if(!mmu_enabled) M600_wait_for_user(HotendTempBckp);
|
|
|
|
-
|
|
|
|
- lcd_change_fil_state = 0;
|
|
|
|
|
|
+ // Beep, manage nozzle heater and wait for user to start unload filament
|
|
|
|
+ if (!MMU2::mmu2.Enabled())
|
|
|
|
+ M600_wait_for_user(HotendTempBckp);
|
|
|
|
|
|
// Unload filament
|
|
// Unload filament
|
|
- if (mmu_enabled) extr_unload(); //unload just current filament for multimaterial printers (used also in M702)
|
|
|
|
- else unload_filament(true); //unload filament for single material (used also in M702)
|
|
|
|
- //finish moves
|
|
|
|
- st_synchronize();
|
|
|
|
-
|
|
|
|
- if (!mmu_enabled)
|
|
|
|
|
|
+ if (MMU2::mmu2.Enabled())
|
|
|
|
+ mmu_M600_unload_filament();
|
|
|
|
+ else
|
|
|
|
+ unload_filament(FILAMENTCHANGE_FINALRETRACT, true); // unload filament for single material (used also in M702)
|
|
|
|
+ st_synchronize(); // finish moves
|
|
{
|
|
{
|
|
- KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
- lcd_change_fil_state = lcd_show_fullscreen_message_yes_no_and_wait_P(
|
|
|
|
- _i("Was filament unload successful?"), ////MSG_UNLOAD_SUCCESSFUL c=20 r=2
|
|
|
|
- false, true);
|
|
|
|
- if (lcd_change_fil_state == 0)
|
|
|
|
|
|
+ FSensorBlockRunout fsBlockRunout;
|
|
|
|
+
|
|
|
|
+ if (!MMU2::mmu2.Enabled())
|
|
{
|
|
{
|
|
- lcd_clear();
|
|
|
|
- lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT));
|
|
|
|
- current_position[X_AXIS] -= 100;
|
|
|
|
- plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED);
|
|
|
|
- st_synchronize();
|
|
|
|
- lcd_show_fullscreen_message_and_wait_P(_i("Please open idler and remove filament manually."));////MSG_CHECK_IDLER c=20 r=5
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (mmu_enabled)
|
|
|
|
- {
|
|
|
|
- if (!automatic) {
|
|
|
|
- if (saved_printing) mmu_eject_filament(mmu_extruder, false); //if M600 was invoked by filament senzor (FINDA) eject filament so user can easily remove it
|
|
|
|
- mmu_M600_wait_and_beep();
|
|
|
|
- if (saved_printing) {
|
|
|
|
-
|
|
|
|
|
|
+ KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
+ uint8_t choice =
|
|
|
|
+ lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, LCD_LEFT_BUTTON_CHOICE); ////MSG_UNLOAD_SUCCESSFUL c=20 r=2
|
|
|
|
+ if (choice == LCD_MIDDLE_BUTTON_CHOICE) {
|
|
lcd_clear();
|
|
lcd_clear();
|
|
lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT));
|
|
lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT));
|
|
-
|
|
|
|
- mmu_command(MmuCmd::R0);
|
|
|
|
- manage_response(false, false);
|
|
|
|
|
|
+ current_position[X_AXIS] -= 100;
|
|
|
|
+ plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED);
|
|
|
|
+ st_synchronize();
|
|
|
|
+ lcd_show_fullscreen_message_and_wait_P(_i("Please open idler and remove filament manually.")); ////MSG_CHECK_IDLER c=20 r=5
|
|
}
|
|
}
|
|
|
|
+ M600_load_filament();
|
|
|
|
+ }
|
|
|
|
+ else // MMU is enabled
|
|
|
|
+ {
|
|
|
|
+ if (!automatic) {
|
|
|
|
+ if (saved_printing){
|
|
|
|
+ // if M600 was invoked by filament senzor (FINDA) eject filament so user can easily remove it
|
|
|
|
+ MMU2::mmu2.eject_filament(MMU2::mmu2.get_current_tool(), false);
|
|
|
|
+ }
|
|
|
|
+ mmu_M600_wait_and_beep();
|
|
|
|
+ if (saved_printing) {
|
|
|
|
+ lcd_clear();
|
|
|
|
+ lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT));
|
|
|
|
+//@@TODO mmu_command(MmuCmd::R0);
|
|
|
|
+// manage_response(false, false);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ mmu_M600_load_filament(automatic, HotendTempBckp);
|
|
|
|
+ }
|
|
|
|
+ if (!automatic)
|
|
|
|
+ M600_check_state(HotendTempBckp);
|
|
|
|
+
|
|
|
|
+ lcd_update_enable(true);
|
|
|
|
+
|
|
|
|
+ // Not let's go back to print
|
|
|
|
+ fanSpeed = fanSpeedBckp;
|
|
|
|
+
|
|
|
|
+ // Feed a little of filament to stabilize pressure
|
|
|
|
+ if (!automatic) {
|
|
|
|
+ current_position[E_AXIS] += FILAMENTCHANGE_RECFEED;
|
|
|
|
+ plan_buffer_line_curposXYZE(FILAMENTCHANGE_EXFEED);
|
|
}
|
|
}
|
|
- mmu_M600_load_filament(automatic, HotendTempBckp);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- M600_load_filament();
|
|
|
|
-
|
|
|
|
- if (!automatic) M600_check_state(HotendTempBckp);
|
|
|
|
|
|
|
|
- lcd_update_enable(true);
|
|
|
|
|
|
+ // Move XY back
|
|
|
|
+ plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED, active_extruder);
|
|
|
|
+ st_synchronize();
|
|
|
|
|
|
- //Not let's go back to print
|
|
|
|
- fanSpeed = fanSpeedBckp;
|
|
|
|
|
|
+ // Move Z back
|
|
|
|
+ plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED, active_extruder);
|
|
|
|
+ st_synchronize();
|
|
|
|
|
|
- //Feed a little of filament to stabilize pressure
|
|
|
|
- if (!automatic)
|
|
|
|
- {
|
|
|
|
- current_position[E_AXIS] += FILAMENTCHANGE_RECFEED;
|
|
|
|
- plan_buffer_line_curposXYZE(FILAMENTCHANGE_EXFEED);
|
|
|
|
|
|
+ // Set E position to original
|
|
|
|
+ plan_set_e_position(lastpos[E_AXIS]);
|
|
|
|
+
|
|
|
|
+ memcpy(current_position, lastpos, sizeof(lastpos));
|
|
|
|
+ set_destination_to_current();
|
|
|
|
+
|
|
|
|
+ // Recover feed rate
|
|
|
|
+ feedmultiply = feedmultiplyBckp;
|
|
|
|
+ char cmd[9];
|
|
|
|
+ sprintf_P(cmd, PSTR("M220 S%i"), feedmultiplyBckp);
|
|
|
|
+ enquecommand(cmd);
|
|
|
|
+
|
|
}
|
|
}
|
|
-
|
|
|
|
- //Move XY back
|
|
|
|
- plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS],
|
|
|
|
- FILAMENTCHANGE_XYFEED, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
- //Move Z back
|
|
|
|
- plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS],
|
|
|
|
- FILAMENTCHANGE_ZFEED, active_extruder);
|
|
|
|
- st_synchronize();
|
|
|
|
-
|
|
|
|
- //Set E position to original
|
|
|
|
- plan_set_e_position(lastpos[E_AXIS]);
|
|
|
|
-
|
|
|
|
- memcpy(current_position, lastpos, sizeof(lastpos));
|
|
|
|
- set_destination_to_current();
|
|
|
|
-
|
|
|
|
- //Recover feed rate
|
|
|
|
- feedmultiply = feedmultiplyBckp;
|
|
|
|
- char cmd[9];
|
|
|
|
- sprintf_P(cmd, PSTR("M220 S%i"), feedmultiplyBckp);
|
|
|
|
- enquecommand(cmd);
|
|
|
|
-
|
|
|
|
-#ifdef IR_SENSOR
|
|
|
|
- //this will set fsensor_watch_autoload to correct value and prevent possible M701 gcode enqueuing when M600 is finished
|
|
|
|
- fsensor_check_autoload();
|
|
|
|
-#endif //IR_SENSOR
|
|
|
|
-
|
|
|
|
|
|
+
|
|
lcd_setstatuspgm(MSG_WELCOME);
|
|
lcd_setstatuspgm(MSG_WELCOME);
|
|
custom_message_type = CustomMsg::Status;
|
|
custom_message_type = CustomMsg::Status;
|
|
}
|
|
}
|
|
|
|
|
|
-void gcode_M701()
|
|
|
|
-{
|
|
|
|
- printf_P(PSTR("gcode_M701 begin\n"));
|
|
|
|
-
|
|
|
|
- if (farm_mode)
|
|
|
|
- {
|
|
|
|
- prusa_statistics(22);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (mmu_enabled)
|
|
|
|
- {
|
|
|
|
- extr_adj(tmp_extruder);//loads current extruder
|
|
|
|
- mmu_extruder = tmp_extruder;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- enable_z();
|
|
|
|
- custom_message_type = CustomMsg::FilamentLoading;
|
|
|
|
|
|
+void gcode_M701(float fastLoadLength, uint8_t mmuSlotIndex){
|
|
|
|
+ FSensorBlockRunout fsBlockRunout;
|
|
|
|
+
|
|
|
|
+ prusa_statistics(22);
|
|
|
|
|
|
-#ifdef FSENSOR_QUALITY
|
|
|
|
- fsensor_oq_meassure_start(40);
|
|
|
|
-#endif //FSENSOR_QUALITY
|
|
|
|
|
|
+ if (MMU2::mmu2.Enabled() && mmuSlotIndex < MMU_FILAMENT_COUNT) {
|
|
|
|
+ MMU2::mmu2.load_filament_to_nozzle(mmuSlotIndex);
|
|
|
|
+ } else {
|
|
|
|
+ custom_message_type = CustomMsg::FilamentLoading;
|
|
|
|
+ lcd_setstatuspgm(_T(MSG_LOADING_FILAMENT));
|
|
|
|
|
|
- lcd_setstatuspgm(_T(MSG_LOADING_FILAMENT));
|
|
|
|
- current_position[E_AXIS] += 40;
|
|
|
|
- plan_buffer_line_curposXYZE(400 / 60); //fast sequence
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ current_position[E_AXIS] += fastLoadLength;
|
|
|
|
+ plan_buffer_line_curposXYZE(FILAMENTCHANGE_EFEED_FIRST); //fast sequence
|
|
|
|
|
|
- raise_z_above(MIN_Z_FOR_LOAD, false);
|
|
|
|
- current_position[E_AXIS] += 30;
|
|
|
|
- plan_buffer_line_curposXYZE(400 / 60); //fast sequence
|
|
|
|
-
|
|
|
|
- load_filament_final_feed(); //slow sequence
|
|
|
|
- st_synchronize();
|
|
|
|
|
|
+ load_filament_final_feed(); // slow sequence
|
|
|
|
+ st_synchronize();
|
|
|
|
|
|
- Sound_MakeCustom(50,500,false);
|
|
|
|
|
|
+ Sound_MakeCustom(50, 500, false);
|
|
|
|
|
|
- if (!farm_mode && loading_flag) {
|
|
|
|
- lcd_load_filament_color_check();
|
|
|
|
- }
|
|
|
|
- lcd_update_enable(true);
|
|
|
|
- lcd_update(2);
|
|
|
|
- lcd_setstatuspgm(MSG_WELCOME);
|
|
|
|
- disable_z();
|
|
|
|
- loading_flag = false;
|
|
|
|
- custom_message_type = CustomMsg::Status;
|
|
|
|
|
|
+ if (!farm_mode && loading_flag) {
|
|
|
|
+ lcd_load_filament_color_check();
|
|
|
|
+ }
|
|
|
|
+ lcd_update_enable(true);
|
|
|
|
+ lcd_update(2);
|
|
|
|
+ lcd_setstatuspgm(MSG_WELCOME);
|
|
|
|
+ loading_flag = false;
|
|
|
|
+ custom_message_type = CustomMsg::Status;
|
|
|
|
+ }
|
|
|
|
|
|
-#ifdef FSENSOR_QUALITY
|
|
|
|
- fsensor_oq_meassure_stop();
|
|
|
|
|
|
+ eFilamentAction = FilamentAction::None;
|
|
|
|
+}
|
|
|
|
|
|
- if (!fsensor_oq_result())
|
|
|
|
- {
|
|
|
|
- bool disable = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Fil. sensor response is poor, disable it?"), false, true);
|
|
|
|
- lcd_update_enable(true);
|
|
|
|
- lcd_update(2);
|
|
|
|
- if (disable)
|
|
|
|
- fsensor_disable();
|
|
|
|
|
|
+// Common gcode shared by the gcodes. This saves some flash memory
|
|
|
|
+static void gcodes_M704_M705_M706(uint16_t gcode)
|
|
|
|
+{
|
|
|
|
+ uint8_t mmuSlotIndex = 0xffU;
|
|
|
|
+ if (MMU2::mmu2.Enabled() && code_seen('P'))
|
|
|
|
+ {
|
|
|
|
+ mmuSlotIndex = code_value_uint8();
|
|
|
|
+ if (mmuSlotIndex < MMU_FILAMENT_COUNT) {
|
|
|
|
+ switch (gcode)
|
|
|
|
+ {
|
|
|
|
+ case 704:
|
|
|
|
+ MMU2::mmu2.load_filament(mmuSlotIndex);
|
|
|
|
+ break;
|
|
|
|
+ case 705:
|
|
|
|
+ MMU2::mmu2.eject_filament(mmuSlotIndex, false);
|
|
|
|
+ break;
|
|
|
|
+ case 706:
|
|
|
|
+#ifdef MMU_HAS_CUTTER
|
|
|
|
+ if (eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED) != 0){
|
|
|
|
+ MMU2::mmu2.cut_filament(mmuSlotIndex);
|
|
|
|
+ }
|
|
|
|
+#endif // MMU_HAS_CUTTER
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-#endif //FSENSOR_QUALITY
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* @brief Get serial number from 32U2 processor
|
|
* @brief Get serial number from 32U2 processor
|
|
*
|
|
*
|
|
@@ -4135,6 +3986,7 @@ extern uint8_t st_backlash_y;
|
|
//!@n M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
|
|
//!@n M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
|
|
//!@n M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
|
|
//!@n M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
|
|
//!@n M304 - Set bed PID parameters P I and D
|
|
//!@n M304 - Set bed PID parameters P I and D
|
|
|
|
+//!@n M310 - Temperature model settings
|
|
//!@n M400 - Finish all moves
|
|
//!@n M400 - Finish all moves
|
|
//!@n M401 - Lower z-probe if present
|
|
//!@n M401 - Lower z-probe if present
|
|
//!@n M402 - Raise z-probe if present
|
|
//!@n M402 - Raise z-probe if present
|
|
@@ -4176,16 +4028,6 @@ There are reasons why some G Codes aren't in numerical order.
|
|
|
|
|
|
void process_commands()
|
|
void process_commands()
|
|
{
|
|
{
|
|
-#ifdef FANCHECK
|
|
|
|
- if(fan_check_error == EFCE_DETECTED) {
|
|
|
|
- fan_check_error = EFCE_REPORTED;
|
|
|
|
- if (usb_timer.running())
|
|
|
|
- lcd_pause_usb_print();
|
|
|
|
- else
|
|
|
|
- lcd_pause_print();
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
if (!buflen) return; //empty command
|
|
if (!buflen) return; //empty command
|
|
|
|
|
|
#ifdef CMDBUFFER_DEBUG
|
|
#ifdef CMDBUFFER_DEBUG
|
|
@@ -4248,7 +4090,7 @@ void process_commands()
|
|
*/
|
|
*/
|
|
|
|
|
|
else if (code_seen_P(PSTR("M0")) || code_seen_P(PSTR("M1 "))) {// M0 and M1 - (Un)conditional stop - Wait for user button press on LCD
|
|
else if (code_seen_P(PSTR("M0")) || code_seen_P(PSTR("M1 "))) {// M0 and M1 - (Un)conditional stop - Wait for user button press on LCD
|
|
- char *src = strchr_pointer + 2;
|
|
|
|
|
|
+ const char *src = strchr_pointer + 2;
|
|
codenum = 0;
|
|
codenum = 0;
|
|
bool hasP = false, hasS = false;
|
|
bool hasP = false, hasS = false;
|
|
if (code_seen('P')) {
|
|
if (code_seen('P')) {
|
|
@@ -4411,13 +4253,11 @@ void process_commands()
|
|
|
|
|
|
Set of internal PRUSA commands
|
|
Set of internal PRUSA commands
|
|
#### Usage
|
|
#### Usage
|
|
- PRUSA [ Ping | PRN | FAN | fn | thx | uvlo | MMURES | RESET | fv | M28 | SN | Fir | Rev | Lang | Lz | FR ]
|
|
|
|
|
|
+ PRUSA [ PRN | FAN | thx | uvlo | MMURES | RESET | fv | M28 | SN | Fir | Rev | Lang | Lz | FR ]
|
|
|
|
|
|
#### Parameters
|
|
#### Parameters
|
|
- - `Ping`
|
|
|
|
- `PRN` - Prints revision of the printer
|
|
- `PRN` - Prints revision of the printer
|
|
- `FAN` - Prints fan details
|
|
- `FAN` - Prints fan details
|
|
- - `fn` - Prints farm no.
|
|
|
|
- `thx`
|
|
- `thx`
|
|
- `uvlo`
|
|
- `uvlo`
|
|
- `MMURES` - Reset MMU
|
|
- `MMURES` - Reset MMU
|
|
@@ -4435,32 +4275,20 @@ void process_commands()
|
|
- `nozzle` - prints nozzle diameter (farm mode only), works like M862.1 P, e.g. `PRUSA nozzle`
|
|
- `nozzle` - prints nozzle diameter (farm mode only), works like M862.1 P, e.g. `PRUSA nozzle`
|
|
*/
|
|
*/
|
|
|
|
|
|
-
|
|
|
|
- if (code_seen_P(PSTR("Ping"))) { // PRUSA Ping
|
|
|
|
- if (farm_mode) {
|
|
|
|
- PingTime = _millis();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if (code_seen_P(PSTR("PRN"))) { // PRUSA PRN
|
|
|
|
- printf_P(_N("%u"), status_number);
|
|
|
|
-
|
|
|
|
- } else if( code_seen_P(PSTR("FANPINTST"))){
|
|
|
|
|
|
+ if (farm_prusa_code_seen()) {}
|
|
|
|
+ else if(code_seen_P(PSTR("FANPINTST"))) {
|
|
gcode_PRUSA_BadRAMBoFanTest();
|
|
gcode_PRUSA_BadRAMBoFanTest();
|
|
- }else if (code_seen_P(PSTR("FAN"))) { // PRUSA FAN
|
|
|
|
- printf_P(_N("E0:%d RPM\nPRN0:%d RPM\n"), 60*fan_speed[0], 60*fan_speed[1]);
|
|
|
|
- }
|
|
|
|
- else if (code_seen_P(PSTR("thx"))) // PRUSA thx
|
|
|
|
- {
|
|
|
|
- no_response = false;
|
|
|
|
- }
|
|
|
|
- else if (code_seen_P(PSTR("uvlo"))) // PRUSA uvlo
|
|
|
|
- {
|
|
|
|
- eeprom_update_byte((uint8_t*)EEPROM_UVLO,0);
|
|
|
|
- enquecommand_P(PSTR("M24"));
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (code_seen_P(PSTR("FAN"))) { // PRUSA FAN
|
|
|
|
+ printf_P(_N("E0:%d RPM\nPRN0:%d RPM\n"), 60*fan_speed[0], 60*fan_speed[1]);
|
|
|
|
+ }
|
|
|
|
+ else if (code_seen_P(PSTR("uvlo"))) { // PRUSA uvlo
|
|
|
|
+ eeprom_update_byte((uint8_t*)EEPROM_UVLO,0);
|
|
|
|
+ enquecommand_P(PSTR("M24"));
|
|
|
|
+ }
|
|
else if (code_seen_P(PSTR("MMURES"))) // PRUSA MMURES
|
|
else if (code_seen_P(PSTR("MMURES"))) // PRUSA MMURES
|
|
{
|
|
{
|
|
- mmu_reset();
|
|
|
|
|
|
+ MMU2::mmu2.Reset(MMU2::MMU2::Software);
|
|
}
|
|
}
|
|
else if (code_seen_P(PSTR("RESET"))) { // PRUSA RESET
|
|
else if (code_seen_P(PSTR("RESET"))) { // PRUSA RESET
|
|
#ifdef WATCHDOG
|
|
#ifdef WATCHDOG
|
|
@@ -4472,30 +4300,7 @@ void process_commands()
|
|
#elif defined(BOOTAPP) //this is a safety precaution. This is because the new bootloader turns off the heaters, but the old one doesn't. The watchdog should be used most of the time.
|
|
#elif defined(BOOTAPP) //this is a safety precaution. This is because the new bootloader turns off the heaters, but the old one doesn't. The watchdog should be used most of the time.
|
|
asm volatile("jmp 0x3E000");
|
|
asm volatile("jmp 0x3E000");
|
|
#endif
|
|
#endif
|
|
- } else if (code_seen_P(PSTR("fv"))) { // PRUSA fv
|
|
|
|
- // get file version
|
|
|
|
- #ifdef SDSUPPORT
|
|
|
|
- card.openFileReadFilteredGcode(strchr_pointer + 3,true);
|
|
|
|
- while (true) {
|
|
|
|
- uint16_t readByte = card.getFilteredGcodeChar();
|
|
|
|
- MYSERIAL.write(readByte);
|
|
|
|
- if (readByte=='\n') {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
- card.closefile();
|
|
|
|
-
|
|
|
|
- #endif // SDSUPPORT
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-#ifdef PRUSA_M28
|
|
|
|
- else if (code_seen_P(PSTR("M28"))) { // PRUSA M28
|
|
|
|
- trace();
|
|
|
|
- prusa_sd_card_upload = true;
|
|
|
|
- card.openFileWrite(strchr_pointer+4);
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-#endif //PRUSA_M28
|
|
|
|
#ifdef PRUSA_SN_SUPPORT
|
|
#ifdef PRUSA_SN_SUPPORT
|
|
else if (code_seen_P(PSTR("SN"))) { // PRUSA SN
|
|
else if (code_seen_P(PSTR("SN"))) { // PRUSA SN
|
|
char SN[20];
|
|
char SN[20];
|
|
@@ -4508,11 +4313,11 @@ void process_commands()
|
|
#endif //PRUSA_SN_SUPPORT
|
|
#endif //PRUSA_SN_SUPPORT
|
|
else if(code_seen_P(PSTR("Fir"))){ // PRUSA Fir
|
|
else if(code_seen_P(PSTR("Fir"))){ // PRUSA Fir
|
|
|
|
|
|
- SERIAL_PROTOCOLLN(FW_VERSION_FULL);
|
|
|
|
|
|
+ SERIAL_PROTOCOLLNPGM(FW_VERSION_FULL);
|
|
|
|
|
|
} else if(code_seen_P(PSTR("Rev"))){ // PRUSA Rev
|
|
} else if(code_seen_P(PSTR("Rev"))){ // PRUSA Rev
|
|
|
|
|
|
- SERIAL_PROTOCOLLN(FILAMENT_SIZE "-" ELECTRONICS "-" NOZZLE_TYPE );
|
|
|
|
|
|
+ SERIAL_PROTOCOLLNPGM(FILAMENT_SIZE "-" ELECTRONICS "-" NOZZLE_TYPE );
|
|
|
|
|
|
} else if(code_seen_P(PSTR("Lang"))) { // PRUSA Lang
|
|
} else if(code_seen_P(PSTR("Lang"))) { // PRUSA Lang
|
|
lang_reset();
|
|
lang_reset();
|
|
@@ -4639,19 +4444,9 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
*/
|
|
*/
|
|
case 0: // G0 -> G1
|
|
case 0: // G0 -> G1
|
|
case 1: // G1
|
|
case 1: // G1
|
|
- if(Stopped == false) {
|
|
|
|
- get_coordinates(); // For X Y Z E F
|
|
|
|
-
|
|
|
|
- // When recovering from a previous print move, restore the originally
|
|
|
|
- // calculated target position on the first USB/SD command. This accounts
|
|
|
|
- // properly for relative moves
|
|
|
|
- if ((saved_target[0] != SAVED_TARGET_UNSET) &&
|
|
|
|
- ((CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_SDCARD) ||
|
|
|
|
- (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR)))
|
|
|
|
- {
|
|
|
|
- memcpy(destination, saved_target, sizeof(destination));
|
|
|
|
- saved_target[0] = SAVED_TARGET_UNSET;
|
|
|
|
- }
|
|
|
|
|
|
+ {
|
|
|
|
+ uint16_t start_segment_idx = restore_interrupted_gcode();
|
|
|
|
+ get_coordinates(); // For X Y Z E F
|
|
|
|
|
|
if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow
|
|
if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow
|
|
total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100);
|
|
total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100);
|
|
@@ -4672,7 +4467,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
}
|
|
}
|
|
#endif //FWRETRACT
|
|
#endif //FWRETRACT
|
|
|
|
|
|
- prepare_move();
|
|
|
|
|
|
+ prepare_move(start_segment_idx);
|
|
//ClearToSend();
|
|
//ClearToSend();
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -4697,21 +4492,24 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
- `F` - The feedrate per minute of the move between the starting point and ending point (if supplied)
|
|
- `F` - The feedrate per minute of the move between the starting point and ending point (if supplied)
|
|
|
|
|
|
*/
|
|
*/
|
|
- case 2:
|
|
|
|
- if(Stopped == false) {
|
|
|
|
- get_arc_coordinates();
|
|
|
|
- prepare_arc_move(true);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- // -------------------------------
|
|
|
|
- case 3:
|
|
|
|
- if(Stopped == false) {
|
|
|
|
- get_arc_coordinates();
|
|
|
|
- prepare_arc_move(false);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
|
|
+ case 2:
|
|
|
|
+ case 3:
|
|
|
|
+ {
|
|
|
|
+ uint16_t start_segment_idx = restore_interrupted_gcode();
|
|
|
|
+#ifdef SF_ARC_FIX
|
|
|
|
+ bool relative_mode_backup = relative_mode;
|
|
|
|
+ relative_mode = true;
|
|
|
|
+#endif
|
|
|
|
+ get_coordinates(); // For X Y Z E F
|
|
|
|
+#ifdef SF_ARC_FIX
|
|
|
|
+ relative_mode=relative_mode_backup;
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
+ offset[0] = code_seen('I') ? code_value() : 0.f;
|
|
|
|
+ offset[1] = code_seen('J') ? code_value() : 0.f;
|
|
|
|
+
|
|
|
|
+ prepare_arc_move((gcode_in_progress == 2), start_segment_idx);
|
|
|
|
+ } break;
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### G4 - Dwell <a href="https://reprap.org/wiki/G-code#G4:_Dwell">G4: Dwell</a>
|
|
### G4 - Dwell <a href="https://reprap.org/wiki/G-code#G4:_Dwell">G4: Dwell</a>
|
|
@@ -4806,11 +4604,11 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
long home_z_value = 0;
|
|
long home_z_value = 0;
|
|
// Which axes should be homed?
|
|
// Which axes should be homed?
|
|
bool home_x = code_seen(axis_codes[X_AXIS]);
|
|
bool home_x = code_seen(axis_codes[X_AXIS]);
|
|
- home_x_value = code_value_long();
|
|
|
|
|
|
+ if (home_x) home_x_value = code_value_long();
|
|
bool home_y = code_seen(axis_codes[Y_AXIS]);
|
|
bool home_y = code_seen(axis_codes[Y_AXIS]);
|
|
- home_y_value = code_value_long();
|
|
|
|
|
|
+ if (home_y) home_y_value = code_value_long();
|
|
bool home_z = code_seen(axis_codes[Z_AXIS]);
|
|
bool home_z = code_seen(axis_codes[Z_AXIS]);
|
|
- home_z_value = code_value_long();
|
|
|
|
|
|
+ if (home_z) home_z_value = code_value_long();
|
|
bool without_mbl = code_seen('W');
|
|
bool without_mbl = code_seen('W');
|
|
// calibrate?
|
|
// calibrate?
|
|
#ifdef TMC2130
|
|
#ifdef TMC2130
|
|
@@ -5110,9 +4908,9 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
lcd_show_fullscreen_message_and_wait_P(_i("Stable ambient temperature 21-26C is needed a rigid stand is required."));////MSG_TEMP_CAL_WARNING c=20 r=4
|
|
lcd_show_fullscreen_message_and_wait_P(_i("Stable ambient temperature 21-26C is needed a rigid stand is required."));////MSG_TEMP_CAL_WARNING c=20 r=4
|
|
- bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false, false);
|
|
|
|
|
|
+ uint8_t result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
|
|
|
|
|
|
- if (result)
|
|
|
|
|
|
+ if (result == LCD_LEFT_BUTTON_CHOICE)
|
|
{
|
|
{
|
|
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
|
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
|
|
plan_buffer_line_curposXYZE(3000 / 60);
|
|
plan_buffer_line_curposXYZE(3000 / 60);
|
|
@@ -5545,30 +5343,23 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+#ifdef PRUSA_FARM
|
|
/*!
|
|
/*!
|
|
### G98 - Activate farm mode <a href="https://reprap.org/wiki/G-code#G98:_Activate_farm_mode">G98: Activate farm mode</a>
|
|
### G98 - Activate farm mode <a href="https://reprap.org/wiki/G-code#G98:_Activate_farm_mode">G98: Activate farm mode</a>
|
|
- Enable Prusa-specific Farm functions and g-code.
|
|
|
|
|
|
+ Enable Prusa-specific Farm functions and g-code.
|
|
See Internal Prusa commands.
|
|
See Internal Prusa commands.
|
|
*/
|
|
*/
|
|
- case 98:
|
|
|
|
- farm_mode = 1;
|
|
|
|
- PingTime = _millis();
|
|
|
|
- eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode);
|
|
|
|
- SilentModeMenu = SILENT_MODE_OFF;
|
|
|
|
- eeprom_update_byte((unsigned char *)EEPROM_SILENT, SilentModeMenu);
|
|
|
|
- fCheckModeInit(); // alternatively invoke printer reset
|
|
|
|
- break;
|
|
|
|
|
|
+ case 98:
|
|
|
|
+ farm_gcode_g98();
|
|
|
|
+ break;
|
|
|
|
|
|
/*! ### G99 - Deactivate farm mode <a href="https://reprap.org/wiki/G-code#G99:_Deactivate_farm_mode">G99: Deactivate farm mode</a>
|
|
/*! ### G99 - Deactivate farm mode <a href="https://reprap.org/wiki/G-code#G99:_Deactivate_farm_mode">G99: Deactivate farm mode</a>
|
|
- Disables Prusa-specific Farm functions and g-code.
|
|
|
|
- */
|
|
|
|
- case 99:
|
|
|
|
- farm_mode = 0;
|
|
|
|
- lcd_printer_connected();
|
|
|
|
- eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode);
|
|
|
|
- lcd_update(2);
|
|
|
|
- fCheckModeInit(); // alternatively invoke printer reset
|
|
|
|
- break;
|
|
|
|
|
|
+ Disables Prusa-specific Farm functions and g-code.
|
|
|
|
+ */
|
|
|
|
+ case 99:
|
|
|
|
+ farm_gcode_g99();
|
|
|
|
+ break;
|
|
|
|
+#endif //PRUSA_FARM
|
|
default:
|
|
default:
|
|
printf_P(MSG_UNKNOWN_CODE, 'G', cmdbuffer + bufindr + CMDHDRSIZE);
|
|
printf_P(MSG_UNKNOWN_CODE, 'G', cmdbuffer + bufindr + CMDHDRSIZE);
|
|
}
|
|
}
|
|
@@ -5667,23 +5458,32 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
### M24 - Start SD print <a href="https://reprap.org/wiki/G-code#M24:_Start.2Fresume_SD_print">M24: Start/resume SD print</a>
|
|
### M24 - Start SD print <a href="https://reprap.org/wiki/G-code#M24:_Start.2Fresume_SD_print">M24: Start/resume SD print</a>
|
|
*/
|
|
*/
|
|
case 24:
|
|
case 24:
|
|
- if (isPrintPaused)
|
|
|
|
- lcd_resume_print();
|
|
|
|
- else
|
|
|
|
|
|
+ if (isPrintPaused)
|
|
|
|
+ lcd_resume_print();
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (!card.get_sdpos())
|
|
{
|
|
{
|
|
- if (!card.get_sdpos())
|
|
|
|
- {
|
|
|
|
// A new print has started from scratch, reset stats
|
|
// A new print has started from scratch, reset stats
|
|
failstats_reset_print();
|
|
failstats_reset_print();
|
|
|
|
+ sdpos_atomic = 0;
|
|
#ifndef LA_NOCOMPAT
|
|
#ifndef LA_NOCOMPAT
|
|
- la10c_reset();
|
|
|
|
|
|
+ la10c_reset();
|
|
#endif
|
|
#endif
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- card.startFileprint();
|
|
|
|
- starttime=_millis();
|
|
|
|
|
|
+ card.startFileprint();
|
|
|
|
+ starttime=_millis();
|
|
|
|
+ if (MMU2::mmu2.Enabled())
|
|
|
|
+ {
|
|
|
|
+ if (MMU2::mmu2.FindaDetectsFilament() && !fsensor.getFilamentPresent())
|
|
|
|
+ { // Filament only half way into the PTFE. Unload the filament.
|
|
|
|
+ MMU2::mmu2.unload();
|
|
|
|
+ // Tx and Tc gcodes take care of loading the filament to the nozzle.
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- break;
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### M26 - Set SD index <a href="https://reprap.org/wiki/G-code#M26:_Set_SD_position">M26: Set SD position</a>
|
|
### M26 - Set SD index <a href="https://reprap.org/wiki/G-code#M26:_Set_SD_position">M26: Set SD position</a>
|
|
@@ -5773,7 +5573,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
}
|
|
}
|
|
starpos = (strchr(strchr_pointer + 4,'*'));
|
|
starpos = (strchr(strchr_pointer + 4,'*'));
|
|
|
|
|
|
- char* namestartpos = (strchr(strchr_pointer + 4,'!')); //find ! to indicate filename string start.
|
|
|
|
|
|
+ const char* namestartpos = (strchr(strchr_pointer + 4,'!')); //find ! to indicate filename string start.
|
|
if(namestartpos==NULL)
|
|
if(namestartpos==NULL)
|
|
{
|
|
{
|
|
namestartpos=strchr_pointer + 4; //default name position, 4 letters after the M
|
|
namestartpos=strchr_pointer + 4; //default name position, 4 letters after the M
|
|
@@ -5802,6 +5602,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
|
|
{
|
|
{
|
|
// A new print has started from scratch, reset stats
|
|
// A new print has started from scratch, reset stats
|
|
failstats_reset_print();
|
|
failstats_reset_print();
|
|
|
|
+ sdpos_atomic = 0;
|
|
#ifndef LA_NOCOMPAT
|
|
#ifndef LA_NOCOMPAT
|
|
la10c_reset();
|
|
la10c_reset();
|
|
#endif
|
|
#endif
|
|
@@ -6434,7 +6235,7 @@ Sigma_Exit:
|
|
}
|
|
}
|
|
LCD_MESSAGERPGM(_T(MSG_HEATING));
|
|
LCD_MESSAGERPGM(_T(MSG_HEATING));
|
|
heating_status = HeatingStatus::EXTRUDER_HEATING;
|
|
heating_status = HeatingStatus::EXTRUDER_HEATING;
|
|
- if (farm_mode) { prusa_statistics(1); };
|
|
|
|
|
|
+ prusa_statistics(1);
|
|
|
|
|
|
#ifdef AUTOTEMP
|
|
#ifdef AUTOTEMP
|
|
autotemp_enabled=false;
|
|
autotemp_enabled=false;
|
|
@@ -6465,7 +6266,7 @@ Sigma_Exit:
|
|
|
|
|
|
LCD_MESSAGERPGM(_T(MSG_HEATING_COMPLETE));
|
|
LCD_MESSAGERPGM(_T(MSG_HEATING_COMPLETE));
|
|
heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
|
|
heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
|
|
- if (farm_mode) { prusa_statistics(2); };
|
|
|
|
|
|
+ prusa_statistics(2);
|
|
|
|
|
|
//starttime=_millis();
|
|
//starttime=_millis();
|
|
previous_millis_cmd.start();
|
|
previous_millis_cmd.start();
|
|
@@ -6491,7 +6292,7 @@ Sigma_Exit:
|
|
bool CooldownNoWait = false;
|
|
bool CooldownNoWait = false;
|
|
LCD_MESSAGERPGM(_T(MSG_BED_HEATING));
|
|
LCD_MESSAGERPGM(_T(MSG_BED_HEATING));
|
|
heating_status = HeatingStatus::BED_HEATING;
|
|
heating_status = HeatingStatus::BED_HEATING;
|
|
- if (farm_mode) { prusa_statistics(1); };
|
|
|
|
|
|
+ prusa_statistics(1);
|
|
if (code_seen('S'))
|
|
if (code_seen('S'))
|
|
{
|
|
{
|
|
setTargetBed(code_value());
|
|
setTargetBed(code_value());
|
|
@@ -6740,9 +6541,9 @@ Sigma_Exit:
|
|
axis_steps_per_sqr_second[i] *= factor;
|
|
axis_steps_per_sqr_second[i] *= factor;
|
|
}
|
|
}
|
|
cs.axis_steps_per_unit[i] = value;
|
|
cs.axis_steps_per_unit[i] = value;
|
|
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
|
|
|
|
- fsensor_set_axis_steps_per_unit(value);
|
|
|
|
-#endif
|
|
|
|
|
|
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
|
|
+ fsensor.init();
|
|
|
|
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
cs.axis_steps_per_unit[i] = code_value();
|
|
cs.axis_steps_per_unit[i] = code_value();
|
|
@@ -7755,6 +7556,69 @@ Sigma_Exit:
|
|
PID_autotune(temp, e, c);
|
|
PID_autotune(temp, e, c);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+
|
|
|
|
+#ifdef TEMP_MODEL
|
|
|
|
+ /*!
|
|
|
|
+ ### M310 - Temperature model settings <a href="https://reprap.org/wiki/G-code#M310:_Temperature_model_settings">M310: Temperature model settings</a>
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M310 ; report values
|
|
|
|
+ M310 [ A ] [ F ] ; autotune
|
|
|
|
+ M310 [ S ] ; set 0=disable 1=enable
|
|
|
|
+ M310 [ I ] [ R ] ; set resistance at index
|
|
|
|
+ M310 [ P | C ] ; set power, capacitance
|
|
|
|
+ M310 [ B | E | W ] ; set beeper, warning and error threshold
|
|
|
|
+ M310 [ T ] ; set ambient temperature correction
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `I` - resistance index position (0-15)
|
|
|
|
+ - `R` - resistance value at index (K/W; requires `I`)
|
|
|
|
+ - `P` - power (W)
|
|
|
|
+ - `C` - capacitance (J/K)
|
|
|
|
+ - `S` - set 0=disable 1=enable
|
|
|
|
+ - `B` - beep and warn when reaching warning threshold 0=disable 1=enable (default: 1)
|
|
|
|
+ - `E` - error threshold (K/s; default in variant)
|
|
|
|
+ - `W` - warning threshold (K/s; default in variant)
|
|
|
|
+ - `T` - ambient temperature correction (K; default in variant)
|
|
|
|
+ - `A` - autotune C+R values
|
|
|
|
+ - `F` - force model self-test state (0=off 1=on) during autotune using current values
|
|
|
|
+ */
|
|
|
|
+ case 310:
|
|
|
|
+ {
|
|
|
|
+ // parse all parameters
|
|
|
|
+ float P = NAN, C = NAN, R = NAN, E = NAN, W = NAN, T = NAN;
|
|
|
|
+ int8_t I = -1, S = -1, B = -1, A = -1, F = -1;
|
|
|
|
+ if(code_seen('C')) C = code_value();
|
|
|
|
+ if(code_seen('P')) P = code_value();
|
|
|
|
+ if(code_seen('I')) I = code_value_short();
|
|
|
|
+ if(code_seen('R')) R = code_value();
|
|
|
|
+ if(code_seen('S')) S = code_value_short();
|
|
|
|
+ if(code_seen('B')) B = code_value_short();
|
|
|
|
+ if(code_seen('E')) E = code_value();
|
|
|
|
+ if(code_seen('W')) W = code_value();
|
|
|
|
+ if(code_seen('T')) T = code_value();
|
|
|
|
+ if(code_seen('A')) A = code_value_short();
|
|
|
|
+ if(code_seen('F')) F = code_value_short();
|
|
|
|
+
|
|
|
|
+ // report values if nothing has been requested
|
|
|
|
+ if(isnan(C) && isnan(P) && isnan(R) && isnan(E) && isnan(W) && isnan(T) && I < 0 && S < 0 && B < 0 && A < 0) {
|
|
|
|
+ temp_model_report_settings();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // update all parameters
|
|
|
|
+ if(B >= 0) temp_model_set_warn_beep(B);
|
|
|
|
+ if(!isnan(C) || !isnan(P) || !isnan(T) || !isnan(W) || !isnan(E)) temp_model_set_params(C, P, T, W, E);
|
|
|
|
+ if(I >= 0 && !isnan(R)) temp_model_set_resistance(I, R);
|
|
|
|
+
|
|
|
|
+ // enable the model last, if requested
|
|
|
|
+ if(S >= 0) temp_model_set_enabled(S);
|
|
|
|
+
|
|
|
|
+ // run autotune
|
|
|
|
+ if(A >= 0) temp_model_autotune(A, F > 0);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### M400 - Wait for all moves to finish <a href="https://reprap.org/wiki/G-code#M400:_Wait_for_current_moves_to_finish">M400: Wait for current moves to finish</a>
|
|
### M400 - Wait for all moves to finish <a href="https://reprap.org/wiki/G-code#M400:_Wait_for_current_moves_to_finish">M400: Wait for current moves to finish</a>
|
|
@@ -7783,14 +7647,13 @@ Sigma_Exit:
|
|
{
|
|
{
|
|
// currently three different materials are needed (default, flex and PVA)
|
|
// currently three different materials are needed (default, flex and PVA)
|
|
// add storing this information for different load/unload profiles etc. in the future
|
|
// add storing this information for different load/unload profiles etc. in the future
|
|
- // firmware does not wait for "ok" from mmu
|
|
|
|
- if (mmu_enabled)
|
|
|
|
|
|
+ if (MMU2::mmu2.Enabled())
|
|
{
|
|
{
|
|
uint8_t extruder = 255;
|
|
uint8_t extruder = 255;
|
|
uint8_t filament = FILAMENT_UNDEFINED;
|
|
uint8_t filament = FILAMENT_UNDEFINED;
|
|
if(code_seen('E')) extruder = code_value_uint8();
|
|
if(code_seen('E')) extruder = code_value_uint8();
|
|
if(code_seen('F')) filament = code_value_uint8();
|
|
if(code_seen('F')) filament = code_value_uint8();
|
|
- mmu_set_filament_type(extruder, filament);
|
|
|
|
|
|
+ MMU2::mmu2.set_filament_type(extruder, filament);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -7866,6 +7729,7 @@ Sigma_Exit:
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef ENABLE_AUTO_BED_LEVELING
|
|
/*!
|
|
/*!
|
|
### M851 - Set Z-Probe Offset <a href="https://reprap.org/wiki/G-code#M851:_Set_Z-Probe_Offset">M851: Set Z-Probe Offset"</a>
|
|
### M851 - Set Z-Probe Offset <a href="https://reprap.org/wiki/G-code#M851:_Set_Z-Probe_Offset">M851: Set Z-Probe Offset"</a>
|
|
Sets the Z-probe Z offset. This offset is used to determine the actual Z position of the nozzle when using a probe to home Z with G28. This value may also be used by G81 (Prusa) / G29 (Marlin) to apply correction to the Z position.
|
|
Sets the Z-probe Z offset. This offset is used to determine the actual Z position of the nozzle when using a probe to home Z with G28. This value may also be used by G81 (Prusa) / G29 (Marlin) to apply correction to the Z position.
|
|
@@ -7912,6 +7776,7 @@ Sigma_Exit:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
#endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET
|
|
#endif // CUSTOM_M_CODE_SET_Z_PROBE_OFFSET
|
|
|
|
+#endif // ENABLE_AUTO_BED_LEVELING
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### M552 - Set IP address <a href="https://reprap.org/wiki/G-code#M552:_Set_IP_address.2C_enable.2Fdisable_network_interface">M552: Set IP address, enable/disable network interface"</a>
|
|
### M552 - Set IP address <a href="https://reprap.org/wiki/G-code#M552:_Set_IP_address.2C_enable.2Fdisable_network_interface">M552: Set IP address, enable/disable network interface"</a>
|
|
@@ -7955,7 +7820,7 @@ Sigma_Exit:
|
|
|
|
|
|
- `X` - X position, default 211
|
|
- `X` - X position, default 211
|
|
- `Y` - Y position, default 0
|
|
- `Y` - Y position, default 0
|
|
- - `Z` - relative lift Z, default 2.
|
|
|
|
|
|
+ - `Z` - relative lift Z, default MIN_Z_FOR_SWAP.
|
|
- `E` - initial retract, default -2
|
|
- `E` - initial retract, default -2
|
|
- `L` - later retract distance for removal, default -80
|
|
- `L` - later retract distance for removal, default -80
|
|
- `AUTO` - Automatically (only with MMU)
|
|
- `AUTO` - Automatically (only with MMU)
|
|
@@ -7966,7 +7831,7 @@ Sigma_Exit:
|
|
|
|
|
|
float x_position = current_position[X_AXIS];
|
|
float x_position = current_position[X_AXIS];
|
|
float y_position = current_position[Y_AXIS];
|
|
float y_position = current_position[Y_AXIS];
|
|
- float z_shift = 0; // is it necessary to be a float?
|
|
|
|
|
|
+ float z_shift = MIN_Z_FOR_SWAP;
|
|
float e_shift_init = 0;
|
|
float e_shift_init = 0;
|
|
float e_shift_late = 0;
|
|
float e_shift_late = 0;
|
|
bool automatic = false;
|
|
bool automatic = false;
|
|
@@ -7995,16 +7860,10 @@ Sigma_Exit:
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
- //Lift Z
|
|
|
|
- if(code_seen('Z'))
|
|
|
|
- {
|
|
|
|
- z_shift = code_value();
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- z_shift = gcode_M600_filament_change_z_shift<uint8_t>();
|
|
|
|
- }
|
|
|
|
- //Move XY to side
|
|
|
|
|
|
+ // Z lift. For safety only allow positive values
|
|
|
|
+ if (code_seen('Z')) z_shift = fabs(code_value());
|
|
|
|
+
|
|
|
|
+ //Move XY to side
|
|
if(code_seen('X'))
|
|
if(code_seen('X'))
|
|
{
|
|
{
|
|
x_position = code_value();
|
|
x_position = code_value();
|
|
@@ -8026,7 +7885,7 @@ Sigma_Exit:
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
- if (mmu_enabled && code_seen_P(PSTR("AUTO")))
|
|
|
|
|
|
+ if (MMU2::mmu2.Enabled() && code_seen_P(PSTR("AUTO")))
|
|
automatic = true;
|
|
automatic = true;
|
|
|
|
|
|
gcode_M600(automatic, x_position, y_position, z_shift, e_shift_init, e_shift_late);
|
|
gcode_M600(automatic, x_position, y_position, z_shift, e_shift_init, e_shift_late);
|
|
@@ -8265,14 +8124,6 @@ Sigma_Exit:
|
|
nDiameter=(uint16_t)(code_value()*1000.0+0.5); // [,um]
|
|
nDiameter=(uint16_t)(code_value()*1000.0+0.5); // [,um]
|
|
nozzle_diameter_check(nDiameter);
|
|
nozzle_diameter_check(nDiameter);
|
|
}
|
|
}
|
|
-/*
|
|
|
|
- else if(code_seen('S')&&farm_mode)
|
|
|
|
- {
|
|
|
|
- nDiameter=(uint16_t)(code_value()*1000.0+0.5); // [,um]
|
|
|
|
- eeprom_update_byte((uint8_t*)EEPROM_NOZZLE_DIAMETER,(uint8_t)ClNozzleDiameter::_Diameter_Undef); // for correct synchronization after farm-mode exiting
|
|
|
|
- eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,nDiameter);
|
|
|
|
- }
|
|
|
|
-*/
|
|
|
|
else if(code_seen('Q'))
|
|
else if(code_seen('Q'))
|
|
SERIAL_PROTOCOLLN((float)eeprom_read_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM)/1000.0);
|
|
SERIAL_PROTOCOLLN((float)eeprom_read_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM)/1000.0);
|
|
break;
|
|
break;
|
|
@@ -8281,6 +8132,8 @@ Sigma_Exit:
|
|
{
|
|
{
|
|
uint16_t nPrinterModel;
|
|
uint16_t nPrinterModel;
|
|
nPrinterModel=(uint16_t)code_value_long();
|
|
nPrinterModel=(uint16_t)code_value_long();
|
|
|
|
+ // based on current state of MMU (active/stopped/connecting) perform a runtime update of the printer type
|
|
|
|
+ fSetMmuMode(MMU2::mmu2.Enabled());
|
|
printer_model_check(nPrinterModel);
|
|
printer_model_check(nPrinterModel);
|
|
}
|
|
}
|
|
else if(code_seen('Q'))
|
|
else if(code_seen('Q'))
|
|
@@ -8288,7 +8141,10 @@ Sigma_Exit:
|
|
break;
|
|
break;
|
|
case ClPrintChecking::_Smodel: // ~ .3
|
|
case ClPrintChecking::_Smodel: // ~ .3
|
|
if(code_seen('P'))
|
|
if(code_seen('P'))
|
|
- printer_smodel_check(strchr_pointer);
|
|
|
|
|
|
+ {
|
|
|
|
+ fSetMmuMode(MMU2::mmu2.Enabled());
|
|
|
|
+ printer_smodel_check(strchr_pointer);
|
|
|
|
+ }
|
|
else if(code_seen('Q'))
|
|
else if(code_seen('Q'))
|
|
SERIAL_PROTOCOLLNRPGM(sPrinterName);
|
|
SERIAL_PROTOCOLLNRPGM(sPrinterName);
|
|
break;
|
|
break;
|
|
@@ -8619,10 +8475,10 @@ Sigma_Exit:
|
|
cs.axis_steps_per_unit[i] /= fac;
|
|
cs.axis_steps_per_unit[i] /= fac;
|
|
position[i] /= fac;
|
|
position[i] /= fac;
|
|
}
|
|
}
|
|
-#if defined(FILAMENT_SENSOR) && defined(PAT9125)
|
|
|
|
- if (i == E_AXIS)
|
|
|
|
- fsensor_set_axis_steps_per_unit(cs.axis_steps_per_unit[i]);
|
|
|
|
-#endif
|
|
|
|
|
|
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
|
|
+ if (i == E_AXIS)
|
|
|
|
+ fsensor.init();
|
|
|
|
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -8673,44 +8529,213 @@ Sigma_Exit:
|
|
break;
|
|
break;
|
|
|
|
|
|
/*!
|
|
/*!
|
|
- ### M701 - Load filament <a href="https://reprap.org/wiki/G-code#M701:_Load_filament">M701: Load filament</a>
|
|
|
|
|
|
+ ### M701 - Load filament to extruder <a href="https://reprap.org/wiki/G-code#M701:_Load_filament">M701: Load filament</a>
|
|
|
|
+ Load filament into the active extruder.
|
|
#### Usage
|
|
#### Usage
|
|
|
|
|
|
- M701 [ E | T ]
|
|
|
|
|
|
+ M701 [ P | T | L | Z ]
|
|
|
|
|
|
#### Parameters
|
|
#### Parameters
|
|
- - `E` - ID of filament to load, ranges from 0 to 4
|
|
|
|
- - `T` - Alias of `E`. Used for compatibility with Marlin
|
|
|
|
|
|
+ - `P` - n index of MMU slot (zero based, so 0-4 like T0 and T4)
|
|
|
|
+ - `T` - Alias of `P`. Used for compatibility with Marlin
|
|
|
|
+ - `L` - Extrude distance for insertion (positive value)(manual reload)
|
|
|
|
+ - `Z` - Move the Z axis by this distance. Default value MIN_Z_FOR_LOAD
|
|
*/
|
|
*/
|
|
- case 701:
|
|
|
|
- {
|
|
|
|
- if (mmu_enabled && (code_seen('E') || code_seen('T')))
|
|
|
|
- tmp_extruder = code_value_uint8();
|
|
|
|
- gcode_M701();
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
|
|
+ case 701:
|
|
|
|
+ {
|
|
|
|
+ uint8_t mmuSlotIndex = 0xffU;
|
|
|
|
+ float fastLoadLength = FILAMENTCHANGE_FIRSTFEED; // Only used without MMU
|
|
|
|
+ float z_target = MIN_Z_FOR_LOAD;
|
|
|
|
+ if( MMU2::mmu2.Enabled() )
|
|
|
|
+ {
|
|
|
|
+ if( code_seen('P') || code_seen('T') ) {
|
|
|
|
+ mmuSlotIndex = code_value_uint8();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (code_seen('L')) fastLoadLength = code_value();
|
|
|
|
+
|
|
|
|
+ // Z lift. For safety only allow positive values
|
|
|
|
+ if (code_seen('Z')) z_target = fabs(code_value());
|
|
|
|
+
|
|
|
|
+ // Raise the Z axis
|
|
|
|
+ float delta = raise_z(z_target);
|
|
|
|
+
|
|
|
|
+ // Load filament
|
|
|
|
+ gcode_M701(fastLoadLength, mmuSlotIndex);
|
|
|
|
+
|
|
|
|
+ // Restore Z axis
|
|
|
|
+ raise_z(-delta);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### M702 - Unload filament <a href="https://reprap.org/wiki/G-code#M702:_Unload_filament">G32: Undock Z Probe sled</a>
|
|
### M702 - Unload filament <a href="https://reprap.org/wiki/G-code#M702:_Unload_filament">G32: Undock Z Probe sled</a>
|
|
#### Usage
|
|
#### Usage
|
|
|
|
|
|
- M702 [ C ]
|
|
|
|
|
|
+ M702 [ U | Z ]
|
|
|
|
|
|
#### Parameters
|
|
#### Parameters
|
|
- - `C` - Unload just current filament
|
|
|
|
- - without any parameters unload all filaments
|
|
|
|
|
|
+ - `U` - Retract distance for removal (manual reload). Default value is 0.
|
|
|
|
+ - `Z` - Move the Z axis by this distance. Default value MIN_Z_FOR_UNLOAD.
|
|
*/
|
|
*/
|
|
- case 702:
|
|
|
|
- {
|
|
|
|
- if (code_seen('C')) {
|
|
|
|
- if(mmu_enabled) extr_unload(); //! if "C" unload current filament; if mmu is not present no action is performed
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- if(mmu_enabled) extr_unload(); //! unload current filament
|
|
|
|
- else unload_filament();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
|
|
+ case 702:
|
|
|
|
+ {
|
|
|
|
+ float z_target = MIN_Z_FOR_UNLOAD;
|
|
|
|
+ float unloadLength = FILAMENTCHANGE_FINALRETRACT;
|
|
|
|
+ if (code_seen('U')) unloadLength = code_value();
|
|
|
|
+
|
|
|
|
+ // For safety only allow positive values
|
|
|
|
+ if (code_seen('Z')) z_target = fabs(code_value());
|
|
|
|
+
|
|
|
|
+ // Raise the Z axis
|
|
|
|
+ float delta = raise_z(z_target);
|
|
|
|
+
|
|
|
|
+ // Unload filament
|
|
|
|
+ if (MMU2::mmu2.Enabled()) MMU2::mmu2.unload();
|
|
|
|
+ else unload_filament(unloadLength);
|
|
|
|
+
|
|
|
|
+ // Restore Z axis
|
|
|
|
+ raise_z(-delta);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ /*!
|
|
|
|
+ ### M704 - Load to MMU <a href="https://reprap.org/wiki/G-code#M704:_Load_to_MMU">M704: Load to MMU</a>
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M704 [ P ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `P` - n index of slot (zero based, so 0-4 like T0 and T4)
|
|
|
|
+ */
|
|
|
|
+ case 704:
|
|
|
|
+ {
|
|
|
|
+ gcodes_M704_M705_M706(704);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ /*!
|
|
|
|
+ ### M705 - Eject filament <a href="https://reprap.org/wiki/G-code#M705:_Eject_filament">M705: Eject filament</a>
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M705 [ P ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `P` - n index of slot (zero based, so 0-4 like T0 and T4)
|
|
|
|
+ */
|
|
|
|
+ case 705:
|
|
|
|
+ {
|
|
|
|
+ gcodes_M704_M705_M706(705);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /*!
|
|
|
|
+ ### M706 - Cut filament <a href="https://reprap.org/wiki/G-code#M706:_Cut_filament">M706: Cut filament</a>
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M706 [ P ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `P` - n index of slot (zero based, so 0-4 like T0 and T4)
|
|
|
|
+ */
|
|
|
|
+ case 706:
|
|
|
|
+ {
|
|
|
|
+ gcodes_M704_M705_M706(706);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ /*!
|
|
|
|
+ ### M707 - Read from MMU register <a href="https://reprap.org/wiki/G-code#M707:_Read_from_MMU_register">M707: Read from MMU register</a>
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M707 [ A ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `A` - Address of register in hexidecimal.
|
|
|
|
+
|
|
|
|
+ #### Example
|
|
|
|
+
|
|
|
|
+ M707 A0x1b - Read a 8bit integer from register 0x1b and prints the result onto the serial line.
|
|
|
|
+
|
|
|
|
+ Does nothing if the A parameter is not present or if MMU is not enabled.
|
|
|
|
+
|
|
|
|
+ */
|
|
|
|
+ case 707: {
|
|
|
|
+ if ( MMU2::mmu2.Enabled() ) {
|
|
|
|
+ if( code_seen('A') ) {
|
|
|
|
+ MMU2::mmu2.ReadRegister(uint8_t(strtol(strchr_pointer+1, NULL, 16)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+
|
|
|
|
+ /*!
|
|
|
|
+ ### M708 - Write to MMU register <a href="https://reprap.org/wiki/G-code#M708:_Write_to_MMU_register">M707: Write to MMU register</a>
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M708 [ A | X ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `A` - Address of register in hexidecimal.
|
|
|
|
+ - `X` - Data to write (16-bit integer). Default value 0.
|
|
|
|
+
|
|
|
|
+ #### Example
|
|
|
|
+ M708 A0x1b X05 - Write to register 0x1b the value 05.
|
|
|
|
+
|
|
|
|
+ Does nothing if A parameter is missing or if MMU is not enabled.
|
|
|
|
+ */
|
|
|
|
+ case 708: {
|
|
|
|
+ if ( MMU2::mmu2.Enabled() ){
|
|
|
|
+ uint8_t addr = 0;
|
|
|
|
+ if( code_seen('A') ) {
|
|
|
|
+ addr = uint8_t(strtol(strchr_pointer+1, NULL, 16));
|
|
|
|
+ }
|
|
|
|
+ uint16_t data = 0;
|
|
|
|
+ if( code_seen('X') ) {
|
|
|
|
+ data = code_value_short();
|
|
|
|
+ }
|
|
|
|
+ if(addr){
|
|
|
|
+ MMU2::mmu2.WriteRegister(addr, data);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+
|
|
|
|
+ /*!
|
|
|
|
+ ### M709 - MMU reset <a href="https://reprap.org/wiki/G-code#M709:_MMU_reset">M709: MMU reset</a>
|
|
|
|
+ The MK3S cannot not power off the MMU, for that reason the functionality is not supported.
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ M709 [ X ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `X` - Reset MMU (0:soft reset | 1:hardware reset)
|
|
|
|
+
|
|
|
|
+ #### Example
|
|
|
|
+
|
|
|
|
+ M709 X0 - issue an X0 command via communication into the MMU (soft reset)
|
|
|
|
+
|
|
|
|
+ M709 X1 - toggle the MMU's reset pin (hardware reset)
|
|
|
|
+
|
|
|
|
+ */
|
|
|
|
+ case 709:
|
|
|
|
+ {
|
|
|
|
+ if (MMU2::mmu2.Enabled() && code_seen('X'))
|
|
|
|
+ {
|
|
|
|
+ switch (code_value_uint8())
|
|
|
|
+ {
|
|
|
|
+ case 0:
|
|
|
|
+ MMU2::mmu2.Reset(MMU2::MMU2::Software);
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ MMU2::mmu2.Reset(MMU2::MMU2::ResetPin);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### M999 - Restart after being stopped <a href="https://reprap.org/wiki/G-code#M999:_Restart_after_being_stopped_by_error">M999: Restart after being stopped by error</a>
|
|
### M999 - Restart after being stopped <a href="https://reprap.org/wiki/G-code#M999:_Restart_after_being_stopped_by_error">M999: Restart after being stopped by error</a>
|
|
@@ -8719,7 +8744,7 @@ Sigma_Exit:
|
|
case 999:
|
|
case 999:
|
|
Stopped = false;
|
|
Stopped = false;
|
|
lcd_reset_alert_level();
|
|
lcd_reset_alert_level();
|
|
- gcode_LastN = Stopped_gcode_LastN;
|
|
|
|
|
|
+//@@TODO gcode_LastN = Stopped_gcode_LastN;
|
|
FlushSerialRequestResend();
|
|
FlushSerialRequestResend();
|
|
break;
|
|
break;
|
|
/*!
|
|
/*!
|
|
@@ -8743,139 +8768,8 @@ Sigma_Exit:
|
|
@n Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
|
|
@n Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
|
|
@n Tc Load to nozzle after filament was prepared by Tc and extruder nozzle is already heated.
|
|
@n Tc Load to nozzle after filament was prepared by Tc and extruder nozzle is already heated.
|
|
*/
|
|
*/
|
|
- else if(code_seen('T'))
|
|
|
|
- {
|
|
|
|
- static const char duplicate_Tcode_ignored[] PROGMEM = "Duplicate T-code ignored.";
|
|
|
|
-
|
|
|
|
- int index;
|
|
|
|
- bool load_to_nozzle = false;
|
|
|
|
- for (index = 1; *(strchr_pointer + index) == ' ' || *(strchr_pointer + index) == '\t'; index++);
|
|
|
|
-
|
|
|
|
- *(strchr_pointer + index) = tolower(*(strchr_pointer + index));
|
|
|
|
-
|
|
|
|
- if ((*(strchr_pointer + index) < '0' || *(strchr_pointer + index) > '4') && *(strchr_pointer + index) != '?' && *(strchr_pointer + index) != 'x' && *(strchr_pointer + index) != 'c') {
|
|
|
|
- SERIAL_ECHOLNPGM("Invalid T code.");
|
|
|
|
- }
|
|
|
|
- else if (*(strchr_pointer + index) == 'x'){ //load to bondtech gears; if mmu is not present do nothing
|
|
|
|
- if (mmu_enabled)
|
|
|
|
- {
|
|
|
|
- tmp_extruder = choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT));
|
|
|
|
- if ((tmp_extruder == mmu_extruder) && mmu_fil_loaded) //dont execute the same T-code twice in a row
|
|
|
|
- {
|
|
|
|
- puts_P(duplicate_Tcode_ignored);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- st_synchronize();
|
|
|
|
- mmu_command(MmuCmd::T0 + tmp_extruder);
|
|
|
|
- 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_continue_loading(usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal));
|
|
|
|
- mmu_extruder = tmp_extruder; //filament change is finished
|
|
|
|
- mmu_load_to_nozzle();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- if (*(strchr_pointer + index) == '?')
|
|
|
|
- {
|
|
|
|
- if(mmu_enabled)
|
|
|
|
- {
|
|
|
|
- tmp_extruder = choose_menu_P(_T(MSG_SELECT_FILAMENT), _T(MSG_FILAMENT));
|
|
|
|
- load_to_nozzle = true;
|
|
|
|
- } else
|
|
|
|
- {
|
|
|
|
- tmp_extruder = choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- tmp_extruder = code_value();
|
|
|
|
- if (mmu_enabled && lcd_autoDepleteEnabled())
|
|
|
|
- {
|
|
|
|
- tmp_extruder = ad_getAlternative(tmp_extruder);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- st_synchronize();
|
|
|
|
-
|
|
|
|
- if (mmu_enabled)
|
|
|
|
- {
|
|
|
|
- if ((tmp_extruder == mmu_extruder) && mmu_fil_loaded) //dont execute the same T-code twice in a row
|
|
|
|
- {
|
|
|
|
- puts_P(duplicate_Tcode_ignored);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
-#if defined(MMU_HAS_CUTTER) && defined(MMU_ALWAYS_CUT)
|
|
|
|
- if (EEPROM_MMU_CUTTER_ENABLED_always == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
|
|
|
|
- {
|
|
|
|
- mmu_command(MmuCmd::K0 + tmp_extruder);
|
|
|
|
- manage_response(true, true, MMU_UNLOAD_MOVE);
|
|
|
|
- }
|
|
|
|
-#endif //defined(MMU_HAS_CUTTER) && defined(MMU_ALWAYS_CUT)
|
|
|
|
- mmu_command(MmuCmd::T0 + tmp_extruder);
|
|
|
|
- manage_response(true, true, MMU_TCODE_MOVE);
|
|
|
|
- mmu_continue_loading(usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal));
|
|
|
|
-
|
|
|
|
- mmu_extruder = tmp_extruder; //filament change is finished
|
|
|
|
-
|
|
|
|
- if (load_to_nozzle)// for single material usage with mmu
|
|
|
|
- {
|
|
|
|
- mmu_load_to_nozzle();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if (tmp_extruder >= EXTRUDERS) {
|
|
|
|
- SERIAL_ECHO_START;
|
|
|
|
- SERIAL_ECHO('T');
|
|
|
|
- SERIAL_PROTOCOLLN((int)tmp_extruder);
|
|
|
|
- SERIAL_ECHOLNRPGM(_n("Invalid extruder"));////MSG_INVALID_EXTRUDER
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
-#if EXTRUDERS > 1
|
|
|
|
- bool make_move = false;
|
|
|
|
-#endif
|
|
|
|
- if (code_seen('F')) {
|
|
|
|
-#if EXTRUDERS > 1
|
|
|
|
- make_move = true;
|
|
|
|
-#endif
|
|
|
|
- next_feedrate = code_value();
|
|
|
|
- if (next_feedrate > 0.0) {
|
|
|
|
- feedrate = next_feedrate;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-#if EXTRUDERS > 1
|
|
|
|
- if (tmp_extruder != active_extruder) {
|
|
|
|
- // Save current position to return to after applying extruder offset
|
|
|
|
- set_destination_to_current();
|
|
|
|
- // Offset extruder (only by XY)
|
|
|
|
- int i;
|
|
|
|
- for (i = 0; i < 2; i++) {
|
|
|
|
- current_position[i] = current_position[i] -
|
|
|
|
- extruder_offset[i][active_extruder] +
|
|
|
|
- extruder_offset[i][tmp_extruder];
|
|
|
|
- }
|
|
|
|
- // Set the new active extruder and position
|
|
|
|
- active_extruder = tmp_extruder;
|
|
|
|
- plan_set_position_curposXYZE();
|
|
|
|
- // Move to the old position if 'F' was in the parameters
|
|
|
|
- if (make_move && Stopped == false) {
|
|
|
|
- prepare_move();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
- SERIAL_ECHO_START;
|
|
|
|
- SERIAL_ECHORPGM(_n("Active Extruder: "));////MSG_ACTIVE_EXTRUDER
|
|
|
|
- SERIAL_PROTOCOLLN((int)active_extruder);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ else if(code_seen('T')){
|
|
|
|
+ TCodes(strchr_pointer, code_value());
|
|
} // end if(code_seen('T')) (end of T codes)
|
|
} // end if(code_seen('T')) (end of T codes)
|
|
/*!
|
|
/*!
|
|
#### End of T-Codes
|
|
#### End of T-Codes
|
|
@@ -9139,6 +9033,23 @@ Sigma_Exit:
|
|
};
|
|
};
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef TEMP_MODEL_DEBUG
|
|
|
|
+ /*!
|
|
|
|
+ ## D70 - Enable low-level temperature model logging for offline simulation
|
|
|
|
+ #### Usage
|
|
|
|
+
|
|
|
|
+ D70 [ S ]
|
|
|
|
+
|
|
|
|
+ #### Parameters
|
|
|
|
+ - `S` - Enable 0-1 (default 0)
|
|
|
|
+ */
|
|
|
|
+ case 70: {
|
|
|
|
+ if(code_seen('S'))
|
|
|
|
+ temp_model_log_enable(code_value_short());
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
#ifdef HEATBED_ANALYSIS
|
|
#ifdef HEATBED_ANALYSIS
|
|
|
|
|
|
/*!
|
|
/*!
|
|
@@ -9246,7 +9157,7 @@ Sigma_Exit:
|
|
dcode_2130(); break;
|
|
dcode_2130(); break;
|
|
#endif //TMC2130
|
|
#endif //TMC2130
|
|
|
|
|
|
-#if (defined (FILAMENT_SENSOR) && defined(PAT9125))
|
|
|
|
|
|
+#if defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
|
|
|
|
/*!
|
|
/*!
|
|
### D9125 - PAT9125 filament sensor <a href="https://reprap.org/wiki/G-code#D9:_Read.2FWrite_ADC">D9125: PAT9125 filament sensor</a>
|
|
### D9125 - PAT9125 filament sensor <a href="https://reprap.org/wiki/G-code#D9:_Read.2FWrite_ADC">D9125: PAT9125 filament sensor</a>
|
|
@@ -9264,7 +9175,7 @@ Sigma_Exit:
|
|
*/
|
|
*/
|
|
case 9125:
|
|
case 9125:
|
|
dcode_9125(); break;
|
|
dcode_9125(); break;
|
|
-#endif //FILAMENT_SENSOR
|
|
|
|
|
|
+#endif //defined(FILAMENT_SENSOR) && (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
|
|
|
|
|
|
#endif //DEBUG_DCODES
|
|
#endif //DEBUG_DCODES
|
|
|
|
|
|
@@ -9348,8 +9259,7 @@ void update_currents() {
|
|
}
|
|
}
|
|
#endif //MOTHERBOARD == BOARD_RAMBO_MINI_1_0 || MOTHERBOARD == BOARD_RAMBO_MINI_1_3
|
|
#endif //MOTHERBOARD == BOARD_RAMBO_MINI_1_0 || MOTHERBOARD == BOARD_RAMBO_MINI_1_3
|
|
|
|
|
|
-void get_coordinates()
|
|
|
|
-{
|
|
|
|
|
|
+void get_coordinates() {
|
|
bool seen[4]={false,false,false,false};
|
|
bool seen[4]={false,false,false,false};
|
|
for(int8_t i=0; i < NUM_AXIS; i++) {
|
|
for(int8_t i=0; i < NUM_AXIS; i++) {
|
|
if(code_seen(axis_codes[i]))
|
|
if(code_seen(axis_codes[i]))
|
|
@@ -9386,31 +9296,6 @@ void get_coordinates()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void get_arc_coordinates()
|
|
|
|
-{
|
|
|
|
-#ifdef SF_ARC_FIX
|
|
|
|
- bool relative_mode_backup = relative_mode;
|
|
|
|
- relative_mode = true;
|
|
|
|
-#endif
|
|
|
|
- get_coordinates();
|
|
|
|
-#ifdef SF_ARC_FIX
|
|
|
|
- relative_mode=relative_mode_backup;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- if(code_seen('I')) {
|
|
|
|
- offset[0] = code_value();
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- offset[0] = 0.0;
|
|
|
|
- }
|
|
|
|
- if(code_seen('J')) {
|
|
|
|
- offset[1] = code_value();
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- offset[1] = 0.0;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void clamp_to_software_endstops(float target[3])
|
|
void clamp_to_software_endstops(float target[3])
|
|
{
|
|
{
|
|
#ifdef DEBUG_DISABLE_SWLIMITS
|
|
#ifdef DEBUG_DISABLE_SWLIMITS
|
|
@@ -9432,59 +9317,70 @@ void clamp_to_software_endstops(float target[3])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+uint16_t restore_interrupted_gcode() {
|
|
|
|
+ // When recovering from a previous print move, restore the originally
|
|
|
|
+ // calculated start position on the first USB/SD command. This accounts
|
|
|
|
+ // properly for relative moves
|
|
|
|
+ if (
|
|
|
|
+ (saved_start_position[0] != SAVED_START_POSITION_UNSET) && (
|
|
|
|
+ (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_SDCARD) ||
|
|
|
|
+ (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR)
|
|
|
|
+ )
|
|
|
|
+ ) {
|
|
|
|
+ memcpy(current_position, saved_start_position, sizeof(current_position));
|
|
|
|
+ saved_start_position[0] = SAVED_START_POSITION_UNSET;
|
|
|
|
+ return saved_segment_idx;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ return 1; //begin with the first segment
|
|
|
|
+}
|
|
|
|
+
|
|
#ifdef MESH_BED_LEVELING
|
|
#ifdef MESH_BED_LEVELING
|
|
-void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder) {
|
|
|
|
|
|
+void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder, uint16_t start_segment_idx = 0) {
|
|
float dx = x - current_position[X_AXIS];
|
|
float dx = x - current_position[X_AXIS];
|
|
float dy = y - current_position[Y_AXIS];
|
|
float dy = y - current_position[Y_AXIS];
|
|
- int n_segments = 0;
|
|
|
|
|
|
+ uint16_t n_segments = 0;
|
|
|
|
|
|
if (mbl.active) {
|
|
if (mbl.active) {
|
|
float len = fabs(dx) + fabs(dy);
|
|
float len = fabs(dx) + fabs(dy);
|
|
if (len > 0)
|
|
if (len > 0)
|
|
// Split to 3cm segments or shorter.
|
|
// Split to 3cm segments or shorter.
|
|
- n_segments = int(ceil(len / 30.f));
|
|
|
|
|
|
+ n_segments = uint16_t(ceil(len / 30.f));
|
|
}
|
|
}
|
|
|
|
|
|
- if (n_segments > 1) {
|
|
|
|
- // In a multi-segment move explicitly set the final target in the plan
|
|
|
|
- // as the move will be recalculated in it's entirety
|
|
|
|
- float gcode_target[NUM_AXIS];
|
|
|
|
- gcode_target[X_AXIS] = x;
|
|
|
|
- gcode_target[Y_AXIS] = y;
|
|
|
|
- gcode_target[Z_AXIS] = z;
|
|
|
|
- gcode_target[E_AXIS] = e;
|
|
|
|
|
|
+ if (n_segments > 1 && start_segment_idx) {
|
|
|
|
|
|
float dz = z - current_position[Z_AXIS];
|
|
float dz = z - current_position[Z_AXIS];
|
|
float de = e - current_position[E_AXIS];
|
|
float de = e - current_position[E_AXIS];
|
|
|
|
|
|
- for (int i = 1; i < n_segments; ++ i) {
|
|
|
|
|
|
+ for (uint16_t i = start_segment_idx; i < n_segments; ++ i) {
|
|
float t = float(i) / float(n_segments);
|
|
float t = float(i) / float(n_segments);
|
|
plan_buffer_line(current_position[X_AXIS] + t * dx,
|
|
plan_buffer_line(current_position[X_AXIS] + t * dx,
|
|
current_position[Y_AXIS] + t * dy,
|
|
current_position[Y_AXIS] + t * dy,
|
|
current_position[Z_AXIS] + t * dz,
|
|
current_position[Z_AXIS] + t * dz,
|
|
current_position[E_AXIS] + t * de,
|
|
current_position[E_AXIS] + t * de,
|
|
- feed_rate, extruder, gcode_target);
|
|
|
|
- if (waiting_inside_plan_buffer_line_print_aborted)
|
|
|
|
|
|
+ feed_rate, extruder, current_position, i);
|
|
|
|
+ if (planner_aborted)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// The rest of the path.
|
|
// The rest of the path.
|
|
- plan_buffer_line(x, y, z, e, feed_rate, extruder);
|
|
|
|
|
|
+ plan_buffer_line(x, y, z, e, feed_rate, extruder, current_position);
|
|
}
|
|
}
|
|
#endif // MESH_BED_LEVELING
|
|
#endif // MESH_BED_LEVELING
|
|
|
|
|
|
-void prepare_move()
|
|
|
|
|
|
+void prepare_move(uint16_t start_segment_idx)
|
|
{
|
|
{
|
|
clamp_to_software_endstops(destination);
|
|
clamp_to_software_endstops(destination);
|
|
previous_millis_cmd.start();
|
|
previous_millis_cmd.start();
|
|
|
|
|
|
// Do not use feedmultiply for E or Z only moves
|
|
// Do not use feedmultiply for E or Z only moves
|
|
- if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
|
|
|
|
|
|
+ if((current_position[X_AXIS] == destination[X_AXIS]) && (current_position[Y_AXIS] == destination[Y_AXIS])) {
|
|
plan_buffer_line_destinationXYZE(feedrate/60);
|
|
plan_buffer_line_destinationXYZE(feedrate/60);
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
#ifdef MESH_BED_LEVELING
|
|
#ifdef MESH_BED_LEVELING
|
|
- mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder);
|
|
|
|
|
|
+ mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder, start_segment_idx);
|
|
#else
|
|
#else
|
|
plan_buffer_line_destinationXYZE(feedrate*feedmultiply*(1./(60.f*100.f)));
|
|
plan_buffer_line_destinationXYZE(feedrate*feedmultiply*(1./(60.f*100.f)));
|
|
#endif
|
|
#endif
|
|
@@ -9493,10 +9389,10 @@ void prepare_move()
|
|
set_current_to_destination();
|
|
set_current_to_destination();
|
|
}
|
|
}
|
|
|
|
|
|
-void prepare_arc_move(bool isclockwise) {
|
|
|
|
|
|
+void prepare_arc_move(bool isclockwise, uint16_t start_segment_idx) {
|
|
float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
|
|
float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
|
|
// Trace the arc
|
|
// Trace the arc
|
|
- mc_arc(current_position, destination, offset, feedrate * feedmultiply / 60 / 100.0, r, isclockwise, active_extruder);
|
|
|
|
|
|
+ mc_arc(current_position, destination, offset, feedrate * feedmultiply / 60 / 100.0, r, isclockwise, active_extruder, start_segment_idx);
|
|
// As far as the parser is concerned, the position is now == target. In reality the
|
|
// As far as the parser is concerned, the position is now == target. In reality the
|
|
// motion control system might still be processing the action and the real tool position
|
|
// motion control system might still be processing the action and the real tool position
|
|
// in any intermediate location.
|
|
// in any intermediate location.
|
|
@@ -9566,7 +9462,7 @@ static void handleSafetyTimer()
|
|
#if (EXTRUDERS > 1)
|
|
#if (EXTRUDERS > 1)
|
|
#error Implemented only for one extruder.
|
|
#error Implemented only for one extruder.
|
|
#endif //(EXTRUDERS > 1)
|
|
#endif //(EXTRUDERS > 1)
|
|
- if ((PRINTER_ACTIVE) || (!degTargetBed() && !degTargetHotend(0)) || (!safetytimer_inactive_time))
|
|
|
|
|
|
+ if (printer_active() || (!degTargetBed() && !degTargetHotend(0)) || (!safetytimer_inactive_time))
|
|
{
|
|
{
|
|
safetyTimer.stop();
|
|
safetyTimer.stop();
|
|
}
|
|
}
|
|
@@ -9583,134 +9479,13 @@ static void handleSafetyTimer()
|
|
}
|
|
}
|
|
#endif //SAFETYTIMER
|
|
#endif //SAFETYTIMER
|
|
|
|
|
|
-#ifdef IR_SENSOR_ANALOG
|
|
|
|
-#define FS_CHECK_COUNT 16
|
|
|
|
-/// Switching mechanism of the fsensor type.
|
|
|
|
-/// Called from 2 spots which have a very similar behavior
|
|
|
|
-/// 1: ClFsensorPCB::_Old -> ClFsensorPCB::_Rev04 and print _i("FS v0.4 or newer")
|
|
|
|
-/// 2: ClFsensorPCB::_Rev04 -> oFsensorPCB=ClFsensorPCB::_Old and print _i("FS v0.3 or older")
|
|
|
|
-void manage_inactivity_IR_ANALOG_Check(uint16_t &nFSCheckCount, ClFsensorPCB isVersion, ClFsensorPCB switchTo, const char *statusLineTxt_P) {
|
|
|
|
- bool bTemp = (!CHECK_ALL_HEATERS);
|
|
|
|
- bTemp = bTemp && (menu_menu == lcd_status_screen);
|
|
|
|
- bTemp = bTemp && ((oFsensorPCB == isVersion) || (oFsensorPCB == ClFsensorPCB::_Undef));
|
|
|
|
- bTemp = bTemp && fsensor_enabled;
|
|
|
|
- if (bTemp) {
|
|
|
|
- nFSCheckCount++;
|
|
|
|
- if (nFSCheckCount > FS_CHECK_COUNT) {
|
|
|
|
- nFSCheckCount = 0; // not necessary
|
|
|
|
- oFsensorPCB = switchTo;
|
|
|
|
- eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_PCB, (uint8_t)oFsensorPCB);
|
|
|
|
- printf_IRSensorAnalogBoardChange();
|
|
|
|
- lcd_setstatuspgm(statusLineTxt_P);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- nFSCheckCount = 0;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h
|
|
void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h
|
|
{
|
|
{
|
|
#ifdef FILAMENT_SENSOR
|
|
#ifdef FILAMENT_SENSOR
|
|
-bool bInhibitFlag = false;
|
|
|
|
-#ifdef IR_SENSOR_ANALOG
|
|
|
|
-static uint16_t nFSCheckCount=0;
|
|
|
|
-#endif // IR_SENSOR_ANALOG
|
|
|
|
-
|
|
|
|
- if (mmu_enabled == false)
|
|
|
|
- {
|
|
|
|
-//-// if (mcode_in_progress != 600) //M600 not in progress
|
|
|
|
- if (!PRINTER_ACTIVE) bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); //Block Filament sensor actions if PRINTER is not active and Support::SensorInfo menu active
|
|
|
|
-#ifdef IR_SENSOR_ANALOG
|
|
|
|
- bInhibitFlag=bInhibitFlag||bMenuFSDetect; // Block Filament sensor actions if Settings::HWsetup::FSdetect menu active
|
|
|
|
-#endif // IR_SENSOR_ANALOG
|
|
|
|
- if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag) && (menu_menu != lcd_move_e)) //M600 not in progress, preHeat @ autoLoad menu not active
|
|
|
|
- {
|
|
|
|
- if (!moves_planned() && !IS_SD_PRINTING && !usb_timer.running() && (lcd_commands_type != LcdCommands::Layer1Cal) && ! eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
|
|
|
|
- {
|
|
|
|
-#ifdef IR_SENSOR_ANALOG
|
|
|
|
- static uint16_t minVolt = Voltage2Raw(6.F), maxVolt = 0;
|
|
|
|
- // detect min-max, some long term sliding window for filtration may be added
|
|
|
|
- // avoiding floating point operations, thus computing in raw
|
|
|
|
- if( current_voltage_raw_IR > maxVolt )maxVolt = current_voltage_raw_IR;
|
|
|
|
- if( current_voltage_raw_IR < minVolt )minVolt = current_voltage_raw_IR;
|
|
|
|
-
|
|
|
|
-#if 0 // Start: IR Sensor debug info
|
|
|
|
- { // debug print
|
|
|
|
- static uint16_t lastVolt = ~0U;
|
|
|
|
- if( current_voltage_raw_IR != lastVolt ){
|
|
|
|
- printf_P(PSTR("fs volt=%4.2fV (min=%4.2f max=%4.2f)\n"), Raw2Voltage(current_voltage_raw_IR), Raw2Voltage(minVolt), Raw2Voltage(maxVolt) );
|
|
|
|
- lastVolt = current_voltage_raw_IR;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-#endif // End: IR Sensor debug info
|
|
|
|
- //! The trouble is, I can hold the filament in the hole in such a way, that it creates the exact voltage
|
|
|
|
- //! to be detected as the new fsensor
|
|
|
|
- //! We can either fake it by extending the detection window to a looooong time
|
|
|
|
- //! or do some other countermeasures
|
|
|
|
-
|
|
|
|
- //! what we want to detect:
|
|
|
|
- //! if minvolt gets below ~0.3V, it means there is an old fsensor
|
|
|
|
- //! if maxvolt gets above 4.6V, it means we either have an old fsensor or broken cables/fsensor
|
|
|
|
- //! So I'm waiting for a situation, when minVolt gets to range <0, 1.5> and maxVolt gets into range <3.0, 5>
|
|
|
|
- //! If and only if minVolt is in range <0.3, 1.5> and maxVolt is in range <3.0, 4.6>, I'm considering a situation with the new fsensor
|
|
|
|
- if( minVolt >= IRsensor_Ldiode_TRESHOLD && minVolt <= IRsensor_Lmax_TRESHOLD
|
|
|
|
- && maxVolt >= IRsensor_Hmin_TRESHOLD && maxVolt <= IRsensor_Hopen_TRESHOLD
|
|
|
|
- ){
|
|
|
|
- manage_inactivity_IR_ANALOG_Check(nFSCheckCount, ClFsensorPCB::_Old, ClFsensorPCB::_Rev04, _i("FS v0.4 or newer") ); ////MSG_FS_V_04_OR_NEWER c=18
|
|
|
|
- }
|
|
|
|
- //! If and only if minVolt is in range <0.0, 0.3> and maxVolt is in range <4.6, 5.0V>, I'm considering a situation with the old fsensor
|
|
|
|
- //! Note, we are not relying on one voltage here - getting just +5V can mean an old fsensor or a broken new sensor - that's why
|
|
|
|
- //! we need to have both voltages detected correctly to allow switching back to the old fsensor.
|
|
|
|
- else if( minVolt < IRsensor_Ldiode_TRESHOLD
|
|
|
|
- && maxVolt > IRsensor_Hopen_TRESHOLD && maxVolt <= IRsensor_VMax_TRESHOLD
|
|
|
|
- ){
|
|
|
|
- manage_inactivity_IR_ANALOG_Check(nFSCheckCount, ClFsensorPCB::_Rev04, oFsensorPCB=ClFsensorPCB::_Old, _i("FS v0.3 or older")); ////MSG_FS_V_03_OR_OLDER c=18
|
|
|
|
- }
|
|
|
|
-#endif // IR_SENSOR_ANALOG
|
|
|
|
- if (fsensor_check_autoload())
|
|
|
|
- {
|
|
|
|
-#ifdef PAT9125
|
|
|
|
- fsensor_autoload_check_stop();
|
|
|
|
-#endif //PAT9125
|
|
|
|
-//-// if ((int)degHotend0() > extrude_min_temp)
|
|
|
|
-if(0)
|
|
|
|
- {
|
|
|
|
- Sound_MakeCustom(50,1000,false);
|
|
|
|
- loading_flag = true;
|
|
|
|
- enquecommand_front_P((PSTR("M701")));
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
-/*
|
|
|
|
- lcd_update_enable(false);
|
|
|
|
- show_preheat_nozzle_warning();
|
|
|
|
- lcd_update_enable(true);
|
|
|
|
-*/
|
|
|
|
- eFilamentAction=FilamentAction::AutoLoad;
|
|
|
|
- bFilamentFirstRun=false;
|
|
|
|
- if(target_temperature[0] >= extrude_min_temp){
|
|
|
|
- bFilamentPreheatState=true;
|
|
|
|
-// mFilamentItem(target_temperature[0],target_temperature_bed);
|
|
|
|
- menu_submenu(mFilamentItemForce);
|
|
|
|
- } else {
|
|
|
|
- menu_submenu(lcd_generic_preheat_menu);
|
|
|
|
- lcd_timeoutToStatus.start();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
-#ifdef PAT9125
|
|
|
|
- fsensor_autoload_check_stop();
|
|
|
|
-#endif //PAT9125
|
|
|
|
- if (fsensor_enabled && !saved_printing)
|
|
|
|
- fsensor_update();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-#endif //FILAMENT_SENSOR
|
|
|
|
|
|
+ if (fsensor.update()) {
|
|
|
|
+ lcd_draw_update = 1; //cause lcd update so that fsensor event polling can be done from the lcd draw routine.
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
|
|
#ifdef SAFETYTIMER
|
|
#ifdef SAFETYTIMER
|
|
handleSafetyTimer();
|
|
handleSafetyTimer();
|
|
@@ -9795,7 +9570,7 @@ if(0)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
check_axes_activity();
|
|
check_axes_activity();
|
|
- mmu_loop();
|
|
|
|
|
|
+ MMU2::mmu2.mmu_loop();
|
|
|
|
|
|
// handle longpress
|
|
// handle longpress
|
|
if(lcd_longpress_trigger)
|
|
if(lcd_longpress_trigger)
|
|
@@ -9866,6 +9641,7 @@ void UnconditionalStop()
|
|
// Disable all heaters and unroll the temperature wait loop stack
|
|
// Disable all heaters and unroll the temperature wait loop stack
|
|
disable_heater();
|
|
disable_heater();
|
|
cancel_heatup = true;
|
|
cancel_heatup = true;
|
|
|
|
+ heating_status = HeatingStatus::NO_HEATING;
|
|
|
|
|
|
// Clear any saved printing state
|
|
// Clear any saved printing state
|
|
cancel_saved_printing();
|
|
cancel_saved_printing();
|
|
@@ -9885,39 +9661,60 @@ void UnconditionalStop()
|
|
CRITICAL_SECTION_END;
|
|
CRITICAL_SECTION_END;
|
|
}
|
|
}
|
|
|
|
|
|
-// Stop: Emergency stop used by overtemp functions which allows recovery
|
|
|
|
-//
|
|
|
|
-// In addition to stopping the print, this prevents subsequent G[0-3] commands to be
|
|
|
|
-// processed via USB (using "Stopped") until the print is resumed via M999 or
|
|
|
|
-// manually started from scratch with the LCD.
|
|
|
|
|
|
+// Emergency stop used by overtemp functions which allows recovery
|
|
|
|
+// WARNING: This function is called *continuously* during a thermal failure.
|
|
//
|
|
//
|
|
-// Note that the current instruction is completely discarded, so resuming from Stop()
|
|
|
|
-// will introduce either over/under extrusion on the current segment, and will not
|
|
|
|
-// survive a power panic. Switching Stop() to use the pause machinery instead (with
|
|
|
|
-// the addition of disabling the headers) could allow true recovery in the future.
|
|
|
|
-void Stop()
|
|
|
|
|
|
+// This either pauses (for thermal model errors) or stops *without recovery* depending on
|
|
|
|
+// "allow_pause". If pause is allowed, this forces a printer-initiated instantanenous pause (just
|
|
|
|
+// like an LCD pause) that bypasses the host pausing functionality. In this state the printer is
|
|
|
|
+// kept in busy state and *must* be recovered from the LCD.
|
|
|
|
+void ThermalStop(bool allow_pause)
|
|
{
|
|
{
|
|
- // Keep disabling heaters
|
|
|
|
- disable_heater();
|
|
|
|
|
|
+ if(Stopped == false) {
|
|
|
|
+ Stopped = true;
|
|
|
|
+ if(allow_pause && (IS_SD_PRINTING || usb_timer.running())) {
|
|
|
|
+ if (!isPrintPaused) {
|
|
|
|
+ lcd_setalertstatuspgm(_T(MSG_PAUSED_THERMAL_ERROR), LCD_STATUS_CRITICAL);
|
|
|
|
+
|
|
|
|
+ // we cannot make a distinction for the host here, the pause must be instantaneous
|
|
|
|
+ // so we call the lcd_pause_print to save the print state internally. Thermal errors
|
|
|
|
+ // disable heaters and save the original temperatures to saved_*, which will get
|
|
|
|
+ // overwritten by stop_and_save_print_to_ram. For this corner-case, re-instate the
|
|
|
|
+ // original values after the pause handler is called.
|
|
|
|
+ float bed_temp = saved_bed_temperature;
|
|
|
|
+ float ext_temp = saved_extruder_temperature;
|
|
|
|
+ int fan_speed = saved_fan_speed;
|
|
|
|
+ lcd_pause_print();
|
|
|
|
+ saved_bed_temperature = bed_temp;
|
|
|
|
+ saved_extruder_temperature = ext_temp;
|
|
|
|
+ saved_fan_speed = fan_speed;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ // We got a hard thermal error and/or there is no print going on. Just stop.
|
|
|
|
+ lcd_print_stop();
|
|
|
|
|
|
- // Call the regular stop function if that's the first time during a new print
|
|
|
|
- if(Stopped == false) {
|
|
|
|
- Stopped = true;
|
|
|
|
- lcd_print_stop();
|
|
|
|
- Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
|
|
|
|
|
+ // Also prevent further menu entry
|
|
|
|
+ menu_set_block(MENU_BLOCK_THERMAL_ERROR);
|
|
|
|
+ }
|
|
|
|
|
|
- // Eventually report the stopped status (though this is usually overridden by a
|
|
|
|
- // higher-priority alert status message)
|
|
|
|
- SERIAL_ERROR_START;
|
|
|
|
- SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
|
|
|
- LCD_MESSAGERPGM(_T(MSG_STOPPED));
|
|
|
|
- }
|
|
|
|
|
|
+ // Report the status on the serial, switch to a busy state
|
|
|
|
+ SERIAL_ERROR_START;
|
|
|
|
+ SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
|
|
|
|
|
|
- // Return to the status screen to stop any pending menu action which could have been
|
|
|
|
- // started by the user while stuck in the Stopped state. This also ensures the NEW
|
|
|
|
- // error is immediately shown.
|
|
|
|
- if (menu_menu != lcd_status_screen)
|
|
|
|
- lcd_return_to_status();
|
|
|
|
|
|
+ // Eventually report the stopped status on the lcd (though this is usually overridden by a
|
|
|
|
+ // higher-priority alert status message)
|
|
|
|
+ LCD_MESSAGERPGM(_T(MSG_STOPPED));
|
|
|
|
+
|
|
|
|
+ // Make a warning sound! We cannot use Sound_MakeCustom as this would stop further moves.
|
|
|
|
+ // Turn on the speaker here (if not already), and turn it off when back in the main loop.
|
|
|
|
+ WRITE(BEEPER, HIGH);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Return to the status screen to stop any pending menu action which could have been
|
|
|
|
+ // started by the user while stuck in the Stopped state. This also ensures the NEW
|
|
|
|
+ // error is immediately shown.
|
|
|
|
+ if (menu_menu != lcd_status_screen)
|
|
|
|
+ lcd_return_to_status();
|
|
}
|
|
}
|
|
|
|
|
|
bool IsStopped() { return Stopped; };
|
|
bool IsStopped() { return Stopped; };
|
|
@@ -10029,23 +9826,9 @@ bool setTargetedHotend(int code, uint8_t &extruder)
|
|
extruder = code_value_uint8();
|
|
extruder = code_value_uint8();
|
|
if(extruder >= EXTRUDERS) {
|
|
if(extruder >= EXTRUDERS) {
|
|
SERIAL_ECHO_START;
|
|
SERIAL_ECHO_START;
|
|
- switch(code){
|
|
|
|
- case 104:
|
|
|
|
- SERIAL_ECHORPGM(_n("M104 Invalid extruder "));////MSG_M104_INVALID_EXTRUDER
|
|
|
|
- break;
|
|
|
|
- case 105:
|
|
|
|
- SERIAL_ECHORPGM(_n("M105 Invalid extruder "));////MSG_M105_INVALID_EXTRUDER
|
|
|
|
- break;
|
|
|
|
- case 109:
|
|
|
|
- SERIAL_ECHORPGM(_n("M109 Invalid extruder "));////MSG_M109_INVALID_EXTRUDER
|
|
|
|
- break;
|
|
|
|
- case 218:
|
|
|
|
- SERIAL_ECHORPGM(_n("M218 Invalid extruder "));////MSG_M218_INVALID_EXTRUDER
|
|
|
|
- break;
|
|
|
|
- case 221:
|
|
|
|
- SERIAL_ECHORPGM(_n("M221 Invalid extruder "));////MSG_M221_INVALID_EXTRUDER
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ serialprintPGM(PSTR("M"));
|
|
|
|
+ SERIAL_ECHO(code);
|
|
|
|
+ SERIAL_ECHOPGM(" Invalid extruder ");
|
|
SERIAL_PROTOCOLLN((int)extruder);
|
|
SERIAL_PROTOCOLLN((int)extruder);
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -10749,20 +10532,27 @@ void long_pause() //long pause print
|
|
start_pause_print = _millis();
|
|
start_pause_print = _millis();
|
|
|
|
|
|
// Stop heaters
|
|
// Stop heaters
|
|
|
|
+ heating_status = HeatingStatus::NO_HEATING;
|
|
setAllTargetHotends(0);
|
|
setAllTargetHotends(0);
|
|
|
|
|
|
- //lift z
|
|
|
|
- current_position[Z_AXIS] += Z_PAUSE_LIFT;
|
|
|
|
- clamp_to_software_endstops(current_position);
|
|
|
|
- plan_buffer_line_curposXYZE(15);
|
|
|
|
|
|
+ // Lift z
|
|
|
|
+ raise_z(Z_PAUSE_LIFT);
|
|
|
|
|
|
- //Move XY to side
|
|
|
|
- current_position[X_AXIS] = X_PAUSE_POS;
|
|
|
|
- current_position[Y_AXIS] = Y_PAUSE_POS;
|
|
|
|
- plan_buffer_line_curposXYZE(50);
|
|
|
|
|
|
+ // Move XY to side
|
|
|
|
+ if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) {
|
|
|
|
+ current_position[X_AXIS] = X_PAUSE_POS;
|
|
|
|
+ current_position[Y_AXIS] = Y_PAUSE_POS;
|
|
|
|
+ plan_buffer_line_curposXYZE(50);
|
|
|
|
+ }
|
|
|
|
|
|
- // Turn off the print fan
|
|
|
|
- fanSpeed = 0;
|
|
|
|
|
|
+ // did we come here from a thermal error?
|
|
|
|
+ if(get_temp_error()) {
|
|
|
|
+ // time to stop the error beep
|
|
|
|
+ WRITE(BEEPER, LOW);
|
|
|
|
+ } else {
|
|
|
|
+ // Turn off the print fan
|
|
|
|
+ fanSpeed = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void serialecho_temperatures() {
|
|
void serialecho_temperatures() {
|
|
@@ -10829,13 +10619,15 @@ void uvlo_()
|
|
uint16_t feedrate_bckp;
|
|
uint16_t feedrate_bckp;
|
|
if (current_block && !pos_invalid)
|
|
if (current_block && !pos_invalid)
|
|
{
|
|
{
|
|
- memcpy(saved_target, current_block->gcode_target, sizeof(saved_target));
|
|
|
|
|
|
+ memcpy(saved_start_position, current_block->gcode_start_position, sizeof(saved_start_position));
|
|
feedrate_bckp = current_block->gcode_feedrate;
|
|
feedrate_bckp = current_block->gcode_feedrate;
|
|
|
|
+ saved_segment_idx = current_block->segment_idx;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- saved_target[0] = SAVED_TARGET_UNSET;
|
|
|
|
|
|
+ saved_start_position[0] = SAVED_START_POSITION_UNSET;
|
|
feedrate_bckp = feedrate;
|
|
feedrate_bckp = feedrate;
|
|
|
|
+ saved_segment_idx = 0;
|
|
}
|
|
}
|
|
|
|
|
|
// From this point on and up to the print recovery, Z should not move during X/Y travels and
|
|
// From this point on and up to the print recovery, Z should not move during X/Y travels and
|
|
@@ -10866,6 +10658,7 @@ void uvlo_()
|
|
|
|
|
|
// Enable stepper driver interrupt to move Z axis. This should be fine as the planner and
|
|
// Enable stepper driver interrupt to move Z axis. This should be fine as the planner and
|
|
// command queues are empty, SD card printing is disabled, usb is inhibited.
|
|
// command queues are empty, SD card printing is disabled, usb is inhibited.
|
|
|
|
+ planner_aborted = false;
|
|
sei();
|
|
sei();
|
|
|
|
|
|
// Retract
|
|
// Retract
|
|
@@ -10933,10 +10726,12 @@ void uvlo_()
|
|
eeprom_update_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL), cs.travel_acceleration);
|
|
eeprom_update_float((float*)(EEPROM_UVLO_TRAVEL_ACCELL), cs.travel_acceleration);
|
|
|
|
|
|
// Store the saved target
|
|
// Store the saved target
|
|
- eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4), saved_target[X_AXIS]);
|
|
|
|
- eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4), saved_target[Y_AXIS]);
|
|
|
|
- eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+2*4), saved_target[Z_AXIS]);
|
|
|
|
- eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+3*4), saved_target[E_AXIS]);
|
|
|
|
|
|
+ eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+0*4), saved_start_position[X_AXIS]);
|
|
|
|
+ eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+1*4), saved_start_position[Y_AXIS]);
|
|
|
|
+ eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+2*4), saved_start_position[Z_AXIS]);
|
|
|
|
+ eeprom_update_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+3*4), saved_start_position[E_AXIS]);
|
|
|
|
+
|
|
|
|
+ eeprom_update_word((uint16_t*)EEPROM_UVLO_SAVED_SEGMENT_IDX, saved_segment_idx);
|
|
|
|
|
|
#ifdef LIN_ADVANCE
|
|
#ifdef LIN_ADVANCE
|
|
eeprom_update_float((float*)(EEPROM_UVLO_LA_K), extruder_advance_K);
|
|
eeprom_update_float((float*)(EEPROM_UVLO_LA_K), extruder_advance_K);
|
|
@@ -10998,6 +10793,7 @@ void uvlo_tiny()
|
|
|
|
|
|
// Enable stepper driver interrupt to move Z axis. This should be fine as the planner and
|
|
// Enable stepper driver interrupt to move Z axis. This should be fine as the planner and
|
|
// command queues are empty, SD card printing is disabled, usb is inhibited.
|
|
// command queues are empty, SD card printing is disabled, usb is inhibited.
|
|
|
|
+ planner_aborted = false;
|
|
sei();
|
|
sei();
|
|
|
|
|
|
// The axis was moved: adjust Z as done on a regular UVLO.
|
|
// The axis was moved: adjust Z as done on a regular UVLO.
|
|
@@ -11092,7 +10888,7 @@ ISR(INT4_vect) {
|
|
EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once
|
|
EIMSK &= ~(1 << 4); //disable INT4 interrupt to make sure that this code will be executed just once
|
|
SERIAL_ECHOLNPGM("INT4");
|
|
SERIAL_ECHOLNPGM("INT4");
|
|
//fire normal uvlo only in case where EEPROM_UVLO is 0 or if IS_SD_PRINTING is 1.
|
|
//fire normal uvlo only in case where EEPROM_UVLO is 0 or if IS_SD_PRINTING is 1.
|
|
- if(PRINTER_ACTIVE && (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_();
|
|
|
|
|
|
+ if(printer_active() && (!(eeprom_read_byte((uint8_t*)EEPROM_UVLO)))) uvlo_();
|
|
if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)) uvlo_tiny();
|
|
if(eeprom_read_byte((uint8_t*)EEPROM_UVLO)) uvlo_tiny();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -11119,7 +10915,7 @@ void recover_print(uint8_t automatic) {
|
|
// Set the target bed and nozzle temperatures and wait.
|
|
// Set the target bed and nozzle temperatures and wait.
|
|
sprintf_P(cmd, PSTR("M104 S%d"), target_temperature[active_extruder]);
|
|
sprintf_P(cmd, PSTR("M104 S%d"), target_temperature[active_extruder]);
|
|
enquecommand(cmd);
|
|
enquecommand(cmd);
|
|
- sprintf_P(cmd, PSTR("M190 S%d"), target_temperature_bed);
|
|
|
|
|
|
+ sprintf_P(cmd, PSTR("M140 S%d"), target_temperature_bed);
|
|
enquecommand(cmd);
|
|
enquecommand(cmd);
|
|
sprintf_P(cmd, PSTR("M109 S%d"), target_temperature[active_extruder]);
|
|
sprintf_P(cmd, PSTR("M109 S%d"), target_temperature[active_extruder]);
|
|
enquecommand(cmd);
|
|
enquecommand(cmd);
|
|
@@ -11205,10 +11001,12 @@ bool recover_machine_state_after_power_panic()
|
|
extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY));
|
|
extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY));
|
|
|
|
|
|
// 9) Recover the saved target
|
|
// 9) Recover the saved target
|
|
- saved_target[X_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4));
|
|
|
|
- saved_target[Y_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4));
|
|
|
|
- saved_target[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+2*4));
|
|
|
|
- saved_target[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+3*4));
|
|
|
|
|
|
+ saved_start_position[X_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+0*4));
|
|
|
|
+ saved_start_position[Y_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+1*4));
|
|
|
|
+ saved_start_position[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+2*4));
|
|
|
|
+ saved_start_position[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_START_POSITION+3*4));
|
|
|
|
+
|
|
|
|
+ saved_segment_idx = eeprom_read_word((uint16_t*)EEPROM_UVLO_SAVED_SEGMENT_IDX);
|
|
|
|
|
|
#ifdef LIN_ADVANCE
|
|
#ifdef LIN_ADVANCE
|
|
extruder_advance_K = eeprom_read_float((float*)EEPROM_UVLO_LA_K);
|
|
extruder_advance_K = eeprom_read_float((float*)EEPROM_UVLO_LA_K);
|
|
@@ -11222,7 +11020,7 @@ void restore_print_from_eeprom(bool mbl_was_active) {
|
|
int feedmultiply_rec;
|
|
int feedmultiply_rec;
|
|
uint8_t fan_speed_rec;
|
|
uint8_t fan_speed_rec;
|
|
char cmd[48];
|
|
char cmd[48];
|
|
- char filename[13];
|
|
|
|
|
|
+ char filename[FILENAME_LENGTH];
|
|
uint8_t depth = 0;
|
|
uint8_t depth = 0;
|
|
char dir_name[9];
|
|
char dir_name[9];
|
|
|
|
|
|
@@ -11450,13 +11248,16 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
|
|
bool pos_invalid = XY_NO_RESTORE_FLAG;
|
|
bool pos_invalid = XY_NO_RESTORE_FLAG;
|
|
if (current_block && !pos_invalid)
|
|
if (current_block && !pos_invalid)
|
|
{
|
|
{
|
|
- memcpy(saved_target, current_block->gcode_target, sizeof(saved_target));
|
|
|
|
|
|
+ memcpy(saved_start_position, current_block->gcode_start_position, sizeof(saved_start_position));
|
|
saved_feedrate2 = current_block->gcode_feedrate;
|
|
saved_feedrate2 = current_block->gcode_feedrate;
|
|
|
|
+ saved_segment_idx = current_block->segment_idx;
|
|
|
|
+ // printf_P(PSTR("stop_and_save_print_to_ram: %f, %f, %f, %f, %u\n"), saved_start_position[0], saved_start_position[1], saved_start_position[2], saved_start_position[3], saved_segment_idx);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- saved_target[0] = SAVED_TARGET_UNSET;
|
|
|
|
|
|
+ saved_start_position[0] = SAVED_START_POSITION_UNSET;
|
|
saved_feedrate2 = feedrate;
|
|
saved_feedrate2 = feedrate;
|
|
|
|
+ saved_segment_idx = 0;
|
|
}
|
|
}
|
|
|
|
|
|
planner_abort_hard(); //abort printing
|
|
planner_abort_hard(); //abort printing
|
|
@@ -11465,10 +11266,10 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
|
|
if (pos_invalid) saved_pos[X_AXIS] = X_COORD_INVALID;
|
|
if (pos_invalid) saved_pos[X_AXIS] = X_COORD_INVALID;
|
|
|
|
|
|
saved_feedmultiply2 = feedmultiply; //save feedmultiply
|
|
saved_feedmultiply2 = feedmultiply; //save feedmultiply
|
|
- saved_active_extruder = active_extruder; //save active_extruder
|
|
|
|
saved_extruder_temperature = degTargetHotend(active_extruder);
|
|
saved_extruder_temperature = degTargetHotend(active_extruder);
|
|
|
|
+ saved_bed_temperature = degTargetBed();
|
|
saved_extruder_relative_mode = axis_relative_modes & E_AXIS_MASK;
|
|
saved_extruder_relative_mode = axis_relative_modes & E_AXIS_MASK;
|
|
- saved_fanSpeed = fanSpeed;
|
|
|
|
|
|
+ saved_fan_speed = fanSpeed;
|
|
cmdqueue_reset(); //empty cmdqueue
|
|
cmdqueue_reset(); //empty cmdqueue
|
|
card.sdprinting = false;
|
|
card.sdprinting = false;
|
|
// card.closefile();
|
|
// card.closefile();
|
|
@@ -11477,7 +11278,7 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
|
|
st_reset_timer();
|
|
st_reset_timer();
|
|
sei();
|
|
sei();
|
|
if ((z_move != 0) || (e_move != 0)) { // extruder or z move
|
|
if ((z_move != 0) || (e_move != 0)) { // extruder or z move
|
|
-#if 1
|
|
|
|
|
|
+
|
|
// Rather than calling plan_buffer_line directly, push the move into the command queue so that
|
|
// Rather than calling plan_buffer_line directly, push the move into the command queue so that
|
|
// the caller can continue processing. This is used during powerpanic to save the state as we
|
|
// the caller can continue processing. This is used during powerpanic to save the state as we
|
|
// move away from the print.
|
|
// move away from the print.
|
|
@@ -11509,16 +11310,19 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
|
|
// If this call is invoked from the main Arduino loop() function, let the caller know that the command
|
|
// If this call is invoked from the main Arduino loop() function, let the caller know that the command
|
|
// in the command queue is not the original command, but a new one, so it should not be removed from the queue.
|
|
// in the command queue is not the original command, but a new one, so it should not be removed from the queue.
|
|
repeatcommand_front();
|
|
repeatcommand_front();
|
|
-#else
|
|
|
|
- plan_buffer_line(saved_pos[X_AXIS], saved_pos[Y_AXIS], saved_pos[Z_AXIS] + z_move, saved_pos[E_AXIS] + e_move, homing_feedrate[Z_AXIS], active_extruder);
|
|
|
|
- st_synchronize(); //wait moving
|
|
|
|
- memcpy(current_position, saved_pos, sizeof(saved_pos));
|
|
|
|
- set_destination_to_current();
|
|
|
|
-#endif
|
|
|
|
- waiting_inside_plan_buffer_line_print_aborted = true; //unroll the stack
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void restore_extruder_temperature_from_ram() {
|
|
|
|
+ if (degTargetHotend(active_extruder) != saved_extruder_temperature)
|
|
|
|
+ {
|
|
|
|
+ setTargetHotendSafe(saved_extruder_temperature, active_extruder);
|
|
|
|
+ heating_status = HeatingStatus::EXTRUDER_HEATING;
|
|
|
|
+ wait_for_heater(_millis(), active_extruder);
|
|
|
|
+ heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
//! @brief Restore print from ram
|
|
//! @brief Restore print from ram
|
|
//!
|
|
//!
|
|
//! Restore print saved by stop_and_save_print_to_ram(). Is blocking, restores
|
|
//! Restore print saved by stop_and_save_print_to_ram(). Is blocking, restores
|
|
@@ -11538,17 +11342,11 @@ void restore_print_from_ram_and_continue(float e_move)
|
|
if (fan_check_error == EFCE_FIXED) fan_check_error = EFCE_OK; //reenable serial stream processing if printing from usb
|
|
if (fan_check_error == EFCE_FIXED) fan_check_error = EFCE_OK; //reenable serial stream processing if printing from usb
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-// for (int axis = X_AXIS; axis <= E_AXIS; axis++)
|
|
|
|
-// current_position[axis] = st_get_position_mm(axis);
|
|
|
|
- active_extruder = saved_active_extruder; //restore active_extruder
|
|
|
|
- fanSpeed = saved_fanSpeed;
|
|
|
|
- if (degTargetHotend(saved_active_extruder) != saved_extruder_temperature)
|
|
|
|
- {
|
|
|
|
- setTargetHotendSafe(saved_extruder_temperature, saved_active_extruder);
|
|
|
|
- heating_status = HeatingStatus::EXTRUDER_HEATING;
|
|
|
|
- wait_for_heater(_millis(), saved_active_extruder);
|
|
|
|
- heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
|
|
|
|
- }
|
|
|
|
|
|
+ // restore bed temperature (bed can be disabled during a thermal warning)
|
|
|
|
+ if (degBed() != saved_bed_temperature)
|
|
|
|
+ setTargetBed(saved_bed_temperature);
|
|
|
|
+ fanSpeed = saved_fan_speed;
|
|
|
|
+ restore_extruder_temperature_from_ram();
|
|
axis_relative_modes ^= (-saved_extruder_relative_mode ^ axis_relative_modes) & E_AXIS_MASK;
|
|
axis_relative_modes ^= (-saved_extruder_relative_mode ^ axis_relative_modes) & E_AXIS_MASK;
|
|
float e = saved_pos[E_AXIS] - e_move;
|
|
float e = saved_pos[E_AXIS] - e_move;
|
|
plan_set_e_position(e);
|
|
plan_set_e_position(e);
|
|
@@ -11599,14 +11397,14 @@ void restore_print_from_ram_and_continue(float e_move)
|
|
lcd_setstatuspgm(MSG_WELCOME);
|
|
lcd_setstatuspgm(MSG_WELCOME);
|
|
saved_printing_type = PRINTING_TYPE_NONE;
|
|
saved_printing_type = PRINTING_TYPE_NONE;
|
|
saved_printing = false;
|
|
saved_printing = false;
|
|
- waiting_inside_plan_buffer_line_print_aborted = true; //unroll the stack
|
|
|
|
|
|
+ planner_aborted = true; // unroll the stack
|
|
}
|
|
}
|
|
|
|
|
|
// Cancel the state related to a currently saved print
|
|
// Cancel the state related to a currently saved print
|
|
void cancel_saved_printing()
|
|
void cancel_saved_printing()
|
|
{
|
|
{
|
|
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
|
|
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
|
|
- saved_target[0] = SAVED_TARGET_UNSET;
|
|
|
|
|
|
+ saved_start_position[0] = SAVED_START_POSITION_UNSET;
|
|
saved_printing_type = PRINTING_TYPE_NONE;
|
|
saved_printing_type = PRINTING_TYPE_NONE;
|
|
saved_printing = false;
|
|
saved_printing = false;
|
|
}
|
|
}
|
|
@@ -11678,21 +11476,28 @@ void load_filament_final_feed()
|
|
//! @par nozzle_temp nozzle temperature to load filament
|
|
//! @par nozzle_temp nozzle temperature to load filament
|
|
void M600_check_state(float nozzle_temp)
|
|
void M600_check_state(float nozzle_temp)
|
|
{
|
|
{
|
|
- lcd_change_fil_state = 0;
|
|
|
|
- while (lcd_change_fil_state != 1)
|
|
|
|
|
|
+ uint8_t lcd_change_filament_state = 0;
|
|
|
|
+ while (lcd_change_filament_state != 1)
|
|
{
|
|
{
|
|
- lcd_change_fil_state = 0;
|
|
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
- lcd_alright();
|
|
|
|
|
|
+ lcd_change_filament_state = lcd_alright();
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
- switch(lcd_change_fil_state)
|
|
|
|
|
|
+ switch(lcd_change_filament_state)
|
|
{
|
|
{
|
|
// Filament failed to load so load it again
|
|
// Filament failed to load so load it again
|
|
case 2:
|
|
case 2:
|
|
- if (mmu_enabled)
|
|
|
|
- mmu_M600_load_filament(false, nozzle_temp); //nonautomatic load; change to "wrong filament loaded" option?
|
|
|
|
- else
|
|
|
|
|
|
+ if (MMU2::mmu2.Enabled()){
|
|
|
|
+ // Unload filament
|
|
|
|
+ mmu_M600_unload_filament();
|
|
|
|
+
|
|
|
|
+ // Ask to remove any old filament and load new
|
|
|
|
+ mmu_M600_wait_and_beep();
|
|
|
|
+
|
|
|
|
+ // After user clicks knob, MMU will load the filament
|
|
|
|
+ mmu_M600_load_filament(false, nozzle_temp);
|
|
|
|
+ } else {
|
|
M600_load_filament_movements();
|
|
M600_load_filament_movements();
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
|
|
|
|
// Filament loaded properly but color is not clear
|
|
// Filament loaded properly but color is not clear
|
|
@@ -11810,46 +11615,23 @@ void M600_load_filament() {
|
|
//load_filament_time = _millis();
|
|
//load_filament_time = _millis();
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
|
|
-#ifdef PAT9125
|
|
|
|
- fsensor_autoload_check_start();
|
|
|
|
-#endif //PAT9125
|
|
|
|
while(!lcd_clicked())
|
|
while(!lcd_clicked())
|
|
{
|
|
{
|
|
manage_heater();
|
|
manage_heater();
|
|
manage_inactivity(true);
|
|
manage_inactivity(true);
|
|
#ifdef FILAMENT_SENSOR
|
|
#ifdef FILAMENT_SENSOR
|
|
- if (fsensor_check_autoload())
|
|
|
|
- {
|
|
|
|
- Sound_MakeCustom(50,1000,false);
|
|
|
|
|
|
+ if (fsensor.getFilamentLoadEvent()) {
|
|
|
|
+ Sound_MakeCustom(50,1000,false);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
#endif //FILAMENT_SENSOR
|
|
#endif //FILAMENT_SENSOR
|
|
}
|
|
}
|
|
-#ifdef PAT9125
|
|
|
|
- fsensor_autoload_check_stop();
|
|
|
|
-#endif //PAT9125
|
|
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
KEEPALIVE_STATE(IN_HANDLER);
|
|
|
|
|
|
-#ifdef FSENSOR_QUALITY
|
|
|
|
- fsensor_oq_meassure_start(70);
|
|
|
|
-#endif //FSENSOR_QUALITY
|
|
|
|
-
|
|
|
|
M600_load_filament_movements();
|
|
M600_load_filament_movements();
|
|
|
|
|
|
- Sound_MakeCustom(50,1000,false);
|
|
|
|
|
|
+ Sound_MakeCustom(50,1000,false);
|
|
|
|
|
|
-#ifdef FSENSOR_QUALITY
|
|
|
|
- fsensor_oq_meassure_stop();
|
|
|
|
-
|
|
|
|
- if (!fsensor_oq_result())
|
|
|
|
- {
|
|
|
|
- bool disable = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Fil. sensor response is poor, disable it?"), false, true);
|
|
|
|
- lcd_update_enable(true);
|
|
|
|
- lcd_update(2);
|
|
|
|
- if (disable)
|
|
|
|
- fsensor_disable();
|
|
|
|
- }
|
|
|
|
-#endif //FSENSOR_QUALITY
|
|
|
|
lcd_update_enable(false);
|
|
lcd_update_enable(false);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -11871,8 +11653,6 @@ void marlin_wait_for_click()
|
|
KEEPALIVE_STATE(busy_state_backup);
|
|
KEEPALIVE_STATE(busy_state_backup);
|
|
}
|
|
}
|
|
|
|
|
|
-#define FIL_LOAD_LENGTH 60
|
|
|
|
-
|
|
|
|
#ifdef PSU_Delta
|
|
#ifdef PSU_Delta
|
|
bool bEnableForce_z;
|
|
bool bEnableForce_z;
|
|
|
|
|