From 4c4b4c489cf632b9c7535e1971b96782f3b5f78e Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 7 Apr 2020 17:09:48 +0300 Subject: [PATCH 01/77] :bug::recycle: Update the feedrate percentage before drawing the screen --- Firmware/ultralcd.cpp | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 62c410727..c60b6e425 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -997,6 +997,36 @@ void lcd_status_screen() // NOT static due to using ins } } +#ifdef ULTIPANEL_FEEDMULTIPLY + // Dead zone at 100% feedrate + if ((feedmultiply < 100 && (feedmultiply + int(lcd_encoder)) > 100) || + (feedmultiply > 100 && (feedmultiply + int(lcd_encoder)) < 100)) + { + lcd_encoder = 0; + feedmultiply = 100; + } + if (feedmultiply == 100 && int(lcd_encoder) > ENCODER_FEEDRATE_DEADZONE) + { + feedmultiply += int(lcd_encoder) - ENCODER_FEEDRATE_DEADZONE; + lcd_encoder = 0; + } + else if (feedmultiply == 100 && int(lcd_encoder) < -ENCODER_FEEDRATE_DEADZONE) + { + feedmultiply += int(lcd_encoder) + ENCODER_FEEDRATE_DEADZONE; + lcd_encoder = 0; + } + else if (feedmultiply != 100) + { + feedmultiply += int(lcd_encoder); + lcd_encoder = 0; + } +#endif //ULTIPANEL_FEEDMULTIPLY + + if (feedmultiply < 10) + feedmultiply = 10; + else if (feedmultiply > 999) + feedmultiply = 999; + if (lcd_status_update_delay) lcd_status_update_delay--; else @@ -1073,36 +1103,6 @@ void lcd_status_screen() // NOT static due to using ins menu_submenu(lcd_main_menu); lcd_refresh(); // to maybe revive the LCD if static electricity killed it. } - -#ifdef ULTIPANEL_FEEDMULTIPLY - // Dead zone at 100% feedrate - if ((feedmultiply < 100 && (feedmultiply + int(lcd_encoder)) > 100) || - (feedmultiply > 100 && (feedmultiply + int(lcd_encoder)) < 100)) - { - lcd_encoder = 0; - feedmultiply = 100; - } - if (feedmultiply == 100 && int(lcd_encoder) > ENCODER_FEEDRATE_DEADZONE) - { - feedmultiply += int(lcd_encoder) - ENCODER_FEEDRATE_DEADZONE; - lcd_encoder = 0; - } - else if (feedmultiply == 100 && int(lcd_encoder) < -ENCODER_FEEDRATE_DEADZONE) - { - feedmultiply += int(lcd_encoder) + ENCODER_FEEDRATE_DEADZONE; - lcd_encoder = 0; - } - else if (feedmultiply != 100) - { - feedmultiply += int(lcd_encoder); - lcd_encoder = 0; - } -#endif //ULTIPANEL_FEEDMULTIPLY - - if (feedmultiply < 10) - feedmultiply = 10; - else if (feedmultiply > 999) - feedmultiply = 999; } void lcd_commands() From 727a8683281b64b202cef1eb3e88ba57b765267e Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Sat, 11 Apr 2020 16:14:38 +0200 Subject: [PATCH 02/77] Add SD card or USB/Octoprint It happens quite often that we are looking for a bug and later see that it is related to USB/Octoprints and not SD card prints. --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 196d5756d..32122b962 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -15,6 +15,9 @@ Please, before you create a new bug report, please make sure you searched in ope **MMU Upgrade** - [e.g. MMU2S, MMU2, MMU1] **MMU upgrade firmware version [e.g. 1.0.6, 1.0.6-RC2, ...] +**SD card or USB/Octoprint** + Please let us know if you print via SD card or USB/Octoprint + **Describe the bug** A clear and concise description of what the bug is. From 1bac0c176518a13a320d7dd69d400f21902927c7 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Sat, 18 Apr 2020 16:39:04 +0200 Subject: [PATCH 03/77] Add dummy G21 to prevent UNKOWN warnings in serial And as Prusa firmware operates ONLY in milimeters it kind of does what G21 is supposed to do. --- Firmware/Marlin_main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index e4e1e0b2b..d6955f89c 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4276,6 +4276,14 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) #endif //FWRETRACT + /*! + ### G21 - Sets Units to Millimters G21: Set Units to Millimeters + Units are in millimeters. Prusa doesn't support inches. + */ + case 21: + break; //Doing nothing. This is just to prevent serial UNKOWN warnings. + + /*! ### G28 - Home all Axes one at a time G28: Move to Origin (Home) Using `G28` without any parameters will perfom homing of all axes AND mesh bed leveling, while `G28 W` will just home all axes (no mesh bed leveling). From 000f824e39283a18f31a84fb6a0941c1b306d6e7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 18 May 2020 01:11:59 +0200 Subject: [PATCH 04/77] Increase E-jerk LA10->15 flattened zone Increase the flattened response in the e-jerk conversion from the 1-4.5 region to 0.3-4.5 (same slope). This brings a 0.3 LA10 e-jerk to a 3.45 LA15 equivalent. This will better handle the legacy Pretty PETG/CFPETG v3 profiles. --- Firmware/la10compat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/la10compat.cpp b/Firmware/la10compat.cpp index 918659255..98522f645 100644 --- a/Firmware/la10compat.cpp +++ b/Firmware/la10compat.cpp @@ -78,10 +78,10 @@ float la10c_jerk(float j) return j; // bring low E-jerk values into equivalent LA 1.5 values by - // flattening the response in the (1-4.5) range using a piecewise + // flattening the response in the (0.3-4.5) range using a piecewise // function. Is it truly worth to preserve the difference between // 1.5/2.5 E-jerk for LA1.0? Probably not, but we try nonetheless. - j = j < 1.0? j * 3.625: + j = j < 0.3? j * 11.5: j < 4.5? j * 0.25 + 3.375: j; From 285088a715f0e8cfdf7789c2c200b85869b9ed5b Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 18 May 2020 16:45:18 +0200 Subject: [PATCH 05/77] Version changed (3.9.0 build 3421) --- Firmware/Configuration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 9d0874421..2783c738c 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -16,8 +16,8 @@ extern uint16_t nPrinterType; extern PGM_P sPrinterName; // Firmware version -#define FW_VERSION "3.9.0-RC3" -#define FW_COMMIT_NR 3401 +#define FW_VERSION "3.9.0" +#define FW_COMMIT_NR 3421 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN From 2447dbc69fdd602e8844d5f2fdb48678abac8fe8 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Mon, 18 May 2020 16:56:32 +0200 Subject: [PATCH 06/77] Version changed (3.9.0 build 3421) - sync --- Firmware/Configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 2783c738c..a4d797746 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -17,7 +17,7 @@ extern PGM_P sPrinterName; // Firmware version #define FW_VERSION "3.9.0" -#define FW_COMMIT_NR 3421 +#define FW_COMMIT_NR 3421 // FW_VERSION_UNKNOWN means this is an unofficial build. // The firmware should only be checked into github with this symbol. #define FW_DEV_VERSION FW_VERSION_UNKNOWN From 4ffa4dd8fdf00476fcc38077e81aa92e162c3ba1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 09:44:28 +0300 Subject: [PATCH 07/77] Fix missing start on MK3/S --- Firmware/Marlin_main.cpp | 10 +++++++--- Firmware/optiboot_w25x20cl.cpp | 8 ++++---- Firmware/optiboot_w25x20cl.h | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a0ef55910..61f0c1326 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1016,9 +1016,10 @@ void setup() #ifdef W25X20CL bool w25x20cl_success = w25x20cl_init(); + uint8_t optiboot_status = 1; if (w25x20cl_success) { - optiboot_w25x20cl_enter(); + optiboot_status = optiboot_w25x20cl_enter(); #if (LANG_MODE != 0) //secondary language support update_sec_lang_from_external_flash(); #endif //(LANG_MODE != 0) @@ -1064,9 +1065,12 @@ void setup() } MYSERIAL.begin(BAUDRATE); fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream -#ifndef W25X20CL +#if !((LANG_MODE == 1) && defined(W25X20CL)) || (LANG_MODE == 0) SERIAL_PROTOCOLLNPGM("start"); -#endif //W25X20CL +#else + if (optiboot_status == 1) + SERIAL_PROTOCOLLNPGM("start"); +#endif stdout = uartout; SERIAL_ECHO_START; printf_P(PSTR(" " FW_VERSION_FULL "\n")); diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 584c32fed..7cc44801f 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -99,9 +99,9 @@ struct block_t; extern struct block_t *block_buffer; //! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory. -void optiboot_w25x20cl_enter() +uint8_t optiboot_w25x20cl_enter() { - if (boot_app_flags & BOOT_APP_FLG_USER0) return; + if (boot_app_flags & BOOT_APP_FLG_USER0) return 1; uint8_t ch; uint8_t rampz = 0; register uint16_t address = 0; @@ -144,12 +144,12 @@ void optiboot_w25x20cl_enter() delayMicroseconds(1); if (++ boot_timer > boot_timeout) // Timeout expired, continue with the application. - return; + return 0; } ch = UDR0; if (pgm_read_byte(ptr ++) != ch) // Magic was not received correctly, continue with the application - return; + return 0; watchdogReset(); } // Send the cfm magic string. diff --git a/Firmware/optiboot_w25x20cl.h b/Firmware/optiboot_w25x20cl.h index dc7d4395c..95c6465f3 100644 --- a/Firmware/optiboot_w25x20cl.h +++ b/Firmware/optiboot_w25x20cl.h @@ -1,6 +1,6 @@ #ifndef OPTIBOOT_W25X20CL_H #define OPTIBOOT_W25X20CL_H -extern void optiboot_w25x20cl_enter(); +extern uint8_t optiboot_w25x20cl_enter(); #endif /* OPTIBOOT_W25X20CL_H */ From f11ab17746d573325e16f62b7b5d430a03a5f2df Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 09:59:17 +0300 Subject: [PATCH 08/77] Fix warning --- Firmware/Marlin_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 61f0c1326..a57915c67 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1065,7 +1065,7 @@ void setup() } MYSERIAL.begin(BAUDRATE); fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream -#if !((LANG_MODE == 1) && defined(W25X20CL)) || (LANG_MODE == 0) +#ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else if (optiboot_status == 1) From e985d17bd11a35cecf162db8f4e1e6a3c3b52b89 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 10:16:44 +0300 Subject: [PATCH 09/77] Document code --- Firmware/optiboot_w25x20cl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 7cc44801f..231e7760a 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -99,6 +99,8 @@ struct block_t; extern struct block_t *block_buffer; //! @brief Enter an STK500 compatible Optiboot boot loader waiting for flashing the languages to an external flash memory. +//! @return 1 if "start\n" was not sent. Optiboot was skipped +//! @return 0 if "start\n" was sent. Optiboot ran normally. No need to send "start\n" in setup() uint8_t optiboot_w25x20cl_enter() { if (boot_app_flags & BOOT_APP_FLG_USER0) return 1; From b1e446ef97b16a75a79d42c461c4fd46b1aa9f4d Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 13:50:02 +0300 Subject: [PATCH 10/77] Remember the serial characters during Optiboot initialization --- Firmware/Marlin_main.cpp | 13 +++++++------ Firmware/optiboot_w25x20cl.cpp | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a57915c67..68c5d4b04 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1014,6 +1014,12 @@ void setup() lcd_splash(); Sound_Init(); // also guarantee "SET_OUTPUT(BEEPER)" + selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE); + if (selectedSerialPort == 0xFF) selectedSerialPort = 0; + MYSERIAL.begin(BAUDRATE); + fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream + stdout = uartout; + #ifdef W25X20CL bool w25x20cl_success = w25x20cl_init(); uint8_t optiboot_status = 1; @@ -1041,15 +1047,13 @@ void setup() if ((farm_mode == 0xFF && farm_no == 0) || ((uint16_t)farm_no == 0xFFFF)) 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 if ((uint16_t)farm_no == 0xFFFF) farm_no = 0; - - selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE); - if (selectedSerialPort == 0xFF) selectedSerialPort = 0; if (farm_mode) { no_response = true; //we need confirmation by recieving PRUSA thx important_status = 8; prusa_statistics(8); selectedSerialPort = 1; + MYSERIAL.begin(BAUDRATE); #ifdef TMC2130 //increased extruder current (PFW363) tmc2130_current_h[E_AXIS] = 36; @@ -1063,15 +1067,12 @@ void setup() if(!(eeprom_read_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED))) eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED,true); } - MYSERIAL.begin(BAUDRATE); - fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream #ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else if (optiboot_status == 1) SERIAL_PROTOCOLLNPGM("start"); #endif - stdout = uartout; SERIAL_ECHO_START; printf_P(PSTR(" " FW_VERSION_FULL "\n")); diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 231e7760a..648694855 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -122,38 +122,38 @@ uint8_t optiboot_w25x20cl_enter() unsigned long boot_timer = 0; const char *ptr = entry_magic_send; const char *end = strlen_P(entry_magic_send) + ptr; - // Initialize the serial line. - UCSR0A |= (1 << U2X0); - UBRR0L = (((float)(F_CPU))/(((float)(115200))*8.0)-1.0+0.5); - UCSR0B = (1 << RXEN0) | (1 << TXEN0); // Flush the serial line. while (RECV_READY) { watchdogReset(); // Dummy register read (discard) (void)(*(char *)UDR0); } + MYSERIAL.flush(); //clear RX buffer + int SerialHead = rx_buffer.head; // Send the initial magic string. while (ptr != end) putch(pgm_read_byte(ptr ++)); watchdogReset(); - // Wait for one second until a magic string (constant entry_magic) is received + // Wait for two seconds until a magic string (constant entry_magic) is received // from the serial line. ptr = entry_magic_receive; end = strlen_P(entry_magic_receive) + ptr; while (ptr != end) { - while (! RECV_READY) { + while (rx_buffer.head == SerialHead) { watchdogReset(); delayMicroseconds(1); if (++ boot_timer > boot_timeout) // Timeout expired, continue with the application. return 0; } - ch = UDR0; + ch = rx_buffer.buffer[SerialHead]; + SerialHead = (unsigned int)(SerialHead + 1) % RX_BUFFER_SIZE; if (pgm_read_byte(ptr ++) != ch) // Magic was not received correctly, continue with the application return 0; watchdogReset(); } + cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt // Send the cfm magic string. ptr = entry_magic_cfm; while (ptr != end) From c84aef3a288e75796fd30eec6164bab79062b6c3 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 27 May 2020 17:40:14 +0300 Subject: [PATCH 11/77] Handle second serial port correctly --- Firmware/Marlin_main.cpp | 5 +++-- Firmware/optiboot_w25x20cl.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 68c5d4b04..651aeb812 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1014,8 +1014,9 @@ void setup() lcd_splash(); Sound_Init(); // also guarantee "SET_OUTPUT(BEEPER)" - selectedSerialPort = eeprom_read_byte((uint8_t*)EEPROM_SECOND_SERIAL_ACTIVE); + selectedSerialPort = eeprom_read_byte((uint8_t *)EEPROM_SECOND_SERIAL_ACTIVE); if (selectedSerialPort == 0xFF) selectedSerialPort = 0; + eeprom_update_byte((uint8_t *)EEPROM_SECOND_SERIAL_ACTIVE, selectedSerialPort); MYSERIAL.begin(BAUDRATE); fdev_setup_stream(uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE); //setup uart out stream stdout = uartout; @@ -1070,7 +1071,7 @@ void setup() #ifndef W25X20CL SERIAL_PROTOCOLLNPGM("start"); #else - if (optiboot_status == 1) + if ((optiboot_status != 0) || (selectedSerialPort != 0)) SERIAL_PROTOCOLLNPGM("start"); #endif SERIAL_ECHO_START; diff --git a/Firmware/optiboot_w25x20cl.cpp b/Firmware/optiboot_w25x20cl.cpp index 648694855..dce4074e1 100644 --- a/Firmware/optiboot_w25x20cl.cpp +++ b/Firmware/optiboot_w25x20cl.cpp @@ -122,12 +122,14 @@ uint8_t optiboot_w25x20cl_enter() unsigned long boot_timer = 0; const char *ptr = entry_magic_send; const char *end = strlen_P(entry_magic_send) + ptr; + const uint8_t selectedSerialPort_bak = selectedSerialPort; // Flush the serial line. while (RECV_READY) { watchdogReset(); // Dummy register read (discard) (void)(*(char *)UDR0); } + selectedSerialPort = 0; //switch to Serial0 MYSERIAL.flush(); //clear RX buffer int SerialHead = rx_buffer.head; // Send the initial magic string. @@ -143,14 +145,20 @@ uint8_t optiboot_w25x20cl_enter() watchdogReset(); delayMicroseconds(1); if (++ boot_timer > boot_timeout) + { // Timeout expired, continue with the application. + selectedSerialPort = selectedSerialPort_bak; //revert Serial setting return 0; + } } ch = rx_buffer.buffer[SerialHead]; SerialHead = (unsigned int)(SerialHead + 1) % RX_BUFFER_SIZE; if (pgm_read_byte(ptr ++) != ch) + { // Magic was not received correctly, continue with the application + selectedSerialPort = selectedSerialPort_bak; //revert Serial setting return 0; + } watchdogReset(); } cbi(UCSR0B, RXCIE0); //disable the MarlinSerial0 interrupt From eb44ee0f5786e84cbe318eebde2257b7a4cd5b24 Mon Sep 17 00:00:00 2001 From: DRracer Date: Mon, 1 Jun 2020 17:51:28 +0200 Subject: [PATCH 12/77] Code size optimization: 2KB down (#2687) * Combine repeated calls into functions with much less parameters -> 2KB down. * Save some bytes by removing unnecessary 1-character strings: "x" -> 'x' used in SERIAL_xxx printing macros. This is also saves some CPU cycles * Fix compilation for MK25S and MK3 * Copy surrounding indentation * Fix compilation for a rare HW setup * rename mesh_planXX_buffer_line back to mesh_plan_buffer_line * Remove active_extruder from remaining plan_buffer_line_destinationXYZE calls and one more fix of indentation --- Firmware/Marlin_main.cpp | 236 +++++++++++++++--------------- Firmware/cardreader.cpp | 16 +- Firmware/fsensor.cpp | 6 +- Firmware/mesh_bed_calibration.cpp | 4 +- Firmware/mmu.cpp | 32 ++-- Firmware/planner.cpp | 12 +- Firmware/planner.h | 6 +- Firmware/ultralcd.cpp | 76 +++++----- 8 files changed, 197 insertions(+), 191 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 651aeb812..36764b21f 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1338,8 +1338,7 @@ void setup() // Initialize current_position accounting for software endstops to // avoid unexpected initial shifts on the first move clamp_to_software_endstops(current_position); - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], - current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); #ifdef FILAMENT_SENSOR fsensor_init(); @@ -1954,7 +1953,7 @@ static void set_bed_level_equation_lsq(double *plane_equation_coefficients) // put the bed at 0 so we don't go below it. current_position[Z_AXIS] = cs.zprobe_zoffset; // in the lsq we reach here after raising the extruder due to the loop structure - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } #else // not AUTO_BED_LEVELING_GRID @@ -1982,7 +1981,7 @@ static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float // put the bed at 0 so we don't go below it. current_position[Z_AXIS] = cs.zprobe_zoffset; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } @@ -2014,7 +2013,7 @@ static void run_z_probe() { current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); // make sure the planner knows where we are as it may be a bit different than we last said to move to - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } static void do_blocking_move_to(float x, float y, float z) { @@ -2135,7 +2134,7 @@ void raise_z_above(float target, bool plan) if (axis_known_position[Z_AXIS] || z_min_endstop) { // current position is known or very low, it's safe to raise Z - if(plan) plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); + if(plan) plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS]); return; } @@ -2148,15 +2147,14 @@ void raise_z_above(float target, bool plan) #ifdef TMC2130 tmc2130_home_enter(Z_AXIS_MASK); #endif //TMC2130 - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60); st_synchronize(); #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(current_position[X_AXIS], current_position[Y_AXIS], - current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } tmc2130_home_exit(); #endif //TMC2130 @@ -2174,22 +2172,22 @@ bool calibrate_z_auto() int axis_up_dir = -home_dir(Z_AXIS); tmc2130_home_enter(Z_AXIS_MASK); current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); set_destination_to_current(); destination[Z_AXIS] += (1.1 * max_length(Z_AXIS) * axis_up_dir); feedrate = homing_feedrate[Z_AXIS]; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate / 60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate / 60); st_synchronize(); // current_position[axis] = 0; - // plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + // plan_set_position_curposXYZE(); tmc2130_home_exit(); enable_endstops(false); current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); set_destination_to_current(); destination[Z_AXIS] += 10 * axis_up_dir; //10mm up feedrate = homing_feedrate[Z_AXIS] / 2; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate / 60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate / 60); st_synchronize(); enable_endstops(endstops_enabled); if (PRINTER_TYPE == PRINTER_MK3) { @@ -2198,7 +2196,7 @@ bool calibrate_z_auto() else { current_position[Z_AXIS] = Z_MAX_POS + 9.0; } - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); return true; } #endif //TMC2130 @@ -2209,9 +2207,9 @@ static void check_Z_crash(void) if (READ(Z_TMC2130_DIAG) != 0) { //Z crash FORCE_HIGH_POWER_END; current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); current_position[Z_AXIS] += MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); + plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS]); st_synchronize(); kill(_T(MSG_BED_LEVELING_FAILED_POINT_LOW)); } @@ -2241,24 +2239,24 @@ void homeaxis(int axis, uint8_t cnt) // and the following movement to endstop has a chance to achieve the required velocity // for the stall guard to work. current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); set_destination_to_current(); // destination[axis] = 11.f; destination[axis] = -3.f * axis_home_dir; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); // Move away from the possible collision with opposite endstop with the collision detection disabled. endstops_hit_on_purpose(); enable_endstops(false); current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); destination[axis] = 1. * axis_home_dir; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); // Now continue to move up to the left end stop with the collision detection enabled. enable_endstops(true); destination[axis] = 1.1 * axis_home_dir * max_length(axis); - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); for (uint8_t i = 0; i < cnt; i++) { @@ -2266,9 +2264,9 @@ void homeaxis(int axis, uint8_t cnt) endstops_hit_on_purpose(); enable_endstops(false); current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); destination[axis] = -10.f * axis_home_dir; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); endstops_hit_on_purpose(); // Now move left up to the collision, this time with a repeatable velocity. @@ -2279,7 +2277,7 @@ void homeaxis(int axis, uint8_t cnt) #else //TMC2130 feedrate = homing_feedrate[axis] / 2; #endif //TMC2130 - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); #ifdef TMC2130 uint16_t mscnt = tmc2130_rd_MSCNT(axis); @@ -2313,10 +2311,10 @@ void homeaxis(int axis, uint8_t cnt) float dist = - axis_home_dir * 0.01f * 64; #endif //TMC2130 current_position[axis] -= dist; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); current_position[axis] += dist; destination[axis] = current_position[axis]; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], 0.5f*feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(0.5f*feedrate/60); st_synchronize(); feedrate = 0.0; @@ -2328,22 +2326,22 @@ void homeaxis(int axis, uint8_t cnt) #endif int axis_home_dir = home_dir(axis); current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); destination[axis] = 1.5 * max_length(axis) * axis_home_dir; feedrate = homing_feedrate[axis]; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); #ifdef TMC2130 check_Z_crash(); #endif //TMC2130 current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); destination[axis] = -home_retract_mm(axis) * axis_home_dir; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); destination[axis] = 2*home_retract_mm(axis) * axis_home_dir; feedrate = homing_feedrate[axis]/2 ; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); st_synchronize(); #ifdef TMC2130 check_Z_crash(); @@ -2366,7 +2364,7 @@ void home_xy() set_destination_to_current(); homeaxis(X_AXIS); homeaxis(Y_AXIS); - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); endstops_hit_on_purpose(); } @@ -2389,7 +2387,7 @@ void refresh_cmd_timeout(void) retracted[active_extruder]=true; prepare_move(); current_position[Z_AXIS]-=cs.retract_zlift; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); prepare_move(); feedrate = oldFeedrate; } else if(!retracting && retracted[active_extruder]) { @@ -2398,7 +2396,7 @@ void refresh_cmd_timeout(void) destination[Z_AXIS]=current_position[Z_AXIS]; destination[E_AXIS]=current_position[E_AXIS]; current_position[Z_AXIS]+=cs.retract_zlift; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); current_position[E_AXIS]-=(swapretract?(retract_length_swap+retract_recover_length_swap):(cs.retract_length+cs.retract_recover_length))*float(extrudemultiply)*0.01f; plan_set_e_position(current_position[E_AXIS]); float oldFeedrate = feedrate; @@ -2601,7 +2599,7 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon int x_axis_home_dir = home_dir(X_AXIS); - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); destination[X_AXIS] = 1.5 * max_length(X_AXIS) * x_axis_home_dir;destination[Y_AXIS] = 1.5 * max_length(Y_AXIS) * home_dir(Y_AXIS); feedrate = homing_feedrate[X_AXIS]; if(homing_feedrate[Y_AXIS]= 0) @@ -2990,7 +2988,7 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level) clean_up_after_endstop_move(l_feedmultiply); // Print head up. current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); st_synchronize(); // if (result >= 0) babystep_apply(); #endif //HEATBED_V2 @@ -3103,18 +3101,18 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float //Retract E current_position[E_AXIS] += e_shift; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED, active_extruder); + plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED); st_synchronize(); //Lift Z current_position[Z_AXIS] += z_shift; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_ZFEED, active_extruder); + plan_buffer_line_curposXYZE(FILAMENTCHANGE_ZFEED); st_synchronize(); //Move XY to side current_position[X_AXIS] = x_position; current_position[Y_AXIS] = y_position; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED, active_extruder); + plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED); st_synchronize(); //Beep, manage nozzle heater and wait for user to start unload filament @@ -3139,7 +3137,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float lcd_set_cursor(0, 2); lcd_puts_P(_T(MSG_PLEASE_WAIT)); current_position[X_AXIS] -= 100; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_XYFEED, active_extruder); + 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=4 } @@ -3176,7 +3174,7 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float if (!automatic) { current_position[E_AXIS] += FILAMENTCHANGE_RECFEED; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_EXFEED, active_extruder); + plan_buffer_line_curposXYZE(FILAMENTCHANGE_EXFEED); } //Move XY back @@ -3234,12 +3232,12 @@ void gcode_M701() lcd_setstatuspgm(_T(MSG_LOADING_FILAMENT)); current_position[E_AXIS] += 40; - plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence + plan_buffer_line_curposXYZE(400 / 60); //fast sequence st_synchronize(); raise_z_above(MIN_Z_FOR_LOAD, false); current_position[E_AXIS] += 30; - plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence + plan_buffer_line_curposXYZE(400 / 60); //fast sequence load_filament_final_feed(); //slow sequence st_synchronize(); @@ -3405,8 +3403,7 @@ static void gcode_G92() current_position[E_AXIS] = values[E_AXIS]; // Set all at once - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], - current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } } @@ -4359,7 +4356,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) current_position[X_AXIS] = uncorrected_position.x; current_position[Y_AXIS] = uncorrected_position.y; current_position[Z_AXIS] = uncorrected_position.z; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); int l_feedmultiply = setup_for_endstop_move(); feedrate = homing_feedrate[Z_AXIS]; @@ -4473,7 +4470,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp); //Apply the correction sending the probe offset current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS]; //The difference is added to current position and sent to planner. - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } break; #ifndef Z_PROBE_SLED @@ -4605,15 +4602,15 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if (result) { current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[Z_AXIS] = 50; current_position[Y_AXIS] = 180; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET)); current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); gcode_G28(false, false, true); @@ -4621,7 +4618,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if ((current_temperature_pinda > 35) && (farm_mode == false)) { //waiting for PIDNA probe to cool down in case that we are not in farm mode current_position[Z_AXIS] = 100; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); if (lcd_wait_for_pinda(35) == false) { //waiting for PINDA probe to cool, if this takes more then time expected, temp. cal. fails lcd_temp_cal_show_result(false); break; @@ -4645,12 +4642,12 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) custom_message_state = 1; lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION)); current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[X_AXIS] = PINDA_PREHEAT_X; current_position[Y_AXIS] = PINDA_PREHEAT_Y; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[Z_AXIS] = PINDA_PREHEAT_Z; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); while (current_temperature_pinda < start_temp) @@ -4662,10 +4659,10 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); //invalidate temp. calibration in case that in will be aborted during the calibration process current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); bool find_z_result = find_bed_induction_sensor_point_z(-1.f); @@ -4693,12 +4690,12 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) setTargetBed(50 + 10 * (temp - 30) / 5); // setTargetHotend(255, 0); current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[X_AXIS] = PINDA_PREHEAT_X; current_position[Y_AXIS] = PINDA_PREHEAT_Y; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[Z_AXIS] = PINDA_PREHEAT_Z; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); while (current_temperature_pinda < temp) { @@ -4706,10 +4703,10 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) serialecho_temperatures(); } current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); find_z_result = find_bed_induction_sensor_point_z(-1.f); if (find_z_result == false) { @@ -4749,7 +4746,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) current_position[X_AXIS] = PINDA_PREHEAT_X; current_position[Y_AXIS] = PINDA_PREHEAT_Y; current_position[Z_AXIS] = PINDA_PREHEAT_Z; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); while (abs(degBed() - PINDA_MIN_T) > 1) { @@ -4765,11 +4762,11 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); //invalidate temp. calibration in case that in will be aborted during the calibration process current_position[Z_AXIS] = 5; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[X_AXIS] = BED_X0; current_position[Y_AXIS] = BED_Y0; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); find_bed_induction_sensor_point_z(-1.f); @@ -4786,7 +4783,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) current_position[X_AXIS] = PINDA_PREHEAT_X; current_position[Y_AXIS] = PINDA_PREHEAT_Y; current_position[Z_AXIS] = PINDA_PREHEAT_Z; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); while (degBed() < t_c) { delay_keep_alive(1000); @@ -4797,10 +4794,10 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) serialecho_temperatures(); } current_position[Z_AXIS] = 5; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); current_position[X_AXIS] = BED_X0; current_position[Y_AXIS] = BED_Y0; - plan_buffer_line_curposXYZE(3000 / 60, active_extruder); + plan_buffer_line_curposXYZE(3000 / 60); st_synchronize(); find_bed_induction_sensor_point_z(-1.f); z_shift = (int)((current_position[Z_AXIS] - zero_z)*cs.axis_steps_per_unit[Z_AXIS]); @@ -4943,7 +4940,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) // Cycle through all points and probe them // First move up. During this first movement, the babystepping will be reverted. current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60); // The move to the first calibration point. current_position[X_AXIS] = BED_X0; current_position[Y_AXIS] = BED_Y0; @@ -4958,7 +4955,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); #endif //SUPPORT_VERBOSITY - plan_buffer_line_curposXYZE(homing_feedrate[X_AXIS] / 30, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[X_AXIS] / 30); // Wait until the move is finished. st_synchronize(); @@ -5010,7 +5007,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if((ix == 0) && (iy == 0)) current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; else current_position[Z_AXIS] += 2.f / nMeasPoints; //use relative movement from Z coordinate where PINDa triggered on previous point. This makes calibration faster. float init_z_bckp = current_position[Z_AXIS]; - plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); st_synchronize(); // Move to XY position of the sensor point. @@ -5031,7 +5028,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) #endif // SUPPORT_VERBOSITY //printf_P(PSTR("after clamping: [%f;%f]\n"), current_position[X_AXIS], current_position[Y_AXIS]); - plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(XY_AXIS_FEEDRATE); st_synchronize(); // Go down until endstop is hit @@ -5043,7 +5040,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if (init_z_bckp - current_position[Z_AXIS] < 0.1f) { //broken cable or initial Z coordinate too low. Go to MESH_HOME_Z_SEARCH and repeat last step (z-probe) again to distinguish between these two cases. //printf_P(PSTR("Another attempt! Current Z position: %f\n"), current_position[Z_AXIS]); current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); st_synchronize(); if (!find_bed_induction_sensor_point_z((has_z && mesh_point > 0) ? z0 - Z_CALIBRATION_THRESHOLD : -10.f, nProbeRetry)) { //if we have data from z calibration max allowed difference is 1mm for each point, if we dont have data max difference is 10mm from initial point @@ -5098,7 +5095,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) MYSERIAL.print(current_position[Z_AXIS], 5); } #endif // SUPPORT_VERBOSITY - plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); st_synchronize(); if (mesh_point != nMeasPoints * nMeasPoints) { Sound_MakeSound(e_SOUND_TYPE_StandardAlert); @@ -5115,14 +5112,14 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) // ~ Z-homing (can not be used "G28", because X & Y-homing would have been done before (Z-homing)) bState=enable_z_endstop(false); current_position[Z_AXIS] -= 1; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); st_synchronize(); enable_z_endstop(true); #ifdef TMC2130 tmc2130_home_enter(Z_AXIS_MASK); #endif // TMC2130 current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 40); st_synchronize(); #ifdef TMC2130 tmc2130_home_exit(); @@ -5252,7 +5249,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) //unretract (after PINDA preheat retraction) if (degHotend(active_extruder) > EXTRUDE_MINTEMP && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50) { current_position[E_AXIS] += default_retraction; - plan_buffer_line_curposXYZE(400, active_extruder); + plan_buffer_line_curposXYZE(400); } KEEPALIVE_STATE(NOT_BUSY); // Restore custom message state @@ -5274,7 +5271,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) if (mbl.active) { SERIAL_PROTOCOLPGM("Num X,Y: "); SERIAL_PROTOCOL(MESH_NUM_X_POINTS); - SERIAL_PROTOCOLPGM(","); + SERIAL_PROTOCOL(','); SERIAL_PROTOCOL(MESH_NUM_Y_POINTS); SERIAL_PROTOCOLPGM("\nZ search height: "); SERIAL_PROTOCOL(MESH_HOME_Z_SEARCH); @@ -5284,7 +5281,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) SERIAL_PROTOCOLPGM(" "); SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5); } - SERIAL_PROTOCOLPGM("\n"); + SERIAL_PROTOCOLLN(); } } else @@ -6292,7 +6289,7 @@ Sigma_Exit: for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) { SERIAL_PROTOCOLPGM(" T"); SERIAL_PROTOCOL(cur_extruder); - SERIAL_PROTOCOLPGM(":"); + SERIAL_PROTOCOL(':'); SERIAL_PROTOCOL_F(degHotend(cur_extruder),1); SERIAL_PROTOCOLPGM(" /"); SERIAL_PROTOCOL_F(degTargetHotend(cur_extruder),1); @@ -7977,9 +7974,8 @@ Sigma_Exit: { SERIAL_PROTOCOLPGM("P:"); SERIAL_PROTOCOL_F(current_temperature_pinda, 1); - SERIAL_PROTOCOLPGM("/"); - SERIAL_PROTOCOL(set_target_pinda); - SERIAL_PROTOCOLLN(""); + SERIAL_PROTOCOL('/'); + SERIAL_PROTOCOLLN(set_target_pinda); codenum = _millis(); } manage_heater(); @@ -8728,7 +8724,7 @@ Sigma_Exit: #else //SNMM if (tmp_extruder >= EXTRUDERS) { SERIAL_ECHO_START; - SERIAL_ECHOPGM("T"); + SERIAL_ECHO('T'); SERIAL_PROTOCOLLN((int)tmp_extruder); SERIAL_ECHOLNRPGM(_n("Invalid extruder"));////MSG_INVALID_EXTRUDER } @@ -8758,7 +8754,7 @@ Sigma_Exit: } // Set the new active extruder and position active_extruder = tmp_extruder; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); // Move to the old position if 'F' was in the parameters if (make_move && Stopped == false) { prepare_move(); @@ -9308,13 +9304,13 @@ void prepare_move() // 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])) { - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); + plan_buffer_line_destinationXYZE(feedrate/60); } else { #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); #else - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder); + plan_buffer_line_destinationXYZE(feedrate*feedmultiply*(1./(60.f*100.f))); #endif } @@ -9946,7 +9942,7 @@ static void wait_for_heater(long codenum, uint8_t extruder) { } else { - SERIAL_PROTOCOLLN("?"); + SERIAL_PROTOCOLLN('?'); } } #else @@ -10077,16 +10073,16 @@ void bed_check(float x_dimension, float y_dimension, int x_points_num, int y_poi card.openFile(filename_wldsd, false); /*destination[Z_AXIS] = mesh_home_z_search; - //plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE, active_extruder); + //plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], Z_LIFT_FEEDRATE, active_extruder); + plan_buffer_line_destinationXYZE(Z_LIFT_FEEDRATE); for(int8_t i=0; i < NUM_AXIS; i++) { current_position[i] = destination[i]; } st_synchronize(); */ destination[Z_AXIS] = measure_z_height; - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], Z_LIFT_FEEDRATE, active_extruder); + plan_buffer_line_destinationXYZE(Z_LIFT_FEEDRATE); for(int8_t i=0; i < NUM_AXIS; i++) { current_position[i] = destination[i]; } @@ -10111,9 +10107,9 @@ void bed_check(float x_dimension, float y_dimension, int x_points_num, int y_poi if (iy & 1) ix = (x_points_num - 1) - ix; // Zig zag float z0 = 0.f; /*destination[Z_AXIS] = mesh_home_z_search; - //plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE, active_extruder); + //plan_buffer_line_curposXYZE(Z_LIFT_FEEDRATE); - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], Z_LIFT_FEEDRATE, active_extruder); + plan_buffer_line_destinationXYZE(Z_LIFT_FEEDRATE); for(int8_t i=0; i < NUM_AXIS; i++) { current_position[i] = destination[i]; } @@ -10126,8 +10122,8 @@ void bed_check(float x_dimension, float y_dimension, int x_points_num, int y_poi destination[X_AXIS] = ix * (x_dimension / (x_points_num - 1)) + shift_x; destination[Y_AXIS] = iy * (y_dimension / (y_points_num - 1)) + shift_y; - mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], XY_AXIS_FEEDRATE/6, active_extruder); - set_current_to_destination(); + mesh_plan_buffer_line_destinationXYZE(XY_AXIS_FEEDRATE/6); + set_current_to_destination(); st_synchronize(); // printf_P(PSTR("X = %f; Y= %f \n"), current_position[X_AXIS], current_position[Y_AXIS]); @@ -10550,12 +10546,12 @@ void long_pause() //long pause print //lift z current_position[Z_AXIS] += Z_PAUSE_LIFT; if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; - plan_buffer_line_curposXYZE(15, active_extruder); + plan_buffer_line_curposXYZE(15); //Move XY to side current_position[X_AXIS] = X_PAUSE_POS; current_position[Y_AXIS] = Y_PAUSE_POS; - plan_buffer_line_curposXYZE(50, active_extruder); + plan_buffer_line_curposXYZE(50); // Turn off the print fan fanSpeed = 0; @@ -10665,7 +10661,7 @@ void uvlo_() // Retract current_position[E_AXIS] -= default_retraction; - plan_buffer_line_curposXYZE(95, active_extruder); + plan_buffer_line_curposXYZE(95); st_synchronize(); disable_e0(); @@ -10678,7 +10674,7 @@ void uvlo_() current_position[Z_AXIS] += float(1024 - z_microsteps) / (z_res * cs.axis_steps_per_unit[Z_AXIS]) + UVLO_Z_AXIS_SHIFT; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS]/60, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS]/60); st_synchronize(); poweroff_z(); @@ -10741,7 +10737,7 @@ void uvlo_() // All is set: with all the juice left, try to move extruder away to detach the nozzle completely from the print poweron_z(); current_position[X_AXIS] = (current_position[X_AXIS] < 0.5f * (X_MIN_POS + X_MAX_POS)) ? X_MIN_POS : X_MAX_POS; - plan_buffer_line_curposXYZE(500, active_extruder); + plan_buffer_line_curposXYZE(500); st_synchronize(); wdt_enable(WDTO_1S); @@ -10792,7 +10788,7 @@ void uvlo_tiny() current_position[Z_AXIS] += float(1024 - z_microsteps) / (z_res * cs.axis_steps_per_unit[Z_AXIS]) + UVLO_TINY_Z_AXIS_SHIFT; - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS]/60, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS]/60); st_synchronize(); poweroff_z(); @@ -10971,7 +10967,7 @@ bool recover_machine_state_after_power_panic() // 5) Set the physical positions from the logical positions using the world2machine transformation // This is only done to inizialize Z/E axes with physical locations, since X/Y are unknown. - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); // 6) Power up the Z motors, mark their positions as known. axis_known_position[Z_AXIS] = true; @@ -11395,9 +11391,9 @@ void print_mesh_bed_leveling_table() for (int8_t y = 0; y < MESH_NUM_Y_POINTS; ++ y) for (int8_t x = 0; x < MESH_NUM_Y_POINTS; ++ x) { MYSERIAL.print(mbl.z_values[y][x], 3); - SERIAL_ECHOPGM(" "); + SERIAL_ECHO(' '); } - SERIAL_ECHOLNPGM(""); + SERIAL_ECHOLN(); } uint16_t print_time_remaining() { @@ -11445,7 +11441,7 @@ static void print_time_remaining_init() void load_filament_final_feed() { current_position[E_AXIS]+= FILAMENTCHANGE_FINALFEED; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_EFEED_FINAL, active_extruder); + plan_buffer_line_curposXYZE(FILAMENTCHANGE_EFEED_FINAL); } //! @brief Wait for user to check the state @@ -11590,7 +11586,7 @@ void M600_load_filament_movements() plan_buffer_line_curposXYZE(50, active_extruder); #else current_position[E_AXIS]+= FILAMENTCHANGE_FIRSTFEED ; - plan_buffer_line_curposXYZE(FILAMENTCHANGE_EFEED_FIRST, active_extruder); + plan_buffer_line_curposXYZE(FILAMENTCHANGE_EFEED_FIRST); #endif load_filament_final_feed(); lcd_loading_filament(); diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index fb25ff6cf..a49cd6d68 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -331,7 +331,7 @@ void CardReader::diveSubfolder (const char *fileName, SdFile& dir) { SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(subdirname); - SERIAL_PROTOCOLLNPGM("."); + SERIAL_PROTOCOLLN('.'); return; } else @@ -430,7 +430,7 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru { SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLLNPGM("."); + SERIAL_PROTOCOLLN('.'); } } else @@ -439,7 +439,7 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru { SERIAL_PROTOCOLRPGM(MSG_SD_OPEN_FILE_FAIL); SERIAL_PROTOCOL(fname); - SERIAL_PROTOCOLLNPGM("."); + SERIAL_PROTOCOLLN('.'); } else { @@ -496,17 +496,15 @@ void CardReader::getStatus() SERIAL_PROTOCOLLNPGM("Print saved"); } else { - SERIAL_PROTOCOL(longFilename); - SERIAL_PROTOCOLPGM("\n"); + SERIAL_PROTOCOLLN(longFilename); SERIAL_PROTOCOLRPGM(_N("SD printing byte "));////MSG_SD_PRINTING_BYTE SERIAL_PROTOCOL(sdpos); - SERIAL_PROTOCOLPGM("/"); + SERIAL_PROTOCOL('/'); SERIAL_PROTOCOLLN(filesize); - uint16_t time = _millis()/60000 - starttime/60000; + uint16_t time = ( _millis() - starttime ) / 60000U; SERIAL_PROTOCOL(itostr2(time/60)); SERIAL_PROTOCOL(':'); - SERIAL_PROTOCOL(itostr2(time%60)); - SERIAL_PROTOCOLPGM("\n"); + SERIAL_PROTOCOLLN(itostr2(time%60)); } } else { diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp index edb2fa894..f5fc768a4 100755 --- a/Firmware/fsensor.cpp +++ b/Firmware/fsensor.cpp @@ -624,7 +624,7 @@ void fsensor_update(void) // move the nozzle away while checking the filament current_position[Z_AXIS] += 0.8; if(current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; - plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS], active_extruder); + plan_buffer_line_curposXYZE(max_feedrate[Z_AXIS]); st_synchronize(); // check the filament in isolation @@ -632,9 +632,9 @@ void fsensor_update(void) fsensor_oq_meassure_start(0); float e_tmp = current_position[E_AXIS]; current_position[E_AXIS] -= 3; - plan_buffer_line_curposXYZE(250/60, active_extruder); + plan_buffer_line_curposXYZE(250/60); current_position[E_AXIS] = e_tmp; - plan_buffer_line_curposXYZE(200/60, active_extruder); + plan_buffer_line_curposXYZE(200/60); st_synchronize(); fsensor_oq_meassure_stop(); diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index 88cbc671a..12fca582e 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -920,7 +920,7 @@ static inline void go_xy(float x, float y, float fr) static inline void go_to_current(float fr) { - plan_buffer_line_curposXYZE(fr, active_extruder); + plan_buffer_line_curposXYZE(fr); st_synchronize(); } @@ -929,7 +929,7 @@ static inline void update_current_position_xyz() current_position[X_AXIS] = st_get_position_mm(X_AXIS); current_position[Y_AXIS] = st_get_position_mm(Y_AXIS); current_position[Z_AXIS] = st_get_position_mm(Z_AXIS); - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); } static inline void update_current_position_z() diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index ebf8c0131..c5981894c 100755 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -540,7 +540,7 @@ void mmu_command(MmuCmd cmd) void mmu_load_step(bool synchronize) { current_position[E_AXIS] = current_position[E_AXIS] + MMU_LOAD_FEEDRATE * 0.1; - plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE); if (synchronize) st_synchronize(); } @@ -605,7 +605,7 @@ bool mmu_get_response(uint8_t move) { printf_P(PSTR("Unload 1\n")); current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001; - plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE); st_synchronize(); } } @@ -623,7 +623,7 @@ bool mmu_get_response(uint8_t move) { printf_P(PSTR("Unload 2\n")); current_position[E_AXIS] = current_position[E_AXIS] - MMU_LOAD_FEEDRATE * MMU_LOAD_TIME_MS*0.001; - plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE); st_synchronize(); } } @@ -701,13 +701,13 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move) //lift z current_position[Z_AXIS] += Z_PAUSE_LIFT; if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; - plan_buffer_line_curposXYZE(15, active_extruder); + plan_buffer_line_curposXYZE(15); st_synchronize(); //Move XY to side current_position[X_AXIS] = X_PAUSE_POS; current_position[Y_AXIS] = Y_PAUSE_POS; - plan_buffer_line_curposXYZE(50, active_extruder); + plan_buffer_line_curposXYZE(50); st_synchronize(); } if (turn_off_nozzle) { @@ -758,17 +758,17 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move) lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); delay_keep_alive(3000); } - mmu_wait_for_heater_blocking(); + mmu_wait_for_heater_blocking(); } if (move_axes) { lcd_clear(); lcd_display_message_fullscreen_P(_i("MMU OK. Resuming position...")); current_position[X_AXIS] = x_position_bckp; current_position[Y_AXIS] = y_position_bckp; - plan_buffer_line_curposXYZE(50, active_extruder); + plan_buffer_line_curposXYZE(50); st_synchronize(); current_position[Z_AXIS] = z_position_bckp; - plan_buffer_line_curposXYZE(15, active_extruder); + plan_buffer_line_curposXYZE(15); st_synchronize(); } else { @@ -807,19 +807,19 @@ void mmu_load_to_nozzle() current_position[E_AXIS] += 7.2f; } float feedrate = 562; - plan_buffer_line_curposXYZE(feedrate / 60, active_extruder); + plan_buffer_line_curposXYZE(feedrate / 60); st_synchronize(); current_position[E_AXIS] += 14.4f; feedrate = 871; - plan_buffer_line_curposXYZE(feedrate / 60, active_extruder); + plan_buffer_line_curposXYZE(feedrate / 60); st_synchronize(); current_position[E_AXIS] += 36.0f; feedrate = 1393; - plan_buffer_line_curposXYZE(feedrate / 60, active_extruder); + plan_buffer_line_curposXYZE(feedrate / 60); st_synchronize(); current_position[E_AXIS] += 14.4f; feedrate = 871; - plan_buffer_line_curposXYZE(feedrate / 60, active_extruder); + plan_buffer_line_curposXYZE(feedrate / 60); st_synchronize(); if (!saved_e_relative_mode) axis_relative_modes &= ~E_AXIS_MASK; } @@ -1072,7 +1072,7 @@ void mmu_filament_ramming() for(uint8_t i = 0; i < (sizeof(ramming_sequence)/sizeof(E_step));++i) { current_position[E_AXIS] += pgm_read_float(&(ramming_sequence[i].extrude)); - plan_buffer_line_curposXYZE(pgm_read_float(&(ramming_sequence[i].feed_rate)), active_extruder); + plan_buffer_line_curposXYZE(pgm_read_float(&(ramming_sequence[i].feed_rate))); st_synchronize(); } } @@ -1446,9 +1446,9 @@ bFilamentAction=false; // NOT in "mmu_fil_eject_menu( static bool can_load() { current_position[E_AXIS] += 60; - plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE); current_position[E_AXIS] -= 52; - plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE); st_synchronize(); uint_least8_t filament_detected_count = 0; @@ -1458,7 +1458,7 @@ static bool can_load() for(uint_least8_t i = 0; i < steps; ++i) { current_position[E_AXIS] -= e_increment; - plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE, active_extruder); + plan_buffer_line_curposXYZE(MMU_LOAD_FEEDRATE); st_synchronize(); if(0 == PIN_GET(IR_SENSOR_PIN)) { diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index fcebfa58f..c0f465c2a 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -671,8 +671,16 @@ void planner_abort_hard() waiting_inside_plan_buffer_line_print_aborted = true; } -void plan_buffer_line_curposXYZE(float feed_rate, uint8_t extruder) { - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feed_rate, extruder ); +void plan_buffer_line_curposXYZE(float feed_rate) { + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feed_rate, active_extruder ); +} + +void plan_buffer_line_destinationXYZE(float feed_rate) { + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feed_rate, active_extruder); +} + +void plan_set_position_curposXYZE(){ + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); } float junction_deviation = 0.1; diff --git a/Firmware/planner.h b/Firmware/planner.h index 2adcf94e7..2096111ea 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -154,7 +154,11 @@ vector_3 plan_get_position(); /// plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[3], ... /// saves almost 5KB. /// The performance penalty is negligible, since these planned lines are usually maintenance moves with the extruder. -void plan_buffer_line_curposXYZE(float feed_rate, uint8_t extruder); +void plan_buffer_line_curposXYZE(float feed_rate); + +void plan_buffer_line_destinationXYZE(float feed_rate); + +void plan_set_position_curposXYZE(); void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, uint8_t extruder, const float* gcode_target = NULL); //void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 9537d9df6..a9fa50d1d 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2919,7 +2919,7 @@ static void _lcd_move(const char *name, int axis, int min, int max) if (max_software_endstops && current_position[axis] > max) current_position[axis] = max; lcd_encoder = 0; world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); - plan_buffer_line_curposXYZE(manual_feedrate[axis] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[axis] / 60); lcd_draw_update = 1; } } @@ -2944,7 +2944,7 @@ static void lcd_move_e() { current_position[E_AXIS] += float((int)lcd_encoder) * move_menu_scale; lcd_encoder = 0; - plan_buffer_line_curposXYZE(manual_feedrate[E_AXIS] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[E_AXIS] / 60); lcd_draw_update = 1; } } @@ -3462,7 +3462,7 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z) { // Don't know where we are. Let's claim we are Z=0, so the soft end stops will not be triggered when moving up. current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); // Until confirmed by the confirmation dialog. for (;;) { @@ -3484,7 +3484,7 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z) // Only move up, whatever direction the user rotates the encoder. current_position[Z_AXIS] += fabs(lcd_encoder); lcd_encoder = 0; - plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60); } } if (lcd_clicked()) { @@ -3520,7 +3520,7 @@ calibrated: else { current_position[Z_AXIS] = Z_MAX_POS+4.f; } - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); return true; canceled: @@ -4038,7 +4038,7 @@ void prusa_statistics_err(char c){ } static void prusa_statistics_case0(uint8_t statnr){ - SERIAL_ECHO("{"); + SERIAL_ECHO('{'); prusa_stat_printerstatus(statnr); prusa_stat_farm_number(); prusa_stat_printinfo(); @@ -4066,7 +4066,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) { } else { - SERIAL_ECHO("{"); + SERIAL_ECHO('{'); prusa_stat_printerstatus(1); prusa_stat_farm_number(); prusa_stat_diameter(); @@ -4899,7 +4899,7 @@ void lcd_language() static void wait_preheat() { current_position[Z_AXIS] = 100; //move in z axis to make space for loading filament - plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60, active_extruder); + plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60); delay_keep_alive(2000); lcd_display_message_fullscreen_P(_T(MSG_WIZARD_HEATING)); lcd_set_custom_characters(); @@ -6387,13 +6387,13 @@ void unload_filament() // extr_unload2(); current_position[E_AXIS] -= 45; - plan_buffer_line_curposXYZE(5200 / 60, active_extruder); + plan_buffer_line_curposXYZE(5200 / 60); st_synchronize(); current_position[E_AXIS] -= 15; - plan_buffer_line_curposXYZE(1000 / 60, active_extruder); + plan_buffer_line_curposXYZE(1000 / 60); st_synchronize(); current_position[E_AXIS] -= 20; - plan_buffer_line_curposXYZE(1000 / 60, active_extruder); + plan_buffer_line_curposXYZE(1000 / 60); st_synchronize(); lcd_display_message_fullscreen_P(_T(MSG_PULL_OUT_FILAMENT)); @@ -7353,13 +7353,13 @@ void lcd_print_stop() cancel_heatup = true; //unroll temperature wait loop stack. current_position[Z_AXIS] += 10; //lift Z. - plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[Z_AXIS] / 60); if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) //if axis are homed, move to parked position. { current_position[X_AXIS] = X_CANCEL_POS; current_position[Y_AXIS] = Y_CANCEL_POS; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); } st_synchronize(); @@ -7713,7 +7713,7 @@ bool lcd_selftest() current_position[Y_AXIS] += 4; #endif //TMC2130 current_position[Z_AXIS] = current_position[Z_AXIS] + 10; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); set_destination_to_current(); _progress = lcd_selftest_screen(TestScreen::AxisZ, _progress, 3, true, 1500); @@ -7725,7 +7725,7 @@ bool lcd_selftest() //raise Z to not damage the bed during and hotend testing current_position[Z_AXIS] += 20; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); } @@ -7733,7 +7733,7 @@ bool lcd_selftest() if (_result) { current_position[Z_AXIS] = current_position[Z_AXIS] + 10; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); _progress = lcd_selftest_screen(TestScreen::Home, 0, 2, true, 0); bool bres = tmc2130_home_calibrate(X_AXIS); @@ -7829,7 +7829,7 @@ bool lcd_selftest() static void reset_crash_det(unsigned char axis) { current_position[axis] += 10; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); if (eeprom_read_byte((uint8_t*)EEPROM_CRASH_DET)) tmc2130_sg_stop_on_crash = true; } @@ -7858,7 +7858,7 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) { // first axis length measurement begin current_position[axis] -= (axis_length + margin); - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); @@ -7868,11 +7868,11 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) { current_position_init = st_get_position_mm(axis); current_position[axis] += 2 * margin; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); current_position[axis] += axis_length; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); @@ -7888,11 +7888,11 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) { current_position[axis] -= margin; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); current_position[axis] -= (axis_length + margin); - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); @@ -7917,7 +7917,7 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) { lcd_selftest_error(TestError::Axis, _error_1, ""); current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); reset_crash_det(axis); enable_endstops(true); endstops_hit_on_purpose(); @@ -7937,13 +7937,13 @@ static bool lcd_selfcheck_axis_sg(unsigned char axis) { lcd_selftest_error(TestError::Pulley, _error_1, ""); current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); reset_crash_det(axis); endstops_hit_on_purpose(); return false; } current_position[axis] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); reset_crash_det(axis); endstops_hit_on_purpose(); return true; @@ -7965,13 +7965,13 @@ static bool lcd_selfcheck_axis(int _axis, int _travel) if (_axis == X_AXIS) { current_position[Z_AXIS] += 17; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); } do { current_position[_axis] = current_position[_axis] - 1; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); #ifdef TMC2130 if ((READ(Z_MIN_PIN) ^ (bool)Z_MIN_ENDSTOP_INVERTING)) @@ -8051,7 +8051,7 @@ static bool lcd_selfcheck_axis(int _axis, int _travel) } } current_position[_axis] = 0; //simulate axis home to avoid negative numbers for axis position, especially Z. - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + plan_set_position_curposXYZE(); return _stepresult; } @@ -8074,17 +8074,17 @@ static bool lcd_selfcheck_pulleys(int axis) current_position_init = current_position[axis]; current_position[axis] += 2; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); for (i = 0; i < 5; i++) { refresh_cmd_timeout(); current_position[axis] = current_position[axis] + move; st_current_set(0, 850); //set motor current higher - plan_buffer_line_curposXYZE(200, active_extruder); + plan_buffer_line_curposXYZE(200); st_synchronize(); if (SilentModeMenu != SILENT_MODE_OFF) st_current_set(0, tmp_motor[0]); //set back to normal operation currents else st_current_set(0, tmp_motor_loud[0]); //set motor current back current_position[axis] = current_position[axis] - move; - plan_buffer_line_curposXYZE(50, active_extruder); + plan_buffer_line_curposXYZE(50); st_synchronize(); if (((READ(X_MIN_PIN) ^ X_MIN_ENDSTOP_INVERTING) == 1) || ((READ(Y_MIN_PIN) ^ Y_MIN_ENDSTOP_INVERTING) == 1)) { @@ -8101,7 +8101,7 @@ static bool lcd_selfcheck_pulleys(int axis) endstop_triggered = true; if (current_position_init - 1 <= current_position[axis] && current_position_init + 1 >= current_position[axis]) { current_position[axis] += 10; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); return(true); } @@ -8112,7 +8112,7 @@ static bool lcd_selfcheck_pulleys(int axis) } else { current_position[axis] -= 1; - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); if (_millis() > timeout_counter) { lcd_selftest_error(TestError::Pulley, (axis == 0) ? "X" : "Y", ""); @@ -8142,7 +8142,7 @@ static bool lcd_selfcheck_endstops() #endif //!TMC2130 if ((READ(Z_MIN_PIN) ^ Z_MIN_ENDSTOP_INVERTING) == 1) current_position[2] += 10; } - plan_buffer_line_curposXYZE(manual_feedrate[0] / 60, active_extruder); + plan_buffer_line_curposXYZE(manual_feedrate[0] / 60); st_synchronize(); if ( @@ -8653,7 +8653,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan) static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_scale, bool _clear, int _delay) { - lcd_update_enable(false); + lcd_update_enable(false); const char *_indicator = (_progress >= _progress_scale) ? "-" : "|"; @@ -8701,7 +8701,7 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s { //SERIAL_ECHOLNPGM("Other tests"); - TestScreen _step_block = TestScreen::AxisX; + TestScreen _step_block = TestScreen::AxisX; lcd_selftest_screen_step(2, 2, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "X", _indicator); _step_block = TestScreen::AxisY; @@ -8713,8 +8713,8 @@ static int lcd_selftest_screen(TestScreen screen, int _progress, int _progress_s _step_block = TestScreen::Bed; lcd_selftest_screen_step(3, 0, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "Bed", _indicator); - _step_block = TestScreen::Hotend; - lcd_selftest_screen_step(3, 9, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "Hotend", _indicator); + _step_block = TestScreen::Hotend; + lcd_selftest_screen_step(3, 9, ((screen == _step_block) ? 1 : (screen < _step_block) ? 0 : 2), "Hotend", _indicator); } if (_delay > 0) delay_keep_alive(_delay); From 751f810dd787c10964ea4ec3c9832b565f89d07f Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Mon, 1 Jun 2020 18:58:15 +0300 Subject: [PATCH 13/77] ALTFAN implementation (#2692) * ALTFAN implementation * Use CRITICAL_SECTION macros * Use uint16_t instead of unsigned int * Add forgotten CRITICAL_SECTION * Documentation --- Firmware/Marlin_main.cpp | 7 + Firmware/system_timer.h | 5 +- Firmware/temperature.cpp | 160 +++++++++--------- Firmware/temperature.h | 8 +- Firmware/tone04.c | 126 ++++++++++++++ Firmware/tone04.h | 25 +++ Firmware/ultralcd.cpp | 32 +--- .../variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 + 8 files changed, 256 insertions(+), 109 deletions(-) create mode 100644 Firmware/tone04.c create mode 100644 Firmware/tone04.h diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 36764b21f..799e5e9d5 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1252,6 +1252,13 @@ void setup() w25x20cl_err_msg(); printf_P(_n("W25X20CL not responding.\n")); } +#ifdef EXTRUDER_ALTFAN_DETECT + SERIAL_ECHORPGM(_n("Extruder fan type: ")); + if (extruder_altfan_detect()) + SERIAL_ECHOLNRPGM(PSTR("ALTFAN")); + else + SERIAL_ECHOLNRPGM(PSTR("NOCTUA")); +#endif //EXTRUDER_ALTFAN_DETECT plan_init(); // Initialize planner; diff --git a/Firmware/system_timer.h b/Firmware/system_timer.h index 626e82348..9906460ae 100644 --- a/Firmware/system_timer.h +++ b/Firmware/system_timer.h @@ -8,11 +8,12 @@ #ifdef SYSTEM_TIMER_2 #include "timer02.h" +#include "tone04.h" #define _millis millis2 #define _micros micros2 #define _delay delay2 -#define _tone tone -#define _noTone noTone +#define _tone tone4 +#define _noTone noTone4 #define timer02_set_pwm0(pwm0) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index f6f8f3206..c019514c5 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -143,14 +143,18 @@ static volatile bool temp_meas_ready = false; #ifdef FAN_SOFT_PWM static unsigned char soft_pwm_fan; #endif -#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) - unsigned long extruder_autofan_last_check = _millis(); - uint8_t fanSpeedBckp = 255; - bool fan_measuring = false; -#endif +uint8_t fanSpeedBckp = 255; + +#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) + unsigned long extruder_autofan_last_check = _millis(); + + bool fan_measuring = false; + uint8_t fanState = 0; +#ifdef EXTRUDER_ALTFAN_DETECT + bool extruderFanIsAltfan = false; //set to Noctua +#endif //EXTRUDER_ALTFAN_DETECT +#endif #if EXTRUDERS > 3 @@ -210,6 +214,35 @@ static void temp_runaway_check(int _heater_id, float _target_temperature, float static void temp_runaway_stop(bool isPreheat, bool isBed); #endif +#ifdef EXTRUDER_ALTFAN_DETECT +ISR(INT6_vect) { + fan_edge_counter[0]++; +} + +bool extruder_altfan_detect() +{ + setExtruderAutoFanState(3); + + SET_INPUT(TACH_0); + CRITICAL_SECTION_START; + EICRB &= ~(1 << ISC61); + EICRB |= (1 << ISC60); + EIMSK |= (1 << INT6); + fan_edge_counter[0] = 0; + CRITICAL_SECTION_END; + extruder_autofan_last_check = _millis(); + + _delay(1000); + + EIMSK &= ~(1 << INT6); + + countFanSpeed(); + extruderFanIsAltfan = fan_speed[0] > 100; + setExtruderAutoFanState(1); + return extruderFanIsAltfan; +} +#endif //EXTRUDER_ALTFAN_DETECT + // return "false", if all extruder-heaters are 'off' (ie. "true", if any heater is 'on') bool checkAllHotends(void) { @@ -239,9 +272,7 @@ bool checkAllHotends(void) const uint8_t safety_check_cycles_count = (extruder < 0) ? 45 : 10; //10 cycles / 20s delay for extruder and 45 cycles / 90s for heatbed float temp_ambient; -#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) +#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) unsigned long extruder_autofan_last_check = _millis(); #endif @@ -289,9 +320,7 @@ bool checkAllHotends(void) max=max(max,input); min=min(min,input); - #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) + #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) if(_millis() - extruder_autofan_last_check > 2500) { checkExtruderAutoFans(); extruder_autofan_last_check = _millis(); @@ -447,29 +476,31 @@ int getHeaterPower(int heater) { return soft_pwm[heater]; } -#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) +#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) #if defined(FAN_PIN) && FAN_PIN > -1 #if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN" #endif - #if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN - #error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN" - #endif - #if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN - #error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN" - #endif - #endif + #endif -void setExtruderAutoFanState(int pin, bool state) +void setExtruderAutoFanState(uint8_t state) { - unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0; - // this idiom allows both digital and PWM fan outputs (see M42 handling). - pinMode(pin, OUTPUT); - digitalWrite(pin, newFanSpeed); - //analogWrite(pin, newFanSpeed); + //If bit 1 is set (0x02), then the extruder fan speed won't be adjusted according to temperature. Useful for forcing + //the fan to either On or Off during certain tests/errors. + + fanState = state; + uint8_t newFanSpeed = 0; + if (fanState & 0x01) + { +#ifdef EXTRUDER_ALTFAN_DETECT + if (extruderFanIsAltfan) newFanSpeed = EXTRUDER_ALTFAN_SPEED_SILENT; + else newFanSpeed = EXTRUDER_AUTO_FAN_SPEED; +#else //EXTRUDER_ALTFAN_DETECT + newFanSpeed = EXTRUDER_AUTO_FAN_SPEED; +#endif //EXTRUDER_ALTFAN_DETECT + } + timer4_set_fan0(newFanSpeed); } #if (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1))))) @@ -503,7 +534,7 @@ void checkFanSpeed() fans_check_enabled = (eeprom_read_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED) > 0); static unsigned char fan_speed_errors[2] = { 0,0 }; #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 >-1)) - if ((fan_speed[0] == 0) && (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)){ fan_speed_errors[0]++;} + if ((fan_speed[0] < 20) && (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)){ fan_speed_errors[0]++;} else{ fan_speed_errors[0] = 0; host_keepalive(); @@ -577,47 +608,14 @@ void fanSpeedError(unsigned char _fan) { void checkExtruderAutoFans() { - uint8_t fanState = 0; - - // which fan pins need to be turned on? - #if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1 - if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE) - fanState |= 1; - #endif - #if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1 - if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) - { - if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) - fanState |= 1; - else - fanState |= 2; - } - #endif - #if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1 - if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) - { - if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) - fanState |= 1; - else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) - fanState |= 2; - else - fanState |= 4; - } - #endif - - // update extruder auto fan states - #if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1 - setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0); - #endif - #if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1 - if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN) - setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0); - #endif - #if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1 - if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN - && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN) - setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0); - #endif +#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1 + if (!(fanState & 0x02)) + { + fanState &= ~1; + fanState |= current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE; + } + setExtruderAutoFanState(fanState); +#endif } #endif // any extruder auto fan pins set @@ -737,9 +735,7 @@ void manage_heater() #define FAN_CHECK_DURATION 100 //100ms #ifndef DEBUG_DISABLE_FANCHECK - #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ - (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) + #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) #ifdef FAN_SOFT_PWM #ifdef FANCHECK @@ -1098,7 +1094,9 @@ void tp_init() timer0_init(); OCR2B = 128; - TIMSK2 |= (1< +#include +#include "pins.h" + +#ifndef CRITICAL_SECTION_START + #define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); + #define CRITICAL_SECTION_END SREG = _sreg; +#endif //CRITICAL_SECTION_START + + +#include "fastio.h" + +void timer4_init(void) +{ + CRITICAL_SECTION_START; + + SET_OUTPUT(BEEPER); + WRITE(BEEPER, LOW); + + SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN); + + // Set timer mode 9 (PWM,Phase and Frequency Correct) + // Prescaler is CLK/1024 + // Output compare is disabled on all timer pins + // Input capture is disabled + // All interrupts are disabled + TCCR4A = (1 << WGM40); + TCCR4B = (1 << WGM43) | (1 << CS42) | (1 << CS40); + OCR4A = 255; + OCR4B = 255; + OCR4C = 255; + TIMSK4 = 0; + + CRITICAL_SECTION_END; +} + +#ifdef EXTRUDER_0_AUTO_FAN_PIN +void timer4_set_fan0(uint8_t duty) +{ + if (duty == 0 || duty == 255) + { + // We use digital logic if the duty cycle is 0% or 100% + TCCR4A &= ~(1 << COM4C1); + OCR4C = 0; + WRITE(EXTRUDER_0_AUTO_FAN_PIN, duty); + } + else + { + // Use the timer for fan speed. Enable the timer compare output and set the duty cycle. + // This function also handles the impossible scenario of a fan speed change during a Tone. + // Better be safe than sorry. + CRITICAL_SECTION_START; + // Enable the PWM output on the fan pin. + TCCR4A |= (1 << COM4C1); + OCR4C = (((uint32_t)duty) * ((uint32_t)((TIMSK4 & (1 << OCIE4A))?OCR4A:255))) / ((uint32_t)255); + CRITICAL_SECTION_END; + } +} +#endif //EXTRUDER_0_AUTO_FAN_PIN + +// Because of the timer mode change, we need two interrupts. We could also try to assume that the frequency is x2 +// and use a TOGGLE(), but this seems to work well enough so I left it as it is now. +ISR(TIMER4_COMPA_vect) +{ + WRITE(BEEPER, 1); +} + +ISR(TIMER4_OVF_vect) +{ + WRITE(BEEPER, 0); +} + +void tone4(__attribute__((unused)) uint8_t _pin, uint16_t frequency) +{ + //this ocr and prescalarbits calculation is taken from the Arduino core and simplified for one type of timer only + uint8_t prescalarbits = 0b001; + uint32_t ocr = F_CPU / frequency / 2 - 1; + + if (ocr > 0xffff) + { + ocr = F_CPU / frequency / 2 / 64 - 1; + prescalarbits = 0b011; + } + + CRITICAL_SECTION_START; + // Set calcualted prescaler + TCCR4B = (TCCR4B & 0b11111000) | prescalarbits; +#ifdef EXTRUDER_0_AUTO_FAN_PIN + // Scale the fan PWM duty cycle so that it remains constant, but at the tone frequency + OCR4C = (((uint32_t)OCR4C) * ocr) / (uint32_t)((TIMSK4 & (1 << OCIE4A))?OCR4A:255); +#endif //EXTRUDER_0_AUTO_FAN_PIN + // Set calcualted ocr + OCR4A = ocr; + // Enable Output compare A interrupt and timer overflow interrupt + TIMSK4 |= (1 << OCIE4A) | (1 << TOIE4); + CRITICAL_SECTION_END; +} + +void noTone4(__attribute__((unused)) uint8_t _pin) +{ + CRITICAL_SECTION_START; + // Revert prescaler to CLK/1024 + TCCR4B = (TCCR4B & 0b11111000) | (1 << CS42) | (1 << CS40); +#ifdef EXTRUDER_0_AUTO_FAN_PIN + // Scale the fan OCR back to the original value. + OCR4C = (((uint32_t)OCR4C) * (uint32_t)255) / (uint32_t)((TIMSK4 & (1 << OCIE4A))?OCR4A:255); +#endif //EXTRUDER_0_AUTO_FAN_PIN + OCR4A = 255; + // Disable Output compare A interrupt and timer overflow interrupt + TIMSK4 &= ~((1 << OCIE4A) | (1 << TOIE4)); + CRITICAL_SECTION_END; + // Turn beeper off if it was on when noTone was called + WRITE(BEEPER, 0); +} + + +#endif //SYSTEM_TIMER_2 diff --git a/Firmware/tone04.h b/Firmware/tone04.h new file mode 100644 index 000000000..f11eeb6c6 --- /dev/null +++ b/Firmware/tone04.h @@ -0,0 +1,25 @@ +//tone04.h +// use atmega timer4 as main tone timer instead of timer2 +// timer2 is used for System timer. +#ifndef TIMER04_H +#define TIMER04_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif //defined(__cplusplus) + +extern void timer4_init(void); + +extern void timer4_set_fan0(uint8_t duty); + +extern void tone4(uint8_t _pin, uint16_t frequency); + +extern void noTone4(uint8_t _pin); + +#if defined(__cplusplus) +} +#endif //defined(__cplusplus) + +#endif //TIMER02_H diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index a9fa50d1d..e32b6ad1c 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -6673,7 +6673,7 @@ static bool fan_error_selftest() fanSpeedSoftPwm = 255; #endif //FAN_SOFT_PWM manage_heater(); //enables print fan - setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, 1); //force enables the extruder fan untill the first manage_heater() call. + setExtruderAutoFanState(3); //force enables the extruder fan #ifdef FAN_SOFT_PWM extruder_autofan_last_check = _millis(); fan_measuring = true; @@ -6681,6 +6681,7 @@ static bool fan_error_selftest() _delay(1000); //delay_keep_alive would turn off extruder fan, because temerature is too low (maybe) manage_heater(); fanSpeed = 0; + setExtruderAutoFanState(1); //releases lock on the extruder fan #ifdef FAN_SOFT_PWM fanSpeedSoftPwm = 0; #endif //FAN_SOFT_PWM @@ -8468,8 +8469,7 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite, lcd_set_cursor(0, 1); if(check_opposite == true) lcd_puts_P(_T(MSG_SELFTEST_COOLING_FAN)); else lcd_puts_P(_T(MSG_SELFTEST_EXTRUDER_FAN)); - SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN); - WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1); + setExtruderAutoFanState(3); break; case 1: // object cooling fan @@ -8498,23 +8498,6 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite, lcd_button_pressed = false; do { - switch (_fan) - { - case 0: - // extruder cooling fan - SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN); - WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1); - break; - case 1: - // object cooling fan - SET_OUTPUT(FAN_PIN); -#ifdef FAN_SOFT_PWM - fanSpeedSoftPwm = 255; -#else //FAN_SOFT_PWM - analogWrite(FAN_PIN, 255); -#endif //FAN_SOFT_PWM - break; - } if (abs((enc_dif - lcd_encoder_diff)) > 2) { if (enc_dif > lcd_encoder_diff) { _result = !check_opposite; @@ -8541,8 +8524,7 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite, } while (!lcd_clicked()); KEEPALIVE_STATE(IN_HANDLER); - SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN); - WRITE(EXTRUDER_0_AUTO_FAN_PIN, 0); + setExtruderAutoFanState(0); SET_OUTPUT(FAN_PIN); #ifdef FAN_SOFT_PWM fanSpeedSoftPwm = 0; @@ -8562,13 +8544,13 @@ static FanCheck lcd_selftest_fan_auto(int _fan) case 0: fanSpeed = 0; manage_heater(); //turn off fan - setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, 1); //extruder fan + setExtruderAutoFanState(3); //extruder fan #ifdef FAN_SOFT_PWM extruder_autofan_last_check = _millis(); fan_measuring = true; #endif //FAN_SOFT_PWM - _delay(2000); //delay_keep_alive would turn off extruder fan, because temerature is too low - + _delay(2000); + setExtruderAutoFanState(0); //extruder fan manage_heater(); //count average fan speed from 2s delay and turn off fans printf_P(PSTR("Test 1:\n")); diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index ad714c235..1179ae6be 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -331,6 +331,8 @@ #define EXTRUDER_2_AUTO_FAN_PIN -1 #define EXTRUDER_AUTO_FAN_TEMPERATURE 50 #define EXTRUDER_AUTO_FAN_SPEED 255 // == full speed +#define EXTRUDER_ALTFAN_DETECT +#define EXTRUDER_ALTFAN_SPEED_SILENT 128 From d1865fc59ac0abde12d961ac4331ca8b0d783a27 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Wed, 3 Jun 2020 16:14:56 +0200 Subject: [PATCH 14/77] MK3s IR sensor improvement (#2698) * Update EEPROM_FSENSOR_PCB documentation * Update IR sensor check * Rename IR messags and add UNKNOWN state * Update code to use new messages * To be continued * Move fsensor related things from ultralcd.h to fsensor.h * Use defined Thresholds * IR sensor auto detection "0.3 or older" and "0.4 or newer" when trigger status changes. Typo fixes Doxygen documentation * Cleanup spaces * Revert PF-build.sh changes * re-add space in messages * revert doxygen snytax * Remove double _Undef * Fix indentation and doxygen syntax * Fix indentation * Better message handling * Fix indentation * Fix indentation * More indentation fixwa * Extract common code into manage_inactivity_IR_ANALOG_Check Saves ~60B of code * Revert indentation changes on fsensor.cpp * Keep the selftest IR sensor part disabled Everything shall happen at runtime * Fix indentation fsensor_update * Fix another misleading indentation in fsensor_update Co-authored-by: Alex Voinea Co-authored-by: D.R.racer --- Firmware/Marlin_main.cpp | 115 ++++++++++++---------- Firmware/eeprom.h | 5 +- Firmware/fsensor.cpp | 206 ++++++++++++++++++++++----------------- Firmware/fsensor.h | 14 +++ Firmware/messages.c | 5 +- Firmware/messages.h | 5 +- Firmware/ultralcd.cpp | 69 +++++++------ Firmware/ultralcd.h | 19 +--- 8 files changed, 241 insertions(+), 197 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 799e5e9d5..c8558b8ad 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -9451,7 +9451,32 @@ static void handleSafetyTimer() } #endif //SAFETYTIMER -#define FS_CHECK_COUNT 250 +#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 { #ifdef FILAMENT_SENSOR @@ -9464,15 +9489,15 @@ static uint16_t nFSCheckCount=0; { //-// if (mcode_in_progress != 600) //M600 not in progress #ifdef PAT9125 - bInhibitFlag=(menu_menu==lcd_menu_extruder_info); // Support::ExtruderInfo menu active + bInhibitFlag=(menu_menu==lcd_menu_extruder_info); // Support::ExtruderInfo menu active #endif // PAT9125 #ifdef IR_SENSOR - bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active + bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active #ifdef IR_SENSOR_ANALOG - bInhibitFlag=bInhibitFlag||bMenuFSDetect; // Settings::HWsetup::FSdetect menu active + bInhibitFlag=bInhibitFlag||bMenuFSDetect; // Settings::HWsetup::FSdetect menu active #endif // IR_SENSOR_ANALOG #endif // IR_SENSOR - if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active + if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active { if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LcdCommands::Layer1Cal) && ! eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)) { @@ -9483,7 +9508,7 @@ static uint16_t nFSCheckCount=0; if( current_voltage_raw_IR > maxVolt )maxVolt = current_voltage_raw_IR; if( current_voltage_raw_IR < minVolt )minVolt = current_voltage_raw_IR; -#if 0 +#if 0 // Start: IR Sensor debug info { // debug print static uint16_t lastVolt = ~0U; if( current_voltage_raw_IR != lastVolt ){ @@ -9491,38 +9516,29 @@ static uint16_t nFSCheckCount=0; lastVolt = current_voltage_raw_IR; } } -#endif - // 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 +#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.6V, 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, 0.7> and maxVolt gets into range <4.4, 5> - // If and only if minVolt is in range <0.6, 0.7> and maxVolt is in range <4.4, 4.5>, I'm considering a situation with the new fsensor - // otherwise, I don't care - - if( minVolt >= Voltage2Raw(0.3F) && minVolt <= Voltage2Raw(0.5F) - && maxVolt >= Voltage2Raw(4.2F) && maxVolt <= Voltage2Raw(4.6F) + //! 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 ){ - bool bTemp = (!CHECK_ALL_HEATERS); - bTemp = bTemp && (menu_menu==lcd_status_screen); - bTemp = bTemp && ((oFsensorPCB==ClFsensorPCB::_Old)||(oFsensorPCB==ClFsensorPCB::_Undef)); - bTemp = bTemp && fsensor_enabled; - if(bTemp){ - nFSCheckCount++; - if(nFSCheckCount>FS_CHECK_COUNT){ - nFSCheckCount=0; // not necessary - oFsensorPCB=ClFsensorPCB::_Rev04; - eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB); - printf_IRSensorAnalogBoardChange(true); - lcd_setstatuspgm(_i("FS v0.4 or newer"));////c=18 - } - } else { - nFSCheckCount=0; - } + manage_inactivity_IR_ANALOG_Check(nFSCheckCount, ClFsensorPCB::_Old, ClFsensorPCB::_Rev04, _i("FS v0.4 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")); ////c=18 } #endif // IR_SENSOR_ANALOG if (fsensor_check_autoload()) @@ -9533,7 +9549,7 @@ static uint16_t nFSCheckCount=0; //-// if (degHotend0() > EXTRUDE_MINTEMP) if(0) { - Sound_MakeCustom(50,1000,false); + Sound_MakeCustom(50,1000,false); loading_flag = true; enquecommand_front_P((PSTR("M701"))); } @@ -9544,20 +9560,17 @@ if(0) show_preheat_nozzle_warning(); lcd_update_enable(true); */ - eFilamentAction=FilamentAction::AutoLoad; - bFilamentFirstRun=false; - if(target_temperature[0]>=EXTRUDE_MINTEMP) - { - bFilamentPreheatState=true; -// mFilamentItem(target_temperature[0],target_temperature_bed); - menu_submenu(mFilamentItemForce); - } - else - { - menu_submenu(lcd_generic_preheat_menu); - lcd_timeoutToStatus.start(); - } - } + eFilamentAction=FilamentAction::AutoLoad; + bFilamentFirstRun=false; + if(target_temperature[0]>=EXTRUDE_MINTEMP){ + bFilamentPreheatState=true; +// mFilamentItem(target_temperature[0],target_temperature_bed); + menu_submenu(mFilamentItemForce); + } else { + menu_submenu(lcd_generic_preheat_menu); + lcd_timeoutToStatus.start(); + } + } } } else diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 61e078fc0..89d7e7f99 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -341,8 +341,9 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | 0x0D9F 3487 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - bed temp | ^ | D3 Ax0d9f C1 | 0x0DA0 3488 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - PINDA temp | ^ | D3 Ax0da0 C1 | 0x0DA1 3489 | uint8 | ??? | 00h 0 | ffh 255 | ??? | ??? | D3 Ax0da1 C1 -| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ??? | ffh 255 | Filament Sensor type old vs new | ??? | D3 Ax0d48 C1 -| ^ | ^ | ^ | ??? | ^ | Filament Sensor type ??? | ^ | ^ +| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ffh 255 | ffh 255 | Filament Sensor type IR unknown | LCD Support | D3 Ax0d48 C1 +| ^ | ^ | ^ | 00h 0 | ^ | Filament Sensor type IR 0.3 or older | ^ | ^ +| ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor type IR 0.4 or newer | ^ | ^ | 0x0D47 3399 | uint8 | EEPROM_FSENSOR_ACTION_NA | 00h 0 | ffh 255 | Filament Sensor action: __Continue__ | LCD menu | D3 Ax0d47 C1 | ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor action: __Pause__ | ^ | ^ | 0x0D37 3383 | float | EEPROM_UVLO_SAVED_TARGET | ??? | ff ff ff ffh | Power panic saved target all-axis | ??? | D3 Ax0d37 C16 diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp index f5fc768a4..2753ede00 100755 --- a/Firmware/fsensor.cpp +++ b/Firmware/fsensor.cpp @@ -170,6 +170,21 @@ void fsensor_checkpoint_print(void) restore_print_from_ram_and_continue(0); } +#ifdef IR_SENSOR_ANALOG +const char* FsensorIRVersionText() +{ + switch(oFsensorPCB) + { + case ClFsensorPCB::_Old: + return _T(MSG_IR_03_OR_OLDER); + case ClFsensorPCB::_Rev04: + return _T(MSG_IR_04_OR_NEWER); + default: + return _T(MSG_IR_UNKNOWN); + } +} +#endif //IR_SENSOR_ANALOG + void fsensor_init(void) { #ifdef PAT9125 @@ -207,9 +222,9 @@ void fsensor_init(void) } printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED"))); #ifdef IR_SENSOR_ANALOG - printf_P(PSTR(" (sensor board revision:%S)\n"), (oFsensorPCB==ClFsensorPCB::_Rev04) ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER)); + printf_P(PSTR(" (sensor board revision:%S)\n"), FsensorIRVersionText()); #else //IR_SENSOR_ANALOG - printf_P(PSTR("\n")); + MYSERIAL.println(); #endif //IR_SENSOR_ANALOG if (check_for_ir_sensor()){ ir_sensor_detected = true; @@ -611,15 +626,15 @@ void fsensor_enque_M600(){ void fsensor_update(void) { #ifdef PAT9125 - if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX)) - { - fsensor_stop_and_save_print(); + if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX)) + { + fsensor_stop_and_save_print(); KEEPALIVE_STATE(IN_HANDLER); - bool autoload_enabled_tmp = fsensor_autoload_enabled; - fsensor_autoload_enabled = false; - bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled; - fsensor_oq_meassure_enabled = true; + bool autoload_enabled_tmp = fsensor_autoload_enabled; + fsensor_autoload_enabled = false; + bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled; + fsensor_oq_meassure_enabled = true; // move the nozzle away while checking the filament current_position[Z_AXIS] += 0.8; @@ -629,24 +644,23 @@ void fsensor_update(void) // check the filament in isolation fsensor_reset_err_cnt(); - fsensor_oq_meassure_start(0); + fsensor_oq_meassure_start(0); float e_tmp = current_position[E_AXIS]; current_position[E_AXIS] -= 3; plan_buffer_line_curposXYZE(250/60); current_position[E_AXIS] = e_tmp; plan_buffer_line_curposXYZE(200/60); st_synchronize(); - fsensor_oq_meassure_stop(); + fsensor_oq_meassure_stop(); - bool err = false; - err |= (fsensor_err_cnt > 0); // final error count is non-zero - err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit - err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit + bool err = false; + err |= (fsensor_err_cnt > 0); // final error count is non-zero + err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit + err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit fsensor_restore_print_and_continue(); fsensor_autoload_enabled = autoload_enabled_tmp; fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp; - unsigned long now = _millis(); if (!err && (now - fsensor_softfail_last) > FSENSOR_SOFTERR_DELTA) fsensor_softfail_ccnt = 0; @@ -663,70 +677,70 @@ void fsensor_update(void) fsensor_softfail_last = 0; fsensor_enque_M600(); } - } + } #else //PAT9125 - if (CHECK_FSENSOR && ir_sensor_detected) + if (CHECK_FSENSOR && ir_sensor_detected) { - if(digitalRead(IR_SENSOR_PIN)) - { // IR_SENSOR_PIN ~ H + if(digitalRead(IR_SENSOR_PIN)) + { // IR_SENSOR_PIN ~ H #ifdef IR_SENSOR_ANALOG - if(!bIRsensorStateFlag) + if(!bIRsensorStateFlag) + { + bIRsensorStateFlag=true; + nIRsensorLastTime=_millis(); + } + else + { + if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY) { - bIRsensorStateFlag=true; - nIRsensorLastTime=_millis(); - } - else - { - if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY) - { - uint8_t nMUX1,nMUX2; - uint16_t nADC; - bIRsensorStateFlag=false; - // sequence for direct data reading from AD converter - DISABLE_TEMPERATURE_INTERRUPT(); - nMUX1=ADMUX; // ADMUX saving - nMUX2=ADCSRB; - adc_setmux(VOLT_IR_PIN); - ADCSRA|=(1<4.6V - // If it does, it means a disconnected cables or faulty board - if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) ) - { - fsensor_disable(); - fsensor_not_responding = true; - printf_P(PSTR("IR sensor not responding (%d)!\n"),1); - if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause) + uint8_t nMUX1,nMUX2; + uint16_t nADC; + bIRsensorStateFlag=false; + // sequence for direct data reading from AD converter + DISABLE_TEMPERATURE_INTERRUPT(); + nMUX1=ADMUX; // ADMUX saving + nMUX2=ADCSRB; + adc_setmux(VOLT_IR_PIN); + ADCSRA|=(1<4.6V + // If it does, it means a disconnected cables or faulty board + if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) ) + { + fsensor_disable(); + fsensor_not_responding = true; + printf_P(PSTR("IR sensor not responding (%d)!\n"),1); + if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause) - // if we are printing and FS action is set to "Pause", force pause the print - if(oFsensorActionNA==ClFsensorActionNA::_Pause) - lcd_pause_print(); - } - else - { + // if we are printing and FS action is set to "Pause", force pause the print + if(oFsensorActionNA==ClFsensorActionNA::_Pause) + lcd_pause_print(); + } + else + { #endif //IR_SENSOR_ANALOG - fsensor_checkpoint_print(); - fsensor_enque_M600(); + fsensor_checkpoint_print(); + fsensor_enque_M600(); #ifdef IR_SENSOR_ANALOG - } - } + } } - } - else - { // IR_SENSOR_PIN ~ L - bIRsensorStateFlag=false; + } + } + else + { // IR_SENSOR_PIN ~ L + bIRsensorStateFlag=false; #endif //IR_SENSOR_ANALOG - } - } + } + } #endif //PAT9125 } @@ -734,24 +748,36 @@ void fsensor_update(void) /// This is called only upon start of the printer or when switching the fsensor ON in the menu /// We cannot do temporal window checks here (aka the voltage has been in some range for a period of time) bool fsensor_IR_check(){ - if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){ - // If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly. - // Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way, - // that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual - // and would have been considered more like a sabotage than normal printer operation - printf_P(PSTR("fsensor in forbidden range 1.5-3V - bad lever\n")); - return false; - } - - if( oFsensorPCB == ClFsensorPCB::_Rev04 ){ - // newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount - if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){ - printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n")); - return false; - } - } - - // otherwise the IR fsensor is considered working correctly - return true; + if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){ + /// If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly. + /// Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way, + /// that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual + /// and would have been considered more like a sabotage than normal printer operation + printf_P(PSTR("fsensor in forbidden range 1.5-3V - check sensor\n")); + return false; + } + if( oFsensorPCB == ClFsensorPCB::_Rev04 ){ + /// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount + if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){ + printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n")); + return false; + } + /// newer IR sensor cannot normally produce 0-0.3V, this is considered a failure +#if 0 //Disabled as it has to be decided if we gonna use this or not. + if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){ + printf_P(PSTR("fsensor v0.4 in fault range 0.0-0.3V - wrong IR sensor\n")); + return false; + } +#endif + } + /// If IR sensor is "uknown state" and filament is not loaded > 1.5V return false +#if 0 + if( (oFsensorPCB == ClFsensorPCB::_Undef) && ( current_voltage_raw_IR > IRsensor_Lmax_TRESHOLD ) ){ + printf_P(PSTR("Unknown IR sensor version and no filament loaded detected.\n")); + return false; + } +#endif + // otherwise the IR fsensor is considered working correctly + return true; } #endif //IR_SENSOR_ANALOG diff --git a/Firmware/fsensor.h b/Firmware/fsensor.h index 4038d6b61..7eb09ab8b 100755 --- a/Firmware/fsensor.h +++ b/Firmware/fsensor.h @@ -83,6 +83,7 @@ extern uint8_t fsensor_log; //! @} #endif //PAT9125 +#define VOLT_DIV_REF 5 #ifdef IR_SENSOR_ANALOG #define IR_SENSOR_STEADY 10 // [ms] @@ -103,8 +104,21 @@ enum class ClFsensorActionNA:uint_least8_t extern ClFsensorPCB oFsensorPCB; extern ClFsensorActionNA oFsensorActionNA; +extern const char* FsensorIRVersionText(); extern bool fsensor_IR_check(); +constexpr uint16_t Voltage2Raw(float V){ + return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F; +} +constexpr float Raw2Voltage(uint16_t raw){ + return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) ); +} +constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982 +constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910 +constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821 +constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059 +constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368 + #endif //IR_SENSOR_ANALOG #endif //FSENSOR_H diff --git a/Firmware/messages.c b/Firmware/messages.c index 9c31c1266..be613cab1 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -140,8 +140,9 @@ const char MSG_DIM[] PROGMEM_I1 = ISTR("Dim"); ////c=6 const char MSG_AUTO[] PROGMEM_I1 = ISTR("Auto"); ////c=6 #ifdef IR_SENSOR_ANALOG // Beware - the space at the beginning is necessary since it is reused in LCD menu items which are to be with a space -const char MSG_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");////c=18 -const char MSG_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////c=18 +const char MSG_IR_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");////c=18 +const char MSG_IR_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////c=18 +const char MSG_IR_UNKNOWN[] PROGMEM_I1 = ISTR("unknown state");////c=18 #endif //not internationalized messages diff --git a/Firmware/messages.h b/Firmware/messages.h index 599f1d1fa..4653c869e 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -139,8 +139,9 @@ extern const char MSG_BRIGHT[]; extern const char MSG_DIM[]; extern const char MSG_AUTO[]; #ifdef IR_SENSOR_ANALOG -extern const char MSG_04_OR_NEWER[]; -extern const char MSG_03_OR_OLDER[]; +extern const char MSG_IR_04_OR_NEWER[]; +extern const char MSG_IR_03_OR_OLDER[]; +extern const char MSG_IR_UNKNOWN[]; #endif //not internationalized messages diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e32b6ad1c..ce312389a 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2166,18 +2166,7 @@ static void lcd_support_menu() #ifdef IR_SENSOR_ANALOG MENU_ITEM_BACK_P(STR_SEPARATOR); MENU_ITEM_BACK_P(PSTR("Fil. sensor v.:")); - switch(oFsensorPCB) - { - case ClFsensorPCB::_Old: - MENU_ITEM_BACK_P(_T(MSG_03_OR_OLDER)); - break; - case ClFsensorPCB::_Rev04: - MENU_ITEM_BACK_P(_T(MSG_04_OR_NEWER)); - break; - case ClFsensorPCB::_Undef: - default: - MENU_ITEM_BACK_P(PSTR(" unknown state")); - } + MENU_ITEM_BACK_P(FsensorIRVersionText()); #endif // IR_SENSOR_ANALOG MENU_ITEM_BACK_P(STR_SEPARATOR); @@ -5725,7 +5714,9 @@ void lcd_hw_setup_menu(void) // can not be "static" #ifdef IR_SENSOR_ANALOG FSENSOR_ACTION_NA; - MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor); + //! Fsensor Detection isn't ready for mmu yet it is temporarily disabled. + //! @todo Don't forget to remove this as soon Fsensor Detection works with mmu + if(!mmu_enabled) MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor); #endif //IR_SENSOR_ANALOG MENU_END(); } @@ -7508,8 +7499,8 @@ void lcd_belttest() #ifdef IR_SENSOR_ANALOG // called also from marlin_main.cpp -void printf_IRSensorAnalogBoardChange(bool bPCBrev04){ - printf_P(PSTR("Filament sensor board change detected: revision%S\n"), bPCBrev04 ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER)); +void printf_IRSensorAnalogBoardChange(){ + printf_P(PSTR("Filament sensor board change detected: revision%S\n"), FsensorIRVersionText()); } static bool lcd_selftest_IRsensor(bool bStandalone) @@ -7534,8 +7525,8 @@ static bool lcd_selftest_IRsensor(bool bStandalone) return(false); } if((bPCBrev04 ? 1 : 0) != (uint8_t)oFsensorPCB){ // safer then "(uint8_t)bPCBrev04" - printf_IRSensorAnalogBoardChange(bPCBrev04); oFsensorPCB=bPCBrev04 ? ClFsensorPCB::_Rev04 : ClFsensorPCB::_Old; + printf_IRSensorAnalogBoardChange(); eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB); } return(true); @@ -7543,22 +7534,26 @@ static bool lcd_selftest_IRsensor(bool bStandalone) static void lcd_detect_IRsensor(){ bool bAction; - + bool loaded; bMenuFSDetect = true; // inhibits some code inside "manage_inactivity()" - bAction = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is filament loaded?"), false, false); - if(bAction){ - lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action."));////c=20 r=4 + /// Check if filament is loaded. If it is loaded stop detection. + /// @todo Add autodetection with MMU2s + loaded = ! READ(IR_SENSOR_PIN); + if(loaded ){ + lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action.")); return; + } else { + lcd_show_fullscreen_message_and_wait_P(_i("Please check the IR sensor connections and filament is unloaded.")); + bAction = lcd_selftest_IRsensor(true); } - bAction = lcd_selftest_IRsensor(true); - if(bAction){ + if(bAction){ lcd_show_fullscreen_message_and_wait_P(_i("Sensor verified, remove the filament now."));////c=20 r=3 - // the fsensor board has been successfully identified, any previous "not responding" may be cleared now - fsensor_not_responding = false; + // the fsensor board has been successfully identified, any previous "not responding" may be cleared now + fsensor_not_responding = false; } else { lcd_show_fullscreen_message_and_wait_P(_i("Verification failed, remove the filament and try again."));////c=20 r=5 - // here it is unclear what to to with the fsensor_not_responding flag - } + // here it is unclear what to to with the fsensor_not_responding flag + } bMenuFSDetect=false; // de-inhibits some code inside "manage_inactivity()" } #endif //IR_SENSOR_ANALOG @@ -7574,9 +7569,17 @@ bool lcd_selftest() bool _result = true; bool _swapped_fan = false; #ifdef IR_SENSOR_ANALOG - //! Check if IR sensor is in unknown state, set it temporarily to 0.3 or older - //! @todo This has to be improved - if( oFsensorPCB == ClFsensorPCB::_Undef) eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,0); + //! Check if IR sensor is in unknown state, if so run Fsensor Detection + //! As the Fsensor Detection isn't yet ready for the mmu2s we set temporarily the IR sensor 0.3 or older for mmu2s + //! @todo Don't forget to remove this as soon Fsensor Detection works with mmu + if( oFsensorPCB == ClFsensorPCB::_Undef) { + if (!mmu_enabled) { + lcd_detect_IRsensor(); + } + else { + eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,0); + } + } #endif //IR_SENSOR_ANALOG lcd_wait_for_cool_down(); lcd_clear(); @@ -7784,10 +7787,12 @@ bool lcd_selftest() _progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK } #endif //PAT9125 -//#ifdef IR_SENSOR_ANALOG -#if (0) +#if 0 + // Intentionally disabled - that's why we moved the detection to runtime by just checking the two voltages. + // The idea is not to force the user to remove and insert the filament on an assembled printer. +//def IR_SENSOR_ANALOG _progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filament sensor - _result = lcd_selftest_IRsensor(); + _result = lcd_selftest_IRsensor(); if (_result) { _progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //filament sensor OK diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index d68ab14b2..844c7c7d3 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -142,7 +142,7 @@ extern uint8_t farm_status; #ifdef IR_SENSOR_ANALOG extern bool bMenuFSDetect; -void printf_IRSensorAnalogBoardChange(bool bPCBrev04); +void printf_IRSensorAnalogBoardChange(); #endif //IR_SENSOR_ANALOG extern int8_t SilentModeMenu; @@ -257,21 +257,4 @@ enum class WizState : uint8_t void lcd_wizard(WizState state); -#define VOLT_DIV_REF 5 -#ifdef IR_SENSOR_ANALOG -constexpr uint16_t Voltage2Raw(float V){ - return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F; -} -constexpr float Raw2Voltage(uint16_t raw){ - return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) ); -} -constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821 -constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910 -constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059 -constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982 -constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368 - - -#endif //IR_SENSOR_ANALOG - #endif //ULTRALCD_H From fe72ba7a9d322f552c2bf37aa7b257f2a4025364 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 3 Jun 2020 17:45:55 +0200 Subject: [PATCH 15/77] Add PC-blend preheat preset --- Firmware/ultralcd.cpp | 7 +++++++ Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h | 4 ++++ Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 3 +++ Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 3 +++ 9 files changed, 32 insertions(+) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index ce312389a..ef22bda30 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2496,6 +2496,12 @@ static void mFilamentItem_ASA() mFilamentItem(ASA_PREHEAT_HOTEND_TEMP, ASA_PREHEAT_HPB_TEMP); } +static void mFilamentItem_PC() +{ + bFilamentPreheatState = false; + mFilamentItem(PC_PREHEAT_HOTEND_TEMP, PC_PREHEAT_HPB_TEMP); +} + static void mFilamentItem_ABS() { bFilamentPreheatState = false; @@ -2555,6 +2561,7 @@ void lcd_generic_preheat_menu() MENU_ITEM_SUBMENU_P(PSTR("PLA - " STRINGIFY(PLA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PLA_PREHEAT_HPB_TEMP)),mFilamentItem_PLA); MENU_ITEM_SUBMENU_P(PSTR("PET - " STRINGIFY(PET_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PET_PREHEAT_HPB_TEMP)),mFilamentItem_PET); MENU_ITEM_SUBMENU_P(PSTR("ASA - " STRINGIFY(ASA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ASA_PREHEAT_HPB_TEMP)),mFilamentItem_ASA); + MENU_ITEM_SUBMENU_P(PSTR("PC - " STRINGIFY(PCB_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PCB_PREHEAT_HPB_TEMP)),mFilamentItem_PC); MENU_ITEM_SUBMENU_P(PSTR("ABS - " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)),mFilamentItem_ABS); MENU_ITEM_SUBMENU_P(PSTR("HIPS - " STRINGIFY(HIPS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(HIPS_PREHEAT_HPB_TEMP)),mFilamentItem_HIPS); MENU_ITEM_SUBMENU_P(PSTR("PP - " STRINGIFY(PP_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PP_PREHEAT_HPB_TEMP)),mFilamentItem_PP); diff --git a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h index 45b88c7ba..887a90a6f 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h @@ -330,6 +330,10 @@ PREHEAT SETTINGS #define ASA_PREHEAT_HPB_TEMP 105 #define ASA_PREHEAT_FAN_SPEED 0 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_FAN_SPEED 0 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 #define ABS_PREHEAT_FAN_SPEED 0 diff --git a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h index 7b3e24458..c9c4ed6cd 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h @@ -326,6 +326,9 @@ PREHEAT SETTINGS #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 105 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index 36a9b5214..f2ef69e99 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -384,6 +384,9 @@ #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 105 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index ff13a7c61..7eaba3d6c 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -385,6 +385,9 @@ #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 105 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h index 71a23a1a6..ee245bd4b 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo10a-E3Dv6full.h @@ -384,6 +384,9 @@ #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 105 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 diff --git a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h index 8d22a6cc9..6bf30f192 100644 --- a/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25S-RAMBo13a-E3Dv6full.h @@ -385,6 +385,9 @@ #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 105 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index b80217ee3..8215c48f3 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -496,6 +496,9 @@ #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 110 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index 1179ae6be..f7d408a45 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -500,6 +500,9 @@ #define ASA_PREHEAT_HOTEND_TEMP 260 #define ASA_PREHEAT_HPB_TEMP 105 +#define PC_PREHEAT_HOTEND_TEMP 275 +#define PC_PREHEAT_HPB_TEMP 110 + #define ABS_PREHEAT_HOTEND_TEMP 255 #define ABS_PREHEAT_HPB_TEMP 100 From 7e41524101580a8c3461b1df5cf3d6f9423f6830 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 3 Jun 2020 18:05:37 +0200 Subject: [PATCH 16/77] PC-blend preheat temperatures #define typo A typo slipped through in PR#2711, not even the compiler caught it (obviously, it is #define to be stringized): PCB_PREHEAT... -> PC_PREHEAT --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index ef22bda30..5b8d6099a 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2561,7 +2561,7 @@ void lcd_generic_preheat_menu() MENU_ITEM_SUBMENU_P(PSTR("PLA - " STRINGIFY(PLA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PLA_PREHEAT_HPB_TEMP)),mFilamentItem_PLA); MENU_ITEM_SUBMENU_P(PSTR("PET - " STRINGIFY(PET_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PET_PREHEAT_HPB_TEMP)),mFilamentItem_PET); MENU_ITEM_SUBMENU_P(PSTR("ASA - " STRINGIFY(ASA_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ASA_PREHEAT_HPB_TEMP)),mFilamentItem_ASA); - MENU_ITEM_SUBMENU_P(PSTR("PC - " STRINGIFY(PCB_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PCB_PREHEAT_HPB_TEMP)),mFilamentItem_PC); + MENU_ITEM_SUBMENU_P(PSTR("PC - " STRINGIFY(PC_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PC_PREHEAT_HPB_TEMP)),mFilamentItem_PC); MENU_ITEM_SUBMENU_P(PSTR("ABS - " STRINGIFY(ABS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(ABS_PREHEAT_HPB_TEMP)),mFilamentItem_ABS); MENU_ITEM_SUBMENU_P(PSTR("HIPS - " STRINGIFY(HIPS_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(HIPS_PREHEAT_HPB_TEMP)),mFilamentItem_HIPS); MENU_ITEM_SUBMENU_P(PSTR("PP - " STRINGIFY(PP_PREHEAT_HOTEND_TEMP) "/" STRINGIFY(PP_PREHEAT_HPB_TEMP)),mFilamentItem_PP); From 1bf563545954069ea60469558ea23cfd90353469 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 5 Jun 2020 17:17:33 +0300 Subject: [PATCH 17/77] Trigger fan error during selftest for altfan --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 5b8d6099a..ab2fe4d05 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8569,7 +8569,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan) printf_P(PSTR("Print fan speed: %d \n"), fan_speed[1]); printf_P(PSTR("Extr fan speed: %d \n"), fan_speed[0]); - if (!fan_speed[0]) { + if (fan_speed[0] < 20) { return FanCheck::ExtruderFan; } #ifdef FAN_SOFT_PWM From 183b102b6cfb6fb1e6a3ad7ef01f54267c04b4e1 Mon Sep 17 00:00:00 2001 From: DRracer Date: Fri, 5 Jun 2020 16:37:21 +0200 Subject: [PATCH 18/77] Document the RPM condition --- Firmware/ultralcd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index ab2fe4d05..d702e222d 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8569,7 +8569,7 @@ static FanCheck lcd_selftest_fan_auto(int _fan) printf_P(PSTR("Print fan speed: %d \n"), fan_speed[1]); printf_P(PSTR("Extr fan speed: %d \n"), fan_speed[0]); - if (fan_speed[0] < 20) { + if (fan_speed[0] < 20) { // < 1200 RPM would mean either a faulty Noctua or Altfan return FanCheck::ExtruderFan; } #ifdef FAN_SOFT_PWM From 5648f3fef0f3703964a21168bd7d5ba5a60bdeb3 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Mon, 8 Jun 2020 13:07:19 +0200 Subject: [PATCH 19/77] Fix compiler warning enumeration value 'ONE_TO_FALL' not handled in switch. --- Firmware/heatbed_pwm.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Firmware/heatbed_pwm.cpp b/Firmware/heatbed_pwm.cpp index 4cd0bf5e5..8121df3ee 100755 --- a/Firmware/heatbed_pwm.cpp +++ b/Firmware/heatbed_pwm.cpp @@ -59,7 +59,6 @@ enum class States : uint8_t { RISE, ///< 16 fast PWM cycles with increasing duty up to steady ON RISE_TO_ONE, ///< metastate allowing the timer change its state atomically without artefacts on the output pin ONE, ///< steady 1 (ON), no change for the whole period - ONE_TO_FALL, ///< metastate allowing the timer change its state atomically without artefacts on the output pin FALL, ///< 16 fast PWM cycles with decreasing duty down to steady OFF FALL_TO_ZERO ///< metastate allowing the timer change its state atomically without artefacts on the output pin }; @@ -155,12 +154,7 @@ ISR(TIMER0_OVF_vect) // timer compare interrupt service routine return; // want full duty for the next ONE cycle again - so keep on heating and just wait for the next timer ovf } // otherwise moving towards FALL - // @@TODO it looks like ONE_TO_FALL isn't necessary, there are no artefacts at all state = States::ONE;//_TO_FALL; -// TCCR0B = (1 << CS00); // change prescaler to 1, i.e. 62.5kHz -// break; -// case States::ONE_TO_FALL: -// OCR0B = 255; // zero duty state=States::FALL; fastCounter = fastMax - 1;// we'll do 16-1 cycles of RISE TCNT0 = 255; // force overflow on the next clock cycle From 200696c764c8d7f462d5f21ed3b3e6e27c86c755 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Mon, 8 Jun 2020 14:27:58 +0200 Subject: [PATCH 20/77] Fix compiler warning unused variable kill_message. (cherry picked from commit 54e2b6a829a221cc3abbff3a39ca7d3cafed3a09) Pick only unused kill_message. --- Firmware/Marlin_main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c8558b8ad..91594edc2 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4977,7 +4977,6 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) } #endif // SUPPORT_VERBOSITY int l_feedmultiply = setup_for_endstop_move(false); //save feedrate and feedmultiply, sets feedmultiply to 100 - const char *kill_message = NULL; while (mesh_point != nMeasPoints * nMeasPoints) { // Get coords of a measuring point. uint8_t ix = mesh_point % nMeasPoints; // from 0 to MESH_NUM_X_POINTS - 1 From f6df3f2394ab9aa3896136235e7ff20d588d0712 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Mon, 8 Jun 2020 13:45:29 +0200 Subject: [PATCH 21/77] Unused function warning fix. (cherry picked from commit 54e2b6a829a221cc3abbff3a39ca7d3cafed3a09) Pick only unused function warning fix. --- Firmware/ultralcd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index d702e222d..fda0d1196 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5602,6 +5602,7 @@ do\ }\ while (0) +#if 0 // temporarily unused static void lcd_check_gcode_set(void) { switch(oCheckGcode) @@ -5620,6 +5621,7 @@ switch(oCheckGcode) } eeprom_update_byte((uint8_t*)EEPROM_CHECK_GCODE,(uint8_t)oCheckGcode); } +#endif #define SETTINGS_GCODE \ do\ From 4c5fe053337dc111e5cde9a3563ccaecd8b1e14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20B=C4=9Bl?= <35807926+mkbel@users.noreply.github.com> Date: Thu, 11 Jun 2020 18:32:36 +0200 Subject: [PATCH 22/77] Update README.md Mention gawk dependency for multi language. --- README.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fb1c79689..79ab9b74a 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,28 @@ The firmware for the Original Prusa i3 printers is proudly based on [Marlin 1.0. 1. Clone this repository and checkout the correct branch for your desired release version. -2. Set your printer model. +1. Set your printer model. - For MK3 --> skip to step 3. - If you have a different printer model, follow step [2.b](#2b) from Windows build +1. Install GNU AWK `sudo apt-get install gawk` +If you use mawk instead of gawk you get strange errors when multi language support is generated like: +`awk: line 2: function strtonum never defined +sed: couldn't write 4 items to stdout: Broken pipe +./lang-build.sh: 121: ./lang-build.sh: arithmetic expression: expecting EOF: "0x"awk: line 2: function strtonum never defined +sed: couldn't write 4 items to stdout: Broken pipe +tr: write error: Broken pipe +./lang-build.sh: 121: ./lang-build.sh: arithmetic expression: expecting EOF: "0x"awk: line 2: function strtonum never defined +sed: couldn't write 4 items to stdout: Broken pipe +tr: write error: Broken pipe +tr: write error +cut: write error: Broken pipeNG! - some texts not found in lang_en.txt! updating binary: + primary language ids...awk: line 2: function strtonum never defined +sed: couldn't flush stdout: Broken pipe` -3. Run `./build.sh` +1. Run `./build.sh` - Output hex file is at `"PrusaFirmware/lang/firmware.hex"` . In the same folder you can hex files for other languages as well. -4. Connect your printer and flash with PrusaSlicer ( Configuration --> Flash printer firmware ) or Slic3r PE. +1. Connect your printer and flash with PrusaSlicer ( Configuration --> Flash printer firmware ) or Slic3r PE. - If you wish to flash from Arduino, follow step [2.c](#2c) from Windows build first. From fca40156677c54a544d612b196d31dafce5006bb Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Thu, 11 Jun 2020 19:38:40 +0200 Subject: [PATCH 23/77] Remove st_current_init() call from lcd_temp_calibration_set(). There is no known purpose of this call. lcd_temp_calibration_set() is switching on/off pinda temperature compensation from LCD settings menu (this is called "Temp. cal." on LCD). st_current_init() does nothing on Einsy board, it enables and sets motor current selecting outputs on Rambo board (it used to be called digipot in history) --- Firmware/ultralcd.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index fda0d1196..1c2660827 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4637,7 +4637,6 @@ void lcd_pinda_calibration_menu() void lcd_temp_calibration_set() { temp_cal_active = !temp_cal_active; eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, temp_cal_active); - st_current_init(); } #ifdef HAS_SECOND_SERIAL_PORT From bbe9e3b4eaebb6ba4f95a4d6fa4ac9e143bd4cf0 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Thu, 11 Jun 2020 20:00:55 +0200 Subject: [PATCH 24/77] Remove temp_cal_active variable. This saves 18B of FLASH and 1B of RAM memory. This variable was duplicate to EEPROM variable of the same name. --- Firmware/Marlin.h | 1 - Firmware/Marlin_main.cpp | 13 ++++--------- Firmware/ultralcd.cpp | 5 ++--- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 52444337a..5c03552bf 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -334,7 +334,6 @@ extern unsigned long stoptime; extern int bowden_length[4]; extern bool is_usb_printing; extern bool homing_flag; -extern bool temp_cal_active; extern bool loading_flag; extern unsigned int usb_printing_counter; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 91594edc2..80bdd90f4 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -202,8 +202,6 @@ int bowden_length[4] = {385, 385, 385, 385}; bool is_usb_printing = false; bool homing_flag = false; -bool temp_cal_active = false; - unsigned long kicktime = _millis()+100000; unsigned int usb_printing_counter; @@ -1465,8 +1463,7 @@ void setup() if (eeprom_read_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE) == 255) { eeprom_write_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE, 0); - temp_cal_active = false; - } else temp_cal_active = eeprom_read_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE); + } if (eeprom_read_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA) == 255) { //eeprom_write_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); @@ -1474,7 +1471,6 @@ void setup() int16_t z_shift = 0; for (uint8_t i = 0; i < 5; i++) EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + i * 2, &z_shift); eeprom_write_byte((uint8_t*)EEPROM_TEMP_CAL_ACTIVE, 0); - temp_cal_active = false; } if (eeprom_read_byte((uint8_t*)EEPROM_UVLO) == 255) { eeprom_write_byte((uint8_t*)EEPROM_UVLO, 0); @@ -1547,7 +1543,7 @@ void setup() lcd_show_fullscreen_message_and_wait_P(_T(MSG_BABYSTEP_Z_NOT_SET)); lcd_update_enable(true); } - else if (calibration_status() == CALIBRATION_STATUS_CALIBRATED && temp_cal_active == true && calibration_status_pinda() == false) { + else if (calibration_status() == CALIBRATION_STATUS_CALIBRATED && eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) && calibration_status_pinda() == false) { //lcd_show_fullscreen_message_and_wait_P(_i("Temperature calibration has not been run yet"));////MSG_PINDA_NOT_CALIBRATED c=20 r=4 lcd_update_enable(true); } @@ -4827,7 +4823,6 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) disable_e2(); setTargetBed(0); //set bed target temperature back to 0 lcd_show_fullscreen_message_and_wait_P(_T(MSG_TEMP_CALIBRATION_DONE)); - temp_cal_active = true; eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, 1); lcd_update_enable(true); lcd_update(2); @@ -5253,7 +5248,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) go_home_with_z_lift(); // SERIAL_ECHOLNPGM("Go home finished"); //unretract (after PINDA preheat retraction) - if (degHotend(active_extruder) > EXTRUDE_MINTEMP && temp_cal_active == true && calibration_status_pinda() == true && target_temperature_bed >= 50) { + if ((degHotend(active_extruder) > EXTRUDE_MINTEMP) && eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) && calibration_status_pinda() && (target_temperature_bed >= 50)) { current_position[E_AXIS] += default_retraction; plan_buffer_line_curposXYZE(400); } @@ -10548,7 +10543,7 @@ float temp_comp_interpolation(float inp_temperature) { #ifdef PINDA_THERMISTOR float temp_compensation_pinda_thermistor_offset(float temperature_pinda) { - if (!temp_cal_active) return 0; + if (!eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE)) return 0; if (!calibration_status_pinda()) return 0; return temp_comp_interpolation(temperature_pinda) / cs.axis_steps_per_unit[Z_AXIS]; } diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index fda0d1196..a4d2fd54e 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -3920,14 +3920,12 @@ void lcd_temp_cal_show_result(bool result) { eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 1); SERIAL_ECHOLNPGM("Temperature calibration done. Continue with pressing the knob."); lcd_show_fullscreen_message_and_wait_P(_T(MSG_TEMP_CALIBRATION_DONE)); - temp_cal_active = true; eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, 1); } else { eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); SERIAL_ECHOLNPGM("Temperature calibration failed. Continue with pressing the knob."); lcd_show_fullscreen_message_and_wait_P(_i("Temperature calibration failed"));////MSG_TEMP_CAL_FAILED c=20 r=8 - temp_cal_active = false; eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, 0); } lcd_update_enable(true); @@ -4635,6 +4633,7 @@ void lcd_pinda_calibration_menu() } void lcd_temp_calibration_set() { + bool temp_cal_active = eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE); temp_cal_active = !temp_cal_active; eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, temp_cal_active); st_current_init(); @@ -5766,7 +5765,7 @@ static void lcd_settings_menu() MENU_ITEM_SUBMENU_P(_i("Lin. correction"), lcd_settings_linearity_correction_menu); #endif //LINEARITY_CORRECTION && TMC2130 - MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), temp_cal_active ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set); + MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set); #ifdef HAS_SECOND_SERIAL_PORT MENU_ITEM_TOGGLE_P(_T(MSG_RPI_PORT), (selectedSerialPort == 0) ? _T(MSG_OFF) : _T(MSG_ON), lcd_second_serial_set); From bdf53387b1ef00c4b15707f08c4f1f1eddc5d661 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 16 Jun 2020 00:15:13 +0200 Subject: [PATCH 25/77] Disable temperature compensation and temperature calibration menu if superPINDA is detected. Even though functionality was added, 20B of flash memory has been saved. --- Firmware/ultralcd.cpp | 20 ++++++++++++++++--- .../variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 ++ .../variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index a4d2fd54e..13d8a1fb2 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -334,6 +334,15 @@ bool bSettings; // flag (i.e. 'fake parameter' const char STR_SEPARATOR[] PROGMEM = "------------"; +static bool has_temperature_compensation() +{ +#ifdef DETECT_SUPERPINDA + return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; +#else + return true; +#endif +} + static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* filename, char* longFilename) { @@ -5764,8 +5773,10 @@ static void lcd_settings_menu() #if defined (TMC2130) && defined (LINEARITY_CORRECTION) MENU_ITEM_SUBMENU_P(_i("Lin. correction"), lcd_settings_linearity_correction_menu); #endif //LINEARITY_CORRECTION && TMC2130 - - MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set); + if(has_temperature_compensation()) + { + MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), eeprom_read_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE) ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set); + } #ifdef HAS_SECOND_SERIAL_PORT MENU_ITEM_TOGGLE_P(_T(MSG_RPI_PORT), (selectedSerialPort == 0) ? _T(MSG_OFF) : _T(MSG_ON), lcd_second_serial_set); @@ -5869,7 +5880,10 @@ static void lcd_calibration_menu() //MENU_ITEM_FUNCTION_P(MSG_RESET_CALIBRATE_E, lcd_extr_cal_reset); #endif #ifndef MK1BP - MENU_ITEM_SUBMENU_P(_i("Temp. calibration"), lcd_pinda_calibration_menu);////MSG_CALIBRATION_PINDA_MENU c=17 r=1 + if(has_temperature_compensation()) + { + MENU_ITEM_SUBMENU_P(_i("Temp. calibration"), lcd_pinda_calibration_menu);////MSG_CALIBRATION_PINDA_MENU c=17 r=1 + } #endif //MK1BP } diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 8215c48f3..b135d8d13 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -294,6 +294,8 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif +#define DETECT_SUPERPINDA +#define PINDA_MINTEMP BED_MINTEMP // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index f7d408a45..e618c54ef 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -296,6 +296,8 @@ #if BED_MINTEMP_DELAY>USHRT_MAX #error "Check maximal allowed value @ ShortTimer (see BED_MINTEMP_DELAY definition)" #endif +#define DETECT_SUPERPINDA +#define PINDA_MINTEMP BED_MINTEMP // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) From 23cc22bc229801fbcdd5db8480f9eb38dc8f7fdb Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 16 Jun 2020 00:41:21 +0200 Subject: [PATCH 26/77] Move has_temperature_compensation() into temperature.cpp. No change in FLASH usage. --- Firmware/temperature.cpp | 11 +++++++++++ Firmware/temperature.h | 1 + Firmware/ultralcd.cpp | 9 --------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index c019514c5..bd232cf57 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -2196,4 +2196,15 @@ float unscalePID_d(float d) #endif //PIDTEMP +#ifdef PINDA_THERMISTOR +bool has_temperature_compensation() +{ +#ifdef DETECT_SUPERPINDA + return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; +#else + return true; +#endif +} +#endif //PINDA_THERMISTOR + diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 617b9cb6b..32ff6961a 100755 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -63,6 +63,7 @@ extern float current_temperature_bed; #ifdef PINDA_THERMISTOR extern uint16_t current_temperature_raw_pinda; extern float current_temperature_pinda; +bool has_temperature_compensation(); #endif #ifdef AMBIENT_THERMISTOR diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 13d8a1fb2..682a3b2ba 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -334,15 +334,6 @@ bool bSettings; // flag (i.e. 'fake parameter' const char STR_SEPARATOR[] PROGMEM = "------------"; -static bool has_temperature_compensation() -{ -#ifdef DETECT_SUPERPINDA - return (current_temperature_pinda >= PINDA_MINTEMP) ? true : false; -#else - return true; -#endif -} - static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* filename, char* longFilename) { From d398aa1e3fac215bf18ffad4b0591fef179d7d28 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 16 Jun 2020 00:44:59 +0200 Subject: [PATCH 27/77] Skip PINDA_THERMISTOR block in PINDA probe temperature calibration if PINDA_THERMISTOR is not detected. Costs 1328B of FLASH, something must be wrong. --- Firmware/Marlin_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 80bdd90f4..c18da74c5 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4580,7 +4580,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) case 76: { #ifdef PINDA_THERMISTOR - if (true) + if (has_temperature_compensation()) { if (calibration_status() >= CALIBRATION_STATUS_XYZ_CALIBRATION) { From 40ffea64ab5a98d0c2594e626562d302c1903bc7 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 16 Jun 2020 01:09:40 +0200 Subject: [PATCH 28/77] Do not compile temperature compensation code for PINDAv1 if PINDA_THERMISTOR macro is defined. This saves nearly all of additional FLASH usage of previous commit. It is only 70B worse than if no skipping is done in temperature compensation gcode G76. --- Firmware/Marlin_main.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c18da74c5..48636adaf 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4562,6 +4562,8 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) ### G76 - PINDA probe temperature calibration G76: PINDA probe temperature calibration This G-code is used to calibrate the temperature drift of the PINDA (inductive Sensor). + superPINDA sensor + The PINDAv2 sensor has a built-in thermistor which has the advantage that the calibration can be done once for all materials. The Original i3 Prusa MK2/s uses PINDAv1 and this calibration improves the temperature drift, but not as good as the PINDAv2. @@ -4580,8 +4582,13 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) case 76: { #ifdef PINDA_THERMISTOR - if (has_temperature_compensation()) + if (true) { + if (!has_temperature_compensation()) + { + SERIAL_ECHOLNPGM("No PINDA thermistor"); + break; + } if (calibration_status() >= CALIBRATION_STATUS_XYZ_CALIBRATION) { //we need to know accurate position of first calibration point @@ -4727,7 +4734,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) break; } -#endif //PINDA_THERMISTOR +#else //PINDA_THERMISTOR setTargetBed(PINDA_MIN_T); float zero_z; @@ -4828,7 +4835,7 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) lcd_update(2); - +#endif //PINDA_THERMISTOR } break; From d5feed1f6a7f38f21dca0be340e6f456ed74e4ea Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 16 Jun 2020 01:20:17 +0200 Subject: [PATCH 29/77] Refactor: Remove if(true) condition, redundant break statement and decrease indentation. --- Firmware/Marlin_main.cpp | 264 +++++++++++++++++++-------------------- 1 file changed, 130 insertions(+), 134 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 48636adaf..501b37d94 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4582,158 +4582,154 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) case 76: { #ifdef PINDA_THERMISTOR - if (true) - { - if (!has_temperature_compensation()) - { - SERIAL_ECHOLNPGM("No PINDA thermistor"); - break; - } + if (!has_temperature_compensation()) + { + SERIAL_ECHOLNPGM("No PINDA thermistor"); + break; + } - if (calibration_status() >= CALIBRATION_STATUS_XYZ_CALIBRATION) { - //we need to know accurate position of first calibration point - //if xyz calibration was not performed yet, interrupt temperature calibration and inform user that xyz cal. is needed - lcd_show_fullscreen_message_and_wait_P(_i("Please run XYZ calibration first.")); - break; - } - - if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) - { - // We don't know where we are! HOME! - // Push the commands to the front of the message queue in the reverse order! - // There shall be always enough space reserved for these commands. - repeatcommand_front(); // repeat G76 with all its parameters - enquecommand_front_P((PSTR("G28 W0"))); - 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 - bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false, false); - - if (result) - { - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[Z_AXIS] = 50; - current_position[Y_AXIS] = 180; - plan_buffer_line_curposXYZE(3000 / 60); - st_synchronize(); - lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET)); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); - current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); - plan_buffer_line_curposXYZE(3000 / 60); - st_synchronize(); - gcode_G28(false, false, true); + if (calibration_status() >= CALIBRATION_STATUS_XYZ_CALIBRATION) { + //we need to know accurate position of first calibration point + //if xyz calibration was not performed yet, interrupt temperature calibration and inform user that xyz cal. is needed + lcd_show_fullscreen_message_and_wait_P(_i("Please run XYZ calibration first.")); + break; + } - } - if ((current_temperature_pinda > 35) && (farm_mode == false)) { - //waiting for PIDNA probe to cool down in case that we are not in farm mode - current_position[Z_AXIS] = 100; - plan_buffer_line_curposXYZE(3000 / 60); - if (lcd_wait_for_pinda(35) == false) { //waiting for PINDA probe to cool, if this takes more then time expected, temp. cal. fails - lcd_temp_cal_show_result(false); - break; - } - } - lcd_update_enable(true); - KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly - SERIAL_ECHOLNPGM("PINDA probe calibration start"); + if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) + { + // We don't know where we are! HOME! + // Push the commands to the front of the message queue in the reverse order! + // There shall be always enough space reserved for these commands. + repeatcommand_front(); // repeat G76 with all its parameters + enquecommand_front_P((PSTR("G28 W0"))); + 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 + bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false, false); - float zero_z; - int z_shift = 0; //unit: steps - float start_temp = 5 * (int)(current_temperature_pinda / 5); - if (start_temp < 35) start_temp = 35; - if (start_temp < current_temperature_pinda) start_temp += 5; - printf_P(_N("start temperature: %.1f\n"), start_temp); + if (result) + { + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[Z_AXIS] = 50; + current_position[Y_AXIS] = 180; + plan_buffer_line_curposXYZE(3000 / 60); + st_synchronize(); + lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET)); + current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); + current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); + plan_buffer_line_curposXYZE(3000 / 60); + st_synchronize(); + gcode_G28(false, false, true); + + } + if ((current_temperature_pinda > 35) && (farm_mode == false)) { + //waiting for PIDNA probe to cool down in case that we are not in farm mode + current_position[Z_AXIS] = 100; + plan_buffer_line_curposXYZE(3000 / 60); + if (lcd_wait_for_pinda(35) == false) { //waiting for PINDA probe to cool, if this takes more then time expected, temp. cal. fails + lcd_temp_cal_show_result(false); + break; + } + } + lcd_update_enable(true); + KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly + SERIAL_ECHOLNPGM("PINDA probe calibration start"); + + float zero_z; + int z_shift = 0; //unit: steps + float start_temp = 5 * (int)(current_temperature_pinda / 5); + if (start_temp < 35) start_temp = 35; + if (start_temp < current_temperature_pinda) start_temp += 5; + printf_P(_N("start temperature: %.1f\n"), start_temp); // setTargetHotend(200, 0); - setTargetBed(70 + (start_temp - 30)); + setTargetBed(70 + (start_temp - 30)); - custom_message_type = CustomMsg::TempCal; - custom_message_state = 1; - lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION)); - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[X_AXIS] = PINDA_PREHEAT_X; - current_position[Y_AXIS] = PINDA_PREHEAT_Y; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[Z_AXIS] = PINDA_PREHEAT_Z; - plan_buffer_line_curposXYZE(3000 / 60); - st_synchronize(); + custom_message_type = CustomMsg::TempCal; + custom_message_state = 1; + lcd_setstatuspgm(_T(MSG_TEMP_CALIBRATION)); + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[X_AXIS] = PINDA_PREHEAT_X; + current_position[Y_AXIS] = PINDA_PREHEAT_Y; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[Z_AXIS] = PINDA_PREHEAT_Z; + plan_buffer_line_curposXYZE(3000 / 60); + st_synchronize(); - while (current_temperature_pinda < start_temp) - { - delay_keep_alive(1000); - serialecho_temperatures(); - } + while (current_temperature_pinda < start_temp) + { + delay_keep_alive(1000); + serialecho_temperatures(); + } - eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); //invalidate temp. calibration in case that in will be aborted during the calibration process + eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0); //invalidate temp. calibration in case that in will be aborted during the calibration process - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); - plan_buffer_line_curposXYZE(3000 / 60); - st_synchronize(); + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); + current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); + plan_buffer_line_curposXYZE(3000 / 60); + st_synchronize(); - bool find_z_result = find_bed_induction_sensor_point_z(-1.f); - if (find_z_result == false) { - lcd_temp_cal_show_result(find_z_result); - break; - } - zero_z = current_position[Z_AXIS]; + bool find_z_result = find_bed_induction_sensor_point_z(-1.f); + if (find_z_result == false) { + lcd_temp_cal_show_result(find_z_result); + break; + } + zero_z = current_position[Z_AXIS]; - printf_P(_N("\nZERO: %.3f\n"), current_position[Z_AXIS]); + printf_P(_N("\nZERO: %.3f\n"), current_position[Z_AXIS]); - int i = -1; for (; i < 5; i++) - { - float temp = (40 + i * 5); - printf_P(_N("\nStep: %d/6 (skipped)\nPINDA temperature: %d Z shift (mm):0\n"), i + 2, (40 + i*5)); - if (i >= 0) EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + i * 2, &z_shift); - if (start_temp <= temp) break; - } + int i = -1; for (; i < 5; i++) + { + float temp = (40 + i * 5); + printf_P(_N("\nStep: %d/6 (skipped)\nPINDA temperature: %d Z shift (mm):0\n"), i + 2, (40 + i*5)); + if (i >= 0) EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + i * 2, &z_shift); + if (start_temp <= temp) break; + } - for (i++; i < 5; i++) - { - float temp = (40 + i * 5); - printf_P(_N("\nStep: %d/6\n"), i + 2); - custom_message_state = i + 2; - setTargetBed(50 + 10 * (temp - 30) / 5); + for (i++; i < 5; i++) + { + float temp = (40 + i * 5); + printf_P(_N("\nStep: %d/6\n"), i + 2); + custom_message_state = i + 2; + setTargetBed(50 + 10 * (temp - 30) / 5); // setTargetHotend(255, 0); - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[X_AXIS] = PINDA_PREHEAT_X; - current_position[Y_AXIS] = PINDA_PREHEAT_Y; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[Z_AXIS] = PINDA_PREHEAT_Z; - plan_buffer_line_curposXYZE(3000 / 60); - st_synchronize(); - while (current_temperature_pinda < temp) - { - delay_keep_alive(1000); - serialecho_temperatures(); - } - current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; - plan_buffer_line_curposXYZE(3000 / 60); - current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); - current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); - plan_buffer_line_curposXYZE(3000 / 60); - st_synchronize(); - find_z_result = find_bed_induction_sensor_point_z(-1.f); - if (find_z_result == false) { - lcd_temp_cal_show_result(find_z_result); - break; - } - z_shift = (int)((current_position[Z_AXIS] - zero_z)*cs.axis_steps_per_unit[Z_AXIS]); + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[X_AXIS] = PINDA_PREHEAT_X; + current_position[Y_AXIS] = PINDA_PREHEAT_Y; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[Z_AXIS] = PINDA_PREHEAT_Z; + plan_buffer_line_curposXYZE(3000 / 60); + st_synchronize(); + while (current_temperature_pinda < temp) + { + delay_keep_alive(1000); + serialecho_temperatures(); + } + current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; + plan_buffer_line_curposXYZE(3000 / 60); + current_position[X_AXIS] = pgm_read_float(bed_ref_points_4); + current_position[Y_AXIS] = pgm_read_float(bed_ref_points_4 + 1); + plan_buffer_line_curposXYZE(3000 / 60); + st_synchronize(); + find_z_result = find_bed_induction_sensor_point_z(-1.f); + if (find_z_result == false) { + lcd_temp_cal_show_result(find_z_result); + break; + } + z_shift = (int)((current_position[Z_AXIS] - zero_z)*cs.axis_steps_per_unit[Z_AXIS]); - printf_P(_N("\nPINDA temperature: %.1f Z shift (mm): %.3f"), current_temperature_pinda, current_position[Z_AXIS] - zero_z); + printf_P(_N("\nPINDA temperature: %.1f Z shift (mm): %.3f"), current_temperature_pinda, current_position[Z_AXIS] - zero_z); - EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + i * 2, &z_shift); + EEPROM_save_B(EEPROM_PROBE_TEMP_SHIFT + i * 2, &z_shift); - } - lcd_temp_cal_show_result(true); + } + lcd_temp_cal_show_result(true); - break; - } #else //PINDA_THERMISTOR setTargetBed(PINDA_MIN_T); From 9838be851200769d79b1b56b3685845e51b0ec2e Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 16 Jun 2020 02:02:12 +0200 Subject: [PATCH 30/77] Do not compile, if PINDA temperature compensation start point is lower than PINDA_MINTEMP. Document. --- Firmware/Marlin_main.cpp | 12 +++++++++--- Firmware/temperature.cpp | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 501b37d94..8dbc0d840 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4561,13 +4561,15 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) /*! ### G76 - PINDA probe temperature calibration G76: PINDA probe temperature calibration This G-code is used to calibrate the temperature drift of the PINDA (inductive Sensor). - - superPINDA sensor The PINDAv2 sensor has a built-in thermistor which has the advantage that the calibration can be done once for all materials. The Original i3 Prusa MK2/s uses PINDAv1 and this calibration improves the temperature drift, but not as good as the PINDAv2. + superPINDA sensor has internal temperature compensation and no thermistor output. There is no point of doing temperature calibration in such case. + If PINDA_THERMISTOR and DETECT_SUPERPINDA is defined during compilation, calibration is skipped with serial message "No PINDA thermistor". + This can be caused also if PINDA thermistor connection is broken or PINDA temperature is lower than PINDA_MINTEMP. + #### Example ``` @@ -10493,7 +10495,11 @@ float temp_comp_interpolation(float inp_temperature) { if (i>0) EEPROM_read_B(EEPROM_PROBE_TEMP_SHIFT + (i-1) * 2, &shift[i]); //read shift in steps from EEPROM temp_C[i] = 50 + i * 10; //temperature in C #ifdef PINDA_THERMISTOR - temp_C[i] = 35 + i * 5; //temperature in C + constexpr int start_compensating_temp = 35; + temp_C[i] = start_compensating_temp + i * 5; //temperature in degrees C +#ifdef DETECT_SUPERPINDA + static_assert(start_compensating_temp >= PINDA_MINTEMP, "Temperature compensation start point is lower than PINDA_MINTEMP."); +#endif //DETECT_SUPERPINDA #else temp_C[i] = 50 + i * 10; //temperature in C #endif diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index bd232cf57..6e9b6985a 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -2197,6 +2197,11 @@ float unscalePID_d(float d) #endif //PIDTEMP #ifdef PINDA_THERMISTOR +//! @brief PINDA thermistor detected +//! +//! @retval true firmware should do temperature compensation and allow calibration +//! @retval false PINDA thermistor is not detected, disable temperature compensation and calibration +//! bool has_temperature_compensation() { #ifdef DETECT_SUPERPINDA From a0cf5714ceca7d60c5874c376898ecd8badd7d13 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 19 Jun 2020 15:39:16 +0300 Subject: [PATCH 31/77] M220 M221 --- Firmware/Marlin_main.cpp | 58 ++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 8dbc0d840..d4ed0c51b 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -7300,17 +7300,26 @@ Sigma_Exit: */ case 220: // M220 S- set speed factor override percentage { - if (code_seen('B')) //backup current speed factor - { - saved_feedmultiply_mm = feedmultiply; - } - if(code_seen('S')) - { - feedmultiply = code_value() ; - } - if (code_seen('R')) { //restore previous feedmultiply - feedmultiply = saved_feedmultiply_mm; - } + bool codesWereSeen = false; + if (code_seen('B')) //backup current speed factor + { + saved_feedmultiply_mm = feedmultiply; + codesWereSeen = true; + } + if (code_seen('S')) + { + feedmultiply = code_value(); + codesWereSeen = true; + } + if (code_seen('R')) //restore previous feedmultiply + { + feedmultiply = saved_feedmultiply_mm; + codesWereSeen = true; + } + if (!codesWereSeen) + { + printf_P(PSTR("%i%%\n"), feedmultiply); + } } break; @@ -7326,23 +7335,26 @@ Sigma_Exit: */ case 221: // M221 S- set extrude factor override percentage { - if(code_seen('S')) - { - int tmp_code = code_value(); - if (code_seen('T')) + if (code_seen('S')) { - uint8_t extruder; - if(setTargetedHotend(221, extruder)){ - break; - } - extruder_multiply[extruder] = tmp_code; + int tmp_code = code_value(); + if (code_seen('T')) + { + uint8_t extruder; + if (setTargetedHotend(221, extruder)) + break; + extruder_multiply[extruder] = tmp_code; + } + else + { + extrudemultiply = tmp_code ; + } } else { - extrudemultiply = tmp_code ; + printf_P(PSTR("%i%%\n"), extrudemultiply); } - } - calculate_extruder_multipliers(); + calculate_extruder_multipliers(); } break; From 15548958e98ddae4de263d77aa68aa025226e2d2 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Jun 2020 15:19:31 +0200 Subject: [PATCH 32/77] Remove cumulative error in segments without cruising (take 1) PR #2591 made LA compression always account for retractions instead of discarding the current compression steps. While this fixed overextrusion in short segments followed by wipes, it uncovered another issue in how the compression steps are spread during the trapezoid calculations leading to gaps in segments followed by retractions (as highlighted by /some/ prints in #2693). LA1.5 always computes the required target compression steps for a segment at nominal speed. Because of how the extra steps are allocated using multiples of the accelerating frequency, if the segment is truncated before cruising is reached, an additional cycle of steps can be inserted before deceleration starts. Deceleration is also not guaranteed to be symmetric where up to _two_ cycles can be skipped depending on the stepping cycle, leading to a situation where a symmetric acceleration/deceleration block will lead up to a cycle of accumulated compression. While forcing an the extra step during deceleration is possible by tweaking the error term (eISR_Err), this doesn't guarantee balance in all cases. The underlying issue is that the function is aiming a compression which cannot be reached (nominal speed), and not at the effective max speed reached in the trapezoid, thus moving the average result higher over time. We fix this by calculating the effective maximum speed (and compression) reached during the trapezoid, which stops compression on the required cycle irregardless of the error term, balancing the result. This is the first unoptimized POC: this is not for production: a lot of calculations are redundand and could work directly in steps/s^2. --- Firmware/planner.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index c0f465c2a..049dd2022 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -225,12 +225,15 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit uint32_t accel_decel_steps = accelerate_steps + decelerate_steps; // Size of Plateau of Nominal Rate. uint32_t plateau_steps = 0; + // Maximum effective speed reached in the trapezoid (mm/s) + float max_speed; // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will // have to use intersection_distance() to calculate when to abort acceleration and start braking // in order to reach the final_rate exactly at the end of this block. if (accel_decel_steps < block->step_event_count.wide) { plateau_steps = block->step_event_count.wide - accel_decel_steps; + max_speed = block->nominal_speed; } else { uint32_t acceleration_x4 = acceleration << 2; // Avoid negative numbers @@ -263,12 +266,18 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit decelerate_steps = block->step_event_count.wide; accelerate_steps = block->step_event_count.wide - decelerate_steps; } + + // TODO: not for production + float dist = intersection_distance(entry_speed, exit_speed, block->acceleration, block->millimeters); + max_speed = sqrt(2 * block->acceleration * dist + entry_speed*entry_speed); } #ifdef LIN_ADVANCE uint16_t final_adv_steps = 0; + uint16_t max_adv_steps = 0; if (block->use_advance_lead) { final_adv_steps = exit_speed * block->adv_comp; + max_adv_steps = max_speed * block->adv_comp; } #endif @@ -284,6 +293,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit block->final_rate = final_rate; #ifdef LIN_ADVANCE block->final_adv_steps = final_adv_steps; + block->max_adv_steps = max_adv_steps; #endif } CRITICAL_SECTION_END; @@ -1137,9 +1147,8 @@ Having the real displacement of the head, we can calculate the total movement le #ifdef LIN_ADVANCE if (block->use_advance_lead) { // the nominal speed doesn't change past this point: calculate the compression ratio for the - // segment and the required advance steps + // segment (the required advance steps are computed during trapezoid planning) block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS]; - block->max_adv_steps = block->nominal_speed * block->adv_comp; float advance_speed; if (e_D_ratio > 0) From 753e651af3026fba344169e45f677476741cf485 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Jun 2020 16:01:13 +0200 Subject: [PATCH 33/77] Remove cumulative error in segments without cruising (take 2) Reduce per-trapezoid calculations --- Firmware/planner.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 049dd2022..8687055b1 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -267,9 +267,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit accelerate_steps = block->step_event_count.wide - decelerate_steps; } - // TODO: not for production - float dist = intersection_distance(entry_speed, exit_speed, block->acceleration, block->millimeters); - max_speed = sqrt(2 * block->acceleration * dist + entry_speed*entry_speed); + max_speed = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr) / block->speed_factor; } #ifdef LIN_ADVANCE From 7c140bc497d50d1ebda861d79c7fb5fe64d5c673 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Jun 2020 16:19:46 +0200 Subject: [PATCH 34/77] Remove cumulative error in segments without cruising (take 3) Remove another division by precomputing the division directly in adv_comp. --- Firmware/planner.cpp | 104 ++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 8687055b1..54bc692d8 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -225,15 +225,15 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit uint32_t accel_decel_steps = accelerate_steps + decelerate_steps; // Size of Plateau of Nominal Rate. uint32_t plateau_steps = 0; - // Maximum effective speed reached in the trapezoid (mm/s) - float max_speed; + // Maximum effective speed reached in the trapezoid (step/min) + float max_rate; // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will // have to use intersection_distance() to calculate when to abort acceleration and start braking // in order to reach the final_rate exactly at the end of this block. if (accel_decel_steps < block->step_event_count.wide) { plateau_steps = block->step_event_count.wide - accel_decel_steps; - max_speed = block->nominal_speed; + max_rate = block->nominal_rate; } else { uint32_t acceleration_x4 = acceleration << 2; // Avoid negative numbers @@ -267,15 +267,15 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit accelerate_steps = block->step_event_count.wide - decelerate_steps; } - max_speed = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr) / block->speed_factor; + max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr); } #ifdef LIN_ADVANCE uint16_t final_adv_steps = 0; uint16_t max_adv_steps = 0; if (block->use_advance_lead) { - final_adv_steps = exit_speed * block->adv_comp; - max_adv_steps = max_speed * block->adv_comp; + final_adv_steps = final_rate * block->adv_comp; + max_adv_steps = max_rate * block->adv_comp; } #endif @@ -1142,51 +1142,6 @@ Having the real displacement of the head, we can calculate the total movement le block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); -#ifdef LIN_ADVANCE - if (block->use_advance_lead) { - // the nominal speed doesn't change past this point: calculate the compression ratio for the - // segment (the required advance steps are computed during trapezoid planning) - block->adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS]; - - float advance_speed; - if (e_D_ratio > 0) - advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]); - else - advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS]; - - // to save more space we avoid another copy of calc_timer and go through slow division, but we - // still need to replicate the *exact* same step grouping policy (see below) - if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY; - float advance_rate = (F_CPU / 8.0) / advance_speed; - if (advance_speed > 20000) { - block->advance_rate = advance_rate * 4; - block->advance_step_loops = 4; - } - else if (advance_speed > 10000) { - block->advance_rate = advance_rate * 2; - block->advance_step_loops = 2; - } - else - { - // never overflow the internal accumulator with very low rates - if (advance_rate < UINT16_MAX) - block->advance_rate = advance_rate; - else - block->advance_rate = UINT16_MAX; - block->advance_step_loops = 1; - } - - #ifdef LA_DEBUG - if (block->advance_step_loops > 2) - // @wavexx: we should really check for the difference between step_loops and - // advance_step_loops instead. A difference of more than 1 will lead - // to uneven speed and *should* be adjusted here by furthermore - // reducing the speed. - SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed."); - #endif - } -#endif - // Start with a safe speed. // Safe speed is the speed, from which the machine may halt to stop immediately. float safe_speed = block->nominal_speed; @@ -1312,6 +1267,53 @@ Having the real displacement of the head, we can calculate the total movement le // Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated. block->speed_factor = block->nominal_rate / block->nominal_speed; + +#ifdef LIN_ADVANCE + if (block->use_advance_lead) { + // calculate the compression ratio for the segment (the required advance steps are computed + // during trapezoid planning) + float adv_comp = extruder_advance_K * e_D_ratio * cs.axis_steps_per_unit[E_AXIS]; // (step/(mm/s)) + block->adv_comp = adv_comp / block->speed_factor; // step/(step/min) + + float advance_speed; + if (e_D_ratio > 0) + advance_speed = (extruder_advance_K * e_D_ratio * block->acceleration * cs.axis_steps_per_unit[E_AXIS]); + else + advance_speed = cs.max_jerk[E_AXIS] * cs.axis_steps_per_unit[E_AXIS]; + + // to save more space we avoid another copy of calc_timer and go through slow division, but we + // still need to replicate the *exact* same step grouping policy (see below) + if (advance_speed > MAX_STEP_FREQUENCY) advance_speed = MAX_STEP_FREQUENCY; + float advance_rate = (F_CPU / 8.0) / advance_speed; + if (advance_speed > 20000) { + block->advance_rate = advance_rate * 4; + block->advance_step_loops = 4; + } + else if (advance_speed > 10000) { + block->advance_rate = advance_rate * 2; + block->advance_step_loops = 2; + } + else + { + // never overflow the internal accumulator with very low rates + if (advance_rate < UINT16_MAX) + block->advance_rate = advance_rate; + else + block->advance_rate = UINT16_MAX; + block->advance_step_loops = 1; + } + + #ifdef LA_DEBUG + if (block->advance_step_loops > 2) + // @wavexx: we should really check for the difference between step_loops and + // advance_step_loops instead. A difference of more than 1 will lead + // to uneven speed and *should* be adjusted here by furthermore + // reducing the speed. + SERIAL_ECHOLNPGM("LA: More than 2 steps per eISR loop executed."); + #endif + } +#endif + calculate_trapezoid_for_block(block, block->entry_speed, safe_speed); if (block->step_event_count.wide <= 32767) From 51a539608cafafb41fe8ee248c41a91c70f7b145 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 22 Jun 2020 00:19:47 +0200 Subject: [PATCH 35/77] Reset LA_phase at each trapezoid stage There used to be a single stage where an extruder reversal could occur, but since PR #2591 reversals can happen up to two times per trapezoid. Reset LA_phase when ADV_INIT is set, since it is re-inizialized only when needed a few lines afterward. This improves performance by avoiding to check the phase continuosly to the end of the trapezoid. Likewise, always set ADV_INIT during the first cruising step, also to force a LA_phase reset. --- Firmware/stepper.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index de250ec97..57520070f 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -848,12 +848,10 @@ FORCE_INLINE void isr() { #ifdef LIN_ADVANCE if(current_block->use_advance_lead) { - if (!nextAdvanceISR) { - // Due to E-jerk, there can be discontinuities in pressure state where an - // acceleration or deceleration can be skipped or joined with the previous block. - // If LA was not previously active, re-check the pressure level - la_state = ADV_INIT; - } + // Due to E-jerk, there can be discontinuities in pressure state where an + // acceleration or deceleration can be skipped or joined with the previous block. + // If LA was not previously active, re-check the pressure level + la_state = ADV_INIT; } #endif } @@ -865,6 +863,7 @@ FORCE_INLINE void isr() { #ifdef LIN_ADVANCE // avoid multiple instances or function calls to advance_spread if (la_state & ADV_INIT) { + LA_phase = -1; if (current_adv_steps == target_adv_steps) { // nothing to be done in this phase la_state = 0; From 173aa2debad36da6590c53ad0a4114bfcda6a710 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 22 Jun 2020 00:54:50 +0200 Subject: [PATCH 36/77] Fix bogus timer check preventing fast LA steps to be scheduled Simplify and fix the broken timer check when scheduling advance ticks. This dates back to the original LA15 PR, an old bug... --- Firmware/stepper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 57520070f..b1c3d2861 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -1016,7 +1016,7 @@ FORCE_INLINE void advance_isr_scheduler() { // Schedule the next closest tick, ignoring advance if scheduled too // soon in order to avoid skewing the regular stepper acceleration - if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + TCNT1 + 40) < nextMainISR) + if (nextAdvanceISR != ADV_NEVER && (nextAdvanceISR + 40) < nextMainISR) OCR1A = nextAdvanceISR; else OCR1A = nextMainISR; From a36efcb347bc3c1312f401ecaac383073d3856ba Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 22 Jun 2020 15:03:49 +0200 Subject: [PATCH 37/77] Remove cumulative error in segments without cruising (take 4) Avoid sqrt when possible --- Firmware/planner.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 54bc692d8..b5b251ec4 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -225,15 +225,24 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit uint32_t accel_decel_steps = accelerate_steps + decelerate_steps; // Size of Plateau of Nominal Rate. uint32_t plateau_steps = 0; - // Maximum effective speed reached in the trapezoid (step/min) - float max_rate; + +#ifdef LIN_ADVANCE + uint16_t final_adv_steps = 0; + uint16_t max_adv_steps = 0; + if (block->use_advance_lead) { + final_adv_steps = final_rate * block->adv_comp; + } +#endif // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will // have to use intersection_distance() to calculate when to abort acceleration and start braking // in order to reach the final_rate exactly at the end of this block. if (accel_decel_steps < block->step_event_count.wide) { plateau_steps = block->step_event_count.wide - accel_decel_steps; - max_rate = block->nominal_rate; +#ifdef LIN_ADVANCE + if (block->use_advance_lead) + max_adv_steps = block->nominal_rate * block->adv_comp; +#endif } else { uint32_t acceleration_x4 = acceleration << 2; // Avoid negative numbers @@ -267,17 +276,19 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit accelerate_steps = block->step_event_count.wide - decelerate_steps; } - max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr); - } - #ifdef LIN_ADVANCE - uint16_t final_adv_steps = 0; - uint16_t max_adv_steps = 0; - if (block->use_advance_lead) { - final_adv_steps = final_rate * block->adv_comp; - max_adv_steps = max_rate * block->adv_comp; - } + if (block->use_advance_lead) { + if(!accelerate_steps || !decelerate_steps) { + // accelerate_steps=0: deceleration-only ramp, max_rate is effectively unused + // decelerate_steps=0: acceleration-only ramp, max_rate _is_ final_rate + max_adv_steps = final_adv_steps; + } else { + uint16_t max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr); + max_adv_steps = max_rate * block->adv_comp; + } + } #endif + } CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section // This block locks the interrupts globally for 4.38 us, From 1206fc316402012c4607865d32cbc8ad470b71aa Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 22 Jun 2020 15:34:34 +0200 Subject: [PATCH 38/77] Avoid useless cast --- Firmware/planner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index b5b251ec4..bc991fdf8 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -283,7 +283,7 @@ void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit // decelerate_steps=0: acceleration-only ramp, max_rate _is_ final_rate max_adv_steps = final_adv_steps; } else { - uint16_t max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr); + float max_rate = sqrt(acceleration_x2 * accelerate_steps + initial_rate_sqr); max_adv_steps = max_rate * block->adv_comp; } } From 50a09824fd8b3d33d62940b6836db350ea8670d5 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 23 Jun 2020 15:20:46 +0200 Subject: [PATCH 39/77] Avoid scheduling useless eISR ticks When switching to a new trapezoid step with the right pressure, cancel any pending eISR right away. Similarly do not schedule another eISR if the pressure will be reached by the end of the eISR. This was done in the past to preserve the current LA_phase. This is not needed anymore, since it will be reset at each trapezoid step when LA is re-initialized. --- Firmware/stepper.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index b1c3d2861..0c7ecae5d 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -864,9 +864,11 @@ FORCE_INLINE void isr() { // avoid multiple instances or function calls to advance_spread if (la_state & ADV_INIT) { LA_phase = -1; + if (current_adv_steps == target_adv_steps) { - // nothing to be done in this phase + // nothing to be done in this phase, cancel any pending eisr la_state = 0; + nextAdvanceISR = ADV_NEVER; } else { eISR_Err = current_block->advance_rate / 4; @@ -933,20 +935,21 @@ FORCE_INLINE void advance_isr() { current_adv_steps -= e_step_loops; else current_adv_steps = 0; - nextAdvanceISR = eISR_Rate; } else if (current_adv_steps < target_adv_steps) { // compression e_steps += e_step_loops; if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR); current_adv_steps += e_step_loops; - nextAdvanceISR = eISR_Rate; } - else { + + if (current_adv_steps == target_adv_steps) { // advance steps completed nextAdvanceISR = ADV_NEVER; - LA_phase = -1; - e_step_loops = 1; + } + else { + // schedule another tick + nextAdvanceISR = eISR_Rate; } } From f1efce7e525a651f0fcd08005e310ff7f21e6c8b Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 23 Jun 2020 16:40:39 +0200 Subject: [PATCH 40/77] Handle LA termination with double/quad stepping properly Before PR #2591 LA was automatically capped during cruising or deceleration. However we now rely on reaching the current pressure state exactly to stop. When dual/quad stepping inside the eISR we might incur in oscillating behavior if we do not handle it correctly. This might be the cause behind #2757 This now changes e_step_loops to be a phase-local variable, so we now reset it each phase too (instead of per-segment). --- Firmware/stepper.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 0c7ecae5d..13724cc9e 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -348,10 +348,7 @@ FORCE_INLINE void stepper_next_block() #ifdef LIN_ADVANCE if (current_block->use_advance_lead) { - e_step_loops = current_block->advance_step_loops; target_adv_steps = current_block->max_adv_steps; - } else { - e_step_loops = 1; } e_steps = 0; nextAdvanceISR = ADV_NEVER; @@ -871,7 +868,10 @@ FORCE_INLINE void isr() { nextAdvanceISR = ADV_NEVER; } else { + // reset error and iterations per loop for this phase eISR_Err = current_block->advance_rate / 4; + e_step_loops = current_block->advance_step_loops; + if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) { // LA could reverse the direction of extrusion in this phase LA_phase = 0; @@ -929,15 +929,22 @@ FORCE_INLINE void isr() { FORCE_INLINE void advance_isr() { if (current_adv_steps > target_adv_steps) { // decompression + if (e_step_loops != 1) { + uint16_t d_steps = current_adv_steps - target_adv_steps; + if (d_steps < e_step_loops) + e_step_loops = d_steps; + } e_steps -= e_step_loops; if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR); - if(current_adv_steps > e_step_loops) - current_adv_steps -= e_step_loops; - else - current_adv_steps = 0; + current_adv_steps -= e_step_loops; } else if (current_adv_steps < target_adv_steps) { // compression + if (e_step_loops != 1) { + uint16_t d_steps = target_adv_steps - current_adv_steps; + if (d_steps < e_step_loops) + e_step_loops = d_steps; + } e_steps += e_step_loops; if (e_steps) WRITE_NC(E0_DIR_PIN, e_steps < 0? INVERT_E0_DIR: !INVERT_E0_DIR); current_adv_steps += e_step_loops; From c08f37da9661feb946a6602dae49bab3a76071cb Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Wed, 24 Jun 2020 16:56:25 +0200 Subject: [PATCH 41/77] Use nominal rate for phase calculations The local interval calculated by advance_spread() might oscillate too much in narrow intervals. --- Firmware/stepper.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 13724cc9e..80c5be294 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -883,11 +883,13 @@ FORCE_INLINE void isr() { advance_spread(main_Rate); if (LA_phase >= 0) { if (step_loops == e_step_loops) - LA_phase = (eISR_Rate > main_Rate); + LA_phase = (current_block->advance_rate > main_Rate); else { // avoid overflow through division. warning: we need to _guarantee_ step_loops // and e_step_loops are <= 4 due to fastdiv's limit - LA_phase = (fastdiv(eISR_Rate, step_loops) > fastdiv(main_Rate, e_step_loops)); + auto adv_rate_n = fastdiv(current_block->advance_rate, step_loops); + auto main_rate_n = fastdiv(main_Rate, e_step_loops); + LA_phase = (adv_rate_n > main_rate_n); } } } From fb5f09da6d365cb03db7abc01b18532740db3e6b Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Thu, 16 Jul 2020 17:47:48 +0200 Subject: [PATCH 42/77] Fix incorrect precedence for retraction phase The logic was inverted, causing the fastest isr to always retract instead of counter-balance the acceleration properly. --- Firmware/stepper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 80c5be294..c5a6b69c9 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -883,13 +883,13 @@ FORCE_INLINE void isr() { advance_spread(main_Rate); if (LA_phase >= 0) { if (step_loops == e_step_loops) - LA_phase = (current_block->advance_rate > main_Rate); + LA_phase = (current_block->advance_rate < main_Rate); else { // avoid overflow through division. warning: we need to _guarantee_ step_loops // and e_step_loops are <= 4 due to fastdiv's limit auto adv_rate_n = fastdiv(current_block->advance_rate, step_loops); auto main_rate_n = fastdiv(main_Rate, e_step_loops); - LA_phase = (adv_rate_n > main_rate_n); + LA_phase = (adv_rate_n < main_rate_n); } } } From c54474f2db5cf9f04e0308c3c6694fff671a7d65 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Thu, 16 Jul 2020 13:26:15 +0200 Subject: [PATCH 43/77] Guard against planning/numerical errors in short segments Turns out for high-res curved models the numerical error and the SLOWDOWN handling in the planner can cause enough variance in the calculated pressure to trigger LA to continuosly, making matters worse. Clamp LA again, but only during extrusion, so that the runaway error is limited by the current segment length. --- Firmware/stepper.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index c5a6b69c9..949ffd587 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -809,8 +809,11 @@ FORCE_INLINE void isr() { acceleration_time += timer; #ifdef LIN_ADVANCE if (current_block->use_advance_lead) { - if (step_events_completed.wide <= (unsigned long int)step_loops) + if (step_events_completed.wide <= (unsigned long int)step_loops) { la_state = ADV_INIT | ADV_ACC_VARY; + if (e_extruding && current_adv_steps > target_adv_steps) + target_adv_steps = current_adv_steps; + } } #endif } @@ -832,6 +835,8 @@ FORCE_INLINE void isr() { if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) { target_adv_steps = current_block->final_adv_steps; la_state = ADV_INIT | ADV_ACC_VARY; + if (e_extruding && current_adv_steps < target_adv_steps) + target_adv_steps = current_adv_steps; } } #endif @@ -849,6 +854,8 @@ FORCE_INLINE void isr() { // acceleration or deceleration can be skipped or joined with the previous block. // If LA was not previously active, re-check the pressure level la_state = ADV_INIT; + if (e_extruding) + target_adv_steps = current_adv_steps; } #endif } From 9b8f642b28eb5441a8342c73043d1570c0544bd2 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 19 Jul 2020 17:41:38 +0200 Subject: [PATCH 44/77] Account for flow adjustments in LA The e/D ratio should be calculated using the extrusion length. As such, purify the e_D_ratio from the current extruder multiplier in order to account correctly for flow adjustments. --- Firmware/Marlin.h | 2 +- Firmware/planner.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 5c03552bf..697f2f72c 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -299,7 +299,7 @@ extern float feedrate; extern int feedmultiply; extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually -extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner +extern float extruder_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner extern float current_position[NUM_AXIS] ; extern float destination[NUM_AXIS] ; extern float min_pos[3]; diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index bc991fdf8..a994c74fd 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -1098,7 +1098,7 @@ Having the real displacement of the head, we can calculate the total movement le if (block->use_advance_lead) { // all extrusion moves with LA require a compression which is proportional to the // extrusion_length to distance ratio (e/D) - e_D_ratio = (e - position_float[E_AXIS]) / + e_D_ratio = ((e - position_float[E_AXIS]) / extruder_multiplier[extruder]) / sqrt(sq(x - position_float[X_AXIS]) + sq(y - position_float[Y_AXIS]) + sq(z - position_float[Z_AXIS])); From a08ca19adeec3da70725e5b9555bf37bd3e276ba Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 20 Jul 2020 12:42:28 +0200 Subject: [PATCH 45/77] Make flow correction optional, disabled by default If you're using flow to correct for an incorrect source diameter, which is probably the main usage when using the LCD, then LA shouldn't be adjusted. It's still unclear what the effect of M221 in gcode should be regarding overall extrusion width. If M221 means "thicker lines", then LA should also be adjusted accordingly. This stems from the fact that the source diameter/length needs to be known in order to determine a compression factor which is independent of the extrusion width, but the FW only ever sees one value currently (the extrusion length) which combines both. This makes it impossible for the FW to adjust for one OR the other scenario, depending on what you expect for M221 to mean. --- Firmware/Configuration_adv.h | 1 + Firmware/planner.cpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 5386c2815..7deff3c12 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -288,6 +288,7 @@ #define LA_K_DEF 0 // Default K factor (Unit: mm compression per 1mm/s extruder speed) #define LA_K_MAX 10 // Maximum acceptable K factor (exclusive, see notes in planner.cpp:plan_buffer_line) #define LA_LA10_MIN LA_K_MAX // Lin. Advance 1.0 threshold value (inclusive) + //#define LA_FLOWADJ // Adjust LA along with flow/M221 for uniform width //#define LA_NOCOMPAT // Disable Linear Advance 1.0 compatibility //#define LA_LIVE_K // Allow adjusting K in the Tune menu //#define LA_DEBUG // If enabled, this will generate debug information output over USB. diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index a994c74fd..4789b0336 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -1096,12 +1096,20 @@ Having the real displacement of the head, we can calculate the total movement le && delta_mm[E_AXIS] >= 0 && abs(delta_mm[Z_AXIS]) < 0.5; if (block->use_advance_lead) { +#ifdef LA_FLOWADJ + // M221/FLOW should change uniformly the extrusion thickness + float delta_e = (e - position_float[E_AXIS]) / extruder_multiplier[extruder]; +#else + // M221/FLOW only adjusts for an incorrect source diameter + float delta_e = (e - position_float[E_AXIS]); +#endif + float delta_D = sqrt(sq(x - position_float[X_AXIS]) + + sq(y - position_float[Y_AXIS]) + + sq(z - position_float[Z_AXIS])); + // all extrusion moves with LA require a compression which is proportional to the // extrusion_length to distance ratio (e/D) - e_D_ratio = ((e - position_float[E_AXIS]) / extruder_multiplier[extruder]) / - sqrt(sq(x - position_float[X_AXIS]) - + sq(y - position_float[Y_AXIS]) - + sq(z - position_float[Z_AXIS])); + e_D_ratio = delta_e / delta_D; // Check for unusual high e_D ratio to detect if a retract move was combined with the last // print move due to min. steps per segment. Never execute this with advance! This assumes From a95feb56d9cc9bccc185d989272c2c6e258fc553 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Mon, 20 Jul 2020 19:35:25 +0300 Subject: [PATCH 46/77] ALTFAN override --- Firmware/Marlin_main.cpp | 10 +++++++++- Firmware/eeprom.h | 4 +++- Firmware/temperature.cpp | 27 ++++++++++++++++++++++++--- Firmware/temperature.h | 2 ++ Firmware/ultralcd.cpp | 12 ++++++++++++ Firmware/ultralcd.h | 2 ++ 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 8dbc0d840..f3528ca9e 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -8570,7 +8570,15 @@ Sigma_Exit: break; /*! - ### M999 - Restart after being stopped M999: Restart after being stopped by error + ### M666 - Enter experimental menu + Only used by Prusa + */ + case 666: + menu_submenu(lcd_experimental_menu); + break; + + /*! + ### M999 - Restart after being stopped M999: Restart after being stopped by error @todo Usually doesn't work. Should be fixed or removed. Most of the time, if `Stopped` it set, the print fails and is unrecoverable. */ case 999: diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 89d7e7f99..bfc81d82d 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -561,8 +561,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_UVLO_LA_K (EEPROM_BACKLIGHT_TIMEOUT-4) // float +#define EEPROM_ALTFAN_OVERRIDE (EEPROM_UVLO_LA_K-1) //uint8 + //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_UVLO_LA_K +#define EEPROM_LAST_ITEM EEPROM_ALTFAN_OVERRIDE // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 6e9b6985a..084ed2720 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -153,6 +153,7 @@ uint8_t fanSpeedBckp = 255; uint8_t fanState = 0; #ifdef EXTRUDER_ALTFAN_DETECT bool extruderFanIsAltfan = false; //set to Noctua + uint8_t altfanOverride = 0; #endif //EXTRUDER_ALTFAN_DETECT #endif @@ -224,6 +225,14 @@ bool extruder_altfan_detect() setExtruderAutoFanState(3); SET_INPUT(TACH_0); + + altfanOverride = eeprom_read_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE); + if (altfanOverride == EEPROM_EMPTY_VALUE) + { + altfanOverride = 0; + eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, altfanOverride); + } + CRITICAL_SECTION_START; EICRB &= ~(1 << ISC61); EICRB |= (1 << ISC60); @@ -241,6 +250,18 @@ bool extruder_altfan_detect() setExtruderAutoFanState(1); return extruderFanIsAltfan; } + +void altfanOverride_toggle() +{ + altfanOverride = !altfanOverride; + eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, altfanOverride); +} + +bool altfanOverride_get() +{ + return altfanOverride; +} + #endif //EXTRUDER_ALTFAN_DETECT // return "false", if all extruder-heaters are 'off' (ie. "true", if any heater is 'on') @@ -494,7 +515,7 @@ void setExtruderAutoFanState(uint8_t state) if (fanState & 0x01) { #ifdef EXTRUDER_ALTFAN_DETECT - if (extruderFanIsAltfan) newFanSpeed = EXTRUDER_ALTFAN_SPEED_SILENT; + if (extruderFanIsAltfan && !altfanOverride) newFanSpeed = EXTRUDER_ALTFAN_SPEED_SILENT; else newFanSpeed = EXTRUDER_AUTO_FAN_SPEED; #else //EXTRUDER_ALTFAN_DETECT newFanSpeed = EXTRUDER_AUTO_FAN_SPEED; @@ -1356,7 +1377,7 @@ void temp_runaway_stop(bool isPreheat, bool isBed) SERIAL_ERROR_START; isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HOTEND)"); #ifdef EXTRUDER_ALTFAN_DETECT - extruderFanIsAltfan = false; //full speed + altfanOverride = true; //full speed #endif //EXTRUDER_ALTFAN_DETECT setExtruderAutoFanState(3); SET_OUTPUT(FAN_PIN); @@ -1446,7 +1467,7 @@ void max_temp_error(uint8_t e) { WRITE(FAN_PIN, 1); WRITE(BEEPER, 1); #ifdef EXTRUDER_ALTFAN_DETECT - extruderFanIsAltfan = false; //full speed + altfanOverride = true; //full speed #endif //EXTRUDER_ALTFAN_DETECT setExtruderAutoFanState(3); // fanSpeed will consumed by the check_axes_activity() routine. diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 32ff6961a..da88a53c0 100755 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -273,6 +273,8 @@ void check_max_temp(); #ifdef EXTRUDER_ALTFAN_DETECT extern bool extruder_altfan_detect(); + extern void altfanOverride_toggle(); + extern bool altfanOverride_get(); #endif //EXTRUDER_ALTFAN_DETECT extern unsigned long extruder_autofan_last_check; diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 87266914f..bb1d2c716 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -9160,3 +9160,15 @@ void lcd_crash_detect_disable() eeprom_update_byte((uint8_t*)EEPROM_CRASH_DET, 0x00); } #endif + +void lcd_experimental_menu() +{ + MENU_BEGIN(); + MENU_ITEM_BACK_P(_T(MSG_BACK)); + +#ifdef EXTRUDER_ALTFAN_DETECT + MENU_ITEM_TOGGLE_P(_N("ALTFAN det."), altfanOverride_get()?_T(MSG_OFF):_T(MSG_ON), altfanOverride_toggle); +#endif //EXTRUDER_ALTFAN_DETECT + + MENU_END(); +} diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 844c7c7d3..971c07b6b 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -257,4 +257,6 @@ enum class WizState : uint8_t void lcd_wizard(WizState state); +extern void lcd_experimental_menu(); + #endif //ULTRALCD_H From e2856ba4f579c51c6aa58e8614f71a498e021a6c Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 21 Jul 2020 12:52:04 +0300 Subject: [PATCH 47/77] Make the serial number available to the user --- Firmware/Marlin_main.cpp | 45 +++++++++++++++------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 8dbc0d840..49470ae12 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3286,37 +3286,26 @@ void gcode_M701() */ static void gcode_PRUSA_SN() { - if (farm_mode) { - selectedSerialPort = 0; - putchar(';'); - putchar('S'); - int numbersRead = 0; - ShortTimer timeout; - timeout.start(); + uint8_t selectedSerialPort_bak = selectedSerialPort; + selectedSerialPort = 0; + putchar(';'); + putchar('S'); + int numbersRead = 0; + ShortTimer timeout; + timeout.start(); - while (numbersRead < 19) { - while (MSerial.available() > 0) { - uint8_t serial_char = MSerial.read(); - selectedSerialPort = 1; - putchar(serial_char); - numbersRead++; - selectedSerialPort = 0; - } - if (timeout.expired(100u)) break; + while (numbersRead < 19) { + while (MSerial.available() > 0) { + uint8_t serial_char = MSerial.read(); + selectedSerialPort = selectedSerialPort_bak; + putchar(serial_char); + numbersRead++; + selectedSerialPort = 0; } - selectedSerialPort = 1; - putchar('\n'); -#if 0 - for (int b = 0; b < 3; b++) { - _tone(BEEPER, 110); - _delay(50); - _noTone(BEEPER); - _delay(50); - } -#endif - } else { - puts_P(_N("Not in farm mode.")); + if (timeout.expired(100u)) break; } + selectedSerialPort = selectedSerialPort_bak; + putchar('\n'); } //! Detection of faulty RAMBo 1.1b boards equipped with bigger capacitors //! at the TACH_1 pin, which causes bad detection of print fan speed. From ec6a20971e495ea4a97049434ac3e247c7391501 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 29 Jul 2020 11:23:24 +0300 Subject: [PATCH 48/77] Add experimental menu to HW_setup --- Firmware/Marlin_main.cpp | 8 -------- Firmware/eeprom.h | 5 ++++- Firmware/ultralcd.cpp | 32 ++++++++++++++++++++++++++++++++ Firmware/ultralcd.h | 1 + 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index f3528ca9e..2a261db2a 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -8569,14 +8569,6 @@ Sigma_Exit: } break; - /*! - ### M666 - Enter experimental menu - Only used by Prusa - */ - case 666: - menu_submenu(lcd_experimental_menu); - break; - /*! ### M999 - Restart after being stopped M999: Restart after being stopped by error @todo Usually doesn't work. Should be fixed or removed. Most of the time, if `Stopped` it set, the print fails and is unrecoverable. diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index bfc81d82d..ee7fa39ef 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -359,6 +359,8 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | ^ | ^ | ^ | 00h 0 | ^ | LCD backlight mode: __Dim__ | ^ | ^ | 0x0D30 3376 | uint16 | EEPROM_BACKLIGHT_TIMEOUT | 01 00 - ff ff | 0a 00h 65535 | LCD backlight timeout: __10__ seconds | LCD menu | D3 Ax0d30 C2 | 0x0D2C 3372 | float | EEPROM_UVLO_LA_K | ??? | ff ff ff ffh | Power panic saved Linear Advanced K value | ??? | D3 Ax0d2c C4 +| 0x0D2B 3371 | uint8 | EEPROM_ALTFAN_OVERRIDE | 0-1 | 00h | ALTFAN override | LCD menu | D3 Ax0d2b C1 +| 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | 0-1 | 00h | Experimental menu visibility | LCD menu | D3 Ax0d2a C1 | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code @@ -562,9 +564,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE); #define EEPROM_UVLO_LA_K (EEPROM_BACKLIGHT_TIMEOUT-4) // float #define EEPROM_ALTFAN_OVERRIDE (EEPROM_UVLO_LA_K-1) //uint8 +#define EEPROM_EXPERIMENTAL_VISIBILITY (EEPROM_ALTFAN_OVERRIDE-1) //uint8 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items. -#define EEPROM_LAST_ITEM EEPROM_ALTFAN_OVERRIDE +#define EEPROM_LAST_ITEM EEPROM_EXPERIMENTAL_VISIBILITY // !!!!! // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!! // !!!!! diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index bb1d2c716..24e331680 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2113,6 +2113,7 @@ static void lcd_support_menu() bool is_flash_air; // 1byte uint8_t ip[4]; // 4bytes char ip_str[3*4+3+1]; // 16bytes + uint8_t experimental_menu_visibility; } _menu_data_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); @@ -2126,6 +2127,14 @@ static void lcd_support_menu() sprintf_P(_md->ip_str, PSTR("%d.%d.%d.%d"), _md->ip[0], _md->ip[1], _md->ip[2], _md->ip[3]); + + _md->experimental_menu_visibility = eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY); + if (_md->experimental_menu_visibility == EEPROM_EMPTY_VALUE) + { + _md->experimental_menu_visibility = 0; + eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, _md->experimental_menu_visibility); + } + } else if (_md->is_flash_air && _md->ip[0] == 0 && _md->ip[1] == 0 && _md->ip[2] == 0 && _md->ip[3] == 0 && @@ -2210,6 +2219,12 @@ static void lcd_support_menu() MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=18 r=1 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN + if (_md->experimental_menu_visibility) + { + MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu); + } + + #ifdef DEBUG_BUILD MENU_ITEM_SUBMENU_P(PSTR("Debug"), lcd_menu_debug);////c=18 r=1 #endif /* DEBUG_BUILD */ @@ -8997,6 +9012,13 @@ void menu_lcd_longpress_func(void) lcd_quick_feedback(); return; } + if (menu_menu == lcd_hw_setup_menu) + { + // only toggle the experimental menu visibility flag + lcd_quick_feedback(); + lcd_experimental_toggle(); + return; + } // explicitely listed menus which are allowed to rise the move-z or live-adj-z functions // The lists are not the same for both functions, so first decide which function is to be performed @@ -9161,6 +9183,16 @@ void lcd_crash_detect_disable() } #endif +void lcd_experimental_toggle() +{ + uint8_t oldVal = eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY); + if (oldVal == EEPROM_EMPTY_VALUE) + oldVal = 0; + else + oldVal = !oldVal; + eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, oldVal); +} + void lcd_experimental_menu() { MENU_BEGIN(); diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 971c07b6b..95a3cec1a 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -257,6 +257,7 @@ enum class WizState : uint8_t void lcd_wizard(WizState state); +extern void lcd_experimental_toggle(); extern void lcd_experimental_menu(); #endif //ULTRALCD_H From 773c6997efcbb947c5eeca5c3daf387c83ef4743 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 29 Jul 2020 17:36:03 +0300 Subject: [PATCH 49/77] Add comments --- Firmware/ultralcd.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 24e331680..c2a3a8907 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2096,6 +2096,9 @@ static void lcd_preheat_menu() //! @code{.unparsed} //! | Voltages | MSG_MENU_VOLTAGES //! @endcode +//! +//! +//! | Experimental | c=18 r=1 //! //! //! If DEBUG_BUILD is defined @@ -2108,12 +2111,12 @@ static void lcd_preheat_menu() static void lcd_support_menu() { typedef struct - { // 22bytes total + { // 23bytes total int8_t status; // 1byte bool is_flash_air; // 1byte uint8_t ip[4]; // 4bytes char ip_str[3*4+3+1]; // 16bytes - uint8_t experimental_menu_visibility; + uint8_t experimental_menu_visibility; //1byte } _menu_data_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); From feafc5e5abdc1acee8683411c83c4595885332f5 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 27 Jul 2020 19:12:56 +0200 Subject: [PATCH 50/77] Alternative schedule for LA ticks Remove most of the original complexity from advance_spread. Instead of accumulating time to be scheduled, plan ahead of time each eISR tick using the next main interval + an accumulator (eISR_Err), which keeps everything much simpler. The distribution of the advance ticks is now using the real LA frequency, which leaves a bit more time between the last LA tick and the main stepper isr. We take advantage of the accumulator to force a LA tick right after the first main tick, which removes a +/- 1 scheduling error at higher step rates. When decompressing, we force 2 steps instead, so that the direction reversal happens immediately (first tick zeros esteps, second inverts the sign), removing another +/- 1 error at higher step rates. --- Firmware/stepper.cpp | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 949ffd587..8b21ee678 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -125,7 +125,7 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1}; static uint16_t main_Rate; static uint16_t eISR_Rate; - static uint16_t eISR_Err; + static uint32_t eISR_Err; static uint16_t current_adv_steps; static uint16_t target_adv_steps; @@ -733,38 +733,30 @@ FORCE_INLINE uint16_t fastdiv(uint16_t q, uint8_t d) FORCE_INLINE void advance_spread(uint16_t timer) { - if(eISR_Err > timer) + eISR_Err += timer; + + uint8_t ticks = 0; + while(eISR_Err >= current_block->advance_rate) + { + ++ticks; + eISR_Err -= current_block->advance_rate; + } + if(!ticks) { - // advance-step skipped - eISR_Err -= timer; eISR_Rate = timer; nextAdvanceISR = timer; return; } - // at least one step - uint8_t ticks = 1; - uint32_t block = current_block->advance_rate; - uint16_t max_t = timer - eISR_Err; - while (block < max_t) - { - ++ticks; - block += current_block->advance_rate; - } - if (block > timer) - eISR_Err += block - timer; - else - eISR_Err -= timer - block; - - if (ticks <= 4) - eISR_Rate = fastdiv(timer, ticks); + if (ticks <= 3) + eISR_Rate = fastdiv(timer, ticks + 1); else { // >4 ticks are still possible on slow moves - eISR_Rate = timer / ticks; + eISR_Rate = timer / (ticks + 1); } - nextAdvanceISR = eISR_Rate / 2; + nextAdvanceISR = eISR_Rate; } #endif @@ -876,11 +868,12 @@ FORCE_INLINE void isr() { } else { // reset error and iterations per loop for this phase - eISR_Err = current_block->advance_rate / 4; + eISR_Err = current_block->advance_rate; e_step_loops = current_block->advance_step_loops; if ((la_state & ADV_ACC_VARY) && e_extruding && (current_adv_steps > target_adv_steps)) { // LA could reverse the direction of extrusion in this phase + eISR_Err += current_block->advance_rate; LA_phase = 0; } } From 87bc5a78b6b787bc6415a49495aee40fa10f7175 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 1 Jun 2020 17:03:48 +0200 Subject: [PATCH 51/77] Remove bogus comment (BED_MINTEMP *is* implemented) --- Firmware/temperature.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 6e9b6985a..a7b9a3cdf 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1165,7 +1165,6 @@ void tp_init() #endif //MAXTEMP 2 #ifdef BED_MINTEMP - /* No bed MINTEMP error implemented?!? */ while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP bed_minttemp_raw += OVERSAMPLENR; @@ -1173,7 +1172,6 @@ void tp_init() bed_minttemp_raw -= OVERSAMPLENR; #endif } - #endif //BED_MINTEMP #ifdef BED_MAXTEMP while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { From 942fca5b660bada0dfdea9d7b2945c8a0ce6ebf0 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 7 Jun 2020 23:15:06 +0200 Subject: [PATCH 52/77] Remove useless assignment target_temperature_bed is already reset by disable_heaters() in Stop() --- Firmware/temperature.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index a7b9a3cdf..9ac97aec0 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -2002,7 +2002,6 @@ void check_max_temp() #else if (current_temperature_bed_raw >= bed_maxttemp_raw) { #endif - target_temperature_bed = 0; bed_max_temp_error(); } #endif From 65f25b0d7e4260d06073af2aeea3f39ba6cb6990 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 8 Jun 2020 02:16:00 +0200 Subject: [PATCH 53/77] Remove redundant disable_heater() calls in max/min_temp handling In max/min_temp handlers remove the redundant disable_heater() call. Handlers already need to call Stop(), which will disable all heaters as the first step. Fix comments in order to mention that all heaters get disabled. Use "MAX/MINTEMP BED" correctly in both the LCD and serial. --- Firmware/temperature.cpp | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 9ac97aec0..c9e63def3 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1426,19 +1426,16 @@ enum { LCDALERT_NONE = 0, LCDALERT_HEATERMINTEMP, LCDALERT_BEDMINTEMP, LCDALERT_ uint8_t last_alert_sent_to_lcd = LCDALERT_NONE; void max_temp_error(uint8_t e) { - disable_heater(); if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLN((int)e); - SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !"); + SERIAL_ERRORLNPGM(": Heaters switched off. MAXTEMP triggered !"); LCD_ALERTMESSAGEPGM("Err: MAXTEMP"); } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE Stop(); - - - #endif + SET_OUTPUT(FAN_PIN); SET_OUTPUT(BEEPER); WRITE(FAN_PIN, 1); @@ -1457,12 +1454,11 @@ void min_temp_error(uint8_t e) { return; #endif //if (current_temperature_ambient < MINTEMP_MINAMBIENT) return; - disable_heater(); static const char err[] PROGMEM = "Err: MINTEMP"; if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLN((int)e); - SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !"); + SERIAL_ERRORLNPGM(": Heaters switched off. MINTEMP triggered !"); lcd_setalertstatuspgm(err); last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP; } else if( last_alert_sent_to_lcd != LCDALERT_HEATERMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time) @@ -1482,32 +1478,24 @@ void min_temp_error(uint8_t e) { } void bed_max_temp_error(void) { -#if HEATER_BED_PIN > -1 - //WRITE(HEATER_BED_PIN, 0); -#endif if(IsStopped() == false) { SERIAL_ERROR_START; - SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !"); + SERIAL_ERRORLNPGM("Heaters switched off. MAXTEMP BED triggered !"); LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED"); } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE Stop(); #endif - } void bed_min_temp_error(void) { #ifdef DEBUG_DISABLE_MINTEMP return; -#endif -//if (current_temperature_ambient < MINTEMP_MINAMBIENT) return; -#if HEATER_BED_PIN > -1 - //WRITE(HEATER_BED_PIN, 0); #endif static const char err[] PROGMEM = "Err: MINTEMP BED"; if(IsStopped() == false) { SERIAL_ERROR_START; - SERIAL_ERRORLNPGM("Temperature heated bed switched off. MINTEMP triggered !"); + SERIAL_ERRORLNPGM("Heaters switched off. MINTEMP BED triggered !"); lcd_setalertstatuspgm(err); last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP; } else if( last_alert_sent_to_lcd != LCDALERT_BEDMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time) From 3336db7954a7204dbf5ae859515dcc11e9dcba18 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 8 Jun 2020 02:56:11 +0200 Subject: [PATCH 54/77] Add some important notes about thermistor ADC handling --- Firmware/temperature.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index c9e63def3..7f293f2ed 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -639,6 +639,7 @@ void manage_heater() return; // more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms) + // ADC values need to be converted before checking: converted values are later used in MINTEMP updateTemperaturesFromRawValues(); check_max_temp(); From a60ed81a3507814c60354534e4c4f4f9230d2aa6 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 8 Jun 2020 03:14:49 +0200 Subject: [PATCH 55/77] Implement MIN/MAX AMBIENT safety checks Take advantage of the NTC thermistor found on the Einsy as an additional safety measure, following the steps of the other MIN/MAXTEMP errors. Introduce two configurable params AMBIENT_MINTEMP and AMBIENT_MAXTEMP in the variant defines and set them for the MK3/MK3S to -30/+100 respectively. AMBIENT_MINTEMP is primarily intended to catch a defective board thermistor (to ensure MAXTEMP would be properly triggered) and thus the trigger temperature is set just above the sensing limit and well below the operating range. AMBIENT_MAXTEMP is set at 100C, which is instead 20C above the maximum recommended operating temperature of the Einsy. The NTC thermistor is located just above the main power connector on the bottom of the board, and could also help in detecting a faulty connection which can result in rapid overheating of the contacts. As for MAXTEMP, we cut power to the heaters, print fan and motors to reduce power draw. Resume is not possible except by resetting the printer, since the user is highly advised to inspect the board for problems before attempting to continue. --- Firmware/Configuration_adv.h | 4 + Firmware/temperature.cpp | 87 ++++++++++++++++++- Firmware/thermistortables.h | 2 + .../variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 + .../variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 2 + 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 5386c2815..f206c43c2 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -436,6 +436,10 @@ const unsigned int dropsegments=5; //everything with less than this number of st #undef BED_MINTEMP #undef BED_MAXTEMP #endif +#if TEMP_SENSOR_AMBIENT == 0 + #undef AMBIENT_MINTEMP + #undef AMBIENT_MAXTEMP +#endif #endif //__CONFIGURATION_ADV_H diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 7f293f2ed..75d52817e 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -180,6 +180,12 @@ static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; #ifdef BED_MAXTEMP static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP; #endif +#ifdef AMBIENT_MINTEMP +static int ambient_minttemp_raw = AMBIENT_RAW_LO_TEMP; +#endif +#ifdef AMBIENT_MAXTEMP +static int ambient_maxttemp_raw = AMBIENT_RAW_HI_TEMP; +#endif static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE ); static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN ); @@ -1183,6 +1189,25 @@ void tp_init() #endif } #endif //BED_MAXTEMP + +#ifdef AMBIENT_MINTEMP + while(analog2tempAmbient(ambient_minttemp_raw) < AMBIENT_MINTEMP) { +#if HEATER_AMBIENT_RAW_LO_TEMP < HEATER_AMBIENT_RAW_HI_TEMP + ambient_minttemp_raw += OVERSAMPLENR; +#else + ambient_minttemp_raw -= OVERSAMPLENR; +#endif + } +#endif //AMBIENT_MINTEMP +#ifdef AMBIENT_MAXTEMP + while(analog2tempAmbient(ambient_maxttemp_raw) > AMBIENT_MAXTEMP) { +#if HEATER_AMBIENT_RAW_LO_TEMP < HEATER_AMBIENT_RAW_HI_TEMP + ambient_maxttemp_raw -= OVERSAMPLENR; +#else + ambient_maxttemp_raw += OVERSAMPLENR; +#endif + } +#endif //AMBIENT_MAXTEMP } #if (defined (TEMP_RUNAWAY_BED_HYSTERESIS) && TEMP_RUNAWAY_BED_TIMEOUT > 0) || (defined (TEMP_RUNAWAY_EXTRUDER_HYSTERESIS) && TEMP_RUNAWAY_EXTRUDER_TIMEOUT > 0) @@ -1509,6 +1534,35 @@ void bed_min_temp_error(void) { #endif } + +#ifdef AMBIENT_THERMISTOR +void ambient_max_temp_error(void) { + if(IsStopped() == false) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Heaters switched off. MAXTEMP AMBIENT triggered !"); + LCD_ALERTMESSAGEPGM("Err: MAXTEMP AMBIENT"); + } +#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + Stop(); +#endif +} + +void ambient_min_temp_error(void) { +#ifdef DEBUG_DISABLE_MINTEMP + return; +#endif + if(IsStopped() == false) { + SERIAL_ERROR_START; + SERIAL_ERRORLNPGM("Heaters switched off. MINTEMP AMBIENT triggered !"); + LCD_ALERTMESSAGEPGM("Err: MINTEMP AMBIENT"); + } +#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE + Stop(); +#endif +} +#endif + + #ifdef HEATER_0_USES_MAX6675 #define MAX6675_HEAT_INTERVAL 250 long max6675_previous_millis = MAX6675_HEAT_INTERVAL; @@ -1994,7 +2048,16 @@ void check_max_temp() bed_max_temp_error(); } #endif - +//ambient +#if defined(AMBIENT_MAXTEMP) && (TEMP_SENSOR_AMBIENT != 0) +#if AMBIENT_RAW_LO_TEMP > AMBIENT_RAW_HI_TEMP + if (current_temperature_raw_ambient <= ambient_maxttemp_raw) { +#else + if (current_temperature_raw_ambient >= ambient_maxttemp_raw) { +#endif + ambient_max_temp_error(); + } +#endif } //! number of repeating the same state with consecutive step() calls //! used to slow down text switching @@ -2089,12 +2152,32 @@ void check_min_temp_bed() } } +#ifdef AMBIENT_MINTEMP +void check_min_temp_ambient() +{ +#if AMBIENT_RAW_LO_TEMP > AMBIENT_RAW_HI_TEMP + if (current_temperature_raw_ambient >= ambient_minttemp_raw) { +#else + if (current_temperature_raw_ambient <= ambient_minttemp_raw) { +#endif + ambient_min_temp_error(); + } +} +#endif + void check_min_temp() { static bool bCheckingOnHeater=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over heaterMintemp) static bool bCheckingOnBed=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over bedMintemp) #ifdef AMBIENT_THERMISTOR -if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type, so operator is ">" ;-) +#ifdef AMBIENT_MINTEMP +check_min_temp_ambient(); +#endif +#if AMBIENT_RAW_LO_TEMP > AMBIENT_RAW_HI_TEMP +if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type +#else +if(current_temperature_raw_ambient=<(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) +#endif { // ambient temperature is low #endif //AMBIENT_THERMISTOR // *** 'common' part of code for MK2.5 & MK3 diff --git a/Firmware/thermistortables.h b/Firmware/thermistortables.h index dc934ccfd..721c6b359 100644 --- a/Firmware/thermistortables.h +++ b/Firmware/thermistortables.h @@ -1213,6 +1213,8 @@ const short temptable_1047[][2] PROGMEM = { #endif #if (THERMISTORAMBIENT == 2000) //100k thermistor NTCG104LH104JT1 +# define AMBIENT_RAW_HI_TEMP 0 +# define AMBIENT_RAW_LO_TEMP 16383 const short temptable_2000[][2] PROGMEM = { // Source: https://product.tdk.com/info/en/catalog/datasheets/503021/tpd_ntc-thermistor_ntcg_en.pdf // Calculated using 4.7kohm pullup, voltage divider math, and manufacturer provided temp/resistance diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index b135d8d13..04b4c5266 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -296,6 +296,7 @@ #endif #define DETECT_SUPERPINDA #define PINDA_MINTEMP BED_MINTEMP +#define AMBIENT_MINTEMP -30 // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) @@ -306,6 +307,7 @@ #define HEATER_1_MAXTEMP 305 #define HEATER_2_MAXTEMP 305 #define BED_MAXTEMP 125 +#define AMBIENT_MAXTEMP 100 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) // Define PID constants for extruder with PT100 diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index e618c54ef..c869ec517 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -298,6 +298,7 @@ #endif #define DETECT_SUPERPINDA #define PINDA_MINTEMP BED_MINTEMP +#define AMBIENT_MINTEMP -30 // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) @@ -308,6 +309,7 @@ #define HEATER_1_MAXTEMP 305 #define HEATER_2_MAXTEMP 305 #define BED_MAXTEMP 125 +#define AMBIENT_MAXTEMP 100 #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) // Define PID constants for extruder with PT100 From e1c79c342d75191ea759bfbecba00d9a907df7e0 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Thu, 30 Jul 2020 17:14:13 +0200 Subject: [PATCH 56/77] Re-introduce redundant disable_heaters() calls Partially revert 285b505c73a54e9af01816e3a614de73ad181851 so that we ensure heaters are disabled ASAP in case of potential bugs in the max_*_error functions. --- Firmware/temperature.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 75d52817e..f9fa48fff 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1452,6 +1452,7 @@ enum { LCDALERT_NONE = 0, LCDALERT_HEATERMINTEMP, LCDALERT_BEDMINTEMP, LCDALERT_ uint8_t last_alert_sent_to_lcd = LCDALERT_NONE; void max_temp_error(uint8_t e) { + disable_heater(); if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLN((int)e); @@ -1479,6 +1480,7 @@ void min_temp_error(uint8_t e) { #ifdef DEBUG_DISABLE_MINTEMP return; #endif + disable_heater(); //if (current_temperature_ambient < MINTEMP_MINAMBIENT) return; static const char err[] PROGMEM = "Err: MINTEMP"; if(IsStopped() == false) { @@ -1504,6 +1506,7 @@ void min_temp_error(uint8_t e) { } void bed_max_temp_error(void) { + disable_heater(); if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("Heaters switched off. MAXTEMP BED triggered !"); @@ -1518,7 +1521,8 @@ void bed_min_temp_error(void) { #ifdef DEBUG_DISABLE_MINTEMP return; #endif - static const char err[] PROGMEM = "Err: MINTEMP BED"; + disable_heater(); + static const char err[] PROGMEM = "MINTEMP BED"; if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("Heaters switched off. MINTEMP BED triggered !"); @@ -1537,6 +1541,7 @@ void bed_min_temp_error(void) { #ifdef AMBIENT_THERMISTOR void ambient_max_temp_error(void) { + disable_heater(); if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("Heaters switched off. MAXTEMP AMBIENT triggered !"); @@ -1551,6 +1556,7 @@ void ambient_min_temp_error(void) { #ifdef DEBUG_DISABLE_MINTEMP return; #endif + disable_heater(); if(IsStopped() == false) { SERIAL_ERROR_START; SERIAL_ERRORLNPGM("Heaters switched off. MINTEMP AMBIENT triggered !"); From a8ce9358e55f509f7efde3905261fa702d0cbc5a Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Fri, 31 Jul 2020 20:19:51 +0200 Subject: [PATCH 57/77] Avoid redundant temperature error strings Factor-out MIN/MAXTEMP [BED/AMB] out of the error message, which is now built at runtime instead. Introduce two missing ultralcd functions lcd_setalertstatus and lcd_updatestatus to handle regular strings. 246272 -> 246084 = 188 bytes saved --- Firmware/temperature.cpp | 64 +++++++++++++++++++++++++--------------- Firmware/ultralcd.cpp | 22 ++++++++++++-- Firmware/ultralcd.h | 2 ++ 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index f9fa48fff..657b23fbc 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1451,13 +1451,42 @@ enum { LCDALERT_NONE = 0, LCDALERT_HEATERMINTEMP, LCDALERT_BEDMINTEMP, LCDALERT_ //! to prevent flicker and improve speed uint8_t last_alert_sent_to_lcd = LCDALERT_NONE; + +//! update the current temperature error message +//! @param type short error abbreviation (PROGMEM) +//! @param func optional lcd update function (lcd_setalertstatus when first setting the error) +void temp_update_messagepgm(const char* PROGMEM type, void (*func)(const char*) = lcd_updatestatus) +{ + char msg[LCD_WIDTH]; + strcpy_P(msg, PSTR("Err: ")); + strcat_P(msg, type); + (*func)(msg); +} + +//! signal a temperature error on both the lcd and serial +//! @param type short error abbreviation (PROGMEM) +//! @param e optional extruder index for hotend errors +void temp_error_messagepgm(const char* PROGMEM type, uint8_t e = EXTRUDERS) +{ + temp_update_messagepgm(type, lcd_setalertstatus); + + SERIAL_ERROR_START; + + if(e != EXTRUDERS) { + SERIAL_ERROR((int)e); + SERIAL_ERRORPGM(": "); + } + + SERIAL_ERRORPGM("Heaters switched off. "); + SERIAL_ERRORRPGM(type); + SERIAL_ERRORLNPGM(" triggered!"); +} + + void max_temp_error(uint8_t e) { disable_heater(); if(IsStopped() == false) { - SERIAL_ERROR_START; - SERIAL_ERRORLN((int)e); - SERIAL_ERRORLNPGM(": Heaters switched off. MAXTEMP triggered !"); - LCD_ALERTMESSAGEPGM("Err: MAXTEMP"); + temp_error_messagepgm(PSTR("MAXTEMP"), e); } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE Stop(); @@ -1482,16 +1511,13 @@ void min_temp_error(uint8_t e) { #endif disable_heater(); //if (current_temperature_ambient < MINTEMP_MINAMBIENT) return; - static const char err[] PROGMEM = "Err: MINTEMP"; + static const char err[] PROGMEM = "MINTEMP"; if(IsStopped() == false) { - SERIAL_ERROR_START; - SERIAL_ERRORLN((int)e); - SERIAL_ERRORLNPGM(": Heaters switched off. MINTEMP triggered !"); - lcd_setalertstatuspgm(err); + temp_error_messagepgm(err, e); last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP; } else if( last_alert_sent_to_lcd != LCDALERT_HEATERMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time) // we are already stopped due to some error, only update the status message without flickering - lcd_updatestatuspgm(err); + temp_update_messagepgm(err); last_alert_sent_to_lcd = LCDALERT_HEATERMINTEMP; } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE @@ -1508,9 +1534,7 @@ void min_temp_error(uint8_t e) { void bed_max_temp_error(void) { disable_heater(); if(IsStopped() == false) { - SERIAL_ERROR_START; - SERIAL_ERRORLNPGM("Heaters switched off. MAXTEMP BED triggered !"); - LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED"); + temp_error_messagepgm(PSTR("MAXTEMP BED")); } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE Stop(); @@ -1524,13 +1548,11 @@ void bed_min_temp_error(void) { disable_heater(); static const char err[] PROGMEM = "MINTEMP BED"; if(IsStopped() == false) { - SERIAL_ERROR_START; - SERIAL_ERRORLNPGM("Heaters switched off. MINTEMP BED triggered !"); - lcd_setalertstatuspgm(err); + temp_error_messagepgm(err); last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP; } else if( last_alert_sent_to_lcd != LCDALERT_BEDMINTEMP ){ // only update, if the lcd message is to be changed (i.e. not the same as last time) // we are already stopped due to some error, only update the status message without flickering - lcd_updatestatuspgm(err); + temp_update_messagepgm(err); last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP; } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE @@ -1543,9 +1565,7 @@ void bed_min_temp_error(void) { void ambient_max_temp_error(void) { disable_heater(); if(IsStopped() == false) { - SERIAL_ERROR_START; - SERIAL_ERRORLNPGM("Heaters switched off. MAXTEMP AMBIENT triggered !"); - LCD_ALERTMESSAGEPGM("Err: MAXTEMP AMBIENT"); + temp_error_messagepgm(PSTR("MAXTEMP AMB")); } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE Stop(); @@ -1558,9 +1578,7 @@ void ambient_min_temp_error(void) { #endif disable_heater(); if(IsStopped() == false) { - SERIAL_ERROR_START; - SERIAL_ERRORLNPGM("Heaters switched off. MINTEMP AMBIENT triggered !"); - LCD_ALERTMESSAGEPGM("Err: MINTEMP AMBIENT"); + temp_error_messagepgm(PSTR("MINTEMP AMB")); } #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE Stop(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 87266914f..a08f8a365 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -8951,13 +8951,14 @@ void lcd_finishstatus() { lcd_draw_update = 2; } + void lcd_setstatus(const char* message) { if (lcd_status_message_level > 0) return; - strncpy(lcd_status_message, message, LCD_WIDTH); - lcd_finishstatus(); + lcd_updatestatus(message); } + void lcd_updatestatuspgm(const char *message){ strncpy_P(lcd_status_message, message, LCD_WIDTH); lcd_status_message[LCD_WIDTH] = 0; @@ -8972,12 +8973,29 @@ void lcd_setstatuspgm(const char* message) return; lcd_updatestatuspgm(message); } + +void lcd_updatestatus(const char *message){ + strncpy(lcd_status_message, message, LCD_WIDTH); + lcd_status_message[LCD_WIDTH] = 0; + lcd_finishstatus(); + // hack lcd_draw_update to 1, i.e. without clear + lcd_draw_update = 1; +} + void lcd_setalertstatuspgm(const char* message) { lcd_setstatuspgm(message); lcd_status_message_level = 1; lcd_return_to_status(); } + +void lcd_setalertstatus(const char* message) +{ + lcd_setstatus(message); + lcd_status_message_level = 1; + lcd_return_to_status(); +} + void lcd_reset_alert_level() { lcd_status_message_level = 0; diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 844c7c7d3..a5f07673f 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -23,9 +23,11 @@ void lcd_setstatuspgm(const char* message); //! - always returns the display to the main status screen //! - always makes lcd_reset (which is slow and causes flicker) //! - does not update the message if there is already one (i.e. lcd_status_message_level > 0) +void lcd_setalertstatus(const char* message); void lcd_setalertstatuspgm(const char* message); //! only update the alert message on the main status screen //! has no sideeffects, may be called multiple times +void lcd_updatestatus(const char *message); void lcd_updatestatuspgm(const char *message); void lcd_reset_alert_level(); From ae0d8082de01fe38dee9ebf3b7343c1e4a1a93a2 Mon Sep 17 00:00:00 2001 From: Enno Boland Date: Mon, 3 Aug 2020 09:00:36 +0200 Subject: [PATCH 58/77] Update README.md Fix small typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb1c79689..7aa50c4aa 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ Example: `ninja` -## Runing +## Running `./tests` # 4. Documentation From 12be141188c3511e13978d366164c3afcb0c04b8 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Sat, 6 Jun 2020 19:32:48 +0300 Subject: [PATCH 59/77] Fix high speed deceleration --- Firmware/planner.h | 9 ++++----- Firmware/stepper.cpp | 13 ++++++------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Firmware/planner.h b/Firmware/planner.h index 2096111ea..5978793be 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -77,8 +77,8 @@ typedef struct { unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) unsigned char active_extruder; // Selects the active extruder // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller. - long accelerate_until; // The index of the step event on which to stop acceleration - long decelerate_after; // The index of the step event on which to start decelerating + uint32_t accelerate_until; // The index of the step event on which to stop acceleration + uint32_t decelerate_after; // The index of the step event on which to start decelerating // Fields used by the motion planner to manage acceleration // float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis @@ -100,13 +100,12 @@ typedef struct { // Settings for the trapezoid generator (runs inside an interrupt handler). // Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts. - //FIXME nominal_rate, initial_rate and final_rate are limited to uint16_t by MultiU24X24toH16 in the stepper interrupt anyway! unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec unsigned long initial_rate; // The jerk-adjusted step rate at start of block unsigned long final_rate; // The minimal rate at exit unsigned long acceleration_st; // acceleration steps/sec^2 - //FIXME does it have to be unsigned long? Probably uint8_t would be just fine. - unsigned long fan_speed; + //FIXME does it have to be int? Probably uint8_t would be just fine. Need to change in other places as well + int fan_speed; volatile char busy; diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index de250ec97..5f72b5bd2 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -71,8 +71,7 @@ static dda_isteps_t counter_z, counter_e; volatile dda_usteps_t step_events_completed; // The number of step events executed in the current block -static int32_t acceleration_time, deceleration_time; -//static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; +static uint32_t acceleration_time, deceleration_time; static uint16_t acc_step_rate; // needed for deccelaration start point static uint8_t step_loops; static uint16_t OCR1A_nominal; @@ -799,7 +798,7 @@ FORCE_INLINE void isr() { // 25.12us for acceleration / deceleration. { //WRITE_NC(LOGIC_ANALYZER_CH1, true); - if (step_events_completed.wide <= (unsigned long int)current_block->accelerate_until) { + if (step_events_completed.wide <= current_block->accelerate_until) { // v = t * a -> acc_step_rate = acceleration_time * current_block->acceleration_rate MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate); acc_step_rate += uint16_t(current_block->initial_rate); @@ -817,12 +816,12 @@ FORCE_INLINE void isr() { } #endif } - else if (step_events_completed.wide > (unsigned long int)current_block->decelerate_after) { + else if (step_events_completed.wide > current_block->decelerate_after) { uint16_t step_rate; MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate); step_rate = acc_step_rate - step_rate; // Decelerate from aceleration end point. - if ((step_rate & 0x8000) || step_rate < uint16_t(current_block->final_rate)) { - // Result is negative or too small. + if (step_rate < uint16_t(current_block->final_rate)) { + // Result is too small. step_rate = uint16_t(current_block->final_rate); } // Step_rate to timer interval. @@ -832,7 +831,7 @@ FORCE_INLINE void isr() { #ifdef LIN_ADVANCE if (current_block->use_advance_lead) { - if (step_events_completed.wide <= (unsigned long int)current_block->decelerate_after + step_loops) { + if (step_events_completed.wide <= current_block->decelerate_after + step_loops) { target_adv_steps = current_block->final_adv_steps; la_state = ADV_INIT | ADV_ACC_VARY; } From 4654283f542f661a872c9d6d4fd6612a4db0e9f8 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 3 Aug 2020 18:16:20 +0200 Subject: [PATCH 60/77] Restore indentation --- Firmware/planner.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/planner.h b/Firmware/planner.h index 5978793be..425ed9b54 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -77,8 +77,8 @@ typedef struct { unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) unsigned char active_extruder; // Selects the active extruder // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller. - uint32_t accelerate_until; // The index of the step event on which to stop acceleration - uint32_t decelerate_after; // The index of the step event on which to start decelerating + uint32_t accelerate_until; // The index of the step event on which to stop acceleration + uint32_t decelerate_after; // The index of the step event on which to start decelerating // Fields used by the motion planner to manage acceleration // float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis From 8108d50b59fc13c62b72cba065193928c5b67f33 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 3 Aug 2020 18:42:40 +0200 Subject: [PATCH 61/77] Reintroduce/fix check for step_rate underflow during deceleration Check for negative results and results under the final_rate --- Firmware/stepper.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 5f72b5bd2..848cd3c66 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -819,11 +819,18 @@ FORCE_INLINE void isr() { else if (step_events_completed.wide > current_block->decelerate_after) { uint16_t step_rate; MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate); - step_rate = acc_step_rate - step_rate; // Decelerate from aceleration end point. - if (step_rate < uint16_t(current_block->final_rate)) { - // Result is too small. - step_rate = uint16_t(current_block->final_rate); + + if (step_rate > acc_step_rate) { // Check step_rate stays positive + step_rate = uint16_t(current_block->final_rate); } + else { + step_rate = acc_step_rate - step_rate; // Decelerate from acceleration end point. + + // lower limit + if (step_rate < current_block->final_rate) + step_rate = uint16_t(current_block->final_rate); + } + // Step_rate to timer interval. uint16_t timer = calc_timer(step_rate, step_loops); _NEXT_ISR(timer); From aebaca5cdc35c129c9e41acb3a8f08ef483ba3f8 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 3 Aug 2020 18:48:53 +0200 Subject: [PATCH 62/77] Correct comments regarding acceleration ramp Backport fixes from upstream Marlin --- Firmware/stepper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 848cd3c66..ef57ec0db 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -233,7 +233,7 @@ void invert_z_endstop(bool endstop_invert) // The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates // first block->accelerate_until step_events_completed, then keeps going at constant speed until // step_events_completed reaches block->decelerate_after after which it decelerates until the trapezoid generator is reset. -// The slope of acceleration is calculated with the leib ramp alghorithm. +// The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far. // "The Stepper Driver Interrupt" - This timer interrupt is the workhorse. // It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. From 30a806608fca111cab82f7ac07c2804abf8f8225 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 3 Aug 2020 19:01:38 +0200 Subject: [PATCH 63/77] Also convert acceleration_rate to uint32_t acceleration_rate is also unsigned --- Firmware/planner.cpp | 2 +- Firmware/planner.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index c0f465c2a..9ff291a0c 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -1132,7 +1132,7 @@ Having the real displacement of the head, we can calculate the total movement le block->acceleration_st = (block->acceleration_st + (bresenham_oversample >> 1)) / bresenham_oversample; #endif - block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); + block->acceleration_rate = ((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); #ifdef LIN_ADVANCE if (block->use_advance_lead) { diff --git a/Firmware/planner.h b/Firmware/planner.h index 425ed9b54..34899cac4 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -73,7 +73,7 @@ typedef struct { // steps_x.y,z, step_event_count, acceleration_rate, direction_bits and active_extruder are set by plan_buffer_line(). dda_isteps_t steps_x, steps_y, steps_z, steps_e; // Step count along each axis dda_usteps_t step_event_count; // The number of step events required to complete this block - long acceleration_rate; // The acceleration rate used for acceleration calculation + uint32_t acceleration_rate; // The acceleration rate used for acceleration calculation unsigned char direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h) unsigned char active_extruder; // Selects the active extruder // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller. From b8e8f182ca6ffba4b565e6b600df212381c808c5 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 3 Aug 2020 19:03:13 +0200 Subject: [PATCH 64/77] Add reference C implementations for MultiU16X8toH16/MultiU24X24toH16 Higher step counts might still overflow the ASM MultiU24X24toH16. https://github.com/MarlinFirmware/Marlin/commit/e4595fa24a2051e95df8a4ed044d2c94cca18e63 --- Firmware/speed_lookuptable.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Firmware/speed_lookuptable.h b/Firmware/speed_lookuptable.h index 2748dd71a..21c6c767f 100644 --- a/Firmware/speed_lookuptable.h +++ b/Firmware/speed_lookuptable.h @@ -80,15 +80,21 @@ asm volatile ( \ #else //_NO_ASM -// NOTE: currently not implemented -void MultiU16X8toH16(unsigned short& intRes, unsigned char& charIn1, unsigned short& intIn2); -void MultiU24X24toH16(uint16_t& intRes, int32_t& longIn1, long& longIn2); +static inline void MultiU16X8toH16(uint16_t& intRes, uint8_t& charIn1, uint16_t& intIn2) +{ + intRes = ((uint32_t)charIn1 * (uint32_t)intIn2) >> 16; +} + +static inline void MultiU24X24toH16(uint16_t& intRes, uint32_t& longIn1, uint32_t& longIn2) +{ + intRes = ((uint64_t)longIn1 * (uint64_t)longIn2) >> 24; +} #endif //_NO_ASM FORCE_INLINE unsigned short calc_timer(uint16_t step_rate, uint8_t& step_loops) { - unsigned short timer; + uint16_t timer; if(step_rate > MAX_STEP_FREQUENCY) step_rate = MAX_STEP_FREQUENCY; if(step_rate > 20000) { // If steprate > 20kHz >> step 4 times @@ -108,7 +114,7 @@ FORCE_INLINE unsigned short calc_timer(uint16_t step_rate, uint8_t& step_loops) if(step_rate >= (8*256)){ // higher step rate unsigned short table_address = (unsigned short)&speed_lookuptable_fast[(unsigned char)(step_rate>>8)][0]; unsigned char tmp_step_rate = (step_rate & 0x00ff); - unsigned short gain = (unsigned short)pgm_read_word_near(table_address+2); + uint16_t gain = (uint16_t)pgm_read_word_near(table_address+2); MultiU16X8toH16(timer, tmp_step_rate, gain); timer = (unsigned short)pgm_read_word_near(table_address) - timer; } From e0bf92cd4e7b98fe0628c8584a8f263aadf0405b Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 4 Aug 2020 09:54:57 +0300 Subject: [PATCH 65/77] Change bool literal to int --- Firmware/temperature.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 084ed2720..854a884aa 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1377,7 +1377,7 @@ void temp_runaway_stop(bool isPreheat, bool isBed) SERIAL_ERROR_START; isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HOTEND)"); #ifdef EXTRUDER_ALTFAN_DETECT - altfanOverride = true; //full speed + altfanOverride = 1; //full speed #endif //EXTRUDER_ALTFAN_DETECT setExtruderAutoFanState(3); SET_OUTPUT(FAN_PIN); @@ -1467,7 +1467,7 @@ void max_temp_error(uint8_t e) { WRITE(FAN_PIN, 1); WRITE(BEEPER, 1); #ifdef EXTRUDER_ALTFAN_DETECT - altfanOverride = true; //full speed + altfanOverride = 1; //full speed #endif //EXTRUDER_ALTFAN_DETECT setExtruderAutoFanState(3); // fanSpeed will consumed by the check_axes_activity() routine. From 654a3a0d7942c03107f293fde033ef502d9601d4 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 4 Aug 2020 10:43:30 +0300 Subject: [PATCH 66/77] Other requested changes --- Firmware/temperature.cpp | 32 ++++++++++++++++++-------------- Firmware/ultralcd.cpp | 2 +- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 854a884aa..f08c682aa 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -152,8 +152,11 @@ uint8_t fanSpeedBckp = 255; bool fan_measuring = false; uint8_t fanState = 0; #ifdef EXTRUDER_ALTFAN_DETECT - bool extruderFanIsAltfan = false; //set to Noctua - uint8_t altfanOverride = 0; + struct + { + uint8_t isAltfan : 1; + uint8_t altfanOverride : 1; + } altfanStatus; #endif //EXTRUDER_ALTFAN_DETECT #endif @@ -226,12 +229,13 @@ bool extruder_altfan_detect() SET_INPUT(TACH_0); - altfanOverride = eeprom_read_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE); - if (altfanOverride == EEPROM_EMPTY_VALUE) + uint8_t overrideVal = eeprom_read_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE); + if (overrideVal == EEPROM_EMPTY_VALUE) { - altfanOverride = 0; - eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, altfanOverride); + overrideVal = 0; + eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, overrideVal); } + altfanStatus.altfanOverride = overrideVal; CRITICAL_SECTION_START; EICRB &= ~(1 << ISC61); @@ -246,20 +250,20 @@ bool extruder_altfan_detect() EIMSK &= ~(1 << INT6); countFanSpeed(); - extruderFanIsAltfan = fan_speed[0] > 100; + altfanStatus.isAltfan = fan_speed[0] > 100; setExtruderAutoFanState(1); - return extruderFanIsAltfan; + return altfanStatus.isAltfan; } void altfanOverride_toggle() { - altfanOverride = !altfanOverride; - eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, altfanOverride); + altfanStatus.altfanOverride = !altfanStatus.altfanOverride; + eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, altfanStatus.altfanOverride); } bool altfanOverride_get() { - return altfanOverride; + return altfanStatus.altfanOverride; } #endif //EXTRUDER_ALTFAN_DETECT @@ -515,7 +519,7 @@ void setExtruderAutoFanState(uint8_t state) if (fanState & 0x01) { #ifdef EXTRUDER_ALTFAN_DETECT - if (extruderFanIsAltfan && !altfanOverride) newFanSpeed = EXTRUDER_ALTFAN_SPEED_SILENT; + if (altfanStatus.isAltfan && !altfanStatus.altfanOverride) newFanSpeed = EXTRUDER_ALTFAN_SPEED_SILENT; else newFanSpeed = EXTRUDER_AUTO_FAN_SPEED; #else //EXTRUDER_ALTFAN_DETECT newFanSpeed = EXTRUDER_AUTO_FAN_SPEED; @@ -1377,7 +1381,7 @@ void temp_runaway_stop(bool isPreheat, bool isBed) SERIAL_ERROR_START; isBed ? SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HEATBED)") : SERIAL_ERRORLNPGM(" THERMAL RUNAWAY ( PREHEAT HOTEND)"); #ifdef EXTRUDER_ALTFAN_DETECT - altfanOverride = 1; //full speed + altfanStatus.altfanOverride = 1; //full speed #endif //EXTRUDER_ALTFAN_DETECT setExtruderAutoFanState(3); SET_OUTPUT(FAN_PIN); @@ -1467,7 +1471,7 @@ void max_temp_error(uint8_t e) { WRITE(FAN_PIN, 1); WRITE(BEEPER, 1); #ifdef EXTRUDER_ALTFAN_DETECT - altfanOverride = 1; //full speed + altfanStatus.altfanOverride = 1; //full speed #endif //EXTRUDER_ALTFAN_DETECT setExtruderAutoFanState(3); // fanSpeed will consumed by the check_axes_activity() routine. diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index c2a3a8907..3207389d9 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2116,7 +2116,7 @@ static void lcd_support_menu() bool is_flash_air; // 1byte uint8_t ip[4]; // 4bytes char ip_str[3*4+3+1]; // 16bytes - uint8_t experimental_menu_visibility; //1byte + uint8_t experimental_menu_visibility; // 1byte } _menu_data_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); From a2c7dcbbf8484450614abf0c59c63b5494fa0442 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Tue, 4 Aug 2020 13:14:35 +0200 Subject: [PATCH 67/77] Fix indentation --- Firmware/temperature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 657b23fbc..2d09f8e0f 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1546,7 +1546,7 @@ void bed_min_temp_error(void) { return; #endif disable_heater(); - static const char err[] PROGMEM = "MINTEMP BED"; + static const char err[] PROGMEM = "MINTEMP BED"; if(IsStopped() == false) { temp_error_messagepgm(err); last_alert_sent_to_lcd = LCDALERT_BEDMINTEMP; From b3af08d94ad77a2ae8912149f2875f7a136b452a Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Wed, 5 Aug 2020 17:04:11 +0200 Subject: [PATCH 68/77] Fix stack smashing in temperature/fsensor ISR The temperature and fsensor ISR re-enable interrupts while executing. However, we still need to protect the epilogue of the ISR so that the saved return address is not altered while returning. We hoist the body of the function out of the isr in both cases for clarity (and to avoid a stray return bypassing the lock/cli), so that the re-entrant portion is clearly indicated. This should fix the "STATIC MEMORY OVERWRITTEN" error messages randomly happening when stepping at high frequency (where either isr is preempted more frequently). --- Firmware/fsensor.cpp | 40 +++++++++++++++++++++++----------------- Firmware/temperature.cpp | 30 ++++++++++++++++++------------ 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp index 2753ede00..7908c5dbc 100755 --- a/Firmware/fsensor.cpp +++ b/Firmware/fsensor.cpp @@ -478,22 +478,8 @@ bool fsensor_oq_result(void) } #endif //FSENSOR_QUALITY -ISR(FSENSOR_INT_PIN_VECT) +FORCE_INLINE static void fsensor_isr(int st_cnt) { - if (mmu_enabled || ir_sensor_detected) return; - if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return; - fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG; - - // prevent isr re-entry - static bool _lock = false; - if (_lock) return; - _lock = true; - - // fetch fsensor_st_cnt atomically - int st_cnt = fsensor_st_cnt; - fsensor_st_cnt = 0; - sei(); - uint8_t old_err_cnt = fsensor_err_cnt; uint8_t pat9125_res = fsensor_oq_meassure?pat9125_update():pat9125_update_y(); if (!pat9125_res) @@ -578,8 +564,28 @@ ISR(FSENSOR_INT_PIN_VECT) #endif //DEBUG_FSENSOR_LOG pat9125_y = 0; - _lock = false; - return; +} + +ISR(FSENSOR_INT_PIN_VECT) +{ + if (mmu_enabled || ir_sensor_detected) return; + if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return; + fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG; + + // prevent isr re-entry + static bool _lock = false; + if (!_lock) + { + // fetch fsensor_st_cnt atomically + int st_cnt = fsensor_st_cnt; + fsensor_st_cnt = 0; + + _lock = true; + sei(); + fsensor_isr(st_cnt); + cli(); + _lock = false; + } } void fsensor_setup_interrupt(void) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 6e9b6985a..d98a3c5ee 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -1606,18 +1606,8 @@ void adc_ready(void) //callback from adc when sampling finished } // extern "C" -// Timer2 (originaly timer0) is shared with millies -#ifdef SYSTEM_TIMER_2 -ISR(TIMER2_COMPB_vect) -#else //SYSTEM_TIMER_2 -ISR(TIMER0_COMPB_vect) -#endif //SYSTEM_TIMER_2 +FORCE_INLINE static void temperature_isr() { - static bool _lock = false; - if (_lock) return; - _lock = true; - asm("sei"); - if (!temp_meas_ready) adc_cycle(); lcd_buttons_update(); @@ -1983,8 +1973,24 @@ ISR(TIMER0_COMPB_vect) #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1)) check_fans(); #endif //(defined(TACH_0)) +} - _lock = false; +// Timer2 (originaly timer0) is shared with millies +#ifdef SYSTEM_TIMER_2 +ISR(TIMER2_COMPB_vect) +#else //SYSTEM_TIMER_2 +ISR(TIMER0_COMPB_vect) +#endif //SYSTEM_TIMER_2 +{ + static bool _lock = false; + if (!_lock) + { + _lock = true; + sei(); + temperature_isr(); + cli(); + _lock = false; + } } void check_max_temp() From f1a8657093f563be694c6fd832da577c7d51cb00 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Thu, 6 Aug 2020 12:20:38 +0300 Subject: [PATCH 69/77] Minor documentation fixes Add even more comments a --- Firmware/eeprom.h | 4 ++-- Firmware/ultralcd.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index ee7fa39ef..b8bec384c 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -359,8 +359,8 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | ^ | ^ | ^ | 00h 0 | ^ | LCD backlight mode: __Dim__ | ^ | ^ | 0x0D30 3376 | uint16 | EEPROM_BACKLIGHT_TIMEOUT | 01 00 - ff ff | 0a 00h 65535 | LCD backlight timeout: __10__ seconds | LCD menu | D3 Ax0d30 C2 | 0x0D2C 3372 | float | EEPROM_UVLO_LA_K | ??? | ff ff ff ffh | Power panic saved Linear Advanced K value | ??? | D3 Ax0d2c C4 -| 0x0D2B 3371 | uint8 | EEPROM_ALTFAN_OVERRIDE | 0-1 | 00h | ALTFAN override | LCD menu | D3 Ax0d2b C1 -| 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | 0-1 | 00h | Experimental menu visibility | LCD menu | D3 Ax0d2a C1 +| 0x0D2B 3371 | uint8 | EEPROM_ALTFAN_OVERRIDE | 0-1 | 00h 0 | ALTFAN override | LCD menu | D3 Ax0d2b C1 +| 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | 0-1 | 00h 0 | Experimental menu visibility | LCD menu | D3 Ax0d2a C1 | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 3207389d9..683786980 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2098,7 +2098,7 @@ static void lcd_preheat_menu() //! @endcode //! //! -//! | Experimental | c=18 r=1 +//! | Experimental | c=18 //! //! //! If DEBUG_BUILD is defined @@ -2224,7 +2224,7 @@ static void lcd_support_menu() if (_md->experimental_menu_visibility) { - MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu); + MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu);////MSG_MENU_EXPERIMENTAL c=18 } @@ -9202,7 +9202,7 @@ void lcd_experimental_menu() MENU_ITEM_BACK_P(_T(MSG_BACK)); #ifdef EXTRUDER_ALTFAN_DETECT - MENU_ITEM_TOGGLE_P(_N("ALTFAN det."), altfanOverride_get()?_T(MSG_OFF):_T(MSG_ON), altfanOverride_toggle); + MENU_ITEM_TOGGLE_P(_N("ALTFAN det."), altfanOverride_get()?_T(MSG_OFF):_T(MSG_ON), altfanOverride_toggle);////MSG_MENU_ALTFAN c=18 #endif //EXTRUDER_ALTFAN_DETECT MENU_END(); From 96435ad0849cb44a632afb64f69de945e2c4e71e Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 12 Aug 2020 08:48:12 +0300 Subject: [PATCH 70/77] Move experimental menu to HW setup --- Firmware/ultralcd.cpp | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 683786980..c4b287368 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2096,9 +2096,6 @@ static void lcd_preheat_menu() //! @code{.unparsed} //! | Voltages | MSG_MENU_VOLTAGES //! @endcode -//! -//! -//! | Experimental | c=18 //! //! //! If DEBUG_BUILD is defined @@ -2111,12 +2108,11 @@ static void lcd_preheat_menu() static void lcd_support_menu() { typedef struct - { // 23bytes total + { // 22bytes total int8_t status; // 1byte bool is_flash_air; // 1byte uint8_t ip[4]; // 4bytes char ip_str[3*4+3+1]; // 16bytes - uint8_t experimental_menu_visibility; // 1byte } _menu_data_t; static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); @@ -2131,13 +2127,6 @@ static void lcd_support_menu() _md->ip[0], _md->ip[1], _md->ip[2], _md->ip[3]); - _md->experimental_menu_visibility = eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY); - if (_md->experimental_menu_visibility == EEPROM_EMPTY_VALUE) - { - _md->experimental_menu_visibility = 0; - eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, _md->experimental_menu_visibility); - } - } else if (_md->is_flash_air && _md->ip[0] == 0 && _md->ip[1] == 0 && _md->ip[2] == 0 && _md->ip[3] == 0 && @@ -2222,11 +2211,6 @@ static void lcd_support_menu() MENU_ITEM_SUBMENU_P(_i("Voltages"), lcd_menu_voltages);////MSG_MENU_VOLTAGES c=18 r=1 #endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN - if (_md->experimental_menu_visibility) - { - MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu);////MSG_MENU_EXPERIMENTAL c=18 - } - #ifdef DEBUG_BUILD MENU_ITEM_SUBMENU_P(PSTR("Debug"), lcd_menu_debug);////c=18 r=1 @@ -5730,6 +5714,25 @@ static void sheets_menu() void lcd_hw_setup_menu(void) // can not be "static" { + typedef struct + {// 2bytes total + int8_t status; + uint8_t experimental_menu_visibility; + } _menu_data_t; + static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data"); + _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]); + + if (_md->status == 0 || lcd_draw_update) + { + _md->experimental_menu_visibility = eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY); + if (_md->experimental_menu_visibility == EEPROM_EMPTY_VALUE) + { + _md->experimental_menu_visibility = 0; + eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, _md->experimental_menu_visibility); + } + } + + MENU_BEGIN(); MENU_ITEM_BACK_P(_T(bSettings?MSG_SETTINGS:MSG_BACK)); // i.e. default menu-item / menu-item after checking mismatch @@ -5743,6 +5746,12 @@ void lcd_hw_setup_menu(void) // can not be "static" //! @todo Don't forget to remove this as soon Fsensor Detection works with mmu if(!mmu_enabled) MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor); #endif //IR_SENSOR_ANALOG + + if (_md->experimental_menu_visibility) + { + MENU_ITEM_SUBMENU_P(PSTR("Experimental"), lcd_experimental_menu);////MSG_MENU_EXPERIMENTAL c=18 + } + MENU_END(); } From 6b853a4cc335d513a949b3530662e8fa5575bdf8 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 12 Aug 2020 12:19:08 +0300 Subject: [PATCH 71/77] Auto-detect ALTFAN after fw. update --- Firmware/temperature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index f08c682aa..f01fbab28 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -232,7 +232,7 @@ bool extruder_altfan_detect() uint8_t overrideVal = eeprom_read_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE); if (overrideVal == EEPROM_EMPTY_VALUE) { - overrideVal = 0; + overrideVal = (calibration_status() == CALIBRATION_STATUS_CALIBRATED) ? 1 : 0; eeprom_update_byte((uint8_t *)EEPROM_ALTFAN_OVERRIDE, overrideVal); } altfanStatus.altfanOverride = overrideVal; From 5530b99882c90bbc67b69eb18d64743abf4643ab Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 12 Aug 2020 12:46:35 +0300 Subject: [PATCH 72/77] Reboot after factory reset --- Firmware/Dcodes.cpp | 13 ++++--------- Firmware/Marlin.h | 2 ++ Firmware/Marlin_main.cpp | 11 ++++++++--- Firmware/bootapp.c | 8 ++++---- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Firmware/Dcodes.cpp b/Firmware/Dcodes.cpp index 1f902c5ee..85d780011 100644 --- a/Firmware/Dcodes.cpp +++ b/Firmware/Dcodes.cpp @@ -226,9 +226,7 @@ void dcode_0() LOG("D0 - Reset\n"); if (code_seen('B')) //bootloader { - cli(); - wdt_enable(WDTO_15MS); - while(1); + softReset(); } else //reset { @@ -252,8 +250,7 @@ void dcode_1() cli(); for (int i = 0; i < 8192; i++) eeprom_write_byte((unsigned char*)i, (unsigned char)0xff); - wdt_enable(WDTO_15MS); - while(1); + softReset(); } /*! @@ -420,8 +417,7 @@ void dcode_5() boot_dst_addr = (uint32_t)address; boot_src_addr = (uint32_t)(&data); bootapp_print_vars(); - wdt_enable(WDTO_15MS); - while(1); + softReset(); } while (count) { @@ -467,8 +463,7 @@ void dcode_7() boot_copy_size = (uint16_t)0xc00; boot_src_addr = (uint32_t)0x0003e400; boot_dst_addr = (uint32_t)0x0003f400; - wdt_enable(WDTO_15MS); - while(1); + softReset(); */ } diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 5c03552bf..2585d0c86 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -512,4 +512,6 @@ void load_filament_final_feed(); void marlin_wait_for_click(); void raise_z_above(float target, bool plan=true); +void softReset(); + #endif diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 2a261db2a..fa02a9568 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -762,6 +762,7 @@ static void factory_reset(char level) } } + softReset(); break; @@ -3813,9 +3814,7 @@ void process_commands() #if (defined(WATCHDOG) && (MOTHERBOARD == BOARD_EINSY_1_0a)) boot_app_magic = BOOT_APP_MAGIC; boot_app_flags = BOOT_APP_FLG_RUN; - wdt_enable(WDTO_15MS); - cli(); - while(1); + softReset(); #else //WATCHDOG asm volatile("jmp 0x3E000"); #endif //WATCHDOG @@ -11716,6 +11715,12 @@ void disable_force_z() #endif // TMC2130 } +void softReset() +{ + cli(); + wdt_enable(WDTO_15MS); + while(1); +} void enable_force_z() { diff --git a/Firmware/bootapp.c b/Firmware/bootapp.c index 4fd67db2b..c4585af5c 100644 --- a/Firmware/bootapp.c +++ b/Firmware/bootapp.c @@ -9,6 +9,8 @@ extern FILE _uartout; #define uartout (&_uartout) +extern void softReset(); + void bootapp_print_vars(void) { fprintf_P(uartout, PSTR("boot_src_addr =0x%08lx\n"), boot_src_addr); @@ -39,8 +41,7 @@ void bootapp_ram2flash(uint16_t rptr, uint16_t fptr, uint16_t size) boot_src_addr = (uint32_t)rptr; boot_dst_addr = (uint32_t)fptr; bootapp_print_vars(); - wdt_enable(WDTO_15MS); - while(1); + softReset(); } void bootapp_reboot_user0(uint8_t reserved) @@ -50,6 +51,5 @@ void bootapp_reboot_user0(uint8_t reserved) boot_app_flags = BOOT_APP_FLG_USER0; boot_reserved = reserved; bootapp_print_vars(); - wdt_enable(WDTO_15MS); - while(1); + softReset(); } From 8d9dc73d1b8c06a7c7c4f308203227c6ee112bd1 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Wed, 12 Aug 2020 17:25:49 +0300 Subject: [PATCH 73/77] Fix compile error fix compile Fix compile error --- Firmware/Dcodes.cpp | 2 +- Firmware/Marlin.h | 2 +- Firmware/Marlin_main.cpp | 13 ++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Firmware/Dcodes.cpp b/Firmware/Dcodes.cpp index 85d780011..c77cd96e1 100644 --- a/Firmware/Dcodes.cpp +++ b/Firmware/Dcodes.cpp @@ -1,5 +1,5 @@ #include "Dcodes.h" -//#include "Marlin.h" +#include "Marlin.h" #include "Configuration.h" #include "language.h" #include "cmdqueue.h" diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 2585d0c86..3a4b42599 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -512,6 +512,6 @@ void load_filament_final_feed(); void marlin_wait_for_click(); void raise_z_above(float target, bool plan=true); -void softReset(); +extern "C" void softReset(); #endif diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index fa02a9568..a83d64b82 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -648,6 +648,12 @@ void failstats_reset_print() #endif } +void softReset() +{ + cli(); + wdt_enable(WDTO_15MS); + while(1); +} #ifdef MESH_BED_LEVELING @@ -11715,13 +11721,6 @@ void disable_force_z() #endif // TMC2130 } -void softReset() -{ - cli(); - wdt_enable(WDTO_15MS); - while(1); -} - void enable_force_z() { if(bEnableForce_z) From 2c2926882a924d1deabaf046f8a9a82eae9f3594 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 18 Aug 2020 19:29:18 +0300 Subject: [PATCH 74/77] Don't switch unnecessarily. Also "\n" the ";S" request --- Firmware/Marlin_main.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 49470ae12..70a8f7e57 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3287,25 +3287,23 @@ void gcode_M701() static void gcode_PRUSA_SN() { uint8_t selectedSerialPort_bak = selectedSerialPort; + char SN[20]; selectedSerialPort = 0; - putchar(';'); - putchar('S'); - int numbersRead = 0; + SERIAL_ECHOLNRPGM(PSTR(";S")); + uint8_t numbersRead = 0; ShortTimer timeout; timeout.start(); - while (numbersRead < 19) { - while (MSerial.available() > 0) { - uint8_t serial_char = MSerial.read(); - selectedSerialPort = selectedSerialPort_bak; - putchar(serial_char); + while (numbersRead < (sizeof(SN) - 1)) { + if (MSerial.available() > 0) { + SN[numbersRead] = MSerial.read(); numbersRead++; - selectedSerialPort = 0; } if (timeout.expired(100u)) break; } + SN[numbersRead] = 0; selectedSerialPort = selectedSerialPort_bak; - putchar('\n'); + SERIAL_ECHOLN(SN); } //! Detection of faulty RAMBo 1.1b boards equipped with bigger capacitors //! at the TACH_1 pin, which causes bad detection of print fan speed. From 90c36a588746e2d53c9d41acc6a8de08ecb57c27 Mon Sep 17 00:00:00 2001 From: 3d-gussner <3d.gussner@gmail.com> Date: Thu, 20 Aug 2020 15:14:39 +0200 Subject: [PATCH 75/77] Update ALTFAN eeprom documentation EEPROM_ALTFAN_OVERRIDE and EEPROM_EXPERIMENTAL_VISIBILITY are compared to 0xFF in the code that's why I keep the uint8. --- Firmware/eeprom.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index b8bec384c..5cb7ddb85 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -359,8 +359,12 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | ^ | ^ | ^ | 00h 0 | ^ | LCD backlight mode: __Dim__ | ^ | ^ | 0x0D30 3376 | uint16 | EEPROM_BACKLIGHT_TIMEOUT | 01 00 - ff ff | 0a 00h 65535 | LCD backlight timeout: __10__ seconds | LCD menu | D3 Ax0d30 C2 | 0x0D2C 3372 | float | EEPROM_UVLO_LA_K | ??? | ff ff ff ffh | Power panic saved Linear Advanced K value | ??? | D3 Ax0d2c C4 -| 0x0D2B 3371 | uint8 | EEPROM_ALTFAN_OVERRIDE | 0-1 | 00h 0 | ALTFAN override | LCD menu | D3 Ax0d2b C1 -| 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | 0-1 | 00h 0 | Experimental menu visibility | LCD menu | D3 Ax0d2a C1 +| 0x0D2B 3371 | uint8 | EEPROM_ALTFAN_OVERRIDE | ffh 255 | ffh 255 | ALTFAN override unknown state | LCD menu | D3 Ax0d2b C1 +| ^ | ^ | ^ | 00h 0 | ^ | ALTFAN override deactivated | ^ | ^ +| ^ | ^ | ^ | 01h 1 | ^ | ALTFAN override activated | ^ | ^ +| 0x0D2A 3370 | uint8 | EEPROM_EXPERIMENTAL_VISIBILITY | ffh 255 | ffh 255 | Experimental menu visibility unknown state | LCD menu | D3 Ax0d2a C1 +| ^ | ^ | ^ | 00h 0 | ^ | Experimental menu visibility hidden | ^ | ^ +| ^ | ^ | ^ | 01h 1 | ^ | Experimental menu visibility visible | ^ | ^ | Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code From 1659f61dd52ed0be9bc4e825fb10df4414176c2a Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Fri, 21 Aug 2020 10:51:46 +0300 Subject: [PATCH 76/77] Fix fastio extra parenthesis --- Firmware/fastio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/fastio.h b/Firmware/fastio.h index e4f25ed8b..acded8cb6 100644 --- a/Firmware/fastio.h +++ b/Firmware/fastio.h @@ -58,7 +58,7 @@ #define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & MASK(DIO ## IO ## _PIN)) != 0) /// check if pin is an timer -#define _GET_TIMER(IO) ((DIO ## IO ## _PWM) +#define _GET_TIMER(IO) (DIO ## IO ## _PWM) // why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html From 7ac16d5f045aef836a1cf7d36b9f9cfeee45192d Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Mon, 7 Sep 2020 19:42:53 +0300 Subject: [PATCH 77/77] Menu view return patch --- Firmware/menu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/menu.cpp b/Firmware/menu.cpp index d31dce7ee..3c4e89260 100755 --- a/Firmware/menu.cpp +++ b/Firmware/menu.cpp @@ -48,6 +48,7 @@ void menu_goto(menu_func_t menu, const uint32_t encoder, const bool feedback, bo { menu_menu = menu; lcd_encoder = encoder; + menu_top = 0; //reset menu view. Needed if menu_back() is called from deep inside a menu, such as Support asm("sei"); if (reset_menu_state) {