Browse Source

Merge remote-tracking branch 'upstream/MK3' into MK3_Dutch

3d-gussner 4 years ago
parent
commit
6a7ae6231d
50 changed files with 2288 additions and 1970 deletions
  1. 14 0
      .editorconfig
  2. 31 0
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 20 0
      .github/ISSUE_TEMPLATE/enhancement.md
  4. 20 0
      .github/ISSUE_TEMPLATE/feature_request.md
  5. 12 0
      .github/ISSUE_TEMPLATE/question.md
  6. 7 1
      Firmware/Configuration.h
  7. 6 5
      Firmware/Marlin.h
  8. 260 127
      Firmware/Marlin_main.cpp
  9. 16 0
      Firmware/Sd2Card.cpp
  10. 2 0
      Firmware/Sd2Card.h
  11. 3 2
      Firmware/adc.c
  12. 120 0
      Firmware/backlight.cpp
  13. 32 0
      Firmware/backlight.h
  14. 41 52
      Firmware/cardreader.cpp
  15. 3 5
      Firmware/cardreader.h
  16. 33 24
      Firmware/cmdqueue.cpp
  17. 13 4
      Firmware/config.h
  18. 13 2
      Firmware/eeprom.h
  19. 134 38
      Firmware/fsensor.cpp
  20. 29 2
      Firmware/fsensor.h
  21. 3 3
      Firmware/language.c
  22. 46 8
      Firmware/menu.cpp
  23. 4 0
      Firmware/menu.h
  24. 48 14
      Firmware/messages.c
  25. 47 13
      Firmware/messages.h
  26. 17 22
      Firmware/mmu.cpp
  27. 1 0
      Firmware/mmu.h
  28. 2 2
      Firmware/optiboot_w25x20cl.cpp
  29. 3 2
      Firmware/pins_Einsy_1_0.h
  30. 25 11
      Firmware/planner.cpp
  31. 6 2
      Firmware/planner.h
  32. 7 0
      Firmware/sound.cpp
  33. 0 6
      Firmware/sound.h
  34. 11 2
      Firmware/temperature.cpp
  35. 5 0
      Firmware/temperature.h
  36. 8 8
      Firmware/tmc2130.cpp
  37. 464 228
      Firmware/ultralcd.cpp
  38. 14 0
      Firmware/ultralcd.h
  39. 3 1
      Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h
  40. 3 1
      Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h
  41. 61 56
      PF-build.sh
  42. 1 0
      README.md
  43. 2 3
      Tests/PrusaStatistics_test.cpp
  44. 71 141
      lang/lang_en.txt
  45. 105 197
      lang/lang_en_cz.txt
  46. 107 199
      lang/lang_en_de.txt
  47. 105 197
      lang/lang_en_es.txt
  48. 102 198
      lang/lang_en_fr.txt
  49. 104 197
      lang/lang_en_it.txt
  50. 104 197
      lang/lang_en_pl.txt

+ 14 - 0
.editorconfig

@@ -0,0 +1,14 @@
+#-*-mode:conf-*-
+# editorconfig file (see EditorConfig.org)
+
+root                        = true
+
+[*]
+end_of_line                 = lf
+insert_final_newline        = true
+charset                     = utf-8
+trim_trailing_whitespace    = true
+indent_style                = space
+indent_size                 = 4
+tab_width                   = 4
+max_line_length             = 100

+ 31 - 0
.github/ISSUE_TEMPLATE/bug_report.md

@@ -0,0 +1,31 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: "[BUG]<Enter comprehensive title>"
+labels: bug
+assignees: ''
+
+---
+
+Please, before you create a new bug report, please make sure you searched in open and closed issues and couldn't find anything that matches.
+
+**Printer type** - [e.g. MK3S, MK3, MK2.5S, MK2.5, MK2S, MK2]
+**Printer firmware version**-  [e.g. 3.8.1, 3.8.1-RC1, ...]
+
+**MMU Upgrade** - [e.g. MMU2S, MMU2, MMU1]
+**MMU upgrade firmware version [e.g. 1.0.6, 1.0.6-RC2, ...]
+
+**Describe the bug**
+  A clear and concise description of what the bug is.
+  
+**To Reproduce**
+  Please describe steps to reproduce the behavior.
+  
+**Expected behavior**
+  A clear and concise description of what you expected to happen.
+  
+**G-code**
+  Please attach a G-code. This will make it easier for us to replicate the error.
+
+**Video**
+  Please attach a video. It usually helps to solve the problem.

+ 20 - 0
.github/ISSUE_TEMPLATE/enhancement.md

@@ -0,0 +1,20 @@
+---
+name: Enhancement
+about: Suggest an idea for this project
+title: "  [ENHANCEMENT]<Enter comprehensive title>"
+labels: enhancement
+assignees: ''
+
+---
+
+Please, before you create a new feature request, please make sure you searched in open and closed issues and couldn't find anything that matches.
+
+Enter what type of printer or upgrade the enhancement applies to.
+**Printer type** - [e.g. MK3S, MK3, MK2.5S, MK2.5, MK2S, MK2]
+**MMU Upgrade** - [e.g. MMU2S, MMU2, MMU1]
+
+**Is your enhancement related to a problem? Please describe.**
+  A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+  
+**Describe the solution you'd like**
+  A clear and concise description of what you want to happen.

+ 20 - 0
.github/ISSUE_TEMPLATE/feature_request.md

@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: "[FEATURE REQUEST]<Enter comprehensive title>"
+labels: feature request
+assignees: ''
+
+---
+
+Please, before you create a new feature request, please make sure you searched in open and closed issues and couldn't find anything that matches.
+
+If it makes sense, enter what type of printer or upgrade the feature request applies to.
+**Printer type** - [e.g. MK3S, MK3, MK2.5S, MK2.5, MK2S, MK2]
+**MMU Upgrade** - [e.g. MMU2S, MMU2, MMU1]
+
+**Is your feature request related to a problem? Please describe.**
+  A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+  
+**Describe the solution you'd like**
+  A clear and concise description of what you want to happen.

+ 12 - 0
.github/ISSUE_TEMPLATE/question.md

@@ -0,0 +1,12 @@
+---
+name: Question
+about: What do you want to know?
+title: "[QUESTION]<Enter comprehensive title>"
+labels: question
+assignees: ''
+
+---
+
+Please, before you create a new question, please make sure you searched in open and closed issues and couldn't find anything that matches.
+
+**What is your question?**

+ 7 - 1
Firmware/Configuration.h

@@ -345,7 +345,7 @@ your extruder heater takes 2 minutes to hit the target on heating.
   #define Y_PROBE_OFFSET_FROM_EXTRUDER -29
   #define Y_PROBE_OFFSET_FROM_EXTRUDER -29
   #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35
   #define Z_PROBE_OFFSET_FROM_EXTRUDER -12.35
 
 
-  #define Z_RAISE_BEFORE_HOMING 4       // (in mm) Raise Z before homing (G28) for Probe Clearance.
+  #define Z_RAISE_BEFORE_HOMING 5       // (in mm) Raise Z before homing (G28) for Probe Clearance.
                                         // Be sure you have this distance over your Z_MAX_POS in case
                                         // Be sure you have this distance over your Z_MAX_POS in case
 
 
   #define XY_TRAVEL_SPEED 8000         // X and Y axis travel speed between probes, in mm/min
   #define XY_TRAVEL_SPEED 8000         // X and Y axis travel speed between probes, in mm/min
@@ -549,6 +549,12 @@ enum CalibrationStatus
     CALIBRATION_STATUS_UNKNOWN = 0,
     CALIBRATION_STATUS_UNKNOWN = 0,
 };
 };
 
 
+// Try to maintain a minimum distance from the bed even when Z is
+// unknown when doing the following operations
+#define MIN_Z_FOR_LOAD    50
+#define MIN_Z_FOR_UNLOAD  20
+#define MIN_Z_FOR_PREHEAT 10
+
 #include "Configuration_adv.h"
 #include "Configuration_adv.h"
 #include "thermistortables.h"
 #include "thermistortables.h"
 
 

+ 6 - 5
Firmware/Marlin.h

@@ -296,6 +296,7 @@ void setPwmFrequency(uint8_t pin, int val);
 extern bool fans_check_enabled;
 extern bool fans_check_enabled;
 extern float homing_feedrate[];
 extern float homing_feedrate[];
 extern bool axis_relative_modes[];
 extern bool axis_relative_modes[];
+extern float feedrate;
 extern int feedmultiply;
 extern int feedmultiply;
 extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
 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 int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
@@ -358,9 +359,6 @@ extern int fan_speed[2];
 // Handling multiple extruders pins
 // Handling multiple extruders pins
 extern uint8_t active_extruder;
 extern uint8_t active_extruder;
 
 
-
-#endif
-
 //Long pause
 //Long pause
 extern unsigned long pause_time;
 extern unsigned long pause_time;
 extern unsigned long start_pause_print;
 extern unsigned long start_pause_print;
@@ -398,7 +396,7 @@ extern uint16_t gcode_in_progress;
 extern LongTimer safetyTimer;
 extern LongTimer safetyTimer;
 
 
 #define PRINT_PERCENT_DONE_INIT   0xff
 #define PRINT_PERCENT_DONE_INIT   0xff
-#define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CustomMsg::TempCal) || saved_printing || (lcd_commands_type == LcdCommands::Layer1Cal) || card.paused || mmu_print_saved)
+#define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CustomMsg::TempCal) || saved_printing || (lcd_commands_type == LcdCommands::Layer1Cal) || mmu_print_saved)
 
 
 //! Beware - mcode_in_progress is set as soon as the command gets really processed,
 //! Beware - mcode_in_progress is set as soon as the command gets really processed,
 //! which is not the same as posting the M600 command into the command queue
 //! which is not the same as posting the M600 command into the command queue
@@ -457,6 +455,7 @@ extern void print_mesh_bed_leveling_table();
 
 
 extern void stop_and_save_print_to_ram(float z_move, float e_move);
 extern void stop_and_save_print_to_ram(float z_move, float e_move);
 extern void restore_print_from_ram_and_continue(float e_move);
 extern void restore_print_from_ram_and_continue(float e_move);
+extern void cancel_saved_printing();
 
 
 
 
 //estimated time to end of the print
 //estimated time to end of the print
@@ -513,4 +512,6 @@ void M600_wait_for_user(float HotendTempBckp);
 void M600_check_state(float nozzle_temp);
 void M600_check_state(float nozzle_temp);
 void load_filament_final_feed();
 void load_filament_final_feed();
 void marlin_wait_for_click();
 void marlin_wait_for_click();
-void marlin_rise_z(void);
+void raise_z_above(float target, bool plan=true);
+
+#endif

+ 260 - 127
Firmware/Marlin_main.cpp

@@ -63,6 +63,7 @@
 
 
 #include "menu.h"
 #include "menu.h"
 #include "ultralcd.h"
 #include "ultralcd.h"
+#include "backlight.h"
 
 
 #include "planner.h"
 #include "planner.h"
 #include "stepper.h"
 #include "stepper.h"
@@ -309,6 +310,8 @@ bool no_response = false;
 uint8_t important_status;
 uint8_t important_status;
 uint8_t saved_filament_type;
 uint8_t saved_filament_type;
 
 
+#define SAVED_TARGET_UNSET (X_MIN_POS-1)
+float saved_target[NUM_AXIS] = {SAVED_TARGET_UNSET, 0, 0, 0};
 
 
 // save/restore printing in case that mmu was not responding 
 // save/restore printing in case that mmu was not responding 
 bool mmu_print_saved = false;
 bool mmu_print_saved = false;
@@ -329,11 +332,15 @@ float destination[NUM_AXIS] = {  0.0, 0.0, 0.0, 0.0};
 
 
 // For tracing an arc
 // For tracing an arc
 static float offset[3] = {0.0, 0.0, 0.0};
 static float offset[3] = {0.0, 0.0, 0.0};
-static float feedrate = 1500.0, next_feedrate, saved_feedrate;
 
 
-// Determines Absolute or Relative Coordinates.
-// Also there is bool axis_relative_modes[] per axis flag.
-static bool relative_mode = false;  
+// Current feedrate
+float feedrate = 1500.0;
+
+// Feedrate for the next move
+static float next_feedrate;
+
+// Original feedrate saved during homing moves
+static float saved_feedrate;
 
 
 const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42
 const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42
 
 
@@ -373,8 +380,8 @@ bool saved_printing = false; //!< Print is paused and saved in RAM
 static uint32_t saved_sdpos = 0; //!< SD card position, or line number in case of USB printing
 static uint32_t saved_sdpos = 0; //!< SD card position, or line number in case of USB printing
 uint8_t saved_printing_type = PRINTING_TYPE_SD;
 uint8_t saved_printing_type = PRINTING_TYPE_SD;
 static float saved_pos[4] = { 0, 0, 0, 0 };
 static float saved_pos[4] = { 0, 0, 0, 0 };
-//! Feedrate hopefully derived from an active block of the planner at the time the print has been canceled, in mm/min.
-static float saved_feedrate2 = 0;
+static uint16_t saved_feedrate2 = 0; //!< Default feedrate (truncated from float)
+static int saved_feedmultiply2 = 0;
 static uint8_t saved_active_extruder = 0;
 static uint8_t saved_active_extruder = 0;
 static float saved_extruder_temperature = 0.0; //!< Active extruder temperature
 static float saved_extruder_temperature = 0.0; //!< Active extruder temperature
 static bool saved_extruder_under_pressure = false;
 static bool saved_extruder_under_pressure = false;
@@ -989,10 +996,6 @@ void setup()
 
 
 	ultralcd_init();
 	ultralcd_init();
 
 
-#if (LCD_BL_PIN != -1) && defined (LCD_BL_PIN)
-	analogWrite(LCD_BL_PIN, 255); //set full brightnes
-#endif //(LCD_BL_PIN != -1) && defined (LCD_BL_PIN)
-
 	spi_init();
 	spi_init();
 
 
 	lcd_splash();
 	lcd_splash();
@@ -2104,6 +2107,58 @@ bool check_commands() {
 	
 	
 }
 }
 
 
+
+// raise_z_above: slowly raise Z to the requested height
+//
+// contrarily to a simple move, this function will carefully plan a move
+// when the current Z position is unknown. In such cases, stallguard is
+// enabled and will prevent prolonged pushing against the Z tops
+void raise_z_above(float target, bool plan)
+{
+    if (current_position[Z_AXIS] >= target)
+        return;
+
+    // Z needs raising
+    current_position[Z_AXIS] = target;
+
+#if defined(Z_MIN_PIN) && (Z_MIN_PIN > -1) && !defined(DEBUG_DISABLE_ZMINLIMIT)
+    bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
+#else
+    bool z_min_endstop = false;
+#endif
+
+    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);
+        return;
+    }
+
+    // ensure Z is powered in normal mode to overcome initial load
+    enable_z();
+    st_synchronize();
+
+    // rely on crashguard to limit damage
+    bool z_endstop_enabled = enable_z_endstop(true);
+#ifdef TMC2130
+    tmc2130_home_enter(Z_AXIS_MASK);
+#endif //TMC2130
+    plan_buffer_line_curposXYZE(homing_feedrate[Z_AXIS] / 60, active_extruder);
+    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]);
+    }
+    tmc2130_home_exit();
+#endif //TMC2130
+    enable_z_endstop(z_endstop_enabled);
+}
+
+
 #ifdef TMC2130
 #ifdef TMC2130
 bool calibrate_z_auto()
 bool calibrate_z_auto()
 {
 {
@@ -2484,9 +2539,7 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
 
 
 	//if we are homing all axes, first move z higher to protect heatbed/steel sheet
 	//if we are homing all axes, first move z higher to protect heatbed/steel sheet
 	if (home_all_axes) {
 	if (home_all_axes) {
-		current_position[Z_AXIS] += MESH_HOME_Z_SEARCH;
-		feedrate = homing_feedrate[Z_AXIS];
-		plan_buffer_line_curposXYZE(feedrate / 60, active_extruder);
+        raise_z_above(MESH_HOME_Z_SEARCH);
 		st_synchronize();
 		st_synchronize();
 	}
 	}
 #ifdef ENABLE_AUTO_BED_LEVELING
 #ifdef ENABLE_AUTO_BED_LEVELING
@@ -2597,26 +2650,21 @@ static void gcode_G28(bool home_x_axis, long home_x_value, bool home_y_axis, lon
         #ifndef Z_SAFE_HOMING
         #ifndef Z_SAFE_HOMING
           if(home_z) {
           if(home_z) {
             #if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
             #if defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
-              destination[Z_AXIS] = Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS) * (-1);    // Set destination away from bed
-              feedrate = max_feedrate[Z_AXIS];
-              plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
+              raise_z_above(Z_RAISE_BEFORE_HOMING);
               st_synchronize();
               st_synchronize();
             #endif // defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
             #endif // defined (Z_RAISE_BEFORE_HOMING) && (Z_RAISE_BEFORE_HOMING > 0)
             #if (defined(MESH_BED_LEVELING) && !defined(MK1BP))  // If Mesh bed leveling, move X&Y to safe position for home
             #if (defined(MESH_BED_LEVELING) && !defined(MK1BP))  // If Mesh bed leveling, move X&Y to safe position for home
-      			  if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] )) 
-      			  {
-                homeaxis(X_AXIS);
-                homeaxis(Y_AXIS);
-      			  } 
+              raise_z_above(MESH_HOME_Z_SEARCH);
+              st_synchronize();
+              if (!axis_known_position[X_AXIS]) homeaxis(X_AXIS);
+              if (!axis_known_position[Y_AXIS]) homeaxis(Y_AXIS);
               // 1st mesh bed leveling measurement point, corrected.
               // 1st mesh bed leveling measurement point, corrected.
               world2machine_initialize();
               world2machine_initialize();
               world2machine(pgm_read_float(bed_ref_points_4), pgm_read_float(bed_ref_points_4+1), destination[X_AXIS], destination[Y_AXIS]);
               world2machine(pgm_read_float(bed_ref_points_4), pgm_read_float(bed_ref_points_4+1), destination[X_AXIS], destination[Y_AXIS]);
               world2machine_reset();
               world2machine_reset();
               if (destination[Y_AXIS] < Y_MIN_POS)
               if (destination[Y_AXIS] < Y_MIN_POS)
                   destination[Y_AXIS] = Y_MIN_POS;
                   destination[Y_AXIS] = Y_MIN_POS;
-              destination[Z_AXIS] = MESH_HOME_Z_SEARCH;    // Set destination away from bed
-              feedrate = homing_feedrate[Z_AXIS]/10;
-              current_position[Z_AXIS] = 0;
+              feedrate = homing_feedrate[X_AXIS] / 20;
               enable_endstops(false);
               enable_endstops(false);
 #ifdef DEBUG_BUILD
 #ifdef DEBUG_BUILD
               SERIAL_ECHOLNPGM("plan_set_position()");
               SERIAL_ECHOLNPGM("plan_set_position()");
@@ -2775,7 +2823,10 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
 	#ifdef TMC2130
 	#ifdef TMC2130
 	FORCE_HIGH_POWER_START;
 	FORCE_HIGH_POWER_START;
 	#endif // TMC2130
 	#endif // TMC2130
-	// Only Z calibration?
+    
+    FORCE_BL_ON_START;
+	
+    // Only Z calibration?
 	if (!onlyZ)
 	if (!onlyZ)
 	{
 	{
 		setTargetBed(0);
 		setTargetBed(0);
@@ -2963,6 +3014,9 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
 #ifdef TMC2130
 #ifdef TMC2130
 	FORCE_HIGH_POWER_END;
 	FORCE_HIGH_POWER_END;
 #endif // TMC2130
 #endif // TMC2130
+    
+    FORCE_BL_ON_END;
+    
 	return final_result;
 	return final_result;
 }
 }
 
 
@@ -3143,15 +3197,6 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     custom_message_type = CustomMsg::Status;
     custom_message_type = CustomMsg::Status;
 }
 }
 
 
-//! @brief Rise Z if too low to avoid blob/jam before filament loading
-//!
-//! It doesn't plan_buffer_line(), as it expects plan_buffer_line() to be called after
-//! during extruding (loading) filament.
-void marlin_rise_z(void)
-{
-    if (current_position[Z_AXIS] < 20) current_position[Z_AXIS] += 30;
-}
-
 void gcode_M701()
 void gcode_M701()
 {
 {
 	printf_P(PSTR("gcode_M701 begin\n"));
 	printf_P(PSTR("gcode_M701 begin\n"));
@@ -3180,7 +3225,7 @@ void gcode_M701()
 		plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence
 		plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence
 		st_synchronize();
 		st_synchronize();
 
 
-		marlin_rise_z();
+        raise_z_above(MIN_Z_FOR_LOAD, false);
 		current_position[E_AXIS] += 30;
 		current_position[E_AXIS] += 30;
 		plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence
 		plan_buffer_line_curposXYZE(400 / 60, active_extruder); //fast sequence
 		
 		
@@ -3625,7 +3670,7 @@ void process_commands()
     
     
     Set of internal PRUSA commands
     Set of internal PRUSA commands
       
       
-          PRUSA [ Ping | PRN | FAN | fn | thx | uvlo | fsensor_recover | MMURES | RESET | fv | M28 | SN | Fir | Rev | Lang | Lz | Beat | FR ]
+          PRUSA [ Ping | PRN | FAN | fn | thx | uvlo | MMURES | RESET | fv | M28 | SN | Fir | Rev | Lang | Lz | Beat | FR ]
       
       
       - `Ping` 
       - `Ping` 
       - `PRN` - Prints revision of the printer
       - `PRN` - Prints revision of the printer
@@ -3633,7 +3678,6 @@ void process_commands()
       - `fn` - Prints farm no.
       - `fn` - Prints farm no.
       - `thx` 
       - `thx` 
       - `uvlo` 
       - `uvlo` 
-      - `fsensor_recover` - Filament sensor recover - restore print and continue
       - `MMURES` - Reset MMU
       - `MMURES` - Reset MMU
       - `RESET` - (Careful!)
       - `RESET` - (Careful!)
       - `fv`  - ?
       - `fv`  - ?
@@ -3683,12 +3727,6 @@ void process_commands()
                eeprom_update_byte((uint8_t*)EEPROM_UVLO,0); 
                eeprom_update_byte((uint8_t*)EEPROM_UVLO,0); 
                enquecommand_P(PSTR("M24")); 
                enquecommand_P(PSTR("M24")); 
 		}	
 		}	
-#ifdef FILAMENT_SENSOR
-		else if (code_seen("fsensor_recover")) // PRUSA fsensor_recover
-		{
-               fsensor_restore_print_and_continue();
-		}	
-#endif //FILAMENT_SENSOR
 		else if (code_seen("MMURES")) // PRUSA MMURES
 		else if (code_seen("MMURES")) // PRUSA MMURES
 		{
 		{
 			mmu_reset();
 			mmu_reset();
@@ -4013,8 +4051,19 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
 
 
         #endif
         #endif
 
 
+            get_coordinates(); // For X Y Z E F
+
+            // When recovering from a previous print move, restore the originally
+            // calculated target position on the first USB/SD command. This accounts
+            // properly for relative moves
+            if ((saved_target[0] != SAVED_TARGET_UNSET) &&
+                ((CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_SDCARD) ||
+                 (CMDBUFFER_CURRENT_TYPE == CMDBUFFER_CURRENT_TYPE_USB_WITH_LINENR)))
+            {
+                memcpy(destination, saved_target, sizeof(destination));
+                saved_target[0] = SAVED_TARGET_UNSET;
+            }
 
 
-        get_coordinates(); // For X Y Z E F
 		if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow
 		if (total_filament_used > ((current_position[E_AXIS] - destination[E_AXIS]) * 100)) { //protection against total_filament_used overflow
 			total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100);
 			total_filament_used = total_filament_used + ((destination[E_AXIS] - current_position[E_AXIS]) * 100);
 		}
 		}
@@ -5161,15 +5210,19 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
             
             
     //! ### G90 - Switch off relative mode
     //! ### G90 - Switch off relative mode
     // -------------------------------
     // -------------------------------
-    case 90:
-      relative_mode = false;
-      break;
+    case 90: {
+        for(uint8_t i = 0; i != NUM_AXIS; ++i)
+            axis_relative_modes[i] = false;
+    }
+    break;
 
 
     //! ### G91 - Switch on relative mode
     //! ### G91 - Switch on relative mode
     // -------------------------------
     // -------------------------------
-    case 91:
-      relative_mode = true;
-      break;
+    case 91: {
+        for(uint8_t i = 0; i != NUM_AXIS; ++i)
+            axis_relative_modes[i] = true;
+    }
+    break;
 
 
     //! ### G92 - Set position
     //! ### G92 - Set position
     // -----------------------------
     // -----------------------------
@@ -5333,21 +5386,19 @@ if(eSoundMode!=e_SOUND_MODE_SILENT)
       card.openFile(strchr_pointer + 4,true);
       card.openFile(strchr_pointer + 4,true);
       break;
       break;
 
 
-    //! ### M24 - Start SD print
+    //! ### M24 - Start/resume SD print
     // ----------------------------------
     // ----------------------------------
     case 24:
     case 24:
-	  if (!card.paused) 
-		failstats_reset_print();
-      card.startFileprint();
-      starttime=_millis();
+	  if (isPrintPaused)
+          lcd_resume_print();
+      else
+      {
+          failstats_reset_print();
+          card.startFileprint();
+          starttime=_millis();
+      }
 	  break;
 	  break;
 
 
-    //! ### M25 - Pause SD print
-    // ----------------------------------
-    case 25:
-      card.pauseSDPrint();
-      break;
-
     //! ### M26 S\<index\> - Set SD index
     //! ### M26 S\<index\> - Set SD index
     //! Set position in SD card file to index in bytes.
     //! Set position in SD card file to index in bytes.
     //! This command is expected to be called after M23 and before M24.
     //! This command is expected to be called after M23 and before M24.
@@ -5902,7 +5953,7 @@ Sigma_Exit:
     //! ### M112 - Emergency stop
     //! ### M112 - Emergency stop
     // -----------------------------------------
     // -----------------------------------------
     case 112: 
     case 112: 
-      kill(_n(""), 3);
+      kill(MSG_M112_KILL, 3);
       break;
       break;
 
 
     //! ### M140 - Set bed temperature
     //! ### M140 - Set bed temperature
@@ -6165,7 +6216,6 @@ Sigma_Exit:
           LCD_MESSAGERPGM(_T(WELCOME_MSG));
           LCD_MESSAGERPGM(_T(WELCOME_MSG));
           lcd_update(0);
           lcd_update(0);
         break;
         break;
-      #endif
 
 
       //! ### M81 - Turn off Power Supply
       //! ### M81 - Turn off Power Supply
       // --------------------------------------
       // --------------------------------------
@@ -6189,17 +6239,18 @@ Sigma_Exit:
         LCD_MESSAGERPGM(CAT4(CUSTOM_MENDEL_NAME,PSTR(" "),MSG_OFF,PSTR(".")));
         LCD_MESSAGERPGM(CAT4(CUSTOM_MENDEL_NAME,PSTR(" "),MSG_OFF,PSTR(".")));
         lcd_update(0);
         lcd_update(0);
 	  break;
 	  break;
+    #endif
 
 
     //! ### M82 - Set E axis to absolute mode
     //! ### M82 - Set E axis to absolute mode
     // ---------------------------------------
     // ---------------------------------------
     case 82:
     case 82:
-      axis_relative_modes[3] = false;
+      axis_relative_modes[E_AXIS] = false;
       break;
       break;
 
 
     //! ### M83 - Set E axis to relative mode
     //! ### M83 - Set E axis to relative mode
     // ---------------------------------------  
     // ---------------------------------------  
     case 83:
     case 83:
-      axis_relative_modes[3] = true;
+      axis_relative_modes[E_AXIS] = true;
       break;
       break;
 
 
     //! ### M84, M18 - Disable steppers
     //! ### M84, M18 - Disable steppers
@@ -7202,27 +7253,36 @@ Sigma_Exit:
     break;
     break;
     #endif //FILAMENTCHANGEENABLE
     #endif //FILAMENTCHANGEENABLE
 
 
+  //! ### M25 - Pause SD print
   //! ### M601 - Pause print
   //! ### M601 - Pause print
+  //! ### M125 - Pause print (TODO: not implemented)
   // -------------------------------
   // -------------------------------
+	case 25:
 	case 601:
 	case 601:
 	{
 	{
-		cmdqueue_pop_front(); //trick because we want skip this command (M601) after restore
-		lcd_pause_print();
+        if (!isPrintPaused)
+        {
+            st_synchronize();
+            cmdqueue_pop_front(); //trick because we want skip this command (M601) after restore
+            lcd_pause_print();
+        }
 	}
 	}
 	break;
 	break;
 
 
   //! ### M602 - Resume print
   //! ### M602 - Resume print
   // -------------------------------
   // -------------------------------
 	case 602: {
 	case 602: {
-		lcd_resume_print();
+	  if (isPrintPaused)
+          lcd_resume_print();
 	}
 	}
 	break;
 	break;
 
 
   //! ### M603 - Stop print
   //! ### M603 - Stop print
   // -------------------------------
   // -------------------------------
-  case 603: {
+	case 603: {
 		lcd_print_stop();
 		lcd_print_stop();
 	}
 	}
+	break;
 
 
 #ifdef PINDA_THERMISTOR
 #ifdef PINDA_THERMISTOR
   //! ### M860 - Wait for extruder temperature (PINDA)
   //! ### M860 - Wait for extruder temperature (PINDA)
@@ -7611,27 +7671,33 @@ Sigma_Exit:
     case 350: 
     case 350: 
     {
     {
 	#ifdef TMC2130
 	#ifdef TMC2130
-		if(code_seen('E'))
+		for (int i=0; i<NUM_AXIS; i++) 
 		{
 		{
-			uint16_t res_new = code_value();
-			if ((res_new == 8) || (res_new == 16) || (res_new == 32) || (res_new == 64) || (res_new == 128))
+			if(code_seen(axis_codes[i]))
 			{
 			{
-				st_synchronize();
-				uint8_t axis = E_AXIS;
-				uint16_t res = tmc2130_get_res(axis);
-				tmc2130_set_res(axis, res_new);
-				cs.axis_ustep_resolution[axis] = res_new;
-				if (res_new > res)
+				uint16_t res_new = code_value();
+				bool res_valid = (res_new == 8) || (res_new == 16) || (res_new == 32); // resolutions valid for all axis
+				res_valid |= (i != E_AXIS) && ((res_new == 1) || (res_new == 2) || (res_new == 4)); // resolutions valid for X Y Z only
+				res_valid |= (i == E_AXIS) && ((res_new == 64) || (res_new == 128)); // resolutions valid for E only
+				if (res_valid)
 				{
 				{
-					uint16_t fac = (res_new / res);
-					cs.axis_steps_per_unit[axis] *= fac;
-					position[E_AXIS] *= fac;
-				}
-				else
-				{
-					uint16_t fac = (res / res_new);
-					cs.axis_steps_per_unit[axis] /= fac;
-					position[E_AXIS] /= fac;
+					
+					st_synchronize();
+					uint16_t res = tmc2130_get_res(i);
+					tmc2130_set_res(i, res_new);
+					cs.axis_ustep_resolution[i] = res_new;
+					if (res_new > res)
+					{
+						uint16_t fac = (res_new / res);
+						cs.axis_steps_per_unit[i] *= fac;
+						position[i] *= fac;
+					}
+					else
+					{
+						uint16_t fac = (res / res_new);
+						cs.axis_steps_per_unit[i] /= fac;
+						position[i] /= fac;
+					}
 				}
 				}
 			}
 			}
 		}
 		}
@@ -8219,7 +8285,7 @@ void get_coordinates()
   for(int8_t i=0; i < NUM_AXIS; i++) {
   for(int8_t i=0; i < NUM_AXIS; i++) {
     if(code_seen(axis_codes[i]))
     if(code_seen(axis_codes[i]))
     {
     {
-      bool relative = axis_relative_modes[i] || relative_mode;
+      bool relative = axis_relative_modes[i];
       destination[i] = (float)code_value();
       destination[i] = (float)code_value();
       if (i == E_AXIS) {
       if (i == E_AXIS) {
         float emult = extruder_multiplier[active_extruder];
         float emult = extruder_multiplier[active_extruder];
@@ -8302,38 +8368,43 @@ void clamp_to_software_endstops(float target[3])
 }
 }
 
 
 #ifdef MESH_BED_LEVELING
 #ifdef MESH_BED_LEVELING
-    void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder) {
+void mesh_plan_buffer_line(const float &x, const float &y, const float &z, const float &e, const float &feed_rate, const uint8_t extruder) {
         float dx = x - current_position[X_AXIS];
         float dx = x - current_position[X_AXIS];
         float dy = y - current_position[Y_AXIS];
         float dy = y - current_position[Y_AXIS];
-        float dz = z - current_position[Z_AXIS];
         int n_segments = 0;
         int n_segments = 0;
-		
+
         if (mbl.active) {
         if (mbl.active) {
             float len = abs(dx) + abs(dy);
             float len = abs(dx) + abs(dy);
             if (len > 0)
             if (len > 0)
                 // Split to 3cm segments or shorter.
                 // Split to 3cm segments or shorter.
                 n_segments = int(ceil(len / 30.f));
                 n_segments = int(ceil(len / 30.f));
         }
         }
-        
+
         if (n_segments > 1) {
         if (n_segments > 1) {
+            // In a multi-segment move explicitly set the final target in the plan
+            // as the move will be recalculated in it's entirety
+            float gcode_target[NUM_AXIS];
+            gcode_target[X_AXIS] = x;
+            gcode_target[Y_AXIS] = y;
+            gcode_target[Z_AXIS] = z;
+            gcode_target[E_AXIS] = e;
+
+            float dz = z - current_position[Z_AXIS];
             float de = e - current_position[E_AXIS];
             float de = e - current_position[E_AXIS];
+
             for (int i = 1; i < n_segments; ++ i) {
             for (int i = 1; i < n_segments; ++ i) {
                 float t = float(i) / float(n_segments);
                 float t = float(i) / float(n_segments);
-                if (saved_printing || (mbl.active == false)) return;
-                plan_buffer_line(
-                                 current_position[X_AXIS] + t * dx,
+                plan_buffer_line(current_position[X_AXIS] + t * dx,
                                  current_position[Y_AXIS] + t * dy,
                                  current_position[Y_AXIS] + t * dy,
                                  current_position[Z_AXIS] + t * dz,
                                  current_position[Z_AXIS] + t * dz,
                                  current_position[E_AXIS] + t * de,
                                  current_position[E_AXIS] + t * de,
-                                 feed_rate, extruder);
+                                 feed_rate, extruder, gcode_target);
+                if (waiting_inside_plan_buffer_line_print_aborted)
+                    return;
             }
             }
         }
         }
         // The rest of the path.
         // The rest of the path.
         plan_buffer_line(x, y, z, e, feed_rate, extruder);
         plan_buffer_line(x, y, z, e, feed_rate, extruder);
-        current_position[X_AXIS] = x;
-        current_position[Y_AXIS] = y;
-        current_position[Z_AXIS] = z;
-        current_position[E_AXIS] = e;
     }
     }
 #endif  // MESH_BED_LEVELING
 #endif  // MESH_BED_LEVELING
     
     
@@ -8354,9 +8425,7 @@ void prepare_move()
 #endif
 #endif
   }
   }
 
 
-  for(int8_t i=0; i < NUM_AXIS; i++) {
-    current_position[i] = destination[i];
-  }
+  set_current_to_destination();
 }
 }
 
 
 void prepare_arc_move(char isclockwise) {
 void prepare_arc_move(char isclockwise) {
@@ -8564,7 +8633,7 @@ if(0)
 
 
   if( (_millis() - previous_millis_cmd) >  max_inactive_time )
   if( (_millis() - previous_millis_cmd) >  max_inactive_time )
     if(max_inactive_time)
     if(max_inactive_time)
-      kill(_n(""), 4);
+      kill(_n("Inactivity Shutdown"), 4);
   if(stepper_inactive_time)  {
   if(stepper_inactive_time)  {
     if( (_millis() - previous_millis_cmd) >  stepper_inactive_time )
     if( (_millis() - previous_millis_cmd) >  stepper_inactive_time )
     {
     {
@@ -8605,7 +8674,7 @@ if(0)
     // ----------------------------------------------------------------
     // ----------------------------------------------------------------
     if ( killCount >= KILL_DELAY)
     if ( killCount >= KILL_DELAY)
     {
     {
-       kill("", 5);
+       kill(NULL, 5);
     }
     }
   #endif
   #endif
     
     
@@ -8683,6 +8752,16 @@ void kill(const char *full_screen_message, unsigned char id)
   } // Wait for reset
   } // Wait for reset
 }
 }
 
 
+// Stop: Emergency stop used by overtemp functions which allows recovery
+//
+//   In addition to stopping the print, this prevents subsequent G[0-3] commands to be
+//   processed via USB (using "Stopped") until the print is resumed via M999 or
+//   manually started from scratch with the LCD.
+//
+//   Note that the current instruction is completely discarded, so resuming from Stop()
+//   will introduce either over/under extrusion on the current segment, and will not
+//   survive a power panic. Switching Stop() to use the pause machinery instead (with
+//   the addition of disabling the headers) could allow true recovery in the future.
 void Stop()
 void Stop()
 {
 {
   disable_heater();
   disable_heater();
@@ -8867,6 +8946,8 @@ void delay_keep_alive(unsigned int ms)
 }
 }
 
 
 static void wait_for_heater(long codenum, uint8_t extruder) {
 static void wait_for_heater(long codenum, uint8_t extruder) {
+    if (!degTargetHotend(extruder))
+        return;
 
 
 #ifdef TEMP_RESIDENCY_TIME
 #ifdef TEMP_RESIDENCY_TIME
 	long residencyStart;
 	long residencyStart;
@@ -9075,10 +9156,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[X_AXIS] = ix * (x_dimension / (x_points_num - 1)) + shift_x;
 		destination[Y_AXIS] = iy * (y_dimension / (y_points_num - 1)) + shift_y;
 		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);
-		for(int8_t i=0; i < NUM_AXIS; i++) {
-			current_position[i] = destination[i];
-		}
+        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();
 		st_synchronize();
 		st_synchronize();
 
 
 	//	printf_P(PSTR("X = %f; Y= %f \n"), current_position[X_AXIS], current_position[Y_AXIS]);
 	//	printf_P(PSTR("X = %f; Y= %f \n"), current_position[X_AXIS], current_position[Y_AXIS]);
@@ -9493,9 +9572,11 @@ float temp_compensation_pinda_thermistor_offset(float temperature_pinda)
 void long_pause() //long pause print
 void long_pause() //long pause print
 {
 {
 	st_synchronize();
 	st_synchronize();
-	
 	start_pause_print = _millis();
 	start_pause_print = _millis();
 
 
+    // Stop heaters
+    setAllTargetHotends(0);
+
 	//retract
 	//retract
 	current_position[E_AXIS] -= default_retraction;
 	current_position[E_AXIS] -= default_retraction;
 	plan_buffer_line_curposXYZE(400, active_extruder);
 	plan_buffer_line_curposXYZE(400, active_extruder);
@@ -9512,8 +9593,6 @@ void long_pause() //long pause print
 
 
 	// Turn off the print fan
 	// Turn off the print fan
 	fanSpeed = 0;
 	fanSpeed = 0;
-
-	st_synchronize();
 }
 }
 
 
 void serialecho_temperatures() {
 void serialecho_temperatures() {
@@ -9534,6 +9613,11 @@ void uvlo_()
 	unsigned long time_start = _millis();
 	unsigned long time_start = _millis();
 	bool sd_print = card.sdprinting;
 	bool sd_print = card.sdprinting;
     // Conserve power as soon as possible.
     // Conserve power as soon as possible.
+#ifdef LCD_BL_PIN
+    backlightMode = BACKLIGHT_MODE_DIM;
+    backlightLevel_LOW = 0;
+    backlight_update();
+#endif //LCD_BL_PIN
     disable_x();
     disable_x();
     disable_y();
     disable_y();
     
     
@@ -9565,8 +9649,18 @@ void uvlo_()
       if (sd_position < 0) sd_position = 0;
       if (sd_position < 0) sd_position = 0;
     }
     }
 
 
-    // Backup the feedrate in mm/min.
-    int feedrate_bckp = blocks_queued() ? (block_buffer[block_buffer_tail].nominal_speed * 60.f) : feedrate;
+    // save the global state at planning time
+    uint16_t feedrate_bckp;
+    if (blocks_queued())
+    {
+        memcpy(saved_target, current_block->gcode_target, sizeof(saved_target));
+        feedrate_bckp = current_block->gcode_feedrate;
+    }
+    else
+    {
+        saved_target[0] = SAVED_TARGET_UNSET;
+        feedrate_bckp = feedrate;
+    }
 
 
     // After this call, the planner queue is emptied and the current_position is set to a current logical coordinate.
     // After this call, the planner queue is emptied and the current_position is set to a current logical coordinate.
     // The logical coordinate will likely differ from the machine coordinate if the skew calibration and mesh bed leveling
     // The logical coordinate will likely differ from the machine coordinate if the skew calibration and mesh bed leveling
@@ -9633,7 +9727,8 @@ void uvlo_()
     eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), current_position[Y_AXIS]);
     eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION + 4), current_position[Y_AXIS]);
     eeprom_update_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z , current_position[Z_AXIS]);
     eeprom_update_float((float*)EEPROM_UVLO_CURRENT_POSITION_Z , current_position[Z_AXIS]);
     // Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates)
     // Store the current feed rate, temperatures, fan speed and extruder multipliers (flow rates)
-    EEPROM_save_B(EEPROM_UVLO_FEEDRATE, &feedrate_bckp);
+	eeprom_update_word((uint16_t*)EEPROM_UVLO_FEEDRATE, feedrate_bckp);
+    EEPROM_save_B(EEPROM_UVLO_FEEDMULTIPLY, &feedmultiply);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_HOTEND, target_temperature[active_extruder]);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_HOTEND, target_temperature[active_extruder]);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_BED, target_temperature_bed);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO_TARGET_BED, target_temperature_bed);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED, fanSpeed);
     eeprom_update_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED, fanSpeed);
@@ -9645,6 +9740,11 @@ void uvlo_()
 #endif
 #endif
 #endif
 #endif
 	eeprom_update_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY), (uint16_t)extrudemultiply);
 	eeprom_update_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY), (uint16_t)extrudemultiply);
+    // Store the saved target
+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4), saved_target[X_AXIS]);
+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4), saved_target[Y_AXIS]);
+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+2*4), saved_target[Z_AXIS]);
+    eeprom_update_float((float*)(EEPROM_UVLO_SAVED_TARGET+3*4), saved_target[E_AXIS]);
 
 
     // Finaly store the "power outage" flag.
     // Finaly store the "power outage" flag.
 	if(sd_print) eeprom_update_byte((uint8_t*)EEPROM_UVLO, 1);
 	if(sd_print) eeprom_update_byte((uint8_t*)EEPROM_UVLO, 1);
@@ -9893,10 +9993,17 @@ void recover_machine_state_after_power_panic(bool bTiny)
 #endif
 #endif
 #endif
 #endif
   extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY));
   extrudemultiply = (int)eeprom_read_word((uint16_t*)(EEPROM_EXTRUDEMULTIPLY));
+
+  // 9) Recover the saved target
+  saved_target[X_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+0*4));
+  saved_target[Y_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+1*4));
+  saved_target[Z_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+2*4));
+  saved_target[E_AXIS] = eeprom_read_float((float*)(EEPROM_UVLO_SAVED_TARGET+3*4));
 }
 }
 
 
 void restore_print_from_eeprom() {
 void restore_print_from_eeprom() {
 	int feedrate_rec;
 	int feedrate_rec;
+	int feedmultiply_rec;
 	uint8_t fan_speed_rec;
 	uint8_t fan_speed_rec;
 	char cmd[30];
 	char cmd[30];
 	char filename[13];
 	char filename[13];
@@ -9904,9 +10011,12 @@ void restore_print_from_eeprom() {
 	char dir_name[9];
 	char dir_name[9];
 
 
 	fan_speed_rec = eeprom_read_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED);
 	fan_speed_rec = eeprom_read_byte((uint8_t*)EEPROM_UVLO_FAN_SPEED);
-	EEPROM_read_B(EEPROM_UVLO_FEEDRATE, &feedrate_rec);
+    feedrate_rec = eeprom_read_word((uint16_t*)EEPROM_UVLO_FEEDRATE);
+	EEPROM_read_B(EEPROM_UVLO_FEEDMULTIPLY, &feedmultiply_rec);
 	SERIAL_ECHOPGM("Feedrate:");
 	SERIAL_ECHOPGM("Feedrate:");
-	MYSERIAL.println(feedrate_rec);
+	MYSERIAL.print(feedrate_rec);
+	SERIAL_ECHOPGM(", feedmultiply:");
+	MYSERIAL.println(feedmultiply_rec);
 
 
 	depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH);
 	depth = eeprom_read_byte((uint8_t*)EEPROM_DIR_DEPTH);
 	
 	
@@ -9947,9 +10057,11 @@ void restore_print_from_eeprom() {
 	enquecommand(cmd);
 	enquecommand(cmd);
   // Unretract.
   // Unretract.
 	enquecommand_P(PSTR("G1 E"  STRINGIFY(2*default_retraction)" F480"));
 	enquecommand_P(PSTR("G1 E"  STRINGIFY(2*default_retraction)" F480"));
-  // Set the feedrate saved at the power panic.
+  // Set the feedrates saved at the power panic.
 	sprintf_P(cmd, PSTR("G1 F%d"), feedrate_rec);
 	sprintf_P(cmd, PSTR("G1 F%d"), feedrate_rec);
 	enquecommand(cmd);
 	enquecommand(cmd);
+	sprintf_P(cmd, PSTR("M220 S%d"), feedmultiply_rec);
+	enquecommand(cmd);
 	if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS))
 	if (eeprom_read_byte((uint8_t*)EEPROM_UVLO_E_ABS))
 	{
 	{
 	  enquecommand_P(PSTR("M82")); //E axis abslute mode
 	  enquecommand_P(PSTR("M82")); //E axis abslute mode
@@ -10101,16 +10213,21 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
   }
   }
 #endif
 #endif
 
 
-#if 0
-  saved_feedrate2 = feedrate; //save feedrate
-#else
-  // Try to deduce the feedrate from the first block of the planner.
-  // Speed is in mm/min.
-  saved_feedrate2 = blocks_queued() ? (block_buffer[block_buffer_tail].nominal_speed * 60.f) : feedrate;
-#endif
+  // save the global state at planning time
+  if (blocks_queued())
+  {
+      memcpy(saved_target, current_block->gcode_target, sizeof(saved_target));
+      saved_feedrate2 = current_block->gcode_feedrate;
+  }
+  else
+  {
+      saved_target[0] = SAVED_TARGET_UNSET;
+      saved_feedrate2 = feedrate;
+  }
 
 
 	planner_abort_hard(); //abort printing
 	planner_abort_hard(); //abort printing
 	memcpy(saved_pos, current_position, sizeof(saved_pos));
 	memcpy(saved_pos, current_position, sizeof(saved_pos));
+    saved_feedmultiply2 = feedmultiply; //save feedmultiply
 	saved_active_extruder = active_extruder; //save active_extruder
 	saved_active_extruder = active_extruder; //save active_extruder
 	saved_extruder_temperature = degTargetHotend(active_extruder);
 	saved_extruder_temperature = degTargetHotend(active_extruder);
 
 
@@ -10126,7 +10243,9 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
 	sei();
 	sei();
 	if ((z_move != 0) || (e_move != 0)) { // extruder or z move
 	if ((z_move != 0) || (e_move != 0)) { // extruder or z move
 #if 1
 #if 1
-    // Rather than calling plan_buffer_line directly, push the move into the command queue, 
+    // Rather than calling plan_buffer_line directly, push the move into the command queue so that
+    // the caller can continue processing. This is used during powerpanic to save the state as we
+    // move away from the print.
     char buf[48];
     char buf[48];
 
 
 	// First unretract (relative extrusion)
 	// First unretract (relative extrusion)
@@ -10155,6 +10274,7 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
     memcpy(current_position, saved_pos, sizeof(saved_pos));
     memcpy(current_position, saved_pos, sizeof(saved_pos));
     memcpy(destination, current_position, sizeof(destination));
     memcpy(destination, current_position, sizeof(destination));
 #endif
 #endif
+    waiting_inside_plan_buffer_line_print_aborted = true; //unroll the stack
   }
   }
 }
 }
 
 
@@ -10188,7 +10308,6 @@ void restore_print_from_ram_and_continue(float e_move)
 		wait_for_heater(_millis(), saved_active_extruder);
 		wait_for_heater(_millis(), saved_active_extruder);
 		heating_status = 2;
 		heating_status = 2;
 	}
 	}
-	feedrate = saved_feedrate2; //restore feedrate
 	axis_relative_modes[E_AXIS] = saved_extruder_relative_mode;
 	axis_relative_modes[E_AXIS] = saved_extruder_relative_mode;
 	float e = saved_pos[E_AXIS] - e_move;
 	float e = saved_pos[E_AXIS] - e_move;
 	plan_set_e_position(e);
 	plan_set_e_position(e);
@@ -10211,6 +10330,10 @@ void restore_print_from_ram_and_continue(float e_move)
     fans_check_enabled = true;
     fans_check_enabled = true;
   #endif
   #endif
 
 
+    // restore original feedrate/feedmultiply _after_ restoring the extruder position
+	feedrate = saved_feedrate2;
+	feedmultiply = saved_feedmultiply2;
+
 	memcpy(current_position, saved_pos, sizeof(saved_pos));
 	memcpy(current_position, saved_pos, sizeof(saved_pos));
 	memcpy(destination, current_position, sizeof(destination));
 	memcpy(destination, current_position, sizeof(destination));
 	if (saved_printing_type == PRINTING_TYPE_SD) { //was sd printing
 	if (saved_printing_type == PRINTING_TYPE_SD) { //was sd printing
@@ -10226,10 +10349,20 @@ void restore_print_from_ram_and_continue(float e_move)
 	else {
 	else {
 		//not sd printing nor usb printing
 		//not sd printing nor usb printing
 	}
 	}
+
 	SERIAL_PROTOCOLLNRPGM(MSG_OK); //dummy response because of octoprint is waiting for this
 	SERIAL_PROTOCOLLNRPGM(MSG_OK); //dummy response because of octoprint is waiting for this
 	lcd_setstatuspgm(_T(WELCOME_MSG));
 	lcd_setstatuspgm(_T(WELCOME_MSG));
     saved_printing_type = PRINTING_TYPE_NONE;
     saved_printing_type = PRINTING_TYPE_NONE;
 	saved_printing = false;
 	saved_printing = false;
+    waiting_inside_plan_buffer_line_print_aborted = true; //unroll the stack
+}
+
+// Cancel the state related to a currently saved print
+void cancel_saved_printing()
+{
+    saved_target[0] = SAVED_TARGET_UNSET;
+    saved_printing_type = PRINTING_TYPE_NONE;
+    saved_printing = false;
 }
 }
 
 
 void print_world_coordinates()
 void print_world_coordinates()

+ 16 - 0
Firmware/Sd2Card.cpp

@@ -319,6 +319,22 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
       goto fail;
       goto fail;
     }
     }
   }
   }
+
+  // send 0xFF until 0xFF received to give card some clock cycles
+  t0 = (uint16_t)_millis();
+  SERIAL_ECHOLNRPGM(PSTR("Sending 0xFF"));
+  spiSend(0XFF);
+  while ((status_ = spiRec()) != 0xFF)
+  {
+    spiSend(0XFF);
+    if (((uint16_t)_millis() - t0) > SD_CARD_ERROR_FF_TIMEOUT)
+    {
+      error(SD_CARD_ERROR_CMD8);
+      SERIAL_ECHOLNRPGM(PSTR("No 0xFF received"));
+      goto fail;
+    }
+  }
+
   // check SD version
   // check SD version
   if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
   if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
     type(SD_CARD_TYPE_SD1);
     type(SD_CARD_TYPE_SD1);

+ 2 - 0
Firmware/Sd2Card.h

@@ -105,6 +105,8 @@ uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18;
 uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
 uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
 /** crc check error */
 /** crc check error */
 uint8_t const SD_CARD_ERROR_CRC = 0X20;
 uint8_t const SD_CARD_ERROR_CRC = 0X20;
+/** no response to sent 0xFF */
+uint8_t const SD_CARD_ERROR_FF_TIMEOUT = 0X21;
 
 
 /** Toshiba FlashAir: iSDIO */
 /** Toshiba FlashAir: iSDIO */
 uint8_t const SD_CARD_ERROR_CMD48 = 0x80;
 uint8_t const SD_CARD_ERROR_CMD48 = 0x80;

+ 3 - 2
Firmware/adc.c

@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdio.h>
 #include <avr/io.h>
 #include <avr/io.h>
 #include <avr/pgmspace.h>
 #include <avr/pgmspace.h>
+#include "pins.h"
 
 
 uint8_t adc_state;
 uint8_t adc_state;
 uint8_t adc_count;
 uint8_t adc_count;
@@ -24,8 +25,8 @@ void adc_init(void)
 	ADMUX |= (1 << REFS0);
 	ADMUX |= (1 << REFS0);
 	ADCSRA |= (1 << ADEN);
 	ADCSRA |= (1 << ADEN);
 //	ADCSRA |= (1 << ADIF) | (1 << ADSC);
 //	ADCSRA |= (1 << ADIF) | (1 << ADSC);
-	DIDR0 = (ADC_CHAN_MSK & 0xff);
-	DIDR2 = (ADC_CHAN_MSK >> 8);
+	DIDR0 = ((ADC_CHAN_MSK & ADC_DIDR_MSK) & 0xff);
+	DIDR2 = ((ADC_CHAN_MSK & ADC_DIDR_MSK) >> 8);
 	adc_reset();
 	adc_reset();
 //	adc_sim_mask = 0b0101;
 //	adc_sim_mask = 0b0101;
 //	adc_sim_mask = 0b100101;
 //	adc_sim_mask = 0b100101;

+ 120 - 0
Firmware/backlight.cpp

@@ -0,0 +1,120 @@
+//backlight.cpp
+
+#include "backlight.h"
+#include <avr/eeprom.h>
+#include <Arduino.h>
+#include "eeprom.h"
+#include "Marlin.h"
+#include "pins.h"
+#include "fastio.h"
+#include "Timer.h"
+
+#ifdef LCD_BL_PIN
+
+#define BL_FLASH_DELAY_MS 25
+
+bool backlightSupport = 0; //only if it's true will any of the settings be visible to the user
+int16_t backlightLevel_HIGH = 0;
+int16_t backlightLevel_LOW = 0;
+uint8_t backlightMode = BACKLIGHT_MODE_BRIGHT;
+int16_t backlightTimer_period = 10;
+LongTimer backlightTimer;
+
+static void backlightTimer_reset() //used for resetting the timer and waking the display. Triggered on user interactions.
+{
+    if (!backlightSupport) return;
+    backlightTimer.start();
+    backlight_update();
+}
+
+void force_bl_on(bool section_start)
+{
+    if (section_start)
+    {
+        backlightMode = BACKLIGHT_MODE_BRIGHT;
+        if (backlightLevel_HIGH < 30) backlightLevel_HIGH = 30;
+    }
+    else
+    {
+        backlightMode = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_MODE);
+        backlightLevel_HIGH = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH);
+    }
+    backlight_update();
+}
+
+void backlight_wake(const uint8_t flashNo)
+{
+    if (!backlightSupport) return;
+    
+    if (flashNo)
+    {
+        uint8_t backlightMode_bck = backlightMode;
+        for (uint8_t i = 0; i < (((backlightMode_bck == BACKLIGHT_MODE_AUTO) && !backlightTimer.running()) + (flashNo * 2)); i++)
+        {
+            backlightMode = !backlightMode; //toggles between BACKLIGHT_MODE_BRIGHT and BACKLIGHT_MODE_DIM
+            backlight_update();
+            _delay(BL_FLASH_DELAY_MS);
+        }
+        backlightMode = backlightMode_bck;
+    }
+    backlightTimer_reset();
+}
+
+void backlight_save() //saves all backlight data to eeprom.
+{
+    eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH, (uint8_t)backlightLevel_HIGH);
+    eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_LOW, (uint8_t)backlightLevel_LOW);
+    eeprom_update_byte((uint8_t *)EEPROM_BACKLIGHT_MODE, backlightMode);
+    eeprom_update_word((uint16_t *)EEPROM_BACKLIGHT_TIMEOUT, backlightTimer_period);
+}
+
+void backlight_update()
+{
+    if (!backlightSupport) return;
+    
+    if (backlightMode == BACKLIGHT_MODE_AUTO)
+    {
+        if (backlightTimer.expired((uint32_t)backlightTimer_period * 1000ul)) analogWrite(LCD_BL_PIN, backlightLevel_LOW);
+        else if (backlightTimer.running()) analogWrite(LCD_BL_PIN, backlightLevel_HIGH);
+        else {/*do nothing*/;} //display is dimmed.
+    }
+    else if (backlightMode == BACKLIGHT_MODE_DIM) analogWrite(LCD_BL_PIN, backlightLevel_LOW);
+    else analogWrite(LCD_BL_PIN, backlightLevel_HIGH);
+}
+
+void backlight_init()
+{
+//check for backlight support on lcd
+    SET_INPUT(LCD_BL_PIN);
+    WRITE(LCD_BL_PIN,HIGH);
+    _delay(10);
+    backlightSupport = !READ(LCD_BL_PIN);
+    if (!backlightSupport) return;
+
+//initialize backlight
+    backlightMode = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_MODE);
+    if (backlightMode == 0xFF) //set default values
+    {
+        backlightMode = BACKLIGHT_MODE_AUTO;
+        backlightLevel_HIGH = 130;
+        backlightLevel_LOW = 50;
+        backlightTimer_period = 10; //in seconds
+        backlight_save();
+    }
+    backlightLevel_HIGH = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_HIGH);
+    backlightLevel_LOW = eeprom_read_byte((uint8_t *)EEPROM_BACKLIGHT_LEVEL_LOW);
+    backlightTimer_period = eeprom_read_word((uint16_t *)EEPROM_BACKLIGHT_TIMEOUT);
+    
+    SET_OUTPUT(LCD_BL_PIN);
+    backlightTimer_reset();
+}
+
+#else //LCD_BL_PIN
+
+void force_bl_on(__attribute__((unused)) bool section_start) {}
+void backlight_update() {}
+void backlight_init() {}
+void backlight_save() {}
+void backlight_wake(__attribute__((unused)) const uint8_t flashNo) {}
+
+#endif //LCD_BL_PIN

+ 32 - 0
Firmware/backlight.h

@@ -0,0 +1,32 @@
+//backlight.h
+#ifndef _BACKLIGHT_H
+#define _BACKLIGHT_H
+
+#include <inttypes.h>
+#include "Marlin.h"
+#include "pins.h"
+
+enum Backlight_Mode
+{
+	BACKLIGHT_MODE_DIM     = 0,
+	BACKLIGHT_MODE_BRIGHT  = 1,
+	BACKLIGHT_MODE_AUTO    = 2,
+};
+
+extern int16_t backlightLevel_HIGH;
+extern int16_t backlightLevel_LOW;
+extern uint8_t backlightMode;
+extern bool backlightSupport;
+extern int16_t backlightTimer_period;
+
+#define FORCE_BL_ON_START force_bl_on(true)
+#define FORCE_BL_ON_END force_bl_on(false)
+
+extern void force_bl_on(bool section_start);
+extern void backlight_update();
+extern void backlight_init();
+extern void backlight_save();
+extern void backlight_wake(const uint8_t flashNo = 0);
+
+
+#endif //_BACKLIGHT_H

+ 41 - 52
Firmware/cardreader.cpp

@@ -25,7 +25,6 @@ CardReader::CardReader()
    sdpos = 0;
    sdpos = 0;
    sdprinting = false;
    sdprinting = false;
    cardOK = false;
    cardOK = false;
-   paused = false;
    saving = false;
    saving = false;
    logging = false;
    logging = false;
    autostart_atmillis=0;
    autostart_atmillis=0;
@@ -137,8 +136,8 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m
 						SERIAL_ECHOPGM("Access date: ");
 						SERIAL_ECHOPGM("Access date: ");
 						MYSERIAL.println(p.lastAccessDate);
 						MYSERIAL.println(p.lastAccessDate);
 						SERIAL_ECHOLNPGM("");*/
 						SERIAL_ECHOLNPGM("");*/
-						creationDate = p.creationDate;
-						creationTime = p.creationTime;
+						modificationDate = p.lastWriteDate;
+						modificationTime = p.lastWriteTime;
 						//writeDate = p.lastAccessDate;
 						//writeDate = p.lastAccessDate;
 						if (match != NULL) {
 						if (match != NULL) {
 							if (strcasecmp(match, filename) == 0) return;
 							if (strcasecmp(match, filename) == 0) return;
@@ -242,24 +241,13 @@ void CardReader::startFileprint()
   if(cardOK)
   if(cardOK)
   {
   {
     sdprinting = true;
     sdprinting = true;
-	paused = false;
-     Stopped = false;
+    Stopped = false;
 	#ifdef SDCARD_SORT_ALPHA
 	#ifdef SDCARD_SORT_ALPHA
 		//flush_presort();
 		//flush_presort();
 	#endif
 	#endif
   }
   }
 }
 }
 
 
-void CardReader::pauseSDPrint()
-{
-  if(sdprinting)
-  {
-    sdprinting = false;
-	paused = true;
-  }
-}
-
-
 void CardReader::openLogFile(const char* name)
 void CardReader::openLogFile(const char* name)
 {
 {
   logging = true;
   logging = true;
@@ -371,10 +359,10 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru
     {
     {
      if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1)
      if((int)file_subcall_ctr>(int)SD_PROCEDURE_DEPTH-1)
      {
      {
-       SERIAL_ERROR_START;
-       SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
-       SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
-       kill("", 1);
+       // SERIAL_ERROR_START;
+       // SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
+       // SERIAL_ERRORLN(SD_PROCEDURE_DEPTH);
+       kill(_n("trying to call sub-gcode files with too many levels."), 1);
        return;
        return;
      }
      }
      
      
@@ -408,9 +396,7 @@ void CardReader::openFile(const char* name,bool read, bool replace_current/*=tru
     SERIAL_ECHOLN(name);
     SERIAL_ECHOLN(name);
   }
   }
   sdprinting = false;
   sdprinting = false;
-  paused = false;
-  
- 
+
   SdFile myDir;
   SdFile myDir;
   const char *fname=name;
   const char *fname=name;
   diveSubfolder(fname,myDir);
   diveSubfolder(fname,myDir);
@@ -492,24 +478,27 @@ uint32_t CardReader::getFileSize()
 
 
 void CardReader::getStatus()
 void CardReader::getStatus()
 {
 {
-  if(sdprinting){
-    SERIAL_PROTOCOL(longFilename);
-    SERIAL_PROTOCOLPGM("\n");
-    SERIAL_PROTOCOLRPGM(_N("SD printing byte "));////MSG_SD_PRINTING_BYTE
-    SERIAL_PROTOCOL(sdpos);
-    SERIAL_PROTOCOLPGM("/");
-    SERIAL_PROTOCOLLN(filesize);
-    uint16_t time = _millis()/60000 - starttime/60000;
-    SERIAL_PROTOCOL(itostr2(time/60));
-    SERIAL_PROTOCOL(':');
-    SERIAL_PROTOCOL(itostr2(time%60));
-    SERIAL_PROTOCOLPGM("\n");
-  }
-  else if (paused) {
-	SERIAL_PROTOCOLLNPGM("SD print paused");
-  }
-  else if (saved_printing) {
-	SERIAL_PROTOCOLLNPGM("Print saved");
+  if(sdprinting)
+  {
+      if (isPrintPaused) {
+          SERIAL_PROTOCOLLNPGM("SD print paused");
+      }
+      else if (saved_printing) {
+          SERIAL_PROTOCOLLNPGM("Print saved");
+      }
+      else {
+          SERIAL_PROTOCOL(longFilename);
+          SERIAL_PROTOCOLPGM("\n");
+          SERIAL_PROTOCOLRPGM(_N("SD printing byte "));////MSG_SD_PRINTING_BYTE
+          SERIAL_PROTOCOL(sdpos);
+          SERIAL_PROTOCOLPGM("/");
+          SERIAL_PROTOCOLLN(filesize);
+          uint16_t time = _millis()/60000 - starttime/60000;
+          SERIAL_PROTOCOL(itostr2(time/60));
+          SERIAL_PROTOCOL(':');
+          SERIAL_PROTOCOL(itostr2(time%60));
+          SERIAL_PROTOCOLPGM("\n");
+      }
   }
   }
   else {
   else {
     SERIAL_PROTOCOLLNPGM("Not SD printing");
     SERIAL_PROTOCOLLNPGM("Not SD printing");
@@ -763,8 +752,8 @@ void CardReader::presort() {
 		#endif
 		#endif
 		#elif SDSORT_USES_STACK
 		#elif SDSORT_USES_STACK
 		char sortnames[fileCnt][LONG_FILENAME_LENGTH];
 		char sortnames[fileCnt][LONG_FILENAME_LENGTH];
-		uint16_t creation_time[fileCnt];
-		uint16_t creation_date[fileCnt];
+		uint16_t modification_time[fileCnt];
+		uint16_t modification_date[fileCnt];
 		#endif
 		#endif
 
 
 		// Folder sorting needs 1 bit per entry for flags.
 		// Folder sorting needs 1 bit per entry for flags.
@@ -784,8 +773,8 @@ void CardReader::presort() {
 		// retaining only two filenames at a time. This is very
 		// retaining only two filenames at a time. This is very
 		// slow but is safest and uses minimal RAM.
 		// slow but is safest and uses minimal RAM.
 		char name1[LONG_FILENAME_LENGTH + 1];
 		char name1[LONG_FILENAME_LENGTH + 1];
-		uint16_t creation_time_bckp;
-		uint16_t creation_date_bckp;
+		uint16_t modification_time_bckp;
+		uint16_t modification_date_bckp;
 
 
 		#endif
 		#endif
 		position = 0;
 		position = 0;
@@ -811,8 +800,8 @@ void CardReader::presort() {
 				#else
 				#else
 				// Copy filenames into the static array
 				// Copy filenames into the static array
 				strcpy(sortnames[i], LONGEST_FILENAME);
 				strcpy(sortnames[i], LONGEST_FILENAME);
-				creation_time[i] = creationTime;
-				creation_date[i] = creationDate;
+				modification_time[i] = modificationTime;
+				modification_date[i] = modificationDate;
 				#if SDSORT_CACHE_NAMES
 				#if SDSORT_CACHE_NAMES
 				strcpy(sortshort[i], filename);
 				strcpy(sortshort[i], filename);
 				#endif
 				#endif
@@ -837,12 +826,12 @@ void CardReader::presort() {
 			// Compare names from the array or just the two buffered names
 			// Compare names from the array or just the two buffered names
 			#if SDSORT_USES_RAM
 			#if SDSORT_USES_RAM
 			#define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0)
 			#define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0)
-			#define _SORT_CMP_TIME_NODIR() (((creation_date[o1] == creation_date[o2]) && (creation_time[o1] < creation_time[o2])) || \
-																	(creation_date[o1] < creation_date [o2]))
+			#define _SORT_CMP_TIME_NODIR() (((modification_date[o1] == modification_date[o2]) && (modification_time[o1] < modification_time[o2])) || \
+																	(modification_date[o1] < modification_date [o2]))
 			#else
 			#else
 			#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2)
 			#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2)
-			#define _SORT_CMP_TIME_NODIR() (((creation_date_bckp == creationDate) && (creation_time_bckp > creationTime)) || \
-																	(creation_date_bckp > creationDate))
+			#define _SORT_CMP_TIME_NODIR() (((modification_date_bckp == modificationDate) && (modification_time_bckp > modificationTime)) || \
+																	(modification_date_bckp > modificationDate))
 
 
 			#endif
 			#endif
 
 
@@ -893,8 +882,8 @@ void CardReader::presort() {
 					counter++;
 					counter++;
 					getfilename_simple(positions[o1]);
 					getfilename_simple(positions[o1]);
 					strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
 					strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
-					creation_date_bckp = creationDate;
-					creation_time_bckp = creationTime;
+					modification_date_bckp = modificationDate;
+					modification_time_bckp = modificationTime;
 					#if HAS_FOLDER_SORTING
 					#if HAS_FOLDER_SORTING
 					bool dir1 = filenameIsDir;
 					bool dir1 = filenameIsDir;
 					#endif
 					#endif

+ 3 - 5
Firmware/cardreader.h

@@ -25,7 +25,6 @@ public:
   void closefile(bool store_location=false);
   void closefile(bool store_location=false);
   void release();
   void release();
   void startFileprint();
   void startFileprint();
-  void pauseSDPrint();
   uint32_t getFileSize();
   uint32_t getFileSize();
   void getStatus();
   void getStatus();
   void printingHasFinished();
   void printingHasFinished();
@@ -75,9 +74,8 @@ public:
   bool logging;
   bool logging;
   bool sdprinting ;  
   bool sdprinting ;  
   bool cardOK ;
   bool cardOK ;
-  bool paused ;
   char filename[13];
   char filename[13];
-  uint16_t creationTime, creationDate;
+  uint16_t modificationTime, modificationDate;
   uint32_t cluster, position;
   uint32_t cluster, position;
   char longFilename[LONG_FILENAME_LENGTH];
   char longFilename[LONG_FILENAME_LENGTH];
   bool filenameIsDir;
   bool filenameIsDir;
@@ -114,8 +112,8 @@ private:
     #endif
     #endif
   #elif !SDSORT_USES_STACK
   #elif !SDSORT_USES_STACK
     char sortnames[SDSORT_LIMIT][FILENAME_LENGTH];
     char sortnames[SDSORT_LIMIT][FILENAME_LENGTH];
-    uint16_t creation_time[SDSORT_LIMIT];
-    uint16_t creation_date[SDSORT_LIMIT];
+    uint16_t modification_time[SDSORT_LIMIT];
+    uint16_t modification_date[SDSORT_LIMIT];
   #endif
   #endif
 
 
   // Folder sorting uses an isDir array when caching items.
   // Folder sorting uses an isDir array when caching items.

+ 33 - 24
Firmware/cmdqueue.cpp

@@ -500,7 +500,7 @@ void get_command()
 
 
         //If command was e-stop process now
         //If command was e-stop process now
         if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
         if(strcmp(cmdbuffer+bufindw+CMDHDRSIZE, "M112") == 0)
-          kill("", 2);
+          kill(MSG_M112_KILL, 2);
         
         
         // Store the current line into buffer, move to the next line.
         // Store the current line into buffer, move to the next line.
 		// Store type of entry
 		// Store type of entry
@@ -582,30 +582,8 @@ void get_command()
        ((serial_char == '#' || serial_char == ':') && comment_mode == false) ||
        ((serial_char == '#' || serial_char == ':') && comment_mode == false) ||
        serial_count >= (MAX_CMD_SIZE - 1) || n==-1)
        serial_count >= (MAX_CMD_SIZE - 1) || n==-1)
     {
     {
-      if(card.eof()){
-        SERIAL_PROTOCOLLNRPGM(_n("Done printing file"));////MSG_FILE_PRINTED
-        stoptime=_millis();
-        char time[30];
-        unsigned long t=(stoptime-starttime-pause_time)/1000;
-        pause_time = 0;
-        int hours, minutes;
-        minutes=(t/60)%60;
-        hours=t/60/60;
-        save_statistics(total_filament_used, t);
-        sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
-        SERIAL_ECHO_START;
-        SERIAL_ECHOLN(time);
-        lcd_setstatus(time);
-        card.printingHasFinished();
-        card.checkautostart(true);
-
-        if (farm_mode)
-        {
-            prusa_statistics(6);
-            lcd_commands_type = LcdCommands::FarmModeConfirm;
-        }
+      if(card.eof()) break;
 
 
-      }
       if(serial_char=='#')
       if(serial_char=='#')
         stop_buffering=true;
         stop_buffering=true;
 
 
@@ -663,6 +641,37 @@ void get_command()
       else if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
       else if(!comment_mode) cmdbuffer[bufindw+CMDHDRSIZE+serial_count++] = serial_char;
     }
     }
   }
   }
+  if(card.eof())
+  {
+      // file was fully buffered, but commands might still need to be planned!
+      // do *not* clear sdprinting until all SD commands are consumed to ensure
+      // SD state can be resumed from a saved printing state. sdprinting is only
+      // cleared by printingHasFinished after peforming all remaining moves.
+      if(!cmdqueue_calc_sd_length())
+      {
+          SERIAL_PROTOCOLLNRPGM(_n("Done printing file"));////MSG_FILE_PRINTED
+          stoptime=_millis();
+          char time[30];
+          unsigned long t=(stoptime-starttime-pause_time)/1000;
+          pause_time = 0;
+          int hours, minutes;
+          minutes=(t/60)%60;
+          hours=t/60/60;
+          save_statistics(total_filament_used, t);
+          sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
+          SERIAL_ECHO_START;
+          SERIAL_ECHOLN(time);
+          lcd_setstatus(time);
+          card.printingHasFinished();
+          card.checkautostart(true);
+
+          if (farm_mode)
+          {
+              prusa_statistics(6);
+              lcd_commands_type = LcdCommands::FarmModeConfirm;
+          }
+      }
+  }
 
 
   #endif //SDSUPPORT
   #endif //SDSUPPORT
 }
 }

+ 13 - 4
Firmware/config.h

@@ -2,9 +2,21 @@
 #define _CONFIG_H
 #define _CONFIG_H
 
 
 
 
+#include "Configuration_prusa.h"
+#include "pins.h"
+
+#define IR_SENSOR_ANALOG (defined(VOLT_IR_PIN) && defined(IR_SENSOR))
+
 //ADC configuration
 //ADC configuration
+#if !IR_SENSOR_ANALOG
 #define ADC_CHAN_MSK      0b0000001001011111 //used AD channels bit mask (0,1,2,3,4,6,9)
 #define ADC_CHAN_MSK      0b0000001001011111 //used AD channels bit mask (0,1,2,3,4,6,9)
+#define ADC_DIDR_MSK      0b0000001001011111 //AD channels DIDR mask (1 ~ disabled digital input)
 #define ADC_CHAN_CNT      7         //number of used channels)
 #define ADC_CHAN_CNT      7         //number of used channels)
+#else //!IR_SENSOR_ANALOG
+#define ADC_CHAN_MSK      0b0000001101011111 //used AD channels bit mask (0,1,2,3,4,6,8,9)
+#define ADC_DIDR_MSK      0b0000001001011111 //AD channels DIDR mask (1 ~ disabled digital input)
+#define ADC_CHAN_CNT      8         //number of used channels)
+#endif //!IR_SENSOR_ANALOG
 #define ADC_OVRSAMPL      16        //oversampling multiplier
 #define ADC_OVRSAMPL      16        //oversampling multiplier
 #define ADC_CALLBACK      adc_ready //callback function ()
 #define ADC_CALLBACK      adc_ready //callback function ()
 
 
@@ -42,11 +54,8 @@
 #define W25X20CL_SPCR          SPI_SPCR(W25X20CL_SPI_RATE, 1, 1, 1, 0)
 #define W25X20CL_SPCR          SPI_SPCR(W25X20CL_SPI_RATE, 1, 1, 1, 0)
 #define W25X20CL_SPSR          SPI_SPSR(W25X20CL_SPI_RATE)
 #define W25X20CL_SPSR          SPI_SPSR(W25X20CL_SPI_RATE)
 
 
-#include "boards.h"
-#include "Configuration_prusa.h"
-
 //LANG - Multi-language support
 //LANG - Multi-language support
-//#define LANG_MODE              0 // primary language only
+//define LANG_MODE              0 // primary language only
 #define LANG_MODE              1 // sec. language support
 #define LANG_MODE              1 // sec. language support
 
 
 #define LANG_SIZE_RESERVED     0x3000 // reserved space for secondary language (12288 bytes)
 #define LANG_SIZE_RESERVED     0x3000 // reserved space for secondary language (12288 bytes)

+ 13 - 2
Firmware/eeprom.h

@@ -74,7 +74,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
 #define EEPROM_UVLO_CURRENT_POSITION_Z	(EEPROM_FILE_POSITION - 4) //float for current position in Z
 #define EEPROM_UVLO_CURRENT_POSITION_Z	(EEPROM_FILE_POSITION - 4) //float for current position in Z
 #define EEPROM_UVLO_TARGET_HOTEND		(EEPROM_UVLO_CURRENT_POSITION_Z - 1)
 #define EEPROM_UVLO_TARGET_HOTEND		(EEPROM_UVLO_CURRENT_POSITION_Z - 1)
 #define EEPROM_UVLO_TARGET_BED			(EEPROM_UVLO_TARGET_HOTEND - 1)
 #define EEPROM_UVLO_TARGET_BED			(EEPROM_UVLO_TARGET_HOTEND - 1)
-#define EEPROM_UVLO_FEEDRATE			(EEPROM_UVLO_TARGET_BED - 2)
+#define EEPROM_UVLO_FEEDRATE			(EEPROM_UVLO_TARGET_BED - 2) //uint16_t
 #define EEPROM_UVLO_FAN_SPEED			(EEPROM_UVLO_FEEDRATE - 1) 
 #define EEPROM_UVLO_FAN_SPEED			(EEPROM_UVLO_FEEDRATE - 1) 
 #define EEPROM_FAN_CHECK_ENABLED		(EEPROM_UVLO_FAN_SPEED - 1)
 #define EEPROM_FAN_CHECK_ENABLED		(EEPROM_UVLO_FAN_SPEED - 1)
 #define EEPROM_UVLO_MESH_BED_LEVELING     (EEPROM_FAN_CHECK_ENABLED - 9*2)
 #define EEPROM_UVLO_MESH_BED_LEVELING     (EEPROM_FAN_CHECK_ENABLED - 9*2)
@@ -201,9 +201,20 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
 #define EEPROM_SHEETS_BASE (EEPROM_CHECK_GCODE - EEPROM_SHEETS_SIZEOF) // Sheets
 #define EEPROM_SHEETS_BASE (EEPROM_CHECK_GCODE - EEPROM_SHEETS_SIZEOF) // Sheets
 static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
 static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
 
 
+#define EEPROM_FSENSOR_PCB (EEPROM_SHEETS_BASE-1) // uint8
+#define EEPROM_FSENSOR_ACTION_NA (EEPROM_FSENSOR_PCB-1) // uint8
+
+#define EEPROM_UVLO_SAVED_TARGET (EEPROM_FSENSOR_ACTION_NA - 4*4) // 4 x float for saved target for all axes
+#define EEPROM_UVLO_FEEDMULTIPLY (EEPROM_UVLO_SAVED_TARGET - 2) // uint16_t for feedmultiply
+
+#define EEPROM_BACKLIGHT_LEVEL_HIGH (EEPROM_UVLO_FEEDMULTIPLY-1) // uint8
+#define EEPROM_BACKLIGHT_LEVEL_LOW (EEPROM_BACKLIGHT_LEVEL_HIGH-1) // uint8
+#define EEPROM_BACKLIGHT_MODE (EEPROM_BACKLIGHT_LEVEL_LOW-1) // uint8
+#define EEPROM_BACKLIGHT_TIMEOUT (EEPROM_BACKLIGHT_MODE-2) // uint16
+
 
 
 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
 //This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
-#define EEPROM_LAST_ITEM EEPROM_SHEETS_BASE
+#define EEPROM_LAST_ITEM EEPROM_BACKLIGHT_TIMEOUT
 // !!!!!
 // !!!!!
 // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
 // !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
 // !!!!!
 // !!!!!

+ 134 - 38
Firmware/fsensor.cpp

@@ -15,6 +15,10 @@
 #include "mmu.h"
 #include "mmu.h"
 #include "cardreader.h"
 #include "cardreader.h"
 
 
+#include "adc.h"
+#include "temperature.h"
+#include "config.h"
+
 //! @name Basic parameters
 //! @name Basic parameters
 //! @{
 //! @{
 #define FSENSOR_CHUNK_LEN    0.64F  //!< filament sensor chunk length 0.64mm
 #define FSENSOR_CHUNK_LEN    0.64F  //!< filament sensor chunk length 0.64mm
@@ -53,15 +57,8 @@ bool fsensor_enabled = true;
 bool fsensor_watch_runout = true;
 bool fsensor_watch_runout = true;
 //! not responding - is set if any communication error occurred during initialization or readout
 //! not responding - is set if any communication error occurred during initialization or readout
 bool fsensor_not_responding = false;
 bool fsensor_not_responding = false;
-//! printing saved
-bool fsensor_printing_saved = false;
 //! enable/disable quality meassurement
 //! enable/disable quality meassurement
 bool fsensor_oq_meassure_enabled = false;
 bool fsensor_oq_meassure_enabled = false;
-//! as explained in the CHECK_FSENSOR macro: this flag is set to true when fsensor posts
-//! the M600 into the command queue, which elliminates the hazard of having posted multiple M600's
-//! before the first one gets read and started processing.
-//! Btw., the IR fsensor could do up to 6 posts before the command queue managed to start processing the first M600 ;)
-static bool fsensor_m600_enqueued = false;
 
 
 //! number of errors, updated in ISR
 //! number of errors, updated in ISR
 uint8_t fsensor_err_cnt = 0;
 uint8_t fsensor_err_cnt = 0;
@@ -117,6 +114,13 @@ int16_t fsensor_oq_yd_max;
 uint16_t fsensor_oq_sh_sum;
 uint16_t fsensor_oq_sh_sum;
 //! @}
 //! @}
 
 
+#if IR_SENSOR_ANALOG
+ClFsensorPCB oFsensorPCB;
+ClFsensorActionNA oFsensorActionNA;
+bool bIRsensorStateFlag=false;
+unsigned long nIRsensorLastTime;
+#endif //IR_SENSOR_ANALOG
+
 void fsensor_stop_and_save_print(void)
 void fsensor_stop_and_save_print(void)
 {
 {
     printf_P(PSTR("fsensor_stop_and_save_print\n"));
     printf_P(PSTR("fsensor_stop_and_save_print\n"));
@@ -126,20 +130,28 @@ void fsensor_stop_and_save_print(void)
 void fsensor_restore_print_and_continue(void)
 void fsensor_restore_print_and_continue(void)
 {
 {
     printf_P(PSTR("fsensor_restore_print_and_continue\n"));
     printf_P(PSTR("fsensor_restore_print_and_continue\n"));
-	fsensor_watch_runout = true;
 	fsensor_err_cnt = 0;
 	fsensor_err_cnt = 0;
-	fsensor_m600_enqueued = false;
     restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change
     restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change
 }
 }
 
 
+// fsensor_checkpoint_print cuts the current print job at the current position,
+// allowing new instructions to be inserted in the middle
+void fsensor_checkpoint_print(void)
+{
+    printf_P(PSTR("fsensor_checkpoint_print\n"));
+    stop_and_save_print_to_ram(0, 0);
+    restore_print_from_ram_and_continue(0);
+}
+
 void fsensor_init(void)
 void fsensor_init(void)
 {
 {
 #ifdef PAT9125
 #ifdef PAT9125
 	uint8_t pat9125 = pat9125_init();
 	uint8_t pat9125 = pat9125_init();
-    printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
+     printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
 #endif //PAT9125
 #endif //PAT9125
 	uint8_t fsensor = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	uint8_t fsensor = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
 	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
+     fsensor_not_responding = false;
 #ifdef PAT9125
 #ifdef PAT9125
 	uint8_t oq_meassure_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENS_OQ_MEASS_ENABLED);
 	uint8_t oq_meassure_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENS_OQ_MEASS_ENABLED);
 	fsensor_oq_meassure_enabled = (oq_meassure_enabled == 1)?true:false;
 	fsensor_oq_meassure_enabled = (oq_meassure_enabled == 1)?true:false;
@@ -150,19 +162,27 @@ void fsensor_init(void)
 		fsensor = 0; //disable sensor
 		fsensor = 0; //disable sensor
 		fsensor_not_responding = true;
 		fsensor_not_responding = true;
 	}
 	}
-	else
-		fsensor_not_responding = false;
 #endif //PAT9125
 #endif //PAT9125
+#if IR_SENSOR_ANALOG
+     bIRsensorStateFlag=false;
+     oFsensorPCB=(ClFsensorPCB)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_PCB);
+     oFsensorActionNA=(ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA);
+#endif //IR_SENSOR_ANALOG
 	if (fsensor)
 	if (fsensor)
-		fsensor_enable();
+		fsensor_enable(false);                  // (in this case) EEPROM update is not necessary
 	else
 	else
-		fsensor_disable();
-	printf_P(PSTR("FSensor %S\n"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED\n")));
+		fsensor_disable(false);                 // (in this case) EEPROM update is not necessary
+	printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED")));
+#if IR_SENSOR_ANALOG
+     printf_P(PSTR(" (sensor board revision: %S)\n"),(oFsensorPCB==ClFsensorPCB::_Rev03b)?PSTR("03b or newer"):PSTR("03 or older"));
+#else //IR_SENSOR_ANALOG
+     printf_P(PSTR("\n"));
+#endif //IR_SENSOR_ANALOG
 	if (check_for_ir_sensor()) ir_sensor_detected = true;
 	if (check_for_ir_sensor()) ir_sensor_detected = true;
 
 
 }
 }
 
 
-bool fsensor_enable(void)
+bool fsensor_enable(bool bUpdateEEPROM)
 {
 {
 #ifdef PAT9125
 #ifdef PAT9125
 	if (mmu_enabled == false) { //filament sensor is pat9125, enable only if it is working
 	if (mmu_enabled == false) { //filament sensor is pat9125, enable only if it is working
@@ -187,18 +207,34 @@ bool fsensor_enable(void)
 		FSensorStateMenu = 1;
 		FSensorStateMenu = 1;
 	}
 	}
 #else // PAT9125
 #else // PAT9125
-	fsensor_enabled = true;
-	eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x01);
-	FSensorStateMenu = 1;
-#endif // PAT9125
+#if IR_SENSOR_ANALOG
+     if(!fsensor_IR_check())
+          {
+          bUpdateEEPROM=true;
+          fsensor_enabled=false;
+          fsensor_not_responding=true;
+          FSensorStateMenu=0;
+          }
+     else {
+#endif //IR_SENSOR_ANALOG
+     fsensor_enabled=true;
+     fsensor_not_responding=false;
+     FSensorStateMenu=1;
+#if IR_SENSOR_ANALOG
+          }
+#endif //IR_SENSOR_ANALOG
+     if(bUpdateEEPROM)
+          eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, FSensorStateMenu);
+#endif //PAT9125
 	return fsensor_enabled;
 	return fsensor_enabled;
 }
 }
 
 
-void fsensor_disable(void)
-{
+void fsensor_disable(bool bUpdateEEPROM)
+{ 
 	fsensor_enabled = false;
 	fsensor_enabled = false;
-	eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x00); 
 	FSensorStateMenu = 0;
 	FSensorStateMenu = 0;
+     if(bUpdateEEPROM)
+          eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x00); 
 }
 }
 
 
 void fsensor_autoload_set(bool State)
 void fsensor_autoload_set(bool State)
@@ -529,8 +565,6 @@ void fsensor_enque_M600(){
 	printf_P(PSTR("fsensor_update - M600\n"));
 	printf_P(PSTR("fsensor_update - M600\n"));
 	eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
 	eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
 	eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
 	eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
-	enquecommand_front_P(PSTR("PRUSA fsensor_recover"));
-	fsensor_m600_enqueued = true;
 	enquecommand_front_P((PSTR("M600")));
 	enquecommand_front_P((PSTR("M600")));
 }
 }
 
 
@@ -542,7 +576,7 @@ void fsensor_enque_M600(){
 void fsensor_update(void)
 void fsensor_update(void)
 {
 {
 #ifdef PAT9125
 #ifdef PAT9125
-		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX) && ( ! fsensor_m600_enqueued) )
+		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
 		{
 		{
 			bool autoload_enabled_tmp = fsensor_autoload_enabled;
 			bool autoload_enabled_tmp = fsensor_autoload_enabled;
 			fsensor_autoload_enabled = false;
 			fsensor_autoload_enabled = false;
@@ -575,24 +609,86 @@ void fsensor_update(void)
 			err |= (fsensor_oq_er_sum > 2);
 			err |= (fsensor_oq_er_sum > 2);
 			err |= (fsensor_oq_yd_sum < (4 * FSENSOR_OQ_MIN_YD));
 			err |= (fsensor_oq_yd_sum < (4 * FSENSOR_OQ_MIN_YD));
 
 
+            fsensor_restore_print_and_continue();
+			fsensor_autoload_enabled = autoload_enabled_tmp;
+			fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
+
 			if (!err)
 			if (!err)
-			{
 				printf_P(PSTR("fsensor_err_cnt = 0\n"));
 				printf_P(PSTR("fsensor_err_cnt = 0\n"));
-				fsensor_restore_print_and_continue();
-			}
 			else
 			else
-			{
 				fsensor_enque_M600();
 				fsensor_enque_M600();
-				fsensor_watch_runout = false;
-			}
-			fsensor_autoload_enabled = autoload_enabled_tmp;
-			fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
 		}
 		}
 #else //PAT9125
 #else //PAT9125
-		if ((digitalRead(IR_SENSOR_PIN) == 1) && CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected && ( ! fsensor_m600_enqueued) )
-		{
-			fsensor_stop_and_save_print();
-			fsensor_enque_M600();
+		if (CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected)
+        {
+               if(digitalRead(IR_SENSOR_PIN))
+               {                                  // IR_SENSOR_PIN ~ H
+#if IR_SENSOR_ANALOG
+                    if(!bIRsensorStateFlag)
+                    {
+                         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<<ADSC);  // first conversion after ADMUX change discarded (preventively)
+                              while(ADCSRA&(1<<ADSC))
+                                   ;
+                              ADCSRA|=(1<<ADSC);  // second conversion used
+                              while(ADCSRA&(1<<ADSC))
+                                   ;
+                              nADC=ADC;
+                              ADMUX=nMUX1;        // ADMUX restoring
+                              ADCSRB=nMUX2;
+                              ENABLE_TEMPERATURE_INTERRUPT();
+                              // end of sequence for ...
+                              if((oFsensorPCB==ClFsensorPCB::_Rev03b)&&((nADC*OVERSAMPLENR)>((int)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(oFsensorActionNA==ClFsensorActionNA::_Pause)
+                                        lcd_pause_print();
+                              }
+                              else
+                              {
+#endif //IR_SENSOR_ANALOG
+                                  fsensor_checkpoint_print();
+                                  fsensor_enque_M600();
+#if IR_SENSOR_ANALOG
+                              }
+                         }
+                    }
+               }
+               else
+               {                                  // IR_SENSOR_PIN ~ L
+                    bIRsensorStateFlag=false;
+#endif //IR_SENSOR_ANALOG
+               }
 		}
 		}
 #endif //PAT9125
 #endif //PAT9125
 }
 }
+
+#if IR_SENSOR_ANALOG
+bool fsensor_IR_check()
+{
+uint16_t volt_IR_int;
+bool bCheckResult;
+
+volt_IR_int=current_voltage_raw_IR;
+bCheckResult=(volt_IR_int<((int)IRsensor_Lmax_TRESHOLD))||(volt_IR_int>((int)IRsensor_Hmin_TRESHOLD));
+bCheckResult=bCheckResult&&(!((oFsensorPCB==ClFsensorPCB::_Rev03b)&&(volt_IR_int>((int)IRsensor_Hopen_TRESHOLD))));
+return(bCheckResult);
+}
+#endif //IR_SENSOR_ANALOG

+ 29 - 2
Firmware/fsensor.h

@@ -3,6 +3,7 @@
 #define FSENSOR_H
 #define FSENSOR_H
 
 
 #include <inttypes.h>
 #include <inttypes.h>
+#include "config.h"
 
 
 
 
 //! minimum meassured chunk length in steps
 //! minimum meassured chunk length in steps
@@ -20,6 +21,8 @@ extern bool fsensor_oq_meassure_enabled;
 extern void fsensor_stop_and_save_print(void);
 extern void fsensor_stop_and_save_print(void);
 //! restore print - restore position and heatup to original temperature
 //! restore print - restore position and heatup to original temperature
 extern void fsensor_restore_print_and_continue(void);
 extern void fsensor_restore_print_and_continue(void);
+//! split the current gcode stream to insert new instructions
+extern void fsensor_checkpoint_print(void);
 //! @}
 //! @}
 
 
 //! initialize
 //! initialize
@@ -27,8 +30,8 @@ extern void fsensor_init(void);
 
 
 //! @name enable/disable
 //! @name enable/disable
 //! @{
 //! @{
-extern bool fsensor_enable(void);
-extern void fsensor_disable(void);
+extern bool fsensor_enable(bool bUpdateEEPROM=true);
+extern void fsensor_disable(bool bUpdateEEPROM=true);
 //! @}
 //! @}
 
 
 //autoload feature enabled
 //autoload feature enabled
@@ -65,4 +68,28 @@ extern void fsensor_st_block_begin(block_t* bl);
 extern void fsensor_st_block_chunk(block_t* bl, int cnt);
 extern void fsensor_st_block_chunk(block_t* bl, int cnt);
 //! @}
 //! @}
 
 
+
+#if IR_SENSOR_ANALOG
+#define IR_SENSOR_STEADY 10                       // [ms]
+
+enum class ClFsensorPCB:uint_least8_t
+{
+    _Old=0,
+    _Rev03b=1,
+    _Undef=EEPROM_EMPTY_VALUE
+};
+
+enum class ClFsensorActionNA:uint_least8_t
+{
+    _Continue=0,
+    _Pause=1,
+    _Undef=EEPROM_EMPTY_VALUE
+};
+
+extern ClFsensorPCB oFsensorPCB;
+extern ClFsensorActionNA oFsensorActionNA;
+
+extern bool fsensor_IR_check();
+#endif //IR_SENSOR_ANALOG
+
 #endif //FSENSOR_H
 #endif //FSENSOR_H

+ 3 - 3
Firmware/language.c

@@ -17,10 +17,10 @@ uint8_t lang_selected = 0;
 
 
 #if (LANG_MODE == 0) //primary language only
 #if (LANG_MODE == 0) //primary language only
 
 
-uint8_t lang_select(uint8_t lang) { return 0; }
+uint8_t lang_select(__attribute__((unused)) uint8_t lang) { return 0; }
 uint8_t lang_get_count() { return 1; }
 uint8_t lang_get_count() { return 1; }
-uint16_t lang_get_code(uint8_t lang) { return LANG_CODE_EN; }
-const char* lang_get_name_by_code(uint16_t code) { return _n("English"); }
+uint16_t lang_get_code(__attribute__((unused)) uint8_t lang) { return LANG_CODE_EN; }
+const char* lang_get_name_by_code(__attribute__((unused)) uint16_t code) { return _n("English"); }
 void lang_reset(void) { }
 void lang_reset(void) { }
 uint8_t lang_is_selected(void) { return 1; }
 uint8_t lang_is_selected(void) { return 1; }
 
 

+ 46 - 8
Firmware/menu.cpp

@@ -184,6 +184,22 @@ static void menu_draw_item_puts_P(char type_char, const char* str)
     lcd_printf_P(PSTR("%c%-18.18S%c"), menu_selection_mark(), str, type_char);
     lcd_printf_P(PSTR("%c%-18.18S%c"), menu_selection_mark(), str, type_char);
 }
 }
 
 
+static void menu_draw_toggle_puts_P(const char* str, const char* toggle, const uint8_t settings)
+{
+    //settings:
+    //xxxxxcba
+    //a = selection mark. If it's set(1), then '>' will be used as the first character on the line. Else leave blank
+    //b = toggle string is from progmem
+    //c = do not set cursor at all. Must be handled externally.
+    char lineStr[LCD_WIDTH + 1];
+    const char eol = (toggle == NULL)?LCD_STR_ARROW_RIGHT[0]:' ';
+    if (toggle == NULL) toggle = _T(MSG_NA);
+    sprintf_P(lineStr, PSTR("%c%-18.18S"), (settings & 0x01)?'>':' ', str);
+    sprintf_P(lineStr + LCD_WIDTH - ((settings & 0x02)?strlen_P(toggle):strlen(toggle)) - 3, (settings & 0x02)?PSTR("[%S]%c"):PSTR("[%s]%c"), toggle, eol);
+    if (!(settings & 0x04)) lcd_set_cursor(0, menu_row);
+    fputs(lineStr, lcdout);
+}
+
 //! @brief Format sheet name
 //! @brief Format sheet name
 //!
 //!
 //! @param[in] sheet_E Sheet in EEPROM
 //! @param[in] sheet_E Sheet in EEPROM
@@ -375,6 +391,33 @@ uint8_t menu_item_function_P(const char* str, char number, void (*func)(uint8_t)
     return 0;
     return 0;
 }
 }
 
 
+uint8_t menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func, const uint8_t settings)
+{
+	if (menu_item == menu_line)
+	{
+		if (lcd_draw_update) menu_draw_toggle_puts_P(str, toggle, settings | (menu_selection_mark()=='>'));
+		if (menu_clicked && (lcd_encoder == menu_item))
+		{
+			if (toggle == NULL) // print N/A warning message
+			{
+				menu_submenu(func);
+				return menu_item_ret();
+			}
+			else // do the actual toggling
+			{
+				menu_clicked = false;
+				lcd_consume_click();
+				lcd_update_enabled = 0;
+				if (func) func();
+				lcd_update_enabled = 1;
+				return menu_item_ret();
+			}
+		}
+	}
+	menu_item++;
+	return 0;
+}
+
 uint8_t menu_item_gcode_P(const char* str, const char* str_gcode)
 uint8_t menu_item_gcode_P(const char* str, const char* str_gcode)
 {
 {
 	if (menu_item == menu_line)
 	if (menu_item == menu_line)
@@ -390,17 +433,12 @@ uint8_t menu_item_gcode_P(const char* str, const char* str_gcode)
 	return 0;
 	return 0;
 }
 }
 
 
-
-const char menu_20x_space[] PROGMEM = "                    ";
-
 const char menu_fmt_int3[] PROGMEM = "%c%.15S:%s%3d";
 const char menu_fmt_int3[] PROGMEM = "%c%.15S:%s%3d";
 
 
 const char menu_fmt_float31[] PROGMEM = "%-12.12S%+8.1f";
 const char menu_fmt_float31[] PROGMEM = "%-12.12S%+8.1f";
 
 
 const char menu_fmt_float13[] PROGMEM = "%c%-13.13S%+5.3f";
 const char menu_fmt_float13[] PROGMEM = "%c%-13.13S%+5.3f";
 
 
-const char menu_fmt_float13off[] PROGMEM = "%c%-13.13S%6.6S";
-
 template<typename T>
 template<typename T>
 static void menu_draw_P(char chr, const char* str, int16_t val);
 static void menu_draw_P(char chr, const char* str, int16_t val);
 
 
@@ -409,8 +447,8 @@ void menu_draw_P<int16_t*>(char chr, const char* str, int16_t val)
 {
 {
 	int text_len = strlen_P(str);
 	int text_len = strlen_P(str);
 	if (text_len > 15) text_len = 15;
 	if (text_len > 15) text_len = 15;
-	char spaces[21];
-	strcpy_P(spaces, menu_20x_space);
+	char spaces[LCD_WIDTH + 1] = {0};
+    memset(spaces,' ', LCD_WIDTH);
 	if (val <= -100) spaces[15 - text_len - 1] = 0;
 	if (val <= -100) spaces[15 - text_len - 1] = 0;
 	else spaces[15 - text_len] = 0;
 	else spaces[15 - text_len] = 0;
 	lcd_printf_P(menu_fmt_int3, chr, str, spaces, val);
 	lcd_printf_P(menu_fmt_int3, chr, str, spaces, val);
@@ -423,7 +461,7 @@ void menu_draw_P<uint8_t*>(char chr, const char* str, int16_t val)
     float factor = 1.0f + static_cast<float>(val) / 1000.0f;
     float factor = 1.0f + static_cast<float>(val) / 1000.0f;
     if (val <= _md->minEditValue)
     if (val <= _md->minEditValue)
     {
     {
-        lcd_printf_P(menu_fmt_float13off, chr, str, _i(" [off]"));
+        menu_draw_toggle_puts_P(str, _T(MSG_OFF), 0x04 | 0x02 | (chr=='>'));
     }
     }
     else
     else
     {
     {

+ 4 - 0
Firmware/menu.h

@@ -118,6 +118,10 @@ extern uint8_t menu_item_function_P(const char* str, menu_func_t func);
 #define MENU_ITEM_FUNCTION_NR_P(str, number, func, fn_par) do { if (menu_item_function_P(str, number, func, fn_par)) return; } while (0)
 #define MENU_ITEM_FUNCTION_NR_P(str, number, func, fn_par) do { if (menu_item_function_P(str, number, func, fn_par)) return; } while (0)
 extern uint8_t menu_item_function_P(const char* str, char number, void (*func)(uint8_t), uint8_t fn_par);
 extern uint8_t menu_item_function_P(const char* str, char number, void (*func)(uint8_t), uint8_t fn_par);
 
 
+#define MENU_ITEM_TOGGLE_P(str, toggle, func) do { if (menu_item_toggle_P(str, toggle, func, 0x02)) return; } while (0)
+#define MENU_ITEM_TOGGLE(str, toggle, func) do { if (menu_item_toggle_P(str, toggle, func, 0x00)) return; } while (0)
+extern uint8_t menu_item_toggle_P(const char* str, const char* toggle, menu_func_t func, const uint8_t settings);
+
 #define MENU_ITEM_GCODE_P(str, str_gcode) do { if (menu_item_gcode_P(str, str_gcode)) return; } while (0)
 #define MENU_ITEM_GCODE_P(str, str_gcode) do { if (menu_item_gcode_P(str, str_gcode)) return; } while (0)
 extern uint8_t menu_item_gcode_P(const char* str, const char* str_gcode);
 extern uint8_t menu_item_gcode_P(const char* str, const char* str_gcode);
 
 

+ 48 - 14
Firmware/messages.c

@@ -9,7 +9,6 @@
 
 
 //internationalized messages
 //internationalized messages
 const char MSG_AUTO_HOME[] PROGMEM_I1 = ISTR("Auto home"); ////
 const char MSG_AUTO_HOME[] PROGMEM_I1 = ISTR("Auto home"); ////
-const char MSG_AUTO_MODE_ON[] PROGMEM_I1 = ISTR("Mode [auto power]"); ////
 const char MSG_BABYSTEP_Z[] PROGMEM_I1 = ISTR("Live adjust Z"); //// c=18
 const char MSG_BABYSTEP_Z[] PROGMEM_I1 = ISTR("Live adjust Z"); //// c=18
 const char MSG_BABYSTEP_Z_NOT_SET[] PROGMEM_I1 = ISTR("Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."); ////c=20 r=12
 const char MSG_BABYSTEP_Z_NOT_SET[] PROGMEM_I1 = ISTR("Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."); ////c=20 r=12
 const char MSG_BED[] PROGMEM_I1 = ISTR("Bed"); ////
 const char MSG_BED[] PROGMEM_I1 = ISTR("Bed"); ////
@@ -22,9 +21,7 @@ const char MSG_CARD_MENU[] PROGMEM_I1 = ISTR("Print from SD"); ////
 const char MSG_CONFIRM_NOZZLE_CLEAN[] PROGMEM_I1 = ISTR("Please clean the nozzle for calibration. Click when done."); ////c=20 r=8
 const char MSG_CONFIRM_NOZZLE_CLEAN[] PROGMEM_I1 = ISTR("Please clean the nozzle for calibration. Click when done."); ////c=20 r=8
 const char MSG_COOLDOWN[] PROGMEM_I1 = ISTR("Cooldown"); ////
 const char MSG_COOLDOWN[] PROGMEM_I1 = ISTR("Cooldown"); ////
 const char MSG_CRASH_DETECTED[] PROGMEM_I1 = ISTR("Crash detected."); ////c=20 r=1
 const char MSG_CRASH_DETECTED[] PROGMEM_I1 = ISTR("Crash detected."); ////c=20 r=1
-const char MSG_CRASHDETECT_NA[] PROGMEM_I1 = ISTR("Crash det.  [N/A]"); ////
-const char MSG_CRASHDETECT_OFF[] PROGMEM_I1 = ISTR("Crash det.  [off]"); ////
-const char MSG_CRASHDETECT_ON[] PROGMEM_I1 = ISTR("Crash det.   [on]"); ////
+const char MSG_CRASHDETECT[] PROGMEM_I1 = ISTR("Crash det."); ////
 const char MSG_ERROR[] PROGMEM_I1 = ISTR("ERROR:"); ////
 const char MSG_ERROR[] PROGMEM_I1 = ISTR("ERROR:"); ////
 const char MSG_EXTRUDER[] PROGMEM_I1 = ISTR("Extruder"); ////c=17 r=1
 const char MSG_EXTRUDER[] PROGMEM_I1 = ISTR("Extruder"); ////c=17 r=1
 const char MSG_FILAMENT[] PROGMEM_I1 = ISTR("Filament"); ////c=17 r=1
 const char MSG_FILAMENT[] PROGMEM_I1 = ISTR("Filament"); ////c=17 r=1
@@ -40,9 +37,8 @@ const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2[] PROGMEM_I1 = ISTR(" of 4"); ////
 const char MSG_FINISHING_MOVEMENTS[] PROGMEM_I1 = ISTR("Finishing movements"); ////c=20 r=1
 const char MSG_FINISHING_MOVEMENTS[] PROGMEM_I1 = ISTR("Finishing movements"); ////c=20 r=1
 const char MSG_FOLLOW_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."); ////c=20 r=8
 const char MSG_FOLLOW_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."); ////c=20 r=8
 const char MSG_FOLLOW_Z_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("There is still a need to make Z calibration. Please follow the manual, chapter First steps, section Calibration flow."); ////c=20 r=8
 const char MSG_FOLLOW_Z_CALIBRATION_FLOW[] PROGMEM_I1 = ISTR("There is still a need to make Z calibration. Please follow the manual, chapter First steps, section Calibration flow."); ////c=20 r=8
-const char MSG_FSENS_AUTOLOAD_NA[] PROGMEM_I1 = ISTR("F. autoload [N/A]"); ////c=17 r=1
-const char MSG_FSENSOR_OFF[] PROGMEM_I1 = ISTR("Fil. sensor [off]"); ////
-const char MSG_FSENSOR_ON[] PROGMEM_I1 = ISTR("Fil. sensor  [on]"); ////
+const char MSG_FSENSOR_AUTOLOAD[] PROGMEM_I1 = ISTR("F. autoload"); ////c=17 r=1
+const char MSG_FSENSOR[] PROGMEM_I1 = ISTR("Fil. sensor"); ////
 const char MSG_HEATING[] PROGMEM_I1 = ISTR("Heating"); ////
 const char MSG_HEATING[] PROGMEM_I1 = ISTR("Heating"); ////
 const char MSG_HEATING_COMPLETE[] PROGMEM_I1 = ISTR("Heating done."); ////c=20
 const char MSG_HEATING_COMPLETE[] PROGMEM_I1 = ISTR("Heating done."); ////c=20
 const char MSG_HOMEYZ[] PROGMEM_I1 = ISTR("Calibrate Z"); ////
 const char MSG_HOMEYZ[] PROGMEM_I1 = ISTR("Calibrate Z"); ////
@@ -85,14 +81,16 @@ const char MSG_SELFTEST_FILAMENT_SENSOR[] PROGMEM_I1 = ISTR("Filament sensor");
 const char MSG_SELFTEST_WIRINGERROR[] PROGMEM_I1 = ISTR("Wiring error"); ////
 const char MSG_SELFTEST_WIRINGERROR[] PROGMEM_I1 = ISTR("Wiring error"); ////
 const char MSG_SETTINGS[] PROGMEM_I1 = ISTR("Settings"); ////
 const char MSG_SETTINGS[] PROGMEM_I1 = ISTR("Settings"); ////
 const char MSG_HW_SETUP[] PROGMEM_I1 = ISTR("HW Setup"); ////
 const char MSG_HW_SETUP[] PROGMEM_I1 = ISTR("HW Setup"); ////
-const char MSG_SILENT_MODE_OFF[] PROGMEM_I1 = ISTR("Mode [high power]"); ////
-const char MSG_SILENT_MODE_ON[] PROGMEM_I1 = ISTR("Mode     [silent]"); ////
-const char MSG_STEALTH_MODE_OFF[] PROGMEM_I1 = ISTR("Mode     [Normal]"); ////
-const char MSG_STEALTH_MODE_ON[] PROGMEM_I1 = ISTR("Mode    [Stealth]"); ////
+const char MSG_MODE[] PROGMEM_I1 = ISTR("Mode"); ////
+const char MSG_HIGH_POWER[] PROGMEM_I1 = ISTR("High power"); ////
+const char MSG_AUTO_POWER[] PROGMEM_I1 = ISTR("Auto power"); ////
+const char MSG_SILENT[] PROGMEM_I1 = ISTR("Silent"); ////
+const char MSG_NORMAL[] PROGMEM_I1 = ISTR("Normal"); ////
+const char MSG_STEALTH[] PROGMEM_I1 = ISTR("Stealth"); ////
 const char MSG_STEEL_SHEET_CHECK[] PROGMEM_I1 = ISTR("Is steel sheet on heatbed?"); ////c=20 r=2
 const char MSG_STEEL_SHEET_CHECK[] PROGMEM_I1 = ISTR("Is steel sheet on heatbed?"); ////c=20 r=2
 const char MSG_STOP_PRINT[] PROGMEM_I1 = ISTR("Stop print"); ////
 const char MSG_STOP_PRINT[] PROGMEM_I1 = ISTR("Stop print"); ////
 const char MSG_STOPPED[] PROGMEM_I1 = ISTR("STOPPED. "); ////
 const char MSG_STOPPED[] PROGMEM_I1 = ISTR("STOPPED. "); ////
-const char MSG_TEMP_CALIBRATION[] PROGMEM_I1 = ISTR("Temp. cal.          "); ////c=20 r=1
+const char MSG_TEMP_CALIBRATION[] PROGMEM_I1 = ISTR("Temp. cal."); ////c=12 r=1
 const char MSG_TEMP_CALIBRATION_DONE[] PROGMEM_I1 = ISTR("Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal."); ////c=20 r=12
 const char MSG_TEMP_CALIBRATION_DONE[] PROGMEM_I1 = ISTR("Temperature calibration is finished and active. Temp. calibration can be disabled in menu Settings->Temp. cal."); ////c=20 r=12
 const char MSG_UNLOAD_FILAMENT[] PROGMEM_I1 = ISTR("Unload filament"); ////c=17
 const char MSG_UNLOAD_FILAMENT[] PROGMEM_I1 = ISTR("Unload filament"); ////c=17
 const char MSG_UNLOADING_FILAMENT[] PROGMEM_I1 = ISTR("Unloading filament"); ////c=20 r=1
 const char MSG_UNLOADING_FILAMENT[] PROGMEM_I1 = ISTR("Unloading filament"); ////c=20 r=1
@@ -104,13 +102,48 @@ const char MSG_WIZARD_QUIT[] PROGMEM_I1 = ISTR("You can always resume the Wizard
 const char MSG_YES[] PROGMEM_I1 = ISTR("Yes"); ////
 const char MSG_YES[] PROGMEM_I1 = ISTR("Yes"); ////
 const char MSG_V2_CALIBRATION[] PROGMEM_I1 = ISTR("First layer cal."); ////c=17 r=1
 const char MSG_V2_CALIBRATION[] PROGMEM_I1 = ISTR("First layer cal."); ////c=17 r=1
 const char WELCOME_MSG[] PROGMEM_I1 = ISTR(CUSTOM_MENDEL_NAME " OK."); ////c=20
 const char WELCOME_MSG[] PROGMEM_I1 = ISTR(CUSTOM_MENDEL_NAME " OK."); ////c=20
+const char MSG_OFF[] PROGMEM_I1 = ISTR("Off"); ////
+const char MSG_ON[] PROGMEM_I1 = ISTR("On"); ////
+const char MSG_NA[] PROGMEM_I1 = ISTR("N/A"); ////
+const char MSG_AUTO_DEPLETE[] PROGMEM_I1 = ISTR("SpoolJoin"); ////
+const char MSG_CUTTER[] PROGMEM_I1 = ISTR("Cutter"); ////
+const char MSG_NONE[] PROGMEM_I1 = ISTR("None"); ////
+const char MSG_WARN[] PROGMEM_I1 = ISTR("Warn"); ////
+const char MSG_STRICT[] PROGMEM_I1 = ISTR("Strict"); ////
+const char MSG_MODEL[] PROGMEM_I1 = ISTR("Model"); ////
+const char MSG_FIRMWARE[] PROGMEM_I1 = ISTR("Firmware"); ////
+const char MSG_GCODE[] PROGMEM_I1 = ISTR("Gcode"); ////
+const char MSG_NOZZLE_DIAMETER[] PROGMEM_I1 = ISTR("Nozzle d."); ////
+const char MSG_MMU_MODE[] PROGMEM_I1 = ISTR("MMU Mode"); ////
+const char MSG_SD_CARD[] PROGMEM_I1 = ISTR("SD card"); ////
+const char MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY[] PROGMEM_I1 = ISTR("FlashAir"); ////
+const char MSG_SORT[] PROGMEM_I1 = ISTR("Sort"); ////
+const char MSG_SORT_TIME[] PROGMEM_I1 = ISTR("Time"); ////
+const char MSG_SORT_ALPHA[] PROGMEM_I1 = ISTR("Alphabet"); ////
+const char MSG_RPI_PORT[] PROGMEM_I1 = ISTR("RPi port"); ////
+const char MSG_SOUND[] PROGMEM_I1 = ISTR("Sound"); ////
+const char MSG_SOUND_LOUD[] PROGMEM_I1 = ISTR("Loud"); ////
+const char MSG_SOUND_ONCE[] PROGMEM_I1 = ISTR("Once"); ////
+const char MSG_SOUND_BLIND[] PROGMEM_I1 = ISTR("Assist"); ////
+const char MSG_MESH[] PROGMEM_I1 = ISTR("Mesh"); ////
+const char MSG_Z_PROBE_NR[] PROGMEM_I1 = ISTR("Z-probe nr."); ////
+const char MSG_MAGNETS_COMP[] PROGMEM_I1 = ISTR("Magnets comp."); ////
+const char MSG_FS_ACTION[] PROGMEM_I1 = ISTR("FS Action"); ////
+const char MSG_FS_CONTINUE[] PROGMEM_I1 = ISTR("Cont."); ////
+const char MSG_FS_PAUSE[] PROGMEM_I1 = ISTR("Pause"); ////
+const char MSG_BRIGHTNESS[] PROGMEM_I1 = ISTR("Brightness"); ////
+const char MSG_BL_HIGH[] PROGMEM_I1 = ISTR("Level Bright"); ////
+const char MSG_BL_LOW[] PROGMEM_I1 = ISTR("Level Dimmed"); ////
+const char MSG_TIMEOUT[] PROGMEM_I1 = ISTR("Timeout"); ////
+const char MSG_BRIGHT[] PROGMEM_I1 = ISTR("Bright"); ////
+const char MSG_DIM[] PROGMEM_I1 = ISTR("Dim"); ////
+const char MSG_AUTO[] PROGMEM_I1 = ISTR("Auto"); ////
+
 //not internationalized messages
 //not internationalized messages
 const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////
 const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////
 const char MSG_BROWNOUT_RESET[] PROGMEM_N1 = " Brown out Reset"; ////
 const char MSG_BROWNOUT_RESET[] PROGMEM_N1 = " Brown out Reset"; ////
 const char MSG_EXTERNAL_RESET[] PROGMEM_N1 = " External Reset"; ////
 const char MSG_EXTERNAL_RESET[] PROGMEM_N1 = " External Reset"; ////
 const char MSG_FILE_SAVED[] PROGMEM_N1 = "Done saving file."; ////
 const char MSG_FILE_SAVED[] PROGMEM_N1 = "Done saving file."; ////
-const char MSG_OFF[] PROGMEM_N1 = "Off"; ////
-const char MSG_ON[] PROGMEM_N1 = "On "; ////
 const char MSG_POSITION_UNKNOWN[] PROGMEM_N1 = "Home X/Y before Z"; ////
 const char MSG_POSITION_UNKNOWN[] PROGMEM_N1 = "Home X/Y before Z"; ////
 const char MSG_SOFTWARE_RESET[] PROGMEM_N1 = " Software Reset"; ////
 const char MSG_SOFTWARE_RESET[] PROGMEM_N1 = " Software Reset"; ////
 const char MSG_UNKNOWN_COMMAND[] PROGMEM_N1 = "Unknown command: \""; ////
 const char MSG_UNKNOWN_COMMAND[] PROGMEM_N1 = "Unknown command: \""; ////
@@ -134,3 +167,4 @@ const char MSG_OCTOPRINT_RESUMED[] PROGMEM_N1 = "// action:resumed"; ////
 const char MSG_OCTOPRINT_CANCEL[] PROGMEM_N1 = "// action:cancel"; ////
 const char MSG_OCTOPRINT_CANCEL[] PROGMEM_N1 = "// action:cancel"; ////
 const char MSG_FANCHECK_EXTRUDER[] PROGMEM_N1 = "Err: EXTR. FAN ERROR"; ////c=20
 const char MSG_FANCHECK_EXTRUDER[] PROGMEM_N1 = "Err: EXTR. FAN ERROR"; ////c=20
 const char MSG_FANCHECK_PRINT[] PROGMEM_N1 = "Err: PRINT FAN ERROR"; ////c=20
 const char MSG_FANCHECK_PRINT[] PROGMEM_N1 = "Err: PRINT FAN ERROR"; ////c=20
+const char MSG_M112_KILL[] PROGMEM_N1 = "M112 called. Emergency Stop."; ////c=20

+ 47 - 13
Firmware/messages.h

@@ -10,7 +10,6 @@ extern "C" {
 // LCD Menu Messages
 // LCD Menu Messages
 //internationalized messages
 //internationalized messages
 extern const char MSG_AUTO_HOME[];
 extern const char MSG_AUTO_HOME[];
-extern const char MSG_AUTO_MODE_ON[];
 extern const char MSG_BABYSTEP_Z[];
 extern const char MSG_BABYSTEP_Z[];
 extern const char MSG_BABYSTEP_Z_NOT_SET[];
 extern const char MSG_BABYSTEP_Z_NOT_SET[];
 extern const char MSG_BED[];
 extern const char MSG_BED[];
@@ -23,9 +22,7 @@ extern const char MSG_CARD_MENU[];
 extern const char MSG_CONFIRM_NOZZLE_CLEAN[];
 extern const char MSG_CONFIRM_NOZZLE_CLEAN[];
 extern const char MSG_COOLDOWN[];
 extern const char MSG_COOLDOWN[];
 extern const char MSG_CRASH_DETECTED[];
 extern const char MSG_CRASH_DETECTED[];
-extern const char MSG_CRASHDETECT_NA[];
-extern const char MSG_CRASHDETECT_OFF[];
-extern const char MSG_CRASHDETECT_ON[];
+extern const char MSG_CRASHDETECT[];
 extern const char MSG_ERROR[];
 extern const char MSG_ERROR[];
 extern const char MSG_EXTRUDER[];
 extern const char MSG_EXTRUDER[];
 extern const char MSG_FILAMENT[];
 extern const char MSG_FILAMENT[];
@@ -41,9 +38,8 @@ extern const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2[];
 extern const char MSG_FINISHING_MOVEMENTS[];
 extern const char MSG_FINISHING_MOVEMENTS[];
 extern const char MSG_FOLLOW_CALIBRATION_FLOW[];
 extern const char MSG_FOLLOW_CALIBRATION_FLOW[];
 extern const char MSG_FOLLOW_Z_CALIBRATION_FLOW[];
 extern const char MSG_FOLLOW_Z_CALIBRATION_FLOW[];
-extern const char MSG_FSENS_AUTOLOAD_NA[];
-extern const char MSG_FSENSOR_OFF[];
-extern const char MSG_FSENSOR_ON[];
+extern const char MSG_FSENSOR_AUTOLOAD[];
+extern const char MSG_FSENSOR[];
 extern const char MSG_HEATING[];
 extern const char MSG_HEATING[];
 extern const char MSG_HEATING_COMPLETE[];
 extern const char MSG_HEATING_COMPLETE[];
 extern const char MSG_HOMEYZ[];
 extern const char MSG_HOMEYZ[];
@@ -85,10 +81,12 @@ extern const char MSG_SELFTEST_FILAMENT_SENSOR[];
 extern const char MSG_SELFTEST_WIRINGERROR[];
 extern const char MSG_SELFTEST_WIRINGERROR[];
 extern const char MSG_SETTINGS[];
 extern const char MSG_SETTINGS[];
 extern const char MSG_HW_SETUP[];
 extern const char MSG_HW_SETUP[];
-extern const char MSG_SILENT_MODE_OFF[];
-extern const char MSG_SILENT_MODE_ON[];
-extern const char MSG_STEALTH_MODE_OFF[];
-extern const char MSG_STEALTH_MODE_ON[];
+extern const char MSG_MODE[];
+extern const char MSG_HIGH_POWER[];
+extern const char MSG_AUTO_POWER[];
+extern const char MSG_SILENT[];
+extern const char MSG_NORMAL[];
+extern const char MSG_STEALTH[];
 extern const char MSG_STEEL_SHEET_CHECK[];
 extern const char MSG_STEEL_SHEET_CHECK[];
 extern const char MSG_STOP_PRINT[];
 extern const char MSG_STOP_PRINT[];
 extern const char MSG_STOPPED[];
 extern const char MSG_STOPPED[];
@@ -104,12 +102,47 @@ extern const char MSG_WIZARD_QUIT[];
 extern const char MSG_YES[];
 extern const char MSG_YES[];
 extern const char MSG_V2_CALIBRATION[];
 extern const char MSG_V2_CALIBRATION[];
 extern const char WELCOME_MSG[];
 extern const char WELCOME_MSG[];
+extern const char MSG_OFF[];
+extern const char MSG_ON[];
+extern const char MSG_NA[];
+extern const char MSG_AUTO_DEPLETE[];
+extern const char MSG_CUTTER[];
+extern const char MSG_NONE[];
+extern const char MSG_WARN[];
+extern const char MSG_STRICT[];
+extern const char MSG_MODEL[];
+extern const char MSG_FIRMWARE[];
+extern const char MSG_GCODE[];
+extern const char MSG_NOZZLE_DIAMETER[];
+extern const char MSG_MMU_MODE[];
+extern const char MSG_SD_CARD[];
+extern const char MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY[];
+extern const char MSG_SORT[];
+extern const char MSG_SORT_TIME[];
+extern const char MSG_SORT_ALPHA[];
+extern const char MSG_RPI_PORT[];
+extern const char MSG_SOUND[];
+extern const char MSG_SOUND_LOUD[];
+extern const char MSG_SOUND_ONCE[];
+extern const char MSG_SOUND_BLIND[];
+extern const char MSG_MESH[];
+extern const char MSG_Z_PROBE_NR[];
+extern const char MSG_MAGNETS_COMP[];
+extern const char MSG_FS_ACTION[];
+extern const char MSG_FS_CONTINUE[];
+extern const char MSG_FS_PAUSE[];
+extern const char MSG_BRIGHTNESS[];
+extern const char MSG_BL_HIGH[];
+extern const char MSG_BL_LOW[];
+extern const char MSG_TIMEOUT[];
+extern const char MSG_BRIGHT[];
+extern const char MSG_DIM[];
+extern const char MSG_AUTO[];
+
 //not internationalized messages
 //not internationalized messages
 extern const char MSG_BROWNOUT_RESET[];
 extern const char MSG_BROWNOUT_RESET[];
 extern const char MSG_EXTERNAL_RESET[];
 extern const char MSG_EXTERNAL_RESET[];
 extern const char MSG_FILE_SAVED[];
 extern const char MSG_FILE_SAVED[];
-extern const char MSG_OFF[];
-extern const char MSG_ON[];
 extern const char MSG_POSITION_UNKNOWN[];
 extern const char MSG_POSITION_UNKNOWN[];
 extern const char MSG_SOFTWARE_RESET[];
 extern const char MSG_SOFTWARE_RESET[];
 extern const char MSG_UNKNOWN_COMMAND[];
 extern const char MSG_UNKNOWN_COMMAND[];
@@ -135,6 +168,7 @@ extern const char MSG_OCTOPRINT_RESUMED[];
 extern const char MSG_OCTOPRINT_CANCEL[];
 extern const char MSG_OCTOPRINT_CANCEL[];
 extern const char MSG_FANCHECK_EXTRUDER[];
 extern const char MSG_FANCHECK_EXTRUDER[];
 extern const char MSG_FANCHECK_PRINT[];
 extern const char MSG_FANCHECK_PRINT[];
+extern const char MSG_M112_KILL[];
 
 
 #if defined(__cplusplus)
 #if defined(__cplusplus)
 }
 }

+ 17 - 22
Firmware/mmu.cpp

@@ -70,6 +70,7 @@ uint8_t mmu_extruder = MMU_FILAMENT_UNKNOWN;
 uint8_t tmp_extruder = MMU_FILAMENT_UNKNOWN;
 uint8_t tmp_extruder = MMU_FILAMENT_UNKNOWN;
 
 
 int8_t mmu_finda = -1;
 int8_t mmu_finda = -1;
+uint32_t mmu_last_finda_response = 0;
 
 
 int16_t mmu_version = -1;
 int16_t mmu_version = -1;
 
 
@@ -264,6 +265,7 @@ void mmu_loop(void)
 		if (mmu_rx_ok() > 0)
 		if (mmu_rx_ok() > 0)
 		{
 		{
 			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
 			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
+			mmu_last_finda_response = _millis();
 			FDEBUG_PRINTF_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 			FDEBUG_PRINTF_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 			puts_P(PSTR("MMU - ENABLED"));
 			puts_P(PSTR("MMU - ENABLED"));
 			mmu_enabled = true;
 			mmu_enabled = true;
@@ -376,11 +378,11 @@ void mmu_loop(void)
 		if (mmu_rx_ok() > 0)
 		if (mmu_rx_ok() > 0)
 		{
 		{
 			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
 			fscanf_P(uart2io, PSTR("%hhu"), &mmu_finda); //scan finda from buffer
+			mmu_last_finda_response = _millis();
 			FDEBUG_PRINTF_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 			FDEBUG_PRINTF_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 			//printf_P(PSTR("Eact: %d\n"), int(e_active()));
 			//printf_P(PSTR("Eact: %d\n"), int(e_active()));
 			if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
 			if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
-				fsensor_stop_and_save_print();
-				enquecommand_front_P(PSTR("PRUSA fsensor_recover")); //then recover
+				fsensor_checkpoint_print();
 				ad_markDepleted(mmu_extruder);
 				ad_markDepleted(mmu_extruder);
 				if (lcd_autoDepleteEnabled() && !ad_allDepleted())
 				if (lcd_autoDepleteEnabled() && !ad_allDepleted())
 				{
 				{
@@ -1355,7 +1357,7 @@ void lcd_mmu_load_to_nozzle(uint8_t filament_nr)
         manage_response(true, true, MMU_TCODE_MOVE);
         manage_response(true, true, MMU_TCODE_MOVE);
         mmu_continue_loading(false);
         mmu_continue_loading(false);
         mmu_extruder = tmp_extruder; //filament change is finished
         mmu_extruder = tmp_extruder; //filament change is finished
-        marlin_rise_z();
+        raise_z_above(MIN_Z_FOR_LOAD, false);
         mmu_load_to_nozzle();
         mmu_load_to_nozzle();
         load_filament_final_feed();
         load_filament_final_feed();
         st_synchronize();
         st_synchronize();
@@ -1556,34 +1558,27 @@ void mmu_continue_loading(bool blocking)
             increment_load_fail();
             increment_load_fail();
             // no break
             // no break
         case Ls::Retry:
         case Ls::Retry:
-#ifdef MMU_HAS_CUTTER
-            if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
+            ++retry; // overflow not handled, as it is not dangerous.
+            if (retry >= max_retry)
             {
             {
-                mmu_command(MmuCmd::K0 + tmp_extruder);
-                manage_response(true, true, MMU_UNLOAD_MOVE);
-            }
+                state = Ls::Unload;
+#ifdef MMU_HAS_CUTTER
+                if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
+                {
+                    mmu_command(MmuCmd::K0 + tmp_extruder);
+                    manage_response(true, true, MMU_UNLOAD_MOVE);
+                }
 #endif //MMU_HAS_CUTTER
 #endif //MMU_HAS_CUTTER
+            }
             mmu_command(MmuCmd::T0 + tmp_extruder);
             mmu_command(MmuCmd::T0 + tmp_extruder);
             manage_response(true, true, MMU_TCODE_MOVE);
             manage_response(true, true, MMU_TCODE_MOVE);
             success = load_more();
             success = load_more();
             if (success) success = can_load();
             if (success) success = can_load();
-            ++retry; // overflow not handled, as it is not dangerous.
-            if (retry >= max_retry) state = Ls::Unload;
+
             break;
             break;
         case Ls::Unload:
         case Ls::Unload:
             stop_and_save_print_to_ram(0, 0);
             stop_and_save_print_to_ram(0, 0);
-
-            //lift z
-            current_position[Z_AXIS] += Z_PAUSE_LIFT;
-            if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS;
-            plan_buffer_line_curposXYZE(15, active_extruder);
-            st_synchronize();
-
-            //Move XY to side
-            current_position[X_AXIS] = X_PAUSE_POS;
-            current_position[Y_AXIS] = Y_PAUSE_POS;
-            plan_buffer_line_curposXYZE(50, active_extruder);
-            st_synchronize();
+            long_pause();
 
 
             mmu_command(MmuCmd::U0);
             mmu_command(MmuCmd::U0);
             manage_response(false, true, MMU_UNLOAD_MOVE);
             manage_response(false, true, MMU_UNLOAD_MOVE);

+ 1 - 0
Firmware/mmu.h

@@ -14,6 +14,7 @@ extern uint8_t mmu_extruder;
 extern uint8_t tmp_extruder;
 extern uint8_t tmp_extruder;
 
 
 extern int8_t mmu_finda;
 extern int8_t mmu_finda;
+extern uint32_t mmu_last_finda_response;
 extern bool ir_sensor_detected;
 extern bool ir_sensor_detected;
 
 
 extern int16_t mmu_version;
 extern int16_t mmu_version;

+ 2 - 2
Firmware/optiboot_w25x20cl.cpp

@@ -258,11 +258,11 @@ void optiboot_w25x20cl_enter()
         uint32_t addr = (((uint32_t)rampz) << 16) | address;
         uint32_t addr = (((uint32_t)rampz) << 16) | address;
         // During a single bootloader run, only erase a 64kB block once.
         // During a single bootloader run, only erase a 64kB block once.
         // An 8bit bitmask 'pages_erased' covers 512kB of FLASH memory.
         // An 8bit bitmask 'pages_erased' covers 512kB of FLASH memory.
-        if (address == 0 && (pages_erased & (1 << addr)) == 0) {
+        if ((address == 0) && (pages_erased & (1 << (addr >> 16))) == 0) {
           w25x20cl_wait_busy();
           w25x20cl_wait_busy();
           w25x20cl_enable_wr();
           w25x20cl_enable_wr();
           w25x20cl_block64_erase(addr);
           w25x20cl_block64_erase(addr);
-          pages_erased |= (1 << addr);
+          pages_erased |= (1 << (addr >> 16));
         }
         }
         w25x20cl_wait_busy();
         w25x20cl_wait_busy();
         w25x20cl_enable_wr();
         w25x20cl_enable_wr();

+ 3 - 2
Firmware/pins_Einsy_1_0.h

@@ -71,12 +71,13 @@
 #define HEATER_2_PIN        -1
 #define HEATER_2_PIN        -1
 #define TEMP_2_PIN          -1
 #define TEMP_2_PIN          -1
 
 
-#define TEMP_AMBIENT_PIN     5 //A5
+#define TEMP_AMBIENT_PIN     6 //A6
 
 
 #define TEMP_PINDA_PIN       3 //A3
 #define TEMP_PINDA_PIN       3 //A3
 
 
 #define VOLT_PWR_PIN         4 //A4
 #define VOLT_PWR_PIN         4 //A4
 #define VOLT_BED_PIN         9 //A9
 #define VOLT_BED_PIN         9 //A9
+#define VOLT_IR_PIN          8 //A8
 
 
 
 
 #define E0_TMC2130_CS       66
 #define E0_TMC2130_CS       66
@@ -99,7 +100,7 @@
 
 
 //#define KILL_PIN            32
 //#define KILL_PIN            32
 
 
-//#define LCD_BL_PIN          5   //backlight control pin
+#define LCD_BL_PIN          5   //backlight control pin
 #define BEEPER              84  // Beeper on AUX-4
 #define BEEPER              84  // Beeper on AUX-4
 #define LCD_PINS_RS         82
 #define LCD_PINS_RS         82
 #define LCD_PINS_ENABLE     61 // !!! changed from 18 (EINY03)
 #define LCD_PINS_ENABLE     61 // !!! changed from 18 (EINY03)

+ 25 - 11
Firmware/planner.cpp

@@ -659,15 +659,15 @@ float junction_deviation = 0.1;
 // Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in 
 // Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in 
 // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
 // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
 // calculation the caller must also provide the physical length of the line in millimeters.
 // calculation the caller must also provide the physical length of the line in millimeters.
-void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, uint8_t extruder)
+void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, uint8_t extruder, const float* gcode_target)
 {
 {
     // Calculate the buffer head after we push this byte
     // Calculate the buffer head after we push this byte
   int next_buffer_head = next_block_index(block_buffer_head);
   int next_buffer_head = next_block_index(block_buffer_head);
 
 
   // If the buffer is full: good! That means we are well ahead of the robot. 
   // If the buffer is full: good! That means we are well ahead of the robot. 
   // Rest here until there is room in the buffer.
   // Rest here until there is room in the buffer.
+  waiting_inside_plan_buffer_line_print_aborted = false;
   if (block_buffer_tail == next_buffer_head) {
   if (block_buffer_tail == next_buffer_head) {
-      waiting_inside_plan_buffer_line_print_aborted = false;
       do {
       do {
           manage_heater(); 
           manage_heater(); 
           // Vojtech: Don't disable motors inside the planner!
           // Vojtech: Don't disable motors inside the planner!
@@ -687,6 +687,29 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
   planner_update_queue_min_counter();
   planner_update_queue_min_counter();
 #endif /* PLANNER_DIAGNOSTICS */
 #endif /* PLANNER_DIAGNOSTICS */
 
 
+  // Prepare to set up new block
+  block_t *block = &block_buffer[block_buffer_head];
+
+  // Mark block as not busy (Not executed by the stepper interrupt, could be still tinkered with.)
+  block->busy = false;
+
+  // Set sdlen for calculating sd position
+  block->sdlen = 0;
+
+  // Save original destination of the move
+  if (gcode_target)
+      memcpy(block->gcode_target, gcode_target, sizeof(block_t::gcode_target));
+  else
+  {
+      block->gcode_target[X_AXIS] = x;
+      block->gcode_target[Y_AXIS] = y;
+      block->gcode_target[Z_AXIS] = z;
+      block->gcode_target[E_AXIS] = e;
+  }
+
+  // Save the global feedrate at scheduling time
+  block->gcode_feedrate = feedrate;
+
 #ifdef ENABLE_AUTO_BED_LEVELING
 #ifdef ENABLE_AUTO_BED_LEVELING
   apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
   apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
 #endif // ENABLE_AUTO_BED_LEVELING
 #endif // ENABLE_AUTO_BED_LEVELING
@@ -786,15 +809,6 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate
   }
   }
   #endif
   #endif
 
 
-  // Prepare to set up new block
-  block_t *block = &block_buffer[block_buffer_head];
-
-  // Set sdlen for calculating sd position
-  block->sdlen = 0;
-
-  // Mark block as not busy (Not executed by the stepper interrupt, could be still tinkered with.)
-  block->busy = false;
-
   // Number of steps for each axis
   // Number of steps for each axis
 #ifndef COREXY
 #ifndef COREXY
 // default non-h-bot planning
 // default non-h-bot planning

+ 6 - 2
Firmware/planner.h

@@ -116,7 +116,10 @@ typedef struct {
   unsigned long abs_adv_steps_multiplier8; // Factorised by 2^8 to avoid float
   unsigned long abs_adv_steps_multiplier8; // Factorised by 2^8 to avoid float
 #endif
 #endif
 
 
-  uint16_t sdlen;
+  // Save/recovery state data
+  float gcode_target[NUM_AXIS];     // Target (abs mm) of the original Gcode instruction
+  uint16_t gcode_feedrate;          // Default and/or move feedrate
+  uint16_t sdlen;                   // Length of the Gcode instruction
 } block_t;
 } block_t;
 
 
 #ifdef LIN_ADVANCE
 #ifdef LIN_ADVANCE
@@ -147,7 +150,7 @@ vector_3 plan_get_position();
 /// The performance penalty is negligible, since these planned lines are usually maintenance moves with the extruder.
 /// 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, uint8_t extruder);
 
 
-void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, uint8_t extruder);
+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);
 //void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder);
 #endif // ENABLE_AUTO_BED_LEVELING
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
@@ -238,6 +241,7 @@ FORCE_INLINE bool planner_queue_full() {
 // wait for the steppers to stop,
 // wait for the steppers to stop,
 // update planner's current position and the current_position of the front end.
 // update planner's current position and the current_position of the front end.
 extern void planner_abort_hard();
 extern void planner_abort_hard();
+extern bool waiting_inside_plan_buffer_line_print_aborted;
 
 
 #ifdef PREVENT_DANGEROUS_EXTRUDE
 #ifdef PREVENT_DANGEROUS_EXTRUDE
 void set_extrude_min_temp(float temp);
 void set_extrude_min_temp(float temp);

+ 7 - 0
Firmware/sound.cpp

@@ -5,6 +5,7 @@
 //#include <inttypes.h>
 //#include <inttypes.h>
 //#include <avr/eeprom.h>
 //#include <avr/eeprom.h>
 //#include "eeprom.h"
 //#include "eeprom.h"
+#include "backlight.h"
 
 
 
 
 //eSOUND_MODE eSoundMode=e_SOUND_MODE_LOUD;
 //eSOUND_MODE eSoundMode=e_SOUND_MODE_LOUD;
@@ -63,6 +64,7 @@ Sound_SaveMode();
 
 
 //if critical is true then silend and once mode is ignored
 //if critical is true then silend and once mode is ignored
 void Sound_MakeCustom(uint16_t ms,uint16_t tone_,bool critical){
 void Sound_MakeCustom(uint16_t ms,uint16_t tone_,bool critical){
+    backlight_wake();
      if (!critical){
      if (!critical){
           if (eSoundMode != e_SOUND_MODE_SILENT){
           if (eSoundMode != e_SOUND_MODE_SILENT){
                if(!tone_){
                if(!tone_){
@@ -135,6 +137,7 @@ switch(eSoundMode)
 
 
 static void Sound_DoSound_Blind_Alert(void)
 static void Sound_DoSound_Blind_Alert(void)
 {
 {
+    backlight_wake(1);
      uint8_t nI;
      uint8_t nI;
 
 
      for(nI=0; nI<20; nI++)
      for(nI=0; nI<20; nI++)
@@ -148,6 +151,7 @@ static void Sound_DoSound_Blind_Alert(void)
 
 
  static void Sound_DoSound_Encoder_Move(void)
  static void Sound_DoSound_Encoder_Move(void)
 {
 {
+    backlight_wake();
 uint8_t nI;
 uint8_t nI;
 
 
  for(nI=0;nI<5;nI++)
  for(nI=0;nI<5;nI++)
@@ -161,6 +165,7 @@ uint8_t nI;
 
 
 static void Sound_DoSound_Echo(void)
 static void Sound_DoSound_Echo(void)
 {
 {
+    backlight_wake();
 uint8_t nI;
 uint8_t nI;
 
 
 for(nI=0;nI<10;nI++)
 for(nI=0;nI<10;nI++)
@@ -174,6 +179,7 @@ for(nI=0;nI<10;nI++)
 
 
 static void Sound_DoSound_Prompt(void)
 static void Sound_DoSound_Prompt(void)
 {
 {
+    backlight_wake(2);
 WRITE(BEEPER,HIGH);
 WRITE(BEEPER,HIGH);
 _delay_ms(500);
 _delay_ms(500);
 WRITE(BEEPER,LOW);
 WRITE(BEEPER,LOW);
@@ -181,6 +187,7 @@ WRITE(BEEPER,LOW);
 
 
 static void Sound_DoSound_Alert(bool bOnce)
 static void Sound_DoSound_Alert(bool bOnce)
 {
 {
+    backlight_wake();
 uint8_t nI,nMax;
 uint8_t nI,nMax;
 
 
 nMax=bOnce?1:3;
 nMax=bOnce?1:3;

+ 0 - 6
Firmware/sound.h

@@ -3,12 +3,6 @@
 #define SOUND_H
 #define SOUND_H
 
 
 
 
-#define MSG_SOUND_MODE_LOUD   "Sound      [loud]"
-#define MSG_SOUND_MODE_ONCE   "Sound      [once]"
-#define MSG_SOUND_MODE_SILENT "Sound    [silent]"
-#define MSG_SOUND_MODE_BLIND  "Sound    [assist]" 
-
-
 #define e_SOUND_MODE_NULL 0xFF
 #define e_SOUND_MODE_NULL 0xFF
 typedef enum
 typedef enum
      {e_SOUND_MODE_LOUD,e_SOUND_MODE_ONCE,e_SOUND_MODE_SILENT,e_SOUND_MODE_BLIND} eSOUND_MODE;
      {e_SOUND_MODE_LOUD,e_SOUND_MODE_ONCE,e_SOUND_MODE_SILENT,e_SOUND_MODE_BLIND} eSOUND_MODE;

+ 11 - 2
Firmware/temperature.cpp

@@ -44,6 +44,8 @@
 #include "Timer.h"
 #include "Timer.h"
 #include "Configuration_prusa.h"
 #include "Configuration_prusa.h"
 
 
+#include "config.h"
+
 //===========================================================================
 //===========================================================================
 //=============================public variables============================
 //=============================public variables============================
 //===========================================================================
 //===========================================================================
@@ -71,6 +73,10 @@ int current_voltage_raw_pwr = 0;
 int current_voltage_raw_bed = 0;
 int current_voltage_raw_bed = 0;
 #endif
 #endif
 
 
+#if IR_SENSOR_ANALOG
+int current_voltage_raw_IR = 0;
+#endif //IR_SENSOR_ANALOG
+
 int current_temperature_bed_raw = 0;
 int current_temperature_bed_raw = 0;
 float current_temperature_bed = 0.0;
 float current_temperature_bed = 0.0;
   
   
@@ -873,7 +879,7 @@ static float analog2temp(int raw, uint8_t e) {
       SERIAL_ERROR_START;
       SERIAL_ERROR_START;
       SERIAL_ERROR((int)e);
       SERIAL_ERROR((int)e);
       SERIAL_ERRORLNPGM(" - Invalid extruder number !");
       SERIAL_ERRORLNPGM(" - Invalid extruder number !");
-      kill(PSTR(""), 6);
+      kill(NULL, 6);
       return 0.0;
       return 0.0;
   } 
   } 
   #ifdef HEATER_0_USES_MAX6675
   #ifdef HEATER_0_USES_MAX6675
@@ -1576,11 +1582,14 @@ void adc_ready(void) //callback from adc when sampling finished
 	current_voltage_raw_pwr = adc_values[ADC_PIN_IDX(VOLT_PWR_PIN)];
 	current_voltage_raw_pwr = adc_values[ADC_PIN_IDX(VOLT_PWR_PIN)];
 #endif
 #endif
 #ifdef AMBIENT_THERMISTOR
 #ifdef AMBIENT_THERMISTOR
-	current_temperature_raw_ambient = adc_values[ADC_PIN_IDX(TEMP_AMBIENT_PIN)];
+	current_temperature_raw_ambient = adc_values[ADC_PIN_IDX(TEMP_AMBIENT_PIN)]; // 5->6
 #endif //AMBIENT_THERMISTOR
 #endif //AMBIENT_THERMISTOR
 #ifdef VOLT_BED_PIN
 #ifdef VOLT_BED_PIN
 	current_voltage_raw_bed = adc_values[ADC_PIN_IDX(VOLT_BED_PIN)]; // 6->9
 	current_voltage_raw_bed = adc_values[ADC_PIN_IDX(VOLT_BED_PIN)]; // 6->9
 #endif
 #endif
+#if IR_SENSOR_ANALOG
+     current_voltage_raw_IR = adc_values[ADC_PIN_IDX(VOLT_IR_PIN)];
+#endif //IR_SENSOR_ANALOG
 	temp_meas_ready = true;
 	temp_meas_ready = true;
 }
 }
 
 

+ 5 - 0
Firmware/temperature.h

@@ -27,6 +27,8 @@
   #include "stepper.h"
   #include "stepper.h"
 #endif
 #endif
 
 
+#include "config.h"
+
 
 
 #ifdef SYSTEM_TIMER_2
 #ifdef SYSTEM_TIMER_2
 
 
@@ -74,6 +76,9 @@ extern int current_voltage_raw_pwr;
 extern int current_voltage_raw_bed;
 extern int current_voltage_raw_bed;
 #endif
 #endif
 
 
+#if IR_SENSOR_ANALOG
+extern int current_voltage_raw_IR;
+#endif //IR_SENSOR_ANALOG
 
 
 #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
 #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
   extern unsigned char soft_pwm_bed;
   extern unsigned char soft_pwm_bed;

+ 8 - 8
Firmware/tmc2130.cpp

@@ -24,7 +24,7 @@ uint8_t tmc2130_current_h[4] = TMC2130_CURRENTS_H;
 uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
 uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
 
 
 //running currents for homing
 //running currents for homing
-uint8_t tmc2130_current_r_home[4] = {8, 10, 20, 18};
+uint8_t tmc2130_current_r_home[4] = TMC2130_CURRENTS_R_HOME;
 
 
 
 
 //pwm_ampl
 //pwm_ampl
@@ -40,7 +40,7 @@ uint8_t tmc2130_mres[4] = {0, 0, 0, 0}; //will be filed at begin of init
 
 
 
 
 uint8_t tmc2130_sg_thr[4] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
 uint8_t tmc2130_sg_thr[4] = {TMC2130_SG_THRS_X, TMC2130_SG_THRS_Y, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
-uint8_t tmc2130_sg_thr_home[4] = {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E};
+uint8_t tmc2130_sg_thr_home[4] = TMC2130_SG_THRS_HOME;
 
 
 
 
 uint8_t tmc2130_sg_homing_axes_mask = 0x00;
 uint8_t tmc2130_sg_homing_axes_mask = 0x00;
@@ -427,7 +427,7 @@ void tmc2130_check_overtemp()
 
 
 void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r)
 void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r)
 {
 {
-	uint8_t intpol = 1;
+	uint8_t intpol = (mres != 0); // intpol to 256 only if microsteps aren't 256
 	uint8_t toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz)
 	uint8_t toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz)
 	uint8_t hstrt = tmc2130_chopper_config[axis].hstr; //initial 4, modified to 5
 	uint8_t hstrt = tmc2130_chopper_config[axis].hstr; //initial 4, modified to 5
 	uint8_t hend = tmc2130_chopper_config[axis].hend; //original value = 1
 	uint8_t hend = tmc2130_chopper_config[axis].hend; //original value = 1
@@ -600,7 +600,7 @@ void tmc2130_wr_THIGH(uint8_t axis, uint32_t val32)
 
 
 uint8_t tmc2130_usteps2mres(uint16_t usteps)
 uint8_t tmc2130_usteps2mres(uint16_t usteps)
 {
 {
-	uint8_t mres = 8; while (mres && (usteps >>= 1)) mres--;
+	uint8_t mres = 8; while (usteps >>= 1) mres--;
 	return mres;
 	return mres;
 }
 }
 
 
@@ -807,15 +807,15 @@ void tmc2130_goto_step(uint8_t axis, uint8_t step, uint8_t dir, uint16_t delay_u
 	{
 	{
 		dir = tmc2130_get_inv(axis)?0:1;
 		dir = tmc2130_get_inv(axis)?0:1;
 		int steps = (int)step - (int)(mscnt >> shift);
 		int steps = (int)step - (int)(mscnt >> shift);
-		if (steps < 0)
+		if (steps > static_cast<int>(cnt / 2))
 		{
 		{
 			dir ^= 1;
 			dir ^= 1;
-			steps = -steps;
+			steps = cnt - steps; // This can create a negative step value
 		}
 		}
-		if (steps > static_cast<int>(cnt / 2))
+        if (steps < 0)
 		{
 		{
 			dir ^= 1;
 			dir ^= 1;
-			steps = cnt - steps;
+			steps = -steps;
 		}
 		}
 		cnt = steps;
 		cnt = steps;
 	}
 	}

+ 464 - 228
Firmware/ultralcd.cpp

@@ -19,6 +19,8 @@
 #include "lcd.h"
 #include "lcd.h"
 #include "menu.h"
 #include "menu.h"
 
 
+#include "backlight.h"
+
 #include "util.h"
 #include "util.h"
 #include "mesh_bed_leveling.h"
 #include "mesh_bed_leveling.h"
 #include "mesh_bed_calibration.h"
 #include "mesh_bed_calibration.h"
@@ -45,6 +47,10 @@
 #include "io_atmega2560.h"
 #include "io_atmega2560.h"
 #include "first_lay_cal.h"
 #include "first_lay_cal.h"
 
 
+#include "fsensor.h"
+#include "adc.h"
+#include "config.h"
+
 
 
 int scrollstuff = 0;
 int scrollstuff = 0;
 char longFilenameOLD[LONG_FILENAME_LENGTH];
 char longFilenameOLD[LONG_FILENAME_LENGTH];
@@ -52,6 +58,7 @@ char longFilenameOLD[LONG_FILENAME_LENGTH];
 
 
 static void lcd_sd_updir();
 static void lcd_sd_updir();
 static void lcd_mesh_bed_leveling_settings();
 static void lcd_mesh_bed_leveling_settings();
+static void lcd_backlight_menu();
 
 
 int8_t ReInitLCD = 0;
 int8_t ReInitLCD = 0;
 
 
@@ -61,9 +68,6 @@ uint8_t SilentModeMenu_MMU = 1; //activate mmu unit stealth mode
 
 
 int8_t FSensorStateMenu = 1;
 int8_t FSensorStateMenu = 1;
 
 
-extern bool fsensor_enable();
-extern void fsensor_disable();
-
 
 
 #ifdef SDCARD_SORT_ALPHA
 #ifdef SDCARD_SORT_ALPHA
 bool presort_flag = false;
 bool presort_flag = false;
@@ -111,7 +115,9 @@ static const char* lcd_display_message_fullscreen_nonBlocking_P(const char *msg,
 
 
 /* Different menus */
 /* Different menus */
 static void lcd_status_screen();
 static void lcd_status_screen();
+#if (LANG_MODE != 0)
 static void lcd_language_menu();
 static void lcd_language_menu();
+#endif
 static void lcd_main_menu();
 static void lcd_main_menu();
 static void lcd_tune_menu();
 static void lcd_tune_menu();
 //static void lcd_move_menu();
 //static void lcd_move_menu();
@@ -147,6 +153,10 @@ static void mmu_cut_filament_menu();
 static void lcd_menu_fails_stats();
 static void lcd_menu_fails_stats();
 #endif //TMC2130 or FILAMENT_SENSOR
 #endif //TMC2130 or FILAMENT_SENSOR
 
 
+#ifdef TMC2130
+static void lcd_belttest_v();
+#endif //TMC2130
+
 static void lcd_selftest_v();
 static void lcd_selftest_v();
 
 
 #ifdef TMC2130
 #ifdef TMC2130
@@ -193,6 +203,7 @@ enum class TestError : uint_least8_t
     SwappedFan,
     SwappedFan,
     WiringFsensor,
     WiringFsensor,
     TriggeringFsensor,
     TriggeringFsensor,
+    FsensorLevel
 };
 };
 
 
 static int  lcd_selftest_screen(TestScreen screen, int _progress, int _progress_scale, bool _clear, int _delay);
 static int  lcd_selftest_screen(TestScreen screen, int _progress, int _progress_scale, bool _clear, int _delay);
@@ -224,6 +235,9 @@ static FanCheck lcd_selftest_fan_auto(int _fan);
 static bool lcd_selftest_fsensor();
 static bool lcd_selftest_fsensor();
 #endif //PAT9125
 #endif //PAT9125
 static bool selftest_irsensor();
 static bool selftest_irsensor();
+#if IR_SENSOR_ANALOG
+static bool lcd_selftest_IRsensor();
+#endif //IR_SENSOR_ANALOG
 static void lcd_selftest_error(TestError error, const char *_error_1, const char *_error_2);
 static void lcd_selftest_error(TestError error, const char *_error_1, const char *_error_2);
 static void lcd_colorprint_change();
 static void lcd_colorprint_change();
 #ifdef SNMM
 #ifdef SNMM
@@ -310,18 +324,24 @@ bool bSettings;                                   // flag (i.e. 'fake parameter'
 const char STR_SEPARATOR[] PROGMEM = "------------";
 const char STR_SEPARATOR[] PROGMEM = "------------";
 
 
 
 
-static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, char* longFilename)
+static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, const char* filename, char* longFilename)
 {
 {
     char c;
     char c;
-    int enc_dif = lcd_encoder_diff;
+    int enc_dif = lcd_encoder_diff / ENCODER_PULSES_PER_STEP;
     uint8_t n = LCD_WIDTH - 1;
     uint8_t n = LCD_WIDTH - 1;
+
     for(uint_least8_t g = 0; g<4;g++){
     for(uint_least8_t g = 0; g<4;g++){
       lcd_set_cursor(0, g);
       lcd_set_cursor(0, g);
     lcd_print(' ');
     lcd_print(' ');
     }
     }
-
     lcd_set_cursor(0, row);
     lcd_set_cursor(0, row);
     lcd_print('>');
     lcd_print('>');
+
+    if (longFilename[0] == '\0')
+    {
+        longFilename = filename;
+    }
+
     int i = 1;
     int i = 1;
     int j = 0;
     int j = 0;
     char* longFilenameTMP = longFilename;
     char* longFilenameTMP = longFilename;
@@ -339,7 +359,7 @@ static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, char* longF
           n = LCD_WIDTH - 1;
           n = LCD_WIDTH - 1;
           for(int g = 0; g<300 ;g++){
           for(int g = 0; g<300 ;g++){
 			  manage_heater();
 			  manage_heater();
-            if(LCD_CLICKED || ( enc_dif != lcd_encoder_diff )){
+            if(LCD_CLICKED || ( enc_dif != (lcd_encoder_diff / ENCODER_PULSES_PER_STEP))){
 				longFilenameTMP = longFilename;
 				longFilenameTMP = longFilename;
 				*(longFilenameTMP + LCD_WIDTH - 2) = '\0';
 				*(longFilenameTMP + LCD_WIDTH - 2) = '\0';
 				i = 1;
 				i = 1;
@@ -537,7 +557,7 @@ static uint8_t menu_item_sdfile(const char*
 		if (lcd_draw_update)
 		if (lcd_draw_update)
 		{
 		{
 			if (lcd_encoder == menu_item)
 			if (lcd_encoder == menu_item)
-				lcd_implementation_drawmenu_sdfile_selected(menu_row, str_fnl);
+				lcd_implementation_drawmenu_sdfile_selected(menu_row, str_fn, str_fnl);
 			else
 			else
 				lcd_implementation_drawmenu_sdfile(menu_row, str_fn, str_fnl);
 				lcd_implementation_drawmenu_sdfile(menu_row, str_fn, str_fnl);
 		}
 		}
@@ -566,7 +586,7 @@ void lcdui_print_Z_coord(void)
     if (custom_message_type == CustomMsg::MeshBedLeveling)
     if (custom_message_type == CustomMsg::MeshBedLeveling)
         lcd_puts_P(_N("Z   --- "));
         lcd_puts_P(_N("Z   --- "));
     else
     else
-		lcd_printf_P(_N("Z%6.2f "), current_position[Z_AXIS]);
+		lcd_printf_P(_N("Z%6.2f%c"), current_position[Z_AXIS], axis_known_position[Z_AXIS]?' ':'?');
 }
 }
 
 
 #ifdef PLANNER_DIAGNOSTICS
 #ifdef PLANNER_DIAGNOSTICS
@@ -605,6 +625,19 @@ void lcdui_print_percent_done(void)
 	const char* src = is_usb_printing?_N("USB"):(IS_SD_PRINTING?_N(" SD"):_N("   "));
 	const char* src = is_usb_printing?_N("USB"):(IS_SD_PRINTING?_N(" SD"):_N("   "));
 	char per[4];
 	char per[4];
 	bool num = IS_SD_PRINTING || (PRINTER_ACTIVE && (print_percent_done_normal != PRINT_PERCENT_DONE_INIT));
 	bool num = IS_SD_PRINTING || (PRINTER_ACTIVE && (print_percent_done_normal != PRINT_PERCENT_DONE_INIT));
+	if (!num || heating_status) // either not printing or heating
+	{
+		const int8_t sheetNR = eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet));
+		const int8_t nextSheet = eeprom_next_initialized_sheet(sheetNR);
+		if ((nextSheet >= 0) && (sheetNR != nextSheet))
+		{
+			char sheet[8];
+			eeprom_read_block(sheet, EEPROM_Sheets_base->s[sheetNR].name, 7);
+			sheet[7] = '\0';
+			lcd_printf_P(PSTR("%-7s"),sheet);
+			return; //do not also print the percentage
+		}
+	}
 	sprintf_P(per, num?_N("%3hhd"):_N("---"), calc_percent_done());
 	sprintf_P(per, num?_N("%3hhd"):_N("---"), calc_percent_done());
 	lcd_printf_P(_N("%3S%3s%%"), src, per);
 	lcd_printf_P(_N("%3S%3s%%"), src, per);
 }
 }
@@ -709,10 +742,10 @@ void lcdui_print_status_line(void)
 {
 {
 	if (IS_SD_PRINTING)
 	if (IS_SD_PRINTING)
 	{
 	{
-		if (strcmp(longFilenameOLD, card.longFilename) != 0)
+		if (strcmp(longFilenameOLD, (card.longFilename[0] ? card.longFilename : card.filename)) != 0)
 		{
 		{
 			memset(longFilenameOLD, '\0', strlen(longFilenameOLD));
 			memset(longFilenameOLD, '\0', strlen(longFilenameOLD));
-			sprintf_P(longFilenameOLD, PSTR("%s"), card.longFilename);
+			sprintf_P(longFilenameOLD, PSTR("%s"), (card.longFilename[0] ? card.longFilename : card.filename));
 			scrollstuff = 0;
 			scrollstuff = 0;
 		}
 		}
 	}
 	}
@@ -760,16 +793,16 @@ void lcdui_print_status_line(void)
 	}
 	}
 	else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status))
 	else if ((IS_SD_PRINTING) && (custom_message_type == CustomMsg::Status))
 	{ // If printing from SD, show what we are printing
 	{ // If printing from SD, show what we are printing
-		if(strlen(card.longFilename) > LCD_WIDTH)
+		if(strlen(longFilenameOLD) > LCD_WIDTH)
 		{
 		{
 			int inters = 0;
 			int inters = 0;
 			int gh = scrollstuff;
 			int gh = scrollstuff;
 			while (((gh - scrollstuff) < LCD_WIDTH) && (inters == 0))
 			while (((gh - scrollstuff) < LCD_WIDTH) && (inters == 0))
 			{
 			{
-				if (card.longFilename[gh] == '\0')
+				if (longFilenameOLD[gh] == '\0')
 				{
 				{
 					lcd_set_cursor(gh - scrollstuff, 3);
 					lcd_set_cursor(gh - scrollstuff, 3);
-					lcd_print(card.longFilename[gh - 1]);
+					lcd_print(longFilenameOLD[gh - 1]);
 					scrollstuff = 0;
 					scrollstuff = 0;
 					gh = scrollstuff;
 					gh = scrollstuff;
 					inters = 1;
 					inters = 1;
@@ -777,7 +810,7 @@ void lcdui_print_status_line(void)
 				else
 				else
 				{
 				{
 					lcd_set_cursor(gh - scrollstuff, 3);
 					lcd_set_cursor(gh - scrollstuff, 3);
-					lcd_print(card.longFilename[gh - 1]);
+					lcd_print(longFilenameOLD[gh - 1]);
 					gh++;
 					gh++;
 				}
 				}
 			}
 			}
@@ -785,7 +818,7 @@ void lcdui_print_status_line(void)
 		}
 		}
 		else
 		else
 		{
 		{
-			lcd_print(longFilenameOLD);
+			lcd_printf_P(PSTR("%-20s"), longFilenameOLD);
 		}
 		}
 	}
 	}
 	else
 	else
@@ -838,12 +871,13 @@ void lcdui_print_status_line(void)
 			break;
 			break;
 		case CustomMsg::TempCal: // PINDA temp calibration in progress
 		case CustomMsg::TempCal: // PINDA temp calibration in progress
 			{
 			{
+				char statusLine[LCD_WIDTH + 1];
+				sprintf_P(statusLine, PSTR("%-20S"), _T(MSG_TEMP_CALIBRATION));
 				char progress[4];
 				char progress[4];
+				sprintf_P(progress, PSTR("%d/6"), custom_message_state);
+				memcpy(statusLine + 12, progress, sizeof(progress) - 1);
 				lcd_set_cursor(0, 3);
 				lcd_set_cursor(0, 3);
-				lcd_puts_P(_T(MSG_TEMP_CALIBRATION));
-				lcd_set_cursor(12, 3);
-				sprintf(progress, "%d/6", custom_message_state);
-				lcd_print(progress);
+				lcd_print(statusLine);
 			}
 			}
 			break;
 			break;
 		case CustomMsg::TempCompPreheat: // temp compensation preheat
 		case CustomMsg::TempCompPreheat: // temp compensation preheat
@@ -1072,12 +1106,9 @@ void lcd_commands()
 		if (!blocks_queued() && !homing_flag)
 		if (!blocks_queued() && !homing_flag)
 		{
 		{
 			lcd_setstatuspgm(_i("Print paused"));////MSG_PRINT_PAUSED c=20 r=1
 			lcd_setstatuspgm(_i("Print paused"));////MSG_PRINT_PAUSED c=20 r=1
-			long_pause();
-               if (lcd_commands_type == LcdCommands::LongPause) // !!! because "lcd_commands_type" can be changed during/inside "long_pause()"
-               {
-                    lcd_commands_type = LcdCommands::Idle;
-                    lcd_commands_step = 0;
-               }
+            lcd_commands_type = LcdCommands::Idle;
+            lcd_commands_step = 0;
+            long_pause();
 		}
 		}
 	}
 	}
 
 
@@ -1634,9 +1665,8 @@ void lcd_return_to_status()
 //! @brief Pause print, disable nozzle heater, move to park position
 //! @brief Pause print, disable nozzle heater, move to park position
 void lcd_pause_print()
 void lcd_pause_print()
 {
 {
-    lcd_return_to_status();
     stop_and_save_print_to_ram(0.0,0.0);
     stop_and_save_print_to_ram(0.0,0.0);
-    setAllTargetHotends(0);
+    lcd_return_to_status();
     isPrintPaused = true;
     isPrintPaused = true;
     if (LcdCommands::Idle == lcd_commands_type)
     if (LcdCommands::Idle == lcd_commands_type)
     {
     {
@@ -2001,11 +2031,11 @@ static void lcd_menu_temperatures()
     menu_back_if_clicked();
     menu_back_if_clicked();
 }
 }
 
 
-#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN)
+#if defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || IR_SENSOR_ANALOG
 #define VOLT_DIV_R1 10000
 #define VOLT_DIV_R1 10000
 #define VOLT_DIV_R2 2370
 #define VOLT_DIV_R2 2370
 #define VOLT_DIV_FAC ((float)VOLT_DIV_R2 / (VOLT_DIV_R2 + VOLT_DIV_R1))
 #define VOLT_DIV_FAC ((float)VOLT_DIV_R2 / (VOLT_DIV_R2 + VOLT_DIV_R1))
-#define VOLT_DIV_REF 5
+
 //! @brief Show Voltages
 //! @brief Show Voltages
 //!
 //!
 //! @code{.unparsed}
 //! @code{.unparsed}
@@ -2023,10 +2053,17 @@ static void lcd_menu_voltages()
 	float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
 	float volt_pwr = VOLT_DIV_REF * ((float)current_voltage_raw_pwr / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
 	float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
 	float volt_bed = VOLT_DIV_REF * ((float)current_voltage_raw_bed / (1023 * OVERSAMPLENR)) / VOLT_DIV_FAC;
 	lcd_home();
 	lcd_home();
-	lcd_printf_P(PSTR(" PWR:      %d.%01dV\n" " BED:      %d.%01dV"), (int)volt_pwr, (int)(10*fabs(volt_pwr - (int)volt_pwr)), (int)volt_bed, (int)(10*fabs(volt_bed - (int)volt_bed)));
-    menu_back_if_clicked();
+#if !IR_SENSOR_ANALOG
+	lcd_printf_P(PSTR("\n"));
+#endif //!IR_SENSOR_ANALOG
+     lcd_printf_P(PSTR(" PWR:      %4.1fV\n" " BED:      %4.1fV"), volt_pwr, volt_bed);
+#if IR_SENSOR_ANALOG
+     float volt_IR = VOLT_DIV_REF * ((float)current_voltage_raw_IR / (1023 * OVERSAMPLENR));
+     lcd_printf_P(PSTR("\n IR :       %3.1fV"),volt_IR);
+#endif //IR_SENSOR_ANALOG
+     menu_back_if_clicked();
 }
 }
-#endif //defined VOLT_BED_PIN || defined VOLT_PWR_PIN
+#endif //defined (VOLT_BED_PIN) || defined (VOLT_PWR_PIN) || IR_SENSOR_ANALOG
 
 
 #ifdef TMC2130
 #ifdef TMC2130
 //! @brief Show Belt Status
 //! @brief Show Belt Status
@@ -2253,6 +2290,9 @@ static void lcd_support_menu()
 void lcd_set_fan_check() {
 void lcd_set_fan_check() {
 	fans_check_enabled = !fans_check_enabled;
 	fans_check_enabled = !fans_check_enabled;
 	eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED, fans_check_enabled);
 	eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED, fans_check_enabled);
+#ifdef FANCHECK
+	if (fans_check_enabled == false) fan_check_error = EFCE_OK; //reset error if fanCheck is disabled during error. Allows resuming print.
+#endif //FANCHECK
 }
 }
 
 
 #ifdef MMU_HAS_CUTTER
 #ifdef MMU_HAS_CUTTER
@@ -2374,9 +2414,11 @@ void mFilamentItem(uint16_t nTemp, uint16_t nTempBed)
             {
             {
                 lcd_commands_type = LcdCommands::Layer1Cal;
                 lcd_commands_type = LcdCommands::Layer1Cal;
             }
             }
-            else if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
+            else
             {
             {
-                lcd_wizard(WizState::LoadFilHot);
+                raise_z_above(MIN_Z_FOR_PREHEAT);
+                if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
+                    lcd_wizard(WizState::LoadFilHot);
             }
             }
             return;
             return;
         }
         }
@@ -3017,7 +3059,7 @@ static void lcd_menu_xyz_y_min()
 	for (uint8_t i = 0; i < 2; i++)
 	for (uint8_t i = 0; i < 2; i++)
 	{
 	{
 		lcd_set_cursor(11,2+i);
 		lcd_set_cursor(11,2+i);
-		if (distanceMin[i] >= 200) lcd_puts_P(_N("N/A"));  ////c=3 r=1
+		if (distanceMin[i] >= 200) lcd_puts_P(_T(MSG_NA)); ////c=3 r=1
 		else lcd_printf_P(_N("%6.2fmm"), distanceMin[i]);
 		else lcd_printf_P(_N("%6.2fmm"), distanceMin[i]);
 	}
 	}
     if (lcd_clicked())
     if (lcd_clicked())
@@ -3063,7 +3105,7 @@ static void lcd_menu_xyz_skew()
 	}
 	}
 	else{
 	else{
 		lcd_set_cursor(15,0);
 		lcd_set_cursor(15,0);
-		lcd_puts_P(_N("N/A"));
+		lcd_puts_P(_T(MSG_NA));
 	}
 	}
     if (lcd_clicked())
     if (lcd_clicked())
         menu_goto(lcd_menu_xyz_offset, 0, true, true);
         menu_goto(lcd_menu_xyz_offset, 0, true, true);
@@ -3449,6 +3491,8 @@ void lcd_wait_for_cool_down() {
 	lcd_set_custom_characters_degree();
 	lcd_set_custom_characters_degree();
 	setAllTargetHotends(0);
 	setAllTargetHotends(0);
 	setTargetBed(0);
 	setTargetBed(0);
+	int fanSpeedBckp = fanSpeed;
+	fanSpeed = 255;
 	while ((degHotend(0)>MAX_HOTEND_TEMP_CALIBRATION) || (degBed() > MAX_BED_TEMP_CALIBRATION)) {
 	while ((degHotend(0)>MAX_HOTEND_TEMP_CALIBRATION) || (degBed() > MAX_BED_TEMP_CALIBRATION)) {
 		lcd_display_message_fullscreen_P(_i("Waiting for nozzle and bed cooling"));////MSG_WAITING_TEMP c=20 r=3
 		lcd_display_message_fullscreen_P(_i("Waiting for nozzle and bed cooling"));////MSG_WAITING_TEMP c=20 r=3
 
 
@@ -3467,6 +3511,7 @@ void lcd_wait_for_cool_down() {
 		delay_keep_alive(1000);
 		delay_keep_alive(1000);
 		serialecho_temperatures();
 		serialecho_temperatures();
 	}
 	}
+	fanSpeed = fanSpeedBckp;
 	lcd_set_custom_characters_arrows();
 	lcd_set_custom_characters_arrows();
 	lcd_update_enable(true);
 	lcd_update_enable(true);
 }
 }
@@ -3997,13 +4042,13 @@ static void lcd_print_state(uint8_t state)
 {
 {
 	switch (state) {
 	switch (state) {
 		case STATE_ON:
 		case STATE_ON:
-			lcd_puts_P(_i("  1"));
+			lcd_puts_P(_N("  1"));
 		break;
 		break;
 		case STATE_OFF:
 		case STATE_OFF:
-			lcd_puts_P(_i("  0"));
+			lcd_puts_P(_N("  0"));
 		break;
 		break;
 		default: 
 		default: 
-			lcd_puts_P(_i("N/A"));
+			lcd_puts_P(_T(MSG_NA));
 		break;
 		break;
 	}
 	}
 }
 }
@@ -4016,7 +4061,8 @@ static void lcd_show_sensors_state()
 	uint8_t idler_state = STATE_NA;
 	uint8_t idler_state = STATE_NA;
 
 
 	pinda_state = READ(Z_MIN_PIN);
 	pinda_state = READ(Z_MIN_PIN);
-	if (mmu_enabled) {
+	if (mmu_enabled && ((_millis() - mmu_last_finda_response) < 1000ul) )
+	{
 		finda_state = mmu_finda;
 		finda_state = mmu_finda;
 	}
 	}
 	if (ir_sensor_detected) {
 	if (ir_sensor_detected) {
@@ -4073,7 +4119,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 		{   
 		{   
 			prusa_statistics_case0(15);
 			prusa_statistics_case0(15);
 		}
 		}
-		else if (isPrintPaused || card.paused) 
+		else if (isPrintPaused)
 		{
 		{
 			prusa_statistics_case0(14);
 			prusa_statistics_case0(14);
 		}
 		}
@@ -4776,10 +4822,10 @@ void lcd_toshiba_flash_air_compatibility_toggle()
 //!
 //!
 //! @code{.unparsed}
 //! @code{.unparsed}
 //! |01234567890123456789|
 //! |01234567890123456789|
-//! |[Smooth1]Live adj. Z|  c=11
-//! |value set, continue |  c=20
-//! |or start from zero? |  c=20
-//! |>Continue Reset     |  c=a, c=b, a+b = 18
+//! |Sheet Smooth1 actual|  c=a, c=b, a+b = 13
+//! |Z offset: -1.480 mm |  c=a, c=b, a+b = 14
+//! |>Continue           |  c=19
+//! | Start from zero    |  c=19
 //! ----------------------
 //! ----------------------
 //! @endcode
 //! @endcode
 void lcd_first_layer_calibration_reset()
 void lcd_first_layer_calibration_reset()
@@ -4817,8 +4863,9 @@ void lcd_first_layer_calibration_reset()
     char sheet_name[sizeof(Sheet::name)];
     char sheet_name[sizeof(Sheet::name)];
     eeprom_read_block(sheet_name, &EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].name, sizeof(Sheet::name));
     eeprom_read_block(sheet_name, &EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].name, sizeof(Sheet::name));
     lcd_set_cursor(0, 0);
     lcd_set_cursor(0, 0);
-    lcd_printf_P(_i("[%.7s]Live adj. Z\nvalue set, continue\nor start from zero?\n%cContinue%cReset"), //// \n denotes line break, %.7s is replaced by 7 character long sheet name, %+1.3f is replaced by 6 character long floating point number, %c is replaced by > or white space (one character) based on whether first or second option is selected. % denoted place holders can not be reordered. r=4
-            sheet_name, menuData->reset ? ' ' : '>', menuData->reset ? '>' : ' ');
+    float offset = static_cast<int16_t>(eeprom_read_word(reinterpret_cast<uint16_t*>(&EEPROM_Sheets_base->s[(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet)))].z_offset)))/cs.axis_steps_per_unit[Z_AXIS];
+    lcd_printf_P(_i("Sheet %.7s\nZ offset: %+1.3f mm\n%cContinue\n%cStart from zero"), //// \n denotes line break, %.7s is replaced by 7 character long sheet name, %+1.3f is replaced by 6 character long floating point number, %c is replaced by > or white space (one character) based on whether first or second option is selected. % denoted place holders can not be reordered. r=4
+            sheet_name, offset, menuData->reset ? ' ' : '>', menuData->reset ? '>' : ' ');
 
 
 }
 }
 
 
@@ -4890,6 +4937,7 @@ void lcd_wizard() {
 	}
 	}
 }
 }
 
 
+#if (LANG_MODE != 0)
 void lcd_language()
 void lcd_language()
 {
 {
 	lcd_update_enable(true);
 	lcd_update_enable(true);
@@ -4909,6 +4957,7 @@ void lcd_language()
 	else
 	else
 		lang_select(LANG_ID_PRI);
 		lang_select(LANG_ID_PRI);
 }
 }
+#endif
 
 
 static void wait_preheat()
 static void wait_preheat()
 {
 {
@@ -5017,8 +5066,10 @@ void lcd_wizard(WizState state)
 	// Make sure EEPROM_WIZARD_ACTIVE is true if entering using different entry point
 	// Make sure EEPROM_WIZARD_ACTIVE is true if entering using different entry point
 	// other than WizState::Run - it is useful for debugging wizard.
 	// other than WizState::Run - it is useful for debugging wizard.
 	if (state != S::Run) eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1);
 	if (state != S::Run) eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1);
-
-	while (!end) {
+    
+    FORCE_BL_ON_START;
+	
+    while (!end) {
 		printf_P(PSTR("Wizard state: %d\n"), state);
 		printf_P(PSTR("Wizard state: %d\n"), state);
 		switch (state) {
 		switch (state) {
 		case S::Run: //Run wizard?
 		case S::Run: //Run wizard?
@@ -5154,7 +5205,9 @@ void lcd_wizard(WizState state)
 		default: break;
 		default: break;
 		}
 		}
 	}
 	}
-
+    
+    FORCE_BL_ON_END;
+    
 	printf_P(_N("Wizard end state: %d\n"), state);
 	printf_P(_N("Wizard end state: %d\n"), state);
 	switch (state) { //final message
 	switch (state) { //final message
 	case S::Restore: //printer was already calibrated
 	case S::Restore: //printer was already calibrated
@@ -5215,29 +5268,29 @@ do\
         if (fsensor_not_responding && (mmu_enabled == false))\
         if (fsensor_not_responding && (mmu_enabled == false))\
         {\
         {\
             /* Filament sensor not working*/\
             /* Filament sensor not working*/\
-            MENU_ITEM_FUNCTION_P(_i("Fil. sensor [N/A]"), lcd_fsensor_state_set);/*////MSG_FSENSOR_NA*/\
-            MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_fsensor_fail);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_NA), lcd_fsensor_state_set);/*////MSG_FSENSOR_NA*/\
+            MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), NULL, lcd_fsensor_fail);\
         }\
         }\
         else\
         else\
         {\
         {\
             /* Filament sensor turned off, working, no problems*/\
             /* Filament sensor turned off, working, no problems*/\
-            MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_OFF), lcd_fsensor_state_set);\
             if (mmu_enabled == false)\
             if (mmu_enabled == false)\
             {\
             {\
-                MENU_ITEM_SUBMENU_P(_T(MSG_FSENS_AUTOLOAD_NA), lcd_filament_autoload_info);\
+                MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), NULL, lcd_filament_autoload_info);\
             }\
             }\
         }\
         }\
     }\
     }\
     else\
     else\
     {\
     {\
         /* Filament sensor turned on, working, no problems*/\
         /* Filament sensor turned on, working, no problems*/\
-        MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_ON), lcd_fsensor_state_set);\
+        MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_ON), lcd_fsensor_state_set);\
         if (mmu_enabled == false)\
         if (mmu_enabled == false)\
         {\
         {\
             if (fsensor_autoload_enabled)\
             if (fsensor_autoload_enabled)\
-                MENU_ITEM_FUNCTION_P(_i("F. autoload  [on]"), lcd_set_filament_autoload);/*////MSG_FSENS_AUTOLOAD_ON c=17 r=1*/\
+                MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), _T(MSG_ON), lcd_set_filament_autoload);/*////MSG_FSENS_AUTOLOAD_ON c=17 r=1*/\
             else\
             else\
-                MENU_ITEM_FUNCTION_P(_i("F. autoload [off]"), lcd_set_filament_autoload);/*////MSG_FSENS_AUTOLOAD_OFF c=17 r=1*/\
+                MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), _T(MSG_OFF), lcd_set_filament_autoload);/*////MSG_FSENS_AUTOLOAD_OFF c=17 r=1*/\
             /*if (fsensor_oq_meassure_enabled)*/\
             /*if (fsensor_oq_meassure_enabled)*/\
                 /*MENU_ITEM_FUNCTION_P(_i("F. OQ meass. [on]"), lcd_set_filament_oq_meass);*//*////MSG_FSENS_OQMEASS_ON c=17 r=1*/\
                 /*MENU_ITEM_FUNCTION_P(_i("F. OQ meass. [on]"), lcd_set_filament_oq_meass);*//*////MSG_FSENS_OQMEASS_ON c=17 r=1*/\
             /*else*/\
             /*else*/\
@@ -5257,60 +5310,58 @@ static void auto_deplete_switch()
     eeprom_update_byte((unsigned char *)EEPROM_AUTO_DEPLETE, lcd_autoDeplete);
     eeprom_update_byte((unsigned char *)EEPROM_AUTO_DEPLETE, lcd_autoDeplete);
 }
 }
 
 
-static bool settingsAutoDeplete()
+static void settingsAutoDeplete()
 {
 {
     if (mmu_enabled)
     if (mmu_enabled)
     {
     {
         if (!fsensor_enabled)
         if (!fsensor_enabled)
         {
         {
-            if (menu_item_text_P(_i("SpoolJoin   [N/A]"))) return true;
+            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), _T(MSG_NA), NULL);
         }
         }
         else if (lcd_autoDeplete)
         else if (lcd_autoDeplete)
         {
         {
-            if (menu_item_function_P(_i("SpoolJoin    [on]"), auto_deplete_switch)) return true;
+            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), _T(MSG_ON), auto_deplete_switch);
         }
         }
         else
         else
         {
         {
-            if (menu_item_function_P(_i("SpoolJoin   [off]"), auto_deplete_switch)) return true;
+            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), _T(MSG_OFF), auto_deplete_switch);
         }
         }
     }
     }
-    return false;
 }
 }
 
 
 #define SETTINGS_AUTO_DEPLETE \
 #define SETTINGS_AUTO_DEPLETE \
 do\
 do\
 {\
 {\
-    if(settingsAutoDeplete()) return;\
+    settingsAutoDeplete();\
 }\
 }\
 while(0)\
 while(0)\
 
 
 #ifdef MMU_HAS_CUTTER
 #ifdef MMU_HAS_CUTTER
-static bool settingsCutter()
+static void settingsCutter()
 {
 {
     if (mmu_enabled)
     if (mmu_enabled)
     {
     {
         if (EEPROM_MMU_CUTTER_ENABLED_enabled == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
         if (EEPROM_MMU_CUTTER_ENABLED_enabled == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
         {
         {
-            if (menu_item_function_P(_i("Cutter       [on]"), lcd_cutter_enabled)) return true;//// c=17 r=1
+            MENU_ITEM_TOGGLE_P(_T(MSG_CUTTER), _T(MSG_ON), lcd_cutter_enabled);
         }
         }
 #ifdef MMU_ALWAYS_CUT
 #ifdef MMU_ALWAYS_CUT
         else if (EEPROM_MMU_CUTTER_ENABLED_always == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
         else if (EEPROM_MMU_CUTTER_ENABLED_always == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED))
         {
         {
-            if (menu_item_function_P(_i("Cutter   [always]"), lcd_cutter_enabled)) return true;//// c=17 r=1
+            MENU_ITEM_TOGGLE_P(_T(MSG_CUTTER), _i("Always"), lcd_cutter_enabled);
         }
         }
 #endif
 #endif
         else
         else
         {
         {
-            if (menu_item_function_P(_i("Cutter      [off]"), lcd_cutter_enabled)) return true;//// c=17 r=1
+            MENU_ITEM_TOGGLE_P(_T(MSG_CUTTER), _T(MSG_OFF), lcd_cutter_enabled);
         }
         }
     }
     }
-    return false;
 }
 }
 
 
 #define SETTINGS_CUTTER \
 #define SETTINGS_CUTTER \
 do\
 do\
 {\
 {\
-    if(settingsCutter()) return;\
+    settingsCutter();\
 }\
 }\
 while(0)
 while(0)
 #else
 #else
@@ -5325,18 +5376,15 @@ do\
     {\
     {\
         if (SilentModeMenu == SILENT_MODE_NORMAL)\
         if (SilentModeMenu == SILENT_MODE_NORMAL)\
         {\
         {\
-            MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_NORMAL), lcd_silent_mode_set);\
         }\
         }\
-        else MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);\
+        else MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_STEALTH), lcd_silent_mode_set);\
         if (SilentModeMenu == SILENT_MODE_NORMAL)\
         if (SilentModeMenu == SILENT_MODE_NORMAL)\
         {\
         {\
-            if (lcd_crash_detect_enabled())\
-            {\
-                MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_ON), crash_mode_switch);\
-            }\
-            else MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_OFF), crash_mode_switch);\
+            if (lcd_crash_detect_enabled()) MENU_ITEM_TOGGLE_P(_T(MSG_CRASHDETECT), _T(MSG_ON), crash_mode_switch);\
+            else MENU_ITEM_TOGGLE_P(_T(MSG_CRASHDETECT), _T(MSG_OFF), crash_mode_switch);\
         }\
         }\
-        else MENU_ITEM_SUBMENU_P(_T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);\
+        else MENU_ITEM_TOGGLE_P(_T(MSG_CRASHDETECT), NULL, lcd_crash_mode_info);\
     }\
     }\
 }\
 }\
 while (0)
 while (0)
@@ -5350,16 +5398,16 @@ do\
         switch (SilentModeMenu)\
         switch (SilentModeMenu)\
         {\
         {\
         case SILENT_MODE_POWER:\
         case SILENT_MODE_POWER:\
-            MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_HIGH_POWER), lcd_silent_mode_set);\
             break;\
             break;\
         case SILENT_MODE_SILENT:\
         case SILENT_MODE_SILENT:\
-            MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_ON), lcd_silent_mode_set);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_SILENT), lcd_silent_mode_set);\
             break;\
             break;\
         case SILENT_MODE_AUTO:\
         case SILENT_MODE_AUTO:\
-            MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_MODE_ON), lcd_silent_mode_set);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_AUTO_POWER), lcd_silent_mode_set);\
             break;\
             break;\
         default:\
         default:\
-            MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set);\
+            MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_HIGH_POWER), lcd_silent_mode_set);\
             break; /* (probably) not needed*/\
             break; /* (probably) not needed*/\
         }\
         }\
     }\
     }\
@@ -5373,8 +5421,8 @@ do\
 {\
 {\
 	if (mmu_enabled)\
 	if (mmu_enabled)\
 	{\
 	{\
-		if (SilentModeMenu_MMU == 0) MENU_ITEM_FUNCTION_P(_i("MMU Mode [Normal]"), lcd_silent_mode_mmu_set); \
-		else MENU_ITEM_FUNCTION_P(_i("MMU Mode[Stealth]"), lcd_silent_mode_mmu_set); \
+		if (SilentModeMenu_MMU == 0) MENU_ITEM_TOGGLE_P(_T(MSG_MMU_MODE), _T(MSG_NORMAL), lcd_silent_mode_mmu_set);\
+		else MENU_ITEM_TOGGLE_P(_T(MSG_MMU_MODE), _T(MSG_STEALTH), lcd_silent_mode_mmu_set);\
 	}\
 	}\
 }\
 }\
 while (0) 
 while (0) 
@@ -5387,9 +5435,9 @@ while (0)
 do\
 do\
 {\
 {\
     if (card.ToshibaFlashAir_isEnabled())\
     if (card.ToshibaFlashAir_isEnabled())\
-        MENU_ITEM_FUNCTION_P(_i("SD card [flshAir]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1*/\
+        MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY), lcd_toshiba_flash_air_compatibility_toggle);\
     else\
     else\
-        MENU_ITEM_FUNCTION_P(_i("SD card  [normal]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1*/\
+        MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_NORMAL), lcd_toshiba_flash_air_compatibility_toggle);\
 \
 \
     if (!farm_mode)\
     if (!farm_mode)\
     {\
     {\
@@ -5397,9 +5445,9 @@ do\
         EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\
         EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));\
         switch (sdSort)\
         switch (sdSort)\
         {\
         {\
-          case SD_SORT_TIME: MENU_ITEM_FUNCTION_P(_i("Sort       [time]"), lcd_sort_type_set); break;/*////MSG_SORT_TIME c=17 r=1*/\
-          case SD_SORT_ALPHA: MENU_ITEM_FUNCTION_P(_i("Sort   [alphabet]"), lcd_sort_type_set); break;/*////MSG_SORT_ALPHA c=17 r=1*/\
-          default: MENU_ITEM_FUNCTION_P(_i("Sort       [none]"), lcd_sort_type_set);/*////MSG_SORT_NONE c=17 r=1*/\
+          case SD_SORT_TIME: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_TIME), lcd_sort_type_set); break;\
+          case SD_SORT_ALPHA: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_SORT_ALPHA), lcd_sort_type_set); break;\
+          default: MENU_ITEM_TOGGLE_P(_T(MSG_SORT), _T(MSG_NONE), lcd_sort_type_set);\
         }\
         }\
     }\
     }\
 }\
 }\
@@ -5409,9 +5457,9 @@ while (0)
 do\
 do\
 {\
 {\
     if (card.ToshibaFlashAir_isEnabled())\
     if (card.ToshibaFlashAir_isEnabled())\
-        MENU_ITEM_FUNCTION_P(_i("SD card [flshAir]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1*/\
+        MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY), lcd_toshiba_flash_air_compatibility_toggle);\
     else\
     else\
-        MENU_ITEM_FUNCTION_P(_i("SD card  [normal]"), lcd_toshiba_flash_air_compatibility_toggle);/*////MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1*/\
+        MENU_ITEM_TOGGLE_P(_T(MSG_SD_CARD), _T(MSG_NORMAL), lcd_toshiba_flash_air_compatibility_toggle);\
 }\
 }\
 while (0)
 while (0)
 #endif // SDCARD_SORT_ALPHA
 #endif // SDCARD_SORT_ALPHA
@@ -5443,22 +5491,22 @@ while (0)
 do\
 do\
 {\
 {\
     switch(eSoundMode)\
     switch(eSoundMode)\
-         {\
-         case e_SOUND_MODE_LOUD:\
-              MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set);\
-              break;\
-         case e_SOUND_MODE_ONCE:\
-              MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_ONCE),lcd_sound_state_set);\
-              break;\
-         case e_SOUND_MODE_SILENT:\
-              MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_SILENT),lcd_sound_state_set);\
-              break;\
-         case e_SOUND_MODE_BLIND:\
-              MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_BLIND),lcd_sound_state_set);\
-              break;\
-         default:\
-              MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set);\
-         }\
+    {\
+        case e_SOUND_MODE_LOUD:\
+            MENU_ITEM_TOGGLE_P(_T(MSG_SOUND), _T(MSG_SOUND_LOUD), lcd_sound_state_set);\
+            break;\
+        case e_SOUND_MODE_ONCE:\
+            MENU_ITEM_TOGGLE_P(_T(MSG_SOUND), _T(MSG_SOUND_ONCE), lcd_sound_state_set);\
+            break;\
+        case e_SOUND_MODE_SILENT:\
+            MENU_ITEM_TOGGLE_P(_T(MSG_SOUND), _T(MSG_SILENT), lcd_sound_state_set);\
+            break;\
+        case e_SOUND_MODE_BLIND:\
+            MENU_ITEM_TOGGLE_P(_T(MSG_SOUND), _T(MSG_SOUND_BLIND), lcd_sound_state_set);\
+            break;\
+        default:\
+            MENU_ITEM_TOGGLE_P(_T(MSG_SOUND), _T(MSG_SOUND_LOUD), lcd_sound_state_set);\
+    }\
 }\
 }\
 while (0)
 while (0)
 
 
@@ -5488,16 +5536,16 @@ do\
     switch(oCheckMode)\
     switch(oCheckMode)\
          {\
          {\
          case ClCheckMode::_None:\
          case ClCheckMode::_None:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle     [none]"),lcd_check_mode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_NOZZLE), _T(MSG_NONE), lcd_check_mode_set);\
               break;\
               break;\
          case ClCheckMode::_Warn:\
          case ClCheckMode::_Warn:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle     [warn]"),lcd_check_mode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_NOZZLE), _T(MSG_WARN), lcd_check_mode_set);\
               break;\
               break;\
          case ClCheckMode::_Strict:\
          case ClCheckMode::_Strict:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle   [strict]"),lcd_check_mode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_NOZZLE), _T(MSG_STRICT), lcd_check_mode_set);\
               break;\
               break;\
          default:\
          default:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle     [none]"),lcd_check_mode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_NOZZLE), _T(MSG_NONE), lcd_check_mode_set);\
          }\
          }\
 }\
 }\
 while (0)
 while (0)
@@ -5531,20 +5579,15 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,nDiameter);
 #define SETTINGS_NOZZLE \
 #define SETTINGS_NOZZLE \
 do\
 do\
 {\
 {\
+    float fNozzleDiam;\
     switch(oNozzleDiameter)\
     switch(oNozzleDiameter)\
-         {\
-         case ClNozzleDiameter::_Diameter_250:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle d.  [0.25]"),lcd_nozzle_diameter_set);\
-              break;\
-         case ClNozzleDiameter::_Diameter_400:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle d.  [0.40]"),lcd_nozzle_diameter_set);\
-              break;\
-         case ClNozzleDiameter::_Diameter_600:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle d.  [0.60]"),lcd_nozzle_diameter_set);\
-              break;\
-         default:\
-              MENU_ITEM_FUNCTION_P(_i("Nozzle d.  [0.40]"),lcd_nozzle_diameter_set);\
-         }\
+    {\
+        case ClNozzleDiameter::_Diameter_250: fNozzleDiam = 0.25f; break;\
+        case ClNozzleDiameter::_Diameter_400: fNozzleDiam = 0.4f; break;\
+        case ClNozzleDiameter::_Diameter_600: fNozzleDiam = 0.6f; break;\
+        default: fNozzleDiam = 0.4f; break;\
+    }\
+    MENU_ITEM_TOGGLE(_T(MSG_NOZZLE_DIAMETER), ftostr12ns(fNozzleDiam), lcd_nozzle_diameter_set);\
 }\
 }\
 while (0)
 while (0)
 
 
@@ -5573,16 +5616,16 @@ do\
     switch(oCheckModel)\
     switch(oCheckModel)\
          {\
          {\
          case ClCheckModel::_None:\
          case ClCheckModel::_None:\
-              MENU_ITEM_FUNCTION_P(_i("Model      [none]"),lcd_check_model_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_MODEL), _T(MSG_NONE), lcd_check_model_set);\
               break;\
               break;\
          case ClCheckModel::_Warn:\
          case ClCheckModel::_Warn:\
-              MENU_ITEM_FUNCTION_P(_i("Model      [warn]"),lcd_check_model_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_MODEL), _T(MSG_WARN), lcd_check_model_set);\
               break;\
               break;\
          case ClCheckModel::_Strict:\
          case ClCheckModel::_Strict:\
-              MENU_ITEM_FUNCTION_P(_i("Model    [strict]"),lcd_check_model_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_MODEL), _T(MSG_STRICT), lcd_check_model_set);\
               break;\
               break;\
          default:\
          default:\
-              MENU_ITEM_FUNCTION_P(_i("Model      [none]"),lcd_check_model_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_MODEL), _T(MSG_NONE), lcd_check_model_set);\
          }\
          }\
 }\
 }\
 while (0)
 while (0)
@@ -5612,16 +5655,16 @@ do\
     switch(oCheckVersion)\
     switch(oCheckVersion)\
          {\
          {\
          case ClCheckVersion::_None:\
          case ClCheckVersion::_None:\
-              MENU_ITEM_FUNCTION_P(_i("Firmware   [none]"),lcd_check_version_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_FIRMWARE), _T(MSG_NONE), lcd_check_version_set);\
               break;\
               break;\
          case ClCheckVersion::_Warn:\
          case ClCheckVersion::_Warn:\
-              MENU_ITEM_FUNCTION_P(_i("Firmware   [warn]"),lcd_check_version_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_FIRMWARE), _T(MSG_WARN), lcd_check_version_set);\
               break;\
               break;\
          case ClCheckVersion::_Strict:\
          case ClCheckVersion::_Strict:\
-              MENU_ITEM_FUNCTION_P(_i("Firmware [strict]"),lcd_check_version_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_FIRMWARE), _T(MSG_STRICT), lcd_check_version_set);\
               break;\
               break;\
          default:\
          default:\
-              MENU_ITEM_FUNCTION_P(_i("Firmware   [none]"),lcd_check_version_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_FIRMWARE), _T(MSG_NONE), lcd_check_version_set);\
          }\
          }\
 }\
 }\
 while (0)
 while (0)
@@ -5651,16 +5694,16 @@ do\
     switch(oCheckGcode)\
     switch(oCheckGcode)\
          {\
          {\
          case ClCheckGcode::_None:\
          case ClCheckGcode::_None:\
-              MENU_ITEM_FUNCTION_P(_i("Gcode      [none]"),lcd_check_gcode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_GCODE), _T(MSG_NONE), lcd_check_gcode_set);\
               break;\
               break;\
          case ClCheckGcode::_Warn:\
          case ClCheckGcode::_Warn:\
-              MENU_ITEM_FUNCTION_P(_i("Gcode      [warn]"),lcd_check_gcode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_GCODE), _T(MSG_WARN), lcd_check_gcode_set);\
               break;\
               break;\
          case ClCheckGcode::_Strict:\
          case ClCheckGcode::_Strict:\
-              MENU_ITEM_FUNCTION_P(_i("Gcode    [strict]"),lcd_check_gcode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_GCODE), _T(MSG_STRICT), lcd_check_gcode_set);\
               break;\
               break;\
          default:\
          default:\
-              MENU_ITEM_FUNCTION_P(_i("Gcode      [none]"),lcd_check_gcode_set);\
+              MENU_ITEM_TOGGLE_P(_T(MSG_GCODE), _T(MSG_NONE), lcd_check_gcode_set);\
          }\
          }\
 }\
 }\
 while (0)
 while (0)
@@ -5677,6 +5720,41 @@ SETTINGS_VERSION;
 MENU_END();
 MENU_END();
 }
 }
 
 
+#if IR_SENSOR_ANALOG
+static void lcd_fsensor_actionNA_set(void)
+{
+switch(oFsensorActionNA)
+     {
+     case ClFsensorActionNA::_Continue:
+          oFsensorActionNA=ClFsensorActionNA::_Pause;
+          break;
+     case ClFsensorActionNA::_Pause:
+          oFsensorActionNA=ClFsensorActionNA::_Continue;
+          break;
+     default:
+          oFsensorActionNA=ClFsensorActionNA::_Continue;
+     }
+eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA,(uint8_t)oFsensorActionNA);
+}
+
+#define FSENSOR_ACTION_NA \
+do\
+{\
+    switch(oFsensorActionNA)\
+         {\
+         case ClFsensorActionNA::_Continue:\
+              MENU_ITEM_TOGGLE_P(_T(MSG_FS_ACTION), _T(MSG_FS_CONTINUE), lcd_fsensor_actionNA_set);\
+              break;\
+         case ClFsensorActionNA::_Pause:\
+              MENU_ITEM_TOGGLE_P(_T(MSG_FS_ACTION), _T(MSG_FS_PAUSE), lcd_fsensor_actionNA_set);\
+              break;\
+         default:\
+              oFsensorActionNA=ClFsensorActionNA::_Continue;\
+         }\
+}\
+while (0)
+#endif //IR_SENSOR_ANALOG
+
 template <uint8_t number>
 template <uint8_t number>
 static void select_sheet_menu()
 static void select_sheet_menu()
 {
 {
@@ -5708,6 +5786,9 @@ void lcd_hw_setup_menu(void)                      // can not be "static"
     SETTINGS_NOZZLE;
     SETTINGS_NOZZLE;
     MENU_ITEM_SUBMENU_P(_i("Checks"), lcd_checking_menu);
     MENU_ITEM_SUBMENU_P(_i("Checks"), lcd_checking_menu);
 
 
+#if IR_SENSOR_ANALOG
+    FSENSOR_ACTION_NA;
+#endif //IR_SENSOR_ANALOG
     MENU_END();
     MENU_END();
 }
 }
 
 
@@ -5729,10 +5810,7 @@ static void lcd_settings_menu()
 
 
 	SETTINGS_CUTTER;
 	SETTINGS_CUTTER;
 
 
-	if (fans_check_enabled == true)
-		MENU_ITEM_FUNCTION_P(_i("Fans check   [on]"), lcd_set_fan_check);////MSG_FANS_CHECK_ON c=17 r=1
-	else
-		MENU_ITEM_FUNCTION_P(_i("Fans check  [off]"), lcd_set_fan_check);////MSG_FANS_CHECK_OFF c=17 r=1
+	MENU_ITEM_TOGGLE_P(_i("Fans check"), fans_check_enabled ? _T(MSG_ON) : _T(MSG_OFF), lcd_set_fan_check);
 
 
 	SETTINGS_SILENT_MODE;
 	SETTINGS_SILENT_MODE;
 
 
@@ -5750,16 +5828,10 @@ static void lcd_settings_menu()
     MENU_ITEM_SUBMENU_P(_i("Lin. correction"), lcd_settings_linearity_correction_menu);
     MENU_ITEM_SUBMENU_P(_i("Lin. correction"), lcd_settings_linearity_correction_menu);
 #endif //LINEARITY_CORRECTION && TMC2130
 #endif //LINEARITY_CORRECTION && TMC2130
 
 
-  if (temp_cal_active == false)
-	  MENU_ITEM_FUNCTION_P(_i("Temp. cal.  [off]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_OFF c=20 r=1
-  else
-	  MENU_ITEM_FUNCTION_P(_i("Temp. cal.   [on]"), lcd_temp_calibration_set);////MSG_TEMP_CALIBRATION_ON c=20 r=1
+	MENU_ITEM_TOGGLE_P(_T(MSG_TEMP_CALIBRATION), temp_cal_active ? _T(MSG_ON) : _T(MSG_OFF), lcd_temp_calibration_set);
 
 
 #ifdef HAS_SECOND_SERIAL_PORT
 #ifdef HAS_SECOND_SERIAL_PORT
-	if (selectedSerialPort == 0)
-		MENU_ITEM_FUNCTION_P(_i("RPi port    [off]"), lcd_second_serial_set);////MSG_SECOND_SERIAL_OFF c=17 r=1
-	else
-		MENU_ITEM_FUNCTION_P(_i("RPi port     [on]"), lcd_second_serial_set);////MSG_SECOND_SERIAL_ON c=17 r=1
+    MENU_ITEM_TOGGLE_P(_T(MSG_RPI_PORT), (selectedSerialPort == 0) ? _T(MSG_OFF) : _T(MSG_ON), lcd_second_serial_set);
 #endif //HAS_SECOND_SERIAL
 #endif //HAS_SECOND_SERIAL
 
 
 	if (!isPrintPaused && !homing_flag)
 	if (!isPrintPaused && !homing_flag)
@@ -5772,6 +5844,13 @@ static void lcd_settings_menu()
 	SETTINGS_SD;
 	SETTINGS_SD;
 	SETTINGS_SOUND;
 	SETTINGS_SOUND;
 
 
+#ifdef LCD_BL_PIN
+    if (backlightSupport)
+    {
+        MENU_ITEM_SUBMENU_P(_T(MSG_BRIGHTNESS), lcd_backlight_menu);
+    }
+#endif //LCD_BL_PIN
+
 	if (farm_mode)
 	if (farm_mode)
 	{
 	{
 		MENU_ITEM_SUBMENU_P(PSTR("Farm number"), lcd_farm_no);
 		MENU_ITEM_SUBMENU_P(PSTR("Farm number"), lcd_farm_no);
@@ -5820,6 +5899,9 @@ static void lcd_calibration_menu()
          MENU_ITEM_SUBMENU_P(_T(MSG_V2_CALIBRATION), lcd_first_layer_calibration_reset);
          MENU_ITEM_SUBMENU_P(_T(MSG_V2_CALIBRATION), lcd_first_layer_calibration_reset);
     }
     }
 	MENU_ITEM_GCODE_P(_T(MSG_AUTO_HOME), PSTR("G28 W"));
 	MENU_ITEM_GCODE_P(_T(MSG_AUTO_HOME), PSTR("G28 W"));
+#ifdef TMC2130
+	MENU_ITEM_FUNCTION_P(_i("Belt test        "), lcd_belttest_v);////MSG_BELTTEST
+#endif //TMC2130
 	MENU_ITEM_FUNCTION_P(_i("Selftest         "), lcd_selftest_v);////MSG_SELFTEST
 	MENU_ITEM_FUNCTION_P(_i("Selftest         "), lcd_selftest_v);////MSG_SELFTEST
 #ifdef MK1BP
 #ifdef MK1BP
     // MK1
     // MK1
@@ -6360,6 +6442,8 @@ void unload_filament()
 	custom_message_type = CustomMsg::FilamentLoading;
 	custom_message_type = CustomMsg::FilamentLoading;
 	lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
 	lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT));
 
 
+    raise_z_above(MIN_Z_FOR_UNLOAD);
+
 	//		extr_unload2();
 	//		extr_unload2();
 
 
 	current_position[E_AXIS] -= 45;
 	current_position[E_AXIS] -= 45;
@@ -6642,6 +6726,7 @@ static void lcd_test_menu()
 static bool fan_error_selftest()
 static bool fan_error_selftest()
 {
 {
 #ifdef FANCHECK
 #ifdef FANCHECK
+    if (!fans_check_enabled) return 0;
 
 
     fanSpeed = 255;
     fanSpeed = 255;
 #ifdef FAN_SOFT_PWM
 #ifdef FAN_SOFT_PWM
@@ -6672,9 +6757,8 @@ static bool fan_error_selftest()
         return 1;
         return 1;
     }
     }
 #endif
 #endif
+#endif //FANCHECK
     return 0;
     return 0;
-
-#endif //FANCHECK   
 }
 }
 
 
 //! @brief Resume paused print
 //! @brief Resume paused print
@@ -6689,10 +6773,10 @@ void lcd_resume_print()
 
 
     if (fan_error_selftest()) return; //abort if error persists
     if (fan_error_selftest()) return; //abort if error persists
 
 
+    isPrintPaused = false;
     restore_print_from_ram_and_continue(0.0);
     restore_print_from_ram_and_continue(0.0);
     pause_time += (_millis() - start_pause_print); //accumulate time when print is paused for correct statistics calculation
     pause_time += (_millis() - start_pause_print); //accumulate time when print is paused for correct statistics calculation
     refresh_cmd_timeout();
     refresh_cmd_timeout();
-    isPrintPaused = false;
     SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_RESUMED); //resume octoprint
     SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_RESUMED); //resume octoprint
 }
 }
 
 
@@ -6844,7 +6928,7 @@ static void lcd_main_menu()
 			{
 			{
 				MENU_ITEM_FUNCTION_P(_i("Pause print"), lcd_pause_print);////MSG_PAUSE_PRINT
 				MENU_ITEM_FUNCTION_P(_i("Pause print"), lcd_pause_print);////MSG_PAUSE_PRINT
 			}
 			}
-			else
+			else if(isPrintPaused)
 			{
 			{
 				#ifdef FANCHECK
 				#ifdef FANCHECK
 					if((fan_check_error == EFCE_FIXED) || (fan_check_error == EFCE_OK))
 					if((fan_check_error == EFCE_FIXED) || (fan_check_error == EFCE_OK))
@@ -7045,11 +7129,21 @@ static void lcd_tune_menu()
 
 
 #ifdef FILAMENT_SENSOR
 #ifdef FILAMENT_SENSOR
 	if (FSensorStateMenu == 0) {
 	if (FSensorStateMenu == 0) {
-		MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_OFF), lcd_fsensor_state_set);
+          if (fsensor_not_responding && (mmu_enabled == false)) {
+               /* Filament sensor not working*/
+               MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_NA), lcd_fsensor_state_set);
+          }
+          else {
+               /* Filament sensor turned off, working, no problems*/
+               MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_OFF), lcd_fsensor_state_set);
+          }
 	}
 	}
 	else {
 	else {
-		MENU_ITEM_FUNCTION_P(_T(MSG_FSENSOR_ON), lcd_fsensor_state_set);
+		MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_ON), lcd_fsensor_state_set);
 	}
 	}
+#if IR_SENSOR_ANALOG
+     FSENSOR_ACTION_NA;
+#endif //IR_SENSOR_ANALOG
 #endif //FILAMENT_SENSOR
 #endif //FILAMENT_SENSOR
 
 
 	SETTINGS_AUTO_DEPLETE;
 	SETTINGS_AUTO_DEPLETE;
@@ -7058,54 +7152,40 @@ static void lcd_tune_menu()
 
 
      if(farm_mode)
      if(farm_mode)
      {
      {
-          if (fans_check_enabled == true)
-               MENU_ITEM_FUNCTION_P(_i("Fans check   [on]"), lcd_set_fan_check);////MSG_FANS_CHECK_ON c=17 r=1
-          else
-               MENU_ITEM_FUNCTION_P(_i("Fans check  [off]"), lcd_set_fan_check);////MSG_FANS_CHECK_OFF c=17 r=1
+       MENU_ITEM_TOGGLE_P(_i("Fans check"), fans_check_enabled ? _T(MSG_ON) : _T(MSG_OFF), lcd_set_fan_check);
      }
      }
 
 
 #ifdef TMC2130
 #ifdef TMC2130
      if(!farm_mode)
      if(!farm_mode)
      {
      {
-          if (SilentModeMenu == SILENT_MODE_NORMAL) MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_OFF), lcd_silent_mode_set);
-          else MENU_ITEM_FUNCTION_P(_T(MSG_STEALTH_MODE_ON), lcd_silent_mode_set);
+          if (SilentModeMenu == SILENT_MODE_NORMAL) MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_NORMAL), lcd_silent_mode_set);
+          else MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_STEALTH), lcd_silent_mode_set);
 
 
           if (SilentModeMenu == SILENT_MODE_NORMAL)
           if (SilentModeMenu == SILENT_MODE_NORMAL)
           {
           {
-               if (lcd_crash_detect_enabled()) MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_ON), crash_mode_switch);
-               else MENU_ITEM_FUNCTION_P(_T(MSG_CRASHDETECT_OFF), crash_mode_switch);
+               if (lcd_crash_detect_enabled()) MENU_ITEM_TOGGLE_P(_T(MSG_CRASHDETECT), _T(MSG_ON), crash_mode_switch);
+               else MENU_ITEM_TOGGLE_P(_T(MSG_CRASHDETECT), _T(MSG_OFF), crash_mode_switch);
           }
           }
-          else MENU_ITEM_SUBMENU_P(_T(MSG_CRASHDETECT_NA), lcd_crash_mode_info);
+          else MENU_ITEM_TOGGLE_P(_T(MSG_CRASHDETECT), NULL, lcd_crash_mode_info);
      }
      }
 #else //TMC2130
 #else //TMC2130
 	if (!farm_mode) { //dont show in menu if we are in farm mode
 	if (!farm_mode) { //dont show in menu if we are in farm mode
 		switch (SilentModeMenu) {
 		switch (SilentModeMenu) {
-		case SILENT_MODE_POWER: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break;
-		case SILENT_MODE_SILENT: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_ON), lcd_silent_mode_set); break;
-		case SILENT_MODE_AUTO: MENU_ITEM_FUNCTION_P(_T(MSG_AUTO_MODE_ON), lcd_silent_mode_set); break;
-		default: MENU_ITEM_FUNCTION_P(_T(MSG_SILENT_MODE_OFF), lcd_silent_mode_set); break; // (probably) not needed
+		case SILENT_MODE_POWER: MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_HIGH_POWER), lcd_silent_mode_set); break;
+		case SILENT_MODE_SILENT: MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_SILENT), lcd_silent_mode_set); break;
+		case SILENT_MODE_AUTO: MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_AUTO_POWER), lcd_silent_mode_set); break;
+		default: MENU_ITEM_TOGGLE_P(_T(MSG_MODE), _T(MSG_HIGH_POWER), lcd_silent_mode_set); break; // (probably) not needed
 		}
 		}
 	}
 	}
 #endif //TMC2130
 #endif //TMC2130
-	 SETTINGS_MMU_MODE;
-     switch(eSoundMode)
-          {
-          case e_SOUND_MODE_LOUD:
-               MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set);
-               break;
-          case e_SOUND_MODE_ONCE:
-               MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_ONCE),lcd_sound_state_set);
-               break;
-          case e_SOUND_MODE_SILENT:
-               MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_SILENT),lcd_sound_state_set);
-               break;
-          case e_SOUND_MODE_BLIND:
-               MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_BLIND),lcd_sound_state_set);
-               break;
-          default:
-               MENU_ITEM_FUNCTION_P(_i(MSG_SOUND_MODE_LOUD),lcd_sound_state_set);
-          }
-
+	SETTINGS_MMU_MODE;
+    SETTINGS_SOUND;
+#ifdef LCD_BL_PIN
+    if (backlightSupport)
+    {
+        MENU_ITEM_SUBMENU_P(_T(MSG_BRIGHTNESS), lcd_backlight_menu);
+    }
+#endif //LCD_BL_PIN
 	MENU_END();
 	MENU_END();
 }
 }
 
 
@@ -7138,25 +7218,53 @@ static void lcd_mesh_bed_leveling_settings()
 	
 	
 	bool magnet_elimination = (eeprom_read_byte((uint8_t*)EEPROM_MBL_MAGNET_ELIMINATION) > 0);
 	bool magnet_elimination = (eeprom_read_byte((uint8_t*)EEPROM_MBL_MAGNET_ELIMINATION) > 0);
 	uint8_t points_nr = eeprom_read_byte((uint8_t*)EEPROM_MBL_POINTS_NR);
 	uint8_t points_nr = eeprom_read_byte((uint8_t*)EEPROM_MBL_POINTS_NR);
+	char sToggle[4]; //enough for nxn format
 
 
 	MENU_BEGIN();
 	MENU_BEGIN();
-	MENU_ITEM_BACK_P(_T(MSG_SETTINGS)); 
-	if(points_nr == 3) MENU_ITEM_FUNCTION_P(_i("Mesh         [3x3]"), mbl_mesh_toggle); ////MSG_MESH_3x3 c=18
-	else			   MENU_ITEM_FUNCTION_P(_i("Mesh         [7x7]"), mbl_mesh_toggle); ////MSG_MESH_7x7 c=18
-	switch (mbl_z_probe_nr) {
-		case 1: MENU_ITEM_FUNCTION_P(_i("Z-probe nr.    [1]"), mbl_probe_nr_toggle); break; ////MSG_Z_PROBE_NR_1 c=18
-		case 5: MENU_ITEM_FUNCTION_P(_i("Z-probe nr.    [5]"), mbl_probe_nr_toggle); break; ////MSG_Z_PROBE_NR_1 c=18
-		default: MENU_ITEM_FUNCTION_P(_i("Z-probe nr.    [3]"), mbl_probe_nr_toggle); break; ////MSG_Z_PROBE_NR_1 c=18
-	}
-	if (points_nr == 7) {
-		if (magnet_elimination) MENU_ITEM_FUNCTION_P(_i("Magnets comp. [On]"), mbl_magnets_elimination_toggle); ////MSG_MAGNETS_COMP_ON c=18
-		else				    MENU_ITEM_FUNCTION_P(_i("Magnets comp.[Off]"), mbl_magnets_elimination_toggle); ////MSG_MAGNETS_COMP_OFF c=18
-	}
-	else					        menu_item_text_P(_i("Magnets comp.[N/A]")); ////MSG_MAGNETS_COMP_NA c=18
+	MENU_ITEM_BACK_P(_T(MSG_SETTINGS));
+	sToggle[0] = points_nr + '0';
+	sToggle[1] = 'x';
+	sToggle[2] = points_nr + '0';
+	sToggle[3] = 0;
+	MENU_ITEM_TOGGLE(_T(MSG_MESH), sToggle, mbl_mesh_toggle);
+	sToggle[0] = mbl_z_probe_nr + '0';
+	sToggle[1] = 0;
+	MENU_ITEM_TOGGLE(_T(MSG_Z_PROBE_NR), sToggle, mbl_probe_nr_toggle);
+	MENU_ITEM_TOGGLE_P(_T(MSG_MAGNETS_COMP), (points_nr == 7) ? (magnet_elimination ? _T(MSG_ON): _T(MSG_OFF)) : _T(MSG_NA), mbl_magnets_elimination_toggle);
 	MENU_END();
 	MENU_END();
 	//SETTINGS_MBL_MODE;
 	//SETTINGS_MBL_MODE;
 }
 }
 
 
+#ifdef LCD_BL_PIN
+static void backlight_mode_toggle()
+{
+    switch (backlightMode)
+    {
+        case BACKLIGHT_MODE_BRIGHT: backlightMode = BACKLIGHT_MODE_DIM; break;
+        case BACKLIGHT_MODE_DIM: backlightMode = BACKLIGHT_MODE_AUTO; break;
+        case BACKLIGHT_MODE_AUTO: backlightMode = BACKLIGHT_MODE_BRIGHT; break;
+        default: backlightMode = BACKLIGHT_MODE_BRIGHT; break;
+    }
+    backlight_save();
+}
+
+static void lcd_backlight_menu()
+{
+    MENU_BEGIN();
+    ON_MENU_LEAVE(
+        backlight_save();
+    );
+    
+    MENU_ITEM_BACK_P(_T(MSG_BACK));
+    MENU_ITEM_EDIT_int3_P(_T(MSG_BL_HIGH), &backlightLevel_HIGH, backlightLevel_LOW, 255);
+    MENU_ITEM_EDIT_int3_P(_T(MSG_BL_LOW), &backlightLevel_LOW, 0, backlightLevel_HIGH);
+	MENU_ITEM_TOGGLE_P(_T(MSG_MODE), ((backlightMode==BACKLIGHT_MODE_BRIGHT) ? _T(MSG_BRIGHT) : ((backlightMode==BACKLIGHT_MODE_DIM) ? _T(MSG_DIM) : _T(MSG_AUTO))), backlight_mode_toggle);
+    MENU_ITEM_EDIT_int3_P(_T(MSG_TIMEOUT), &backlightTimer_period, 1, 999);
+    
+    MENU_END();
+}
+#endif //LCD_BL_PIN
+
 static void lcd_control_temperature_menu()
 static void lcd_control_temperature_menu()
 {
 {
 #ifdef PIDTEMP
 #ifdef PIDTEMP
@@ -7207,30 +7315,26 @@ static void lcd_sd_updir()
 
 
 void lcd_print_stop()
 void lcd_print_stop()
 {
 {
-//-//
-     if(!card.sdprinting)
-          {
-          SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL);   // for Octoprint
-          }
-	saved_printing = false;
-    saved_printing_type = PRINTING_TYPE_NONE;
+    if (!card.sdprinting) {
+        SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL);   // for Octoprint
+    }
+
+    CRITICAL_SECTION_START;
+
+    // Clear any saved printing state
+    cancel_saved_printing();
 	cancel_heatup = true;
 	cancel_heatup = true;
-#ifdef MESH_BED_LEVELING
-	mbl.active = false;
-#endif
-	// Stop the stoppers, update the position from the stoppers.
-	if (mesh_bed_leveling_flag == false && homing_flag == false)
-	{
-		planner_abort_hard();
-		// Because the planner_abort_hard() initialized current_position[Z] from the stepper,
-		// Z baystep is no more applied. Reset it.
-		babystep_reset();
-	}
-	// Clean the input command queue.
+
+    // Abort the planner/queue/sd
+    planner_abort_hard();
 	cmdqueue_reset();
 	cmdqueue_reset();
-	lcd_setstatuspgm(_T(MSG_PRINT_ABORTED));
 	card.sdprinting = false;
 	card.sdprinting = false;
 	card.closefile();
 	card.closefile();
+    st_reset_timer();
+
+    CRITICAL_SECTION_END;
+
+	lcd_setstatuspgm(_T(MSG_PRINT_ABORTED));
 	stoptime = _millis();
 	stoptime = _millis();
 	unsigned long t = (stoptime - starttime - pause_time) / 1000; //time in s
 	unsigned long t = (stoptime - starttime - pause_time) / 1000; //time in s
 	pause_time = 0;
 	pause_time = 0;
@@ -7332,6 +7436,98 @@ void lcd_sdcard_menu()
   }
   }
   MENU_END();
   MENU_END();
 }
 }
+#ifdef TMC2130
+static void lcd_belttest_v()
+{
+    lcd_belttest();
+    menu_back_if_clicked();
+}
+void lcd_belttest_print(const char* msg, uint16_t X, uint16_t Y)
+{
+    lcd_clear();
+    lcd_printf_P(
+              _N(
+                 "%S:\n"
+                 "%S\n"
+                 "X:%d\n"
+                 "Y:%d"
+                 ),
+              _i("Belt status"),
+              msg,
+              X,Y
+            );
+}
+void lcd_belttest()
+{
+    int _progress = 0;
+    bool _result = true;
+    uint16_t   X = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X));
+    uint16_t   Y = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y));
+    lcd_belttest_print(_i("Checking X..."), X, Y);
+
+    _delay(2000);
+    KEEPALIVE_STATE(IN_HANDLER);
+
+    _result = lcd_selfcheck_axis_sg(X_AXIS);
+    X = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_X));
+    if (!_result){
+        lcd_belttest_print(_i("Error"), X, Y);
+        return;
+    }
+
+    lcd_belttest_print(_i("Checking Y..."), X, Y);
+    _result = lcd_selfcheck_axis_sg(Y_AXIS);
+    Y = eeprom_read_word((uint16_t*)(EEPROM_BELTSTATUS_Y));
+
+    if (!_result){
+        lcd_belttest_print(_i("Error"), X, Y);
+        lcd_clear();
+        return;
+    }
+
+
+    lcd_belttest_print(_i("Done"), X, Y);
+
+    KEEPALIVE_STATE(NOT_BUSY);
+    _delay(3000);
+}
+#endif //TMC2130
+
+#if IR_SENSOR_ANALOG
+static bool lcd_selftest_IRsensor()
+{
+bool bAction;
+bool bPCBrev03b;
+uint16_t volt_IR_int;
+float volt_IR;
+
+volt_IR_int=current_voltage_raw_IR;
+bPCBrev03b=(volt_IR_int<((int)IRsensor_Hopen_TRESHOLD));
+volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
+printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"),volt_IR);
+if(volt_IR_int<((int)IRsensor_Hmin_TRESHOLD))
+     {
+     lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
+     return(false);
+     }
+lcd_show_fullscreen_message_and_wait_P(_i("Please insert filament (but not load them!) into extruder and then press the knob."));
+volt_IR_int=current_voltage_raw_IR;
+volt_IR=VOLT_DIV_REF*((float)volt_IR_int/(1023*OVERSAMPLENR));
+printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"),volt_IR);
+if(volt_IR_int>((int)IRsensor_Lmax_TRESHOLD))
+     {
+     lcd_selftest_error(TestError::FsensorLevel,"LOW","");
+     return(false);
+     }
+if((bPCBrev03b?1:0)!=(uint8_t)oFsensorPCB)        // safer then "(uint8_t)bPCBrev03b"
+     {
+     printf_P(PSTR("Filament sensor board change detected: revision %S\n"),bPCBrev03b?PSTR("03b or newer"):PSTR("03 or older"));
+     oFsensorPCB=bPCBrev03b?ClFsensorPCB::_Rev03b:ClFsensorPCB::_Old;
+     eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
+     }
+return(true);
+}
+#endif //IR_SENSOR_ANALOG
 
 
 static void lcd_selftest_v()
 static void lcd_selftest_v()
 {
 {
@@ -7349,8 +7545,20 @@ bool lcd_selftest()
 	#ifdef TMC2130
 	#ifdef TMC2130
 	  FORCE_HIGH_POWER_START;
 	  FORCE_HIGH_POWER_START;
 	#endif // TMC2130
 	#endif // TMC2130
+#if !IR_SENSOR_ANALOG
+     _delay(2000);
+#endif //!IR_SENSOR_ANALOG
+    
+    FORCE_BL_ON_START;
+    
 	_delay(2000);
 	_delay(2000);
 	KEEPALIVE_STATE(IN_HANDLER);
 	KEEPALIVE_STATE(IN_HANDLER);
+#if IR_SENSOR_ANALOG
+     bool bAction;
+     bAction=lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is filament unloaded?"),false,true);
+     if(!bAction)
+          return(false);
+#endif //IR_SENSOR_ANALOG
 
 
 	_progress = lcd_selftest_screen(TestScreen::ExtruderFan, _progress, 3, true, 2000);
 	_progress = lcd_selftest_screen(TestScreen::ExtruderFan, _progress, 3, true, 2000);
 #if (defined(FANCHECK) && defined(TACH_0))
 #if (defined(FANCHECK) && defined(TACH_0))
@@ -7536,12 +7744,20 @@ bool lcd_selftest()
         {
         {
 #ifdef PAT9125
 #ifdef PAT9125
 			_progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filaments sensor
 			_progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filaments sensor
-            _result = lcd_selftest_fsensor();
+               _result = lcd_selftest_fsensor();
 			if (_result)
 			if (_result)
 			{
 			{
 				_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK
 				_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK
 			}
 			}
 #endif //PAT9125
 #endif //PAT9125
+#if IR_SENSOR_ANALOG
+			_progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filament sensor
+               _result = lcd_selftest_IRsensor();
+			if (_result)
+			{
+				_progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //filament sensor OK
+			}
+#endif //IR_SENSOR_ANALOG
         }
         }
     }
     }
 #endif //FILAMENT_SENSOR
 #endif //FILAMENT_SENSOR
@@ -7568,7 +7784,10 @@ bool lcd_selftest()
 	#ifdef TMC2130
 	#ifdef TMC2130
 	  FORCE_HIGH_POWER_END;
 	  FORCE_HIGH_POWER_END;
 	#endif // TMC2130
 	#endif // TMC2130
-	KEEPALIVE_STATE(NOT_BUSY);
+    
+    FORCE_BL_ON_END;
+	
+    KEEPALIVE_STATE(NOT_BUSY);
 	return(_result);
 	return(_result);
 }
 }
 
 
@@ -7977,7 +8196,9 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
 static void lcd_selftest_error(TestError testError, const char *_error_1, const char *_error_2)
 static void lcd_selftest_error(TestError testError, const char *_error_1, const char *_error_2)
 {
 {
 	lcd_beeper_quick_feedback();
 	lcd_beeper_quick_feedback();
-
+    
+    FORCE_BL_ON_END;
+    
 	target_temperature[0] = 0;
 	target_temperature[0] = 0;
 	target_temperature_bed = 0;
 	target_temperature_bed = 0;
 	manage_heater();
 	manage_heater();
@@ -8077,11 +8298,17 @@ static void lcd_selftest_error(TestError testError, const char *_error_1, const
 		lcd_puts_P(_T(MSG_SELFTEST_WIRINGERROR));
 		lcd_puts_P(_T(MSG_SELFTEST_WIRINGERROR));
 		break;
 		break;
 	case TestError::TriggeringFsensor:
 	case TestError::TriggeringFsensor:
-	    lcd_set_cursor(0, 2);
-        lcd_puts_P(_T(MSG_SELFTEST_FILAMENT_SENSOR));
-        lcd_set_cursor(0, 3);
-        lcd_puts_P(_i("False triggering"));////c=20
-        break;
+          lcd_set_cursor(0, 2);
+          lcd_puts_P(_T(MSG_SELFTEST_FILAMENT_SENSOR));
+          lcd_set_cursor(0, 3);
+          lcd_puts_P(_i("False triggering"));////c=20
+          break;
+	case TestError::FsensorLevel:
+          lcd_set_cursor(0, 2);
+          lcd_puts_P(_T(MSG_SELFTEST_FILAMENT_SENSOR));
+          lcd_set_cursor(0, 3);
+          lcd_printf_P(_i("%s level expected"),_error_1);////c=20
+          break;
 	}
 	}
 
 
 	_delay(1000);
 	_delay(1000);
@@ -8570,6 +8797,7 @@ void ultralcd_init()
         else lcd_autoDeplete = autoDepleteRaw;
         else lcd_autoDeplete = autoDepleteRaw;
 
 
     }
     }
+    backlight_init();
 	lcd_init();
 	lcd_init();
 	lcd_refresh();
 	lcd_refresh();
 	lcd_longpress_func = menu_lcd_longpress_func;
 	lcd_longpress_func = menu_lcd_longpress_func;
@@ -8718,6 +8946,7 @@ uint8_t get_message_level()
 
 
 void menu_lcd_longpress_func(void)
 void menu_lcd_longpress_func(void)
 {
 {
+	backlight_wake();
     if (homing_flag || mesh_bed_leveling_flag || menu_menu == lcd_babystep_z || menu_menu == lcd_move_z)
     if (homing_flag || mesh_bed_leveling_flag || menu_menu == lcd_babystep_z || menu_menu == lcd_move_z)
     {
     {
         // disable longpress during re-entry, while homing or calibration
         // disable longpress during re-entry, while homing or calibration
@@ -8799,6 +9028,7 @@ void menu_lcd_lcdupdate_func(void)
 		lcd_draw_update = 2;
 		lcd_draw_update = 2;
 		lcd_oldcardstatus = IS_SD_INSERTED;
 		lcd_oldcardstatus = IS_SD_INSERTED;
 		lcd_refresh(); // to maybe revive the LCD if static electricity killed it.
 		lcd_refresh(); // to maybe revive the LCD if static electricity killed it.
+        backlight_wake();
 		if (lcd_oldcardstatus)
 		if (lcd_oldcardstatus)
 		{
 		{
 			card.initsd();
 			card.initsd();
@@ -8816,6 +9046,7 @@ void menu_lcd_lcdupdate_func(void)
 		}
 		}
 	}
 	}
 #endif//CARDINSERTED
 #endif//CARDINSERTED
+    backlight_update();
 	if (lcd_next_update_millis < _millis())
 	if (lcd_next_update_millis < _millis())
 	{
 	{
 		if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP)
 		if (abs(lcd_encoder_diff) >= ENCODER_PULSES_PER_STEP)
@@ -8826,9 +9057,14 @@ void menu_lcd_lcdupdate_func(void)
 			Sound_MakeSound(e_SOUND_TYPE_EncoderMove);
 			Sound_MakeSound(e_SOUND_TYPE_EncoderMove);
 			lcd_encoder_diff = 0;
 			lcd_encoder_diff = 0;
 			lcd_timeoutToStatus.start();
 			lcd_timeoutToStatus.start();
+			backlight_wake();
 		}
 		}
 
 
-		if (LCD_CLICKED) lcd_timeoutToStatus.start();
+		if (LCD_CLICKED)
+		{
+			lcd_timeoutToStatus.start();
+			backlight_wake();
+		}
 
 
 		(*menu_menu)();
 		(*menu_menu)();
 
 

+ 14 - 0
Firmware/ultralcd.h

@@ -6,6 +6,9 @@
 #include "conv2str.h"
 #include "conv2str.h"
 #include "menu.h"
 #include "menu.h"
 #include "mesh_bed_calibration.h"
 #include "mesh_bed_calibration.h"
+#include "config.h"
+
+#include "config.h"
 
 
 extern void menu_lcd_longpress_func(void);
 extern void menu_lcd_longpress_func(void);
 extern void menu_lcd_charsetup_func(void);
 extern void menu_lcd_charsetup_func(void);
@@ -47,6 +50,7 @@ unsigned char lcd_choose_color();
 void lcd_load_filament_color_check();
 void lcd_load_filament_color_check();
 //void lcd_mylang();
 //void lcd_mylang();
 
 
+extern void lcd_belttest();
 extern bool lcd_selftest();
 extern bool lcd_selftest();
 
 
 void lcd_menu_statistics(); 
 void lcd_menu_statistics(); 
@@ -217,7 +221,9 @@ void lcd_set_degree();
 void lcd_set_progress();
 void lcd_set_progress();
 #endif
 #endif
 
 
+#if (LANG_MODE != 0)
 void lcd_language();
 void lcd_language();
+#endif
 
 
 void lcd_wizard();
 void lcd_wizard();
 bool lcd_autoDepleteEnabled();
 bool lcd_autoDepleteEnabled();
@@ -244,4 +250,12 @@ enum class WizState : uint8_t
 
 
 void lcd_wizard(WizState state);
 void lcd_wizard(WizState state);
 
 
+#define VOLT_DIV_REF 5
+#if IR_SENSOR_ANALOG
+#define IRsensor_Hmin_TRESHOLD (3.0*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~3.0V (0.6*Vcc)
+#define IRsensor_Lmax_TRESHOLD (1.5*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~1.5V (0.3*Vcc)
+#define IRsensor_Hopen_TRESHOLD (4.6*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k)
+#define IRsensor_Ldiode_TRESHOLD (0.3*1023*OVERSAMPLENR/VOLT_DIV_REF) // ~0.3V
+#endif //IR_SENSOR_ANALOG
+
 #endif //ULTRALCD_H
 #endif //ULTRALCD_H

+ 3 - 1
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -260,11 +260,13 @@
 #define TMC2130_SG_THRS_Y       3     // stallguard sensitivity for Y axis
 #define TMC2130_SG_THRS_Y       3     // stallguard sensitivity for Y axis
 #define TMC2130_SG_THRS_Z       4     // stallguard sensitivity for Z axis
 #define TMC2130_SG_THRS_Z       4     // stallguard sensitivity for Z axis
 #define TMC2130_SG_THRS_E       3     // stallguard sensitivity for E axis
 #define TMC2130_SG_THRS_E       3     // stallguard sensitivity for E axis
+#define TMC2130_SG_THRS_HOME {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E}
 
 
 //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
 //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
 #define TMC2130_CURRENTS_H {16, 20, 35, 30}  // default holding currents for all axes
 #define TMC2130_CURRENTS_H {16, 20, 35, 30}  // default holding currents for all axes
 #define TMC2130_CURRENTS_R {16, 20, 35, 30}  // default running currents for all axes
 #define TMC2130_CURRENTS_R {16, 20, 35, 30}  // default running currents for all axes
-#define TMC2130_UNLOAD_CURRENT_R 12			 // lowe current for M600 to protect filament sensor 
+#define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18}  // homing running currents for all axes
+// #define TMC2130_UNLOAD_CURRENT_R 12			 // lower current for M600 to protect filament sensor - Unused
 
 
 #define TMC2130_STEALTH_Z
 #define TMC2130_STEALTH_Z
 
 

+ 3 - 1
Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h

@@ -262,11 +262,13 @@
 #define TMC2130_SG_THRS_Y       3     // stallguard sensitivity for Y axis
 #define TMC2130_SG_THRS_Y       3     // stallguard sensitivity for Y axis
 #define TMC2130_SG_THRS_Z       4     // stallguard sensitivity for Z axis
 #define TMC2130_SG_THRS_Z       4     // stallguard sensitivity for Z axis
 #define TMC2130_SG_THRS_E       3     // stallguard sensitivity for E axis
 #define TMC2130_SG_THRS_E       3     // stallguard sensitivity for E axis
+#define TMC2130_SG_THRS_HOME {3, 3, TMC2130_SG_THRS_Z, TMC2130_SG_THRS_E}
 
 
 //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
 //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only)
 #define TMC2130_CURRENTS_H {16, 20, 35, 30}  // default holding currents for all axes
 #define TMC2130_CURRENTS_H {16, 20, 35, 30}  // default holding currents for all axes
 #define TMC2130_CURRENTS_R {16, 20, 35, 30}  // default running currents for all axes
 #define TMC2130_CURRENTS_R {16, 20, 35, 30}  // default running currents for all axes
-#define TMC2130_UNLOAD_CURRENT_R 12			 // lowe current for M600 to protect filament sensor 
+#define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18}  // homing running currents for all axes
+// #define TMC2130_UNLOAD_CURRENT_R 12			 // lower current for M600 to protect filament sensor - Unused
 
 
 #define TMC2130_STEALTH_Z
 #define TMC2130_STEALTH_Z
 
 

+ 61 - 56
PF-build.sh

@@ -56,7 +56,7 @@
 #   Some may argue that this is only used by a script, BUT as soon someone accidentally or on purpose starts Arduino IDE
 #   Some may argue that this is only used by a script, BUT as soon someone accidentally or on purpose starts Arduino IDE
 #   it will use the default Arduino IDE folders and so can corrupt the build environment.
 #   it will use the default Arduino IDE folders and so can corrupt the build environment.
 #
 #
-# Version: 1.0.6-Build_9
+# Version: 1.0.6-Build_10
 # Change log:
 # Change log:
 # 12 Jan 2019, 3d-gussner, Fixed "compiler.c.elf.flags=-w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections" in 'platform.txt'
 # 12 Jan 2019, 3d-gussner, Fixed "compiler.c.elf.flags=-w -Os -Wl,-u,vfprintf -lprintf_flt -lm -Wl,--gc-sections" in 'platform.txt'
 # 16 Jan 2019, 3d-gussner, Build_2, Added development check to modify 'Configuration.h' to prevent unwanted LCD messages that Firmware is unknown
 # 16 Jan 2019, 3d-gussner, Build_2, Added development check to modify 'Configuration.h' to prevent unwanted LCD messages that Firmware is unknown
@@ -112,7 +112,9 @@
 #                          Changed Hex-files folder to PF-build-hex as requested in PR
 #                          Changed Hex-files folder to PF-build-hex as requested in PR
 # 23 Jul 2019, 3d-gussner, Added Finding OS version routine so supporting new OS should get easier
 # 23 Jul 2019, 3d-gussner, Added Finding OS version routine so supporting new OS should get easier
 # 26 Jul 2019, 3d-gussner, Change JSON repository to prusa3d after PR https://github.com/prusa3d/Arduino_Boards/pull/1 was merged
 # 26 Jul 2019, 3d-gussner, Change JSON repository to prusa3d after PR https://github.com/prusa3d/Arduino_Boards/pull/1 was merged
-
+# 23 Sep 2019, 3d-gussner, Prepare PF-build.sh for comming Prusa3d/Arduino_Boards version 1.0.2 Pull Request
+# 17 Oct 2019, 3d-gussner, Changed folder and check file names to have seperated build enviroments depening on Arduino IDE version and
+#                          board-versions. 
 #### Start check if OSTYPE is supported
 #### Start check if OSTYPE is supported
 OS_FOUND=$( command -v uname)
 OS_FOUND=$( command -v uname)
 
 
@@ -211,7 +213,8 @@ fi
 #### Set build environment 
 #### Set build environment 
 ARDUINO_ENV="1.8.5"
 ARDUINO_ENV="1.8.5"
 BUILD_ENV="1.0.6"
 BUILD_ENV="1.0.6"
-BOARD="PrusaResearchRambo"
+BOARD="rambo"
+BOARD_PACKAGE_NAME="PrusaResearchRambo"
 BOARD_VERSION="1.0.1"
 BOARD_VERSION="1.0.1"
 BOARD_URL="https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/package_prusa3d_index.json"
 BOARD_URL="https://raw.githubusercontent.com/prusa3d/Arduino_Boards/master/IDE_Board_Manager/package_prusa3d_index.json"
 BOARD_FILENAME="prusa3drambo"
 BOARD_FILENAME="prusa3drambo"
@@ -229,6 +232,7 @@ echo ""
 echo "Ardunio IDE :" $ARDUINO_ENV
 echo "Ardunio IDE :" $ARDUINO_ENV
 echo "Build env   :" $BUILD_ENV
 echo "Build env   :" $BUILD_ENV
 echo "Board       :" $BOARD
 echo "Board       :" $BOARD
+echo "Package name:" $BOARD_PACKAGE_NAME
 echo "Specific Lib:" $LIB
 echo "Specific Lib:" $LIB
 echo ""
 echo ""
 
 
@@ -259,12 +263,12 @@ if [ $TARGET_OS == "windows" ]; then
 		wget https://downloads.arduino.cc/arduino-$ARDUINO_ENV-windows.zip || exit 7
 		wget https://downloads.arduino.cc/arduino-$ARDUINO_ENV-windows.zip || exit 7
 		echo "$(tput sgr 0)"
 		echo "$(tput sgr 0)"
 	fi
 	fi
-	if [ ! -d "../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor" ]; then
+	if [[ ! -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" && ! -e "../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]]; then
 		echo "$(tput setaf 6)Unzipping Windows 32/64-bit Arduino IDE portable...$(tput setaf 2)"
 		echo "$(tput setaf 6)Unzipping Windows 32/64-bit Arduino IDE portable...$(tput setaf 2)"
 		sleep 2
 		sleep 2
 		unzip arduino-$ARDUINO_ENV-windows.zip -d ../PF-build-env-$BUILD_ENV || exit 7
 		unzip arduino-$ARDUINO_ENV-windows.zip -d ../PF-build-env-$BUILD_ENV || exit 7
-		mv ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor
-		echo "# arduino-$ARDUINO_ENV-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$TARGET_OS-$Processor
+		mv ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor
+		echo "# arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
 		echo "$(tput sgr0)"
 		echo "$(tput sgr0)"
 	fi
 	fi
 fi
 fi
@@ -277,55 +281,55 @@ if [ $TARGET_OS == "linux" ]; then
 		wget --no-check-certificate https://downloads.arduino.cc/arduino-$ARDUINO_ENV-linux$Processor.tar.xz || exit 8
 		wget --no-check-certificate https://downloads.arduino.cc/arduino-$ARDUINO_ENV-linux$Processor.tar.xz || exit 8
 		echo "$(tput sgr 0)"
 		echo "$(tput sgr 0)"
 	fi
 	fi
-	if [[ ! -d "../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor" && ! -e "../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$TARGET_OS-$Processor.txt" ]]; then
+	if [[ ! -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" && ! -e "../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]]; then
 		echo "$(tput setaf 6)Unzipping Linux $Processor Arduino IDE portable...$(tput setaf 2)"
 		echo "$(tput setaf 6)Unzipping Linux $Processor Arduino IDE portable...$(tput setaf 2)"
 		sleep 2
 		sleep 2
 		tar -xvf arduino-$ARDUINO_ENV-linux$Processor.tar.xz -C ../PF-build-env-$BUILD_ENV/ || exit 8
 		tar -xvf arduino-$ARDUINO_ENV-linux$Processor.tar.xz -C ../PF-build-env-$BUILD_ENV/ || exit 8
-		mv ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor
-		echo "# arduino-$ARDUINO_ENV-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$TARGET_OS-$Processor.txt
+		mv ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor
+		echo "# arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/arduino-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
 		echo "$(tput sgr0)"
 		echo "$(tput sgr0)"
 	fi
 	fi
 fi
 fi
 # Make Arduino IDE portable
 # Make Arduino IDE portable
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/
 fi
 fi
 
 
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable
 fi
 fi
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/output/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/output
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/output/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/output
 fi
 fi
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages
 fi
 fi
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/sketchbook/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/sketchbook
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/sketchbook/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/sketchbook
 fi
 fi
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/sketchbook/libraries/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/sketchbook/libraries
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/sketchbook/libraries/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/sketchbook/libraries
 fi
 fi
-if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/staging/ ]; then
-	mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/staging
+if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/staging/ ]; then
+	mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/staging
 fi
 fi
 
 
 # Change Arduino IDE preferences
 # Change Arduino IDE preferences
-if [ ! -e ../PF-build-env-$BUILD_ENV/Preferences-$TARGET_OS-$Processor.txt ]; then
-	echo "$(tput setaf 6)Setting $TARGET_OS-$Processor Arduino IDE preferences for portable GUI usage...$(tput setaf 2)"
+if [ ! -e ../PF-build-env-$BUILD_ENV/Preferences-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt ]; then
+	echo "$(tput setaf 6)Setting $ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor Arduino IDE preferences for portable GUI usage...$(tput setaf 2)"
 	sleep 2
 	sleep 2
 	echo "update.check"
 	echo "update.check"
-	sed -i 's/update.check = true/update.check = false/g' ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
+	sed -i 's/update.check = true/update.check = false/g' ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
 	echo "board"
 	echo "board"
-	sed -i 's/board = uno/board = rambo/g' ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
+	sed -i 's/board = uno/board = $BOARD/g' ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
 	echo "editor.linenumbers"
 	echo "editor.linenumbers"
-	sed -i 's/editor.linenumbers = false/editor.linenumbers = true/g' ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
+	sed -i 's/editor.linenumbers = false/editor.linenumbers = true/g' ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
 	echo "boardsmanager.additional.urls"
 	echo "boardsmanager.additional.urls"
-	echo "boardsmanager.additional.urls=$BOARD_URL" >>../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
-	echo "build.verbose=true" >>../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
-	echo "compiler.cache_core=false" >>../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
-	echo "compiler.warning_level=all" >>../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/lib/preferences.txt
-	echo "# Preferences-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/Preferences-$TARGET_OS-$Processor.txt
+	echo "boardsmanager.additional.urls=$BOARD_URL" >>../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
+	echo "build.verbose=true" >>../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
+	echo "compiler.cache_core=false" >>../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
+	echo "compiler.warning_level=all" >>../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/lib/preferences.txt
+	echo "# Preferences-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor" >> ../PF-build-env-$BUILD_ENV/Preferences-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
 	echo "$(tput sgr0)"
 	echo "$(tput sgr0)"
 fi
 fi
 
 
@@ -336,25 +340,26 @@ if [ ! -f "$BOARD_FILENAME-$BOARD_VERSION.tar.bz2" ]; then
 	sleep 2
 	sleep 2
 	wget $BOARD_FILE_URL || exit 9
 	wget $BOARD_FILE_URL || exit 9
 fi
 fi
-if [[ ! -d "../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD/hardware/avr/$BOARD_VERSION" || ! -e "../PF-build-env-$BUILD_ENV/$BOARD_FILENAME-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]]; then
-	echo "$(tput setaf 6)Unzipping $BOARD Arduino IDE portable...$(tput setaf 2)"
+if [[ ! -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME/hardware/avr/$BOARD_VERSION" || ! -e "../PF-build-env-$BUILD_ENV/$BOARD_FILENAME-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]]; then
+	echo "$(tput setaf 6)Unzipping $BOARD_PACKAGE_NAME Arduino IDE portable...$(tput setaf 2)"
 	sleep 2
 	sleep 2
 	tar -xvf $BOARD_FILENAME-$BOARD_VERSION.tar.bz2 -C ../PF-build-env-$BUILD_ENV/ || exit 10
 	tar -xvf $BOARD_FILENAME-$BOARD_VERSION.tar.bz2 -C ../PF-build-env-$BUILD_ENV/ || exit 10
-	if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD ]; then
-		mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD
+	if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME ]; then
+		mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME
 	fi
 	fi
-	if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD ]; then
-		mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD
+	if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME ]; then
+		mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME
 	fi
 	fi
-	if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD/hardware ]; then
-		mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD/hardware
+	if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME/hardware ]; then
+		mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME/hardware
 	fi
 	fi
-	if [ ! -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD/hardware/avr ]; then
-		mkdir ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD/hardware/avr
+	if [ ! -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME/hardware/avr ]; then
+		mkdir ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME/hardware/avr
 	fi
 	fi
 	
 	
-	mv ../PF-build-env-$BUILD_ENV/$BOARD_FILENAME-$BOARD_VERSION ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/$BOARD/hardware/avr/$BOARD_VERSION
-	echo "# $BOARD_FILENAME-$BOARD_VERSION" >> ../PF-build-env-$BUILD_ENV/$BOARD_FILENAME-$BOARD_VERSION-$TARGET_OS-$Processor.txt
+	mv ../PF-build-env-$BUILD_ENV/$BOARD_FILENAME-$BOARD_VERSION ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/$BOARD_PACKAGE_NAME/hardware/avr/$BOARD_VERSION
+	echo "# $BOARD_FILENAME-$BOARD_VERSION" >> ../PF-build-env-$BUILD_ENV/$BOARD_FILENAME-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
+
 	echo "$(tput sgr 0)"
 	echo "$(tput sgr 0)"
 fi	
 fi	
 
 
@@ -365,30 +370,30 @@ if [ ! -f "PF-build-env-$BUILD_ENV.zip" ]; then
 	wget $PF_BUILD_FILE_URL || exit 11
 	wget $PF_BUILD_FILE_URL || exit 11
 	echo "$(tput sgr 0)"
 	echo "$(tput sgr 0)"
 fi
 fi
-if [ ! -e "../PF-build-env-$BUILD_ENV/PF-build-env-$BUILD_ENV-$TARGET_OS-$Processor.txt" ]; then
+if [ ! -e "../PF-build-env-$BUILD_ENV/PF-build-env-$BUILD_ENV-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt" ]; then
 	echo "$(tput setaf 6)Unzipping Prusa Firmware build environment...$(tput setaf 2)"
 	echo "$(tput setaf 6)Unzipping Prusa Firmware build environment...$(tput setaf 2)"
 	sleep 2
 	sleep 2
-	unzip -o PF-build-env-$BUILD_ENV.zip -d ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor || exit 12
-	echo "# PF-build-env-$TARGET_OS-$Processor-$BUILD_ENV" >> ../PF-build-env-$BUILD_ENV/PF-build-env-$BUILD_ENV-$TARGET_OS-$Processor.txt
+	unzip -o PF-build-env-$BUILD_ENV.zip -d ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor || exit 12
+	echo "# PF-build-env-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor-$BUILD_ENV" >> ../PF-build-env-$BUILD_ENV/PF-build-env-$BUILD_ENV-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
 	echo "$(tput sgr0)"
 	echo "$(tput sgr0)"
 fi
 fi
 
 
 # Check if User updated Arduino IDE 1.8.5 boardsmanager and tools
 # Check if User updated Arduino IDE 1.8.5 boardsmanager and tools
-if [ -d "../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/arduino/tools" ]; then
+if [ -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/arduino/tools" ]; then
 	echo "$(tput setaf 6)Arduino IDE boards / tools have been manually updated...$"
 	echo "$(tput setaf 6)Arduino IDE boards / tools have been manually updated...$"
 	echo "Please don't update the 'Arduino AVR boards' as this will prevent running this script (tput setaf 2)"
 	echo "Please don't update the 'Arduino AVR boards' as this will prevent running this script (tput setaf 2)"
 	sleep 2
 	sleep 2
 fi	
 fi	
-if [ -d "../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2" ]; then
+if [ -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2" ]; then
 	echo "$(tput setaf 6)PrusaReasearch compatible tools have been manually updated...$(tput setaf 2)"
 	echo "$(tput setaf 6)PrusaReasearch compatible tools have been manually updated...$(tput setaf 2)"
 	sleep 2
 	sleep 2
 	echo "$(tput setaf 6)Copying Prusa Firmware build environment to manually updated boards / tools...$(tput setaf 2)"
 	echo "$(tput setaf 6)Copying Prusa Firmware build environment to manually updated boards / tools...$(tput setaf 2)"
 	sleep 2
 	sleep 2
-	cp -f ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/hardware/tools/avr/avr/lib/ldscripts/avr6.xn ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/lib/ldscripts/avr6.xn
-	echo "# PF-build-env-portable-$TARGET_OS-$Processor-$BUILD_ENV" >> ../PF-build-env-$BUILD_ENV/PF-build-env-portable-$BUILD_ENV-$TARGET_OS-$Processor.txt
+	cp -f ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/hardware/tools/avr/avr/lib/ldscripts/avr6.xn ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/avr/lib/ldscripts/avr6.xn
+	echo "# PF-build-env-portable-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor-$BUILD_ENV" >> ../PF-build-env-$BUILD_ENV/PF-build-env-portable-$BUILD_ENV-$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor.txt
 	echo "$(tput sgr0)"
 	echo "$(tput sgr0)"
 fi	
 fi	
-if [ -d "../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor/portable/packages/arduino/tools/avr-gcc/5.4.0-atmel3.6.1-arduino2" ]; then
+if [ -d "../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor/portable/packages/arduino/tools/avr-gcc/5.4.0-atmel3.6.1-arduino2" ]; then
 	echo "$(tput setaf 1)Arduino IDE tools have been updated manually to a non supported version!!!"
 	echo "$(tput setaf 1)Arduino IDE tools have been updated manually to a non supported version!!!"
 	echo "Delete ../PF-build-env-$BUILD_ENV and start the script again"
 	echo "Delete ../PF-build-env-$BUILD_ENV and start the script again"
 	echo "Script will not continue until this have been fixed $(tput setaf 2)"
 	echo "Script will not continue until this have been fixed $(tput setaf 2)"
@@ -489,7 +494,7 @@ if [ ! -z "$3" ] ; then
 fi
 fi
 
 
 #Set BUILD_ENV_PATH
 #Set BUILD_ENV_PATH
-cd ../PF-build-env-$BUILD_ENV/$TARGET_OS-$Processor || exit 24
+cd ../PF-build-env-$BUILD_ENV/$ARDUINO_ENV-$BOARD_VERSION-$TARGET_OS-$Processor || exit 24
 BUILD_ENV_PATH="$( pwd -P )"
 BUILD_ENV_PATH="$( pwd -P )"
 
 
 cd ../..
 cd ../..
@@ -634,8 +639,8 @@ do
 	echo "Start to build Prusa Firmware ..."
 	echo "Start to build Prusa Firmware ..."
 	echo "Using variant $VARIANT$(tput setaf 3)"
 	echo "Using variant $VARIANT$(tput setaf 3)"
 	sleep 2
 	sleep 2
-	#$BUILD_ENV_PATH/arduino-builder -dump-prefs -debug-level 10 -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=$BOARD:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14
-	$BUILD_ENV_PATH/arduino-builder -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=$BOARD:avr:rambo -ide-version=10805 -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14
+	#$BUILD_ENV_PATH/arduino-builder -dump-prefs -debug-level 10 -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=$BOARD_PACKAGE_NAME:avr:$BOARD -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14
+	$BUILD_ENV_PATH/arduino-builder -compile -hardware $ARDUINO/hardware -hardware $ARDUINO/portable/packages -tools $ARDUINO/tools-builder -tools $ARDUINO/hardware/tools/avr -tools $ARDUINO/portable/packages -built-in-libraries $ARDUINO/libraries -libraries $ARDUINO/portable/sketchbook/libraries -fqbn=$BOARD_PACKAGE_NAME:avr:$BOARD -build-path=$BUILD_PATH -warnings=all $SCRIPT_PATH/Firmware/Firmware.ino || exit 14
 	echo "$(tput sgr 0)"
 	echo "$(tput sgr 0)"
 
 
 	if [ $LANGUAGES ==  "ALL" ]; then
 	if [ $LANGUAGES ==  "ALL" ]; then

+ 1 - 0
README.md

@@ -178,6 +178,7 @@ Example:
 
 
 # 4. Documentation
 # 4. Documentation
 run [doxygen](http://www.doxygen.nl/) in Firmware folder
 run [doxygen](http://www.doxygen.nl/) in Firmware folder
+or visit https://prusa3d.github.io/Prusa-Firmware-Doc for doxygen generated output
 
 
 # 5. FAQ
 # 5. FAQ
 Q:I built firmware using Arduino and I see "?" instead of numbers in printer user interface.
 Q:I built firmware using Arduino and I see "?" instead of numbers in printer user interface.

+ 2 - 3
Tests/PrusaStatistics_test.cpp

@@ -198,7 +198,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 			SERIAL_ECHOLN("}");
 			SERIAL_ECHOLN("}");
 			status_number = 15;
 			status_number = 15;
 		}
 		}
-		else if (isPrintPaused || card.paused) 
+		else if (isPrintPaused)
 		{
 		{
 			SERIAL_ECHO("{");
 			SERIAL_ECHO("{");
 			prusa_stat_printerstatus(14);
 			prusa_stat_printerstatus(14);
@@ -490,7 +490,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) {
 		{   
 		{   
 			prusa_statistics_case0(15);
 			prusa_statistics_case0(15);
 		}
 		}
-		else if (isPrintPaused || card.paused) 
+		else if (isPrintPaused)
 		{
 		{
 			prusa_statistics_case0(14);
 			prusa_statistics_case0(14);
 		}
 		}
@@ -753,7 +753,6 @@ TEST_CASE("Prusa_statistics test", "[prusa_stats]")
 				SERIALS_RESET();
 				SERIALS_RESET();
 
 
 				isPrintPaused = 0;
 				isPrintPaused = 0;
-				card.paused = 0;
 				IS_SD_PRINTING = 1;
 				IS_SD_PRINTING = 1;
 				old_code::prusa_statistics(test_codes[i],0);
 				old_code::prusa_statistics(test_codes[i],0);
 				new_code::prusa_statistics(test_codes[i],0);
 				new_code::prusa_statistics(test_codes[i],0);

+ 71 - 141
lang/lang_en.txt

@@ -37,14 +37,8 @@
 #MSG_CONFIRM_CARRIAGE_AT_THE_TOP c=20 r=2
 #MSG_CONFIRM_CARRIAGE_AT_THE_TOP c=20 r=2
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-
-#
-"SpoolJoin   [N/A]"
-
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
 
 
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
 "Auto home"
 "Auto home"
@@ -130,18 +124,11 @@
 #
 #
 "Copy selected language?"
 "Copy selected language?"
 
 
-#MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-
+#MSG_CRASHDETECT
+"Crash det."
 #
 #
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 
 
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
 
 
@@ -205,14 +192,8 @@
 #
 #
 "Fail stats MMU"
 "Fail stats MMU"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
 
 
 #
 #
 "Fail stats"
 "Fail stats"
@@ -223,20 +204,11 @@
 #MSG_SELFTEST_FAN c=20
 #MSG_SELFTEST_FAN c=20
 "Fan test"
 "Fan test"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
+#MSG_FANS_CHECK
+"Fans check"
 
 
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
+#MSG_FSENSOR
+"Fil. sensor"
 
 
 #
 #
 "Filam. runouts"
 "Filam. runouts"
@@ -433,11 +405,14 @@
 #MSG_MMU_OK_RESUMING c=20 r=4
 #MSG_MMU_OK_RESUMING c=20 r=4
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
+#MSG_MODE
+"Mode"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
+#MSG_NORMAL
+"Normal"
+
+#MSG_SILENT
+"Silent"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -445,14 +420,14 @@
 #
 #
 "MMU power fails"
 "MMU power fails"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
+#MSG_STEALTH
+"Stealth"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
+#MSG_AUTO_POWER
+"Auto power"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
+#MSG_HIGH_POWER
+"High power"
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -478,7 +453,7 @@
 #MSG_NO_CARD
 #MSG_NO_CARD
 "No SD card"
 "No SD card"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
 
 
 #MSG_NO
 #MSG_NO
@@ -658,20 +633,17 @@
 #MSG_BED_CORRECTION_RIGHT c=14 r=1
 #MSG_BED_CORRECTION_RIGHT c=14 r=1
 "Right side[um]"
 "Right side[um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
+#MSG_RPI_PORT
+"RPi port"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
+#MSG_SD_CARD
+"SD card"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
 
 
 #
 #
 "Right"
 "Right"
@@ -718,38 +690,38 @@
 #MSG_FILE_CNT c=20 r=4
 #MSG_FILE_CNT c=20 r=4
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
+#MSG_SORT
+"Sort"
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
+#MSG_NONE
+"None"
+
+#MSG_SORT_TIME
+"Time"
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
+#MSG_SORT_ALPHA
+"Alphabet"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
+#MSG_SOUND_LOUD
+"Loud"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
+#MSG_SOUND
+"Sound"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
+#MSG_SOUND_ONCE
+"Once"
 
 
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
@@ -778,18 +750,12 @@
 #
 #
 "Select filament:"
 "Select filament:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
-
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
 
 
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 
 
@@ -929,7 +895,10 @@
 "Y-correct:"
 "Y-correct:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
+"Off"
+
+#MSG_ON
+"On"
 
 
 #
 #
 "Back"
 "Back"
@@ -943,14 +912,14 @@
 #
 #
 "FINDA:"
 "FINDA:"
 
 
-#
-"Firmware   [none]"
+#MSG_FIRMWARE
+"Firmware"
 
 
-#
-"Firmware [strict]"
+#MSG_STRICT
+"Strict"
 
 
-#
-"Firmware   [warn]"
+#MSG_WARN
+"Warn"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -958,20 +927,11 @@
 #
 #
 "IR:"
 "IR:"
 
 
-#
-"Magnets comp.[N/A]"
-
-#
-"Magnets comp.[Off]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
 
 
-#
-"Magnets comp. [On]"
-
-#
-"Mesh         [3x3]"
-
-#
-"Mesh         [7x7]"
+#MSG_MESH
+"Mesh"
 
 
 #
 #
 "Mesh bed leveling"
 "Mesh bed leveling"
@@ -979,41 +939,17 @@
 #
 #
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 
 
-#
-"MMU Mode [Normal]"
-
-#
-"MMU Mode[Stealth]"
+#MSG_MMU_MODE
+"MMU Mode"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 
 
-#
-"Model      [none]"
-
-#
-"Model    [strict]"
-
-#
-"Model      [warn]"
+#MSG_MODEL
+"Model"
 
 
-#
-"Nozzle d.  [0.25]"
-
-#
-"Nozzle d.  [0.40]"
-
-#
-"Nozzle d.  [0.60]"
-
-#
-"Nozzle     [none]"
-
-#
-"Nozzle   [strict]"
-
-#
-"Nozzle     [warn]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1060,8 +996,8 @@
 #
 #
 "Sheet"
 "Sheet"
 
 
-#
-"Sound    [assist]"
+#MSG_SOUND_BLIND
+"Assist"
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1069,11 +1005,5 @@
 #
 #
 "Z-correct:"
 "Z-correct:"
 
 
-#
-"Z-probe nr.    [1]"
-
-#
-"Z-probe nr.    [3]"
-
-#
-"Z-probe nr.    [5]"
+#MSG_Z_PROBE_NR
+"Z-probe nr."

+ 105 - 197
lang/lang_en_cz.txt

@@ -50,18 +50,10 @@
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 "Dojely oba Z voziky k~hornimu dorazu?"
 "Dojely oba Z voziky k~hornimu dorazu?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-"SpoolJoin   [zap]"
-
-#
-"SpoolJoin   [N/A]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
 "\x00"
 "\x00"
 
 
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
-"SpoolJoin   [vyp]"
-
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
 "Auto home"
 "Auto home"
 "\x00"
 "\x00"
@@ -174,21 +166,13 @@
 "Copy selected language?"
 "Copy selected language?"
 "Kopirovat vybrany jazyk?"
 "Kopirovat vybrany jazyk?"
 
 
-#MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-"Crash det.  [zap]"
+#MSG_CRASHDETECT
+"Crash det."
+"\x00"
 
 
 #
 #
-"Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Zvolte filament pro kalibraci prvni vrstvy z nasledujiciho menu"
 "Zvolte filament pro kalibraci prvni vrstvy z nasledujiciho menu"
-
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-"\x00"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-"Crash det.  [vyp]"
+"Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 
 
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
@@ -274,17 +258,9 @@
 "Fail stats MMU"
 "Fail stats MMU"
 "Selhani MMU"
 "Selhani MMU"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-"F. autozav. [zap]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-"F. autozav. [N/A]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
-"F. autozav. [vyp]"
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
+"F. autozav."
 
 
 #
 #
 "Fail stats"
 "Fail stats"
@@ -298,25 +274,13 @@
 "Fan test"
 "Fan test"
 "Test ventilatoru"
 "Test ventilatoru"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-"Kontr. vent.[zap]"
-
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-"Kontr. vent.[vyp]"
-
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-"Fil. senzor [zap]"
+#MSG_FANS_CHECK
+"Fans check"
+"Kontr. vent."
 
 
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
-"Fil. senzor [N/A]"
-
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
-"Fil. senzor [vyp]"
+#MSG_FSENSOR
+"Fil. sensor"
+"Fil. senzor"
 
 
 #
 #
 "Filam. runouts"
 "Filam. runouts"
@@ -578,13 +542,17 @@
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 "MMU OK. Pokracuji..."
 "MMU OK. Pokracuji..."
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
-"Mod      [Normal]"
+#MSG_MODE
+"Mode"
+"Mod"
+
+#MSG_NORMAL
+"Normal"
+"\x00"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
-"Mod       [tichy]"
+#MSG_SILENT
+"Silent"
+"Tichy"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -594,17 +562,17 @@
 "MMU power fails"
 "MMU power fails"
 "MMU vypadky proudu"
 "MMU vypadky proudu"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
-"Mod       [tichy]"
+#MSG_STEALTH
+"Stealth"
+"Tichy"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
-"Mod [automaticky]"
+#MSG_AUTO_POWER
+"Auto power"
+"Automaticky"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
-"Mod  [vys. vykon]"
+#MSG_HIGH_POWER
+"High power"
+"Vys. vykon"
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -638,7 +606,7 @@
 "No SD card"
 "No SD card"
 "Zadna SD karta"
 "Zadna SD karta"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
 "\x00"
 "\x00"
 
 
@@ -878,25 +846,21 @@
 "Right side[um]"
 "Right side[um]"
 "Vpravo [um]"
 "Vpravo [um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-"RPi port    [zap]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
-"RPi port    [vyp]"
+#MSG_RPI_PORT
+"RPi port"
+"\x00"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Spusteni Pruvodce vymaze ulozene vysledky vsech kalibraci a spusti kalibracni proces od zacatku. Pokracovat?"
 "Spusteni Pruvodce vymaze ulozene vysledky vsech kalibraci a spusti kalibracni proces od zacatku. Pokracovat?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
+#MSG_SD_CARD
+"SD card"
 "\x00"
 "\x00"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
-"SD card [FlshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
+"\x00"
 
 
 #
 #
 "Right"
 "Right"
@@ -958,49 +922,49 @@
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Nektere soubory nebudou setrideny. Maximalni pocet souboru ve slozce pro setrideni je 100."
 "Nektere soubory nebudou setrideny. Maximalni pocet souboru ve slozce pro setrideni je 100."
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
-"Trideni   [Zadne]"
+#MSG_SORT
+"Sort"
+"Trideni"
+
+#MSG_NONE
+"None"
+"Zadne"
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
-"Trideni     [cas]"
+#MSG_SORT_TIME
+"Time"
+"Cas"
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 "Tezke zkoseni:"
 "Tezke zkoseni:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
-"Trideni [Abeceda]"
+#MSG_SORT_ALPHA
+"Alphabet"
+"Abeceda"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 "Trideni souboru"
 "Trideni souboru"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
-"Zvuk    [hlasity]"
+#MSG_SOUND_LOUD
+"Loud"
+"Hlasity"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 "Lehke zkoseni:"
 "Lehke zkoseni:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
-"Zvuk    [vypnuto]"
+#MSG_SOUND
+"Sound"
+"Zvuk"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 "Vyskytl se problem, srovnavam osu Z ..."
 "Vyskytl se problem, srovnavam osu Z ..."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-"Zvuk     [jednou]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
-"Zvuk      [tichy]"
+#MSG_SOUND_ONCE
+"Once"
+"Jednou"
 
 
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
@@ -1038,22 +1002,14 @@
 "Select filament:"
 "Select filament:"
 "Zvolte filament:"
 "Zvolte filament:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
-"Tepl. kal. "
-
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
-"Tepl. kal.  [zap]"
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
+"Tepl. kal."
 
 
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 "Zvolte teplotu, ktera odpovida vasemu materialu."
 "Zvolte teplotu, ktera odpovida vasemu materialu."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-"Tepl. kal.  [vyp]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 "Teplot. kalibrace"
 "Teplot. kalibrace"
@@ -1232,15 +1188,19 @@
 
 
 #
 #
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
-"\x00"
+"Tiskarna zacne tisknout lomenou caru. Otacenim tlacitka nastavte optimalni vysku. Postupujte podle obrazku v handbooku (kapitola Kalibrace)."
 
 
 #
 #
 "Y-correct:"
 "Y-correct:"
 "Korekce Y:"
 "Korekce Y:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
-" [vyp]"
+"Off"
+"Vyp"
+
+#MSG_ON
+"On"
+"Zap"
 
 
 #
 #
 "Back"
 "Back"
@@ -1258,17 +1218,17 @@
 "FINDA:"
 "FINDA:"
 "\x00"
 "\x00"
 
 
-#
-"Firmware   [none]"
-"Firmware  [Zadne]"
+#MSG_FIRMWARE
+"Firmware"
+"\x00"
 
 
-#
-"Firmware [strict]"
-"Firmware [Prisne]"
+#MSG_STRICT
+"Strict"
+"Prisne"
 
 
-#
-"Firmware   [warn]"
-"Firmware[Varovat]"
+#MSG_WARN
+"Warn"
+"Varovat"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -1278,25 +1238,13 @@
 "IR:"
 "IR:"
 "\x00"
 "\x00"
 
 
-#
-"Magnets comp.[N/A]"
-"Komp. magnetu[N/A]"
-
-#
-"Magnets comp.[Off]"
-"Komp. magnetu[Vyp]"
-
-#
-"Magnets comp. [On]"
-"Komp. magnetu[Zap]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
+"Komp. magnetu"
 
 
-#
-"Mesh         [3x3]"
-"Mesh         [3x3]"
-
-#
-"Mesh         [7x7]"
-"Mesh         [7x7]"
+#MSG_MESH
+"Mesh"
+"\x00"
 
 
 #
 #
 "Mesh bed leveling"
 "Mesh bed leveling"
@@ -1306,53 +1254,21 @@
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detekovan na tiskarne MK3"
 "MK3S firmware detekovan na tiskarne MK3"
 
 
-#
-"MMU Mode [Normal]"
-"MMU mod  [Normal]"
-
-#
-"MMU Mode[Stealth]"
-"MMU Mod   [Tichy]"
+#MSG_MMU_MODE
+"MMU Mode"
+"MMU mod"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 "Probiha zmena modu..."
 "Probiha zmena modu..."
 
 
-#
-"Model      [none]"
-"Model     [Zadne]"
-
-#
-"Model    [strict]"
-"Model    [Prisne]"
-
-#
-"Model      [warn]"
-"Model   [Varovat]"
-
-#
-"Nozzle d.  [0.25]"
-"Tryska     [0.25]"
-
-#
-"Nozzle d.  [0.40]"
-"Tryska     [0.40]"
-
-#
-"Nozzle d.  [0.60]"
-"Tryska     [0.60]"
-
-#
-"Nozzle     [none]"
-"Tryska    [Zadne]"
-
-#
-"Nozzle   [strict]"
-"Tryska   [Prisne]"
+#MSG_MODEL
+"Model"
+"\x00"
 
 
-#
-"Nozzle     [warn]"
-"Tryska  [Varovat]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
+"Tryska"
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1414,9 +1330,9 @@
 "Sheet"
 "Sheet"
 "Plat"
 "Plat"
 
 
-#
-"Sound    [assist]"
-"Zvuk     [Asist.]"
+#MSG_SOUND_BLIND
+"Assist"
+"Asist."
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1426,14 +1342,6 @@
 "Z-correct:"
 "Z-correct:"
 "Korekce Z:"
 "Korekce Z:"
 
 
-#
-"Z-probe nr.    [1]"
-"Pocet mereni Z [1]"
-
-#
-"Z-probe nr.    [3]"
-"Pocet mereni Z [3]"
-
-#
-"Z-probe nr.    [5]"
-"Pocet mereni Z [5]"
+#MSG_Z_PROBE_NR
+"Z-probe nr."
+"Pocet mereni Z"

+ 107 - 199
lang/lang_en_de.txt

@@ -50,17 +50,9 @@
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 "Sind linke+rechte Z- Schlitten ganz oben?"
 "Sind linke+rechte Z- Schlitten ganz oben?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-"SpoolJoin    [an]"
-
-#
-"SpoolJoin   [N/A]"
-"SpoolJoin   [N/V]"
-
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
-"SpoolJoin   [aus]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
+"\x00"
 
 
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
 "Auto home"
 "Auto home"
@@ -174,22 +166,14 @@
 "Copy selected language?"
 "Copy selected language?"
 "Gewaehlte Sprache kopieren?"
 "Gewaehlte Sprache kopieren?"
 
 
-#MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-"Crash Erk.   [an]"
+#MSG_CRASHDETECT
+"Crash det."
+"Crash Erk."
 
 
 #
 #
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Waehlen Sie ein Filament fuer Erste Schichtkalibrierung aus und waehlen Sie es im On-Screen-Menu aus."
 "Waehlen Sie ein Filament fuer Erste Schichtkalibrierung aus und waehlen Sie es im On-Screen-Menu aus."
 
 
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-"Crash Erk.   [nv]"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-"Crash Erk.  [aus]"
-
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
 "Crash erkannt."
 "Crash erkannt."
@@ -274,17 +258,9 @@
 "Fail stats MMU"
 "Fail stats MMU"
 "MMU-Fehler"
 "MMU-Fehler"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-"F.Autoladen  [an]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-"F. Autoload  [nv]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
-"F. Autoload [aus]"
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
+"F. autoladen"
 
 
 #
 #
 "Fail stats"
 "Fail stats"
@@ -298,25 +274,13 @@
 "Fan test"
 "Fan test"
 "Lueftertest"
 "Lueftertest"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-"Luefter Chk. [an]"
-
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-"Luefter Chk.[aus]"
+#MSG_FANS_CHECK
+"Fans check"
+"Luefter Chk."
 
 
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-"Fil. Sensor  [an]"
-
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
-"Fil. Sensor  [nv]"
-
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
-"Fil. Sensor [aus]"
+#MSG_FSENSOR
+"Fil. sensor"
+"\x00"
 
 
 #
 #
 "Filam. runouts"
 "Filam. runouts"
@@ -578,13 +542,17 @@
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 "MMU OK.  Weiterdrucken..."
 "MMU OK.  Weiterdrucken..."
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
-"Modus    [Normal]"
+#MSG_MODE
+"Mode"
+"Modus"
+
+#MSG_NORMAL
+"Normal"
+"\x00"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
-"Modus     [leise]"
+#MSG_SILENT
+"Silent"
+"Leise"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -594,17 +562,17 @@
 "MMU power fails"
 "MMU power fails"
 "MMU Netzfehler"
 "MMU Netzfehler"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
-"Modus   [Stealth]"
+#MSG_STEALTH
+"Stealth"
+"\x00"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
-"Modus[Auto Power]"
+#MSG_AUTO_POWER
+"Auto power"
+"\x00"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
-"Modus[Hohe Leist]"
+#MSG_HIGH_POWER
+"High power"
+"Hohe leist"
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -638,9 +606,9 @@
 "No SD card"
 "No SD card"
 "Keine SD Karte"
 "Keine SD Karte"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
-"N.V."
+"N/V"
 
 
 #MSG_NO
 #MSG_NO
 "No"
 "No"
@@ -878,25 +846,21 @@
 "Right side[um]"
 "Right side[um]"
 "Rechts [um]"
 "Rechts [um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-"RPi Port     [an]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
-"RPi Port    [aus]"
+#MSG_RPI_PORT
+"RPi port"
+"\x00"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Der Assistent wird die aktuellen Kalibrierungsdaten loeschen und von vorne beginnen. Weiterfahren?"
 "Der Assistent wird die aktuellen Kalibrierungsdaten loeschen und von vorne beginnen. Weiterfahren?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
-"SD Karte [normal]"
+#MSG_SD_CARD
+"SD card"
+"SD Karte"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
-"SD Karte[flshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
+"\x00"
 
 
 #
 #
 "Right"
 "Right"
@@ -958,49 +922,49 @@
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Einige Dateien wur- den nicht sortiert. Max. Dateien pro Verzeichnis = 100."
 "Einige Dateien wur- den nicht sortiert. Max. Dateien pro Verzeichnis = 100."
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
-"Sort.      [ohne]"
+#MSG_SORT
+"Sort"
+"Sort."
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
-"Sort.      [Zeit]"
+#MSG_NONE
+"None"
+"Ohne"
+
+#MSG_SORT_TIME
+"Time"
+"Zeit"
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 "Schwer.Schr:"
 "Schwer.Schr:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
-"Sort.  [Alphabet]"
+#MSG_SORT_ALPHA
+"Alphabet"
+"\x00"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 "Sortiere Dateien"
 "Sortiere Dateien"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
-"Sound      [laut]"
+#MSG_SOUND_LOUD
+"Loud"
+"Laut"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 "Leicht.Schr:"
 "Leicht.Schr:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
-"Sound     [stumm]"
+#MSG_SOUND
+"Sound"
+"\x00"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 "Fehler aufgetreten, Z-Kalibrierung erforderlich..."
 "Fehler aufgetreten, Z-Kalibrierung erforderlich..."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-"Sound    [einmal]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
-"Sound     [leise]"
+#MSG_SOUND_ONCE
+"Once"
+"Einmal"
 
 
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
@@ -1038,22 +1002,14 @@
 "Select filament:"
 "Select filament:"
 "Filament auswaehlen:"
 "Filament auswaehlen:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
-"Temp Kalib.         "
-
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
-"Temp. Kal.   [an]"
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
+"Temp Kalib."
 
 
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 "Waehlen Sie die Temperatur, die zu Ihrem Material passt."
 "Waehlen Sie die Temperatur, die zu Ihrem Material passt."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-"Temp. Kal.  [aus]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 "Temp. kalibrieren"
 "Temp. kalibrieren"
@@ -1232,15 +1188,19 @@
 
 
 #
 #
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
-"\x00"
+"Der Drucker beginnt mit dem Drucken einer Zickzacklinie. Drehen Sie den Knopf, bis Sie die optimale Hoehe erreicht haben. Ueberpruefen Sie die Bilder im Handbuch (Kapitel Kalibrierung)."
 
 
 #
 #
 "Y-correct:"
 "Y-correct:"
 "Y-Korrektur:"
 "Y-Korrektur:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
-" [aus]"
+"Off"
+"Aus"
+
+#MSG_ON
+"On"
+"An"
 
 
 #
 #
 "Back"
 "Back"
@@ -1258,17 +1218,17 @@
 "FINDA:"
 "FINDA:"
 "\x00"
 "\x00"
 
 
-#
-"Firmware   [none]"
-"Firmware   [ohne]"
+#MSG_FIRMWARE
+"Firmware"
+"\x00"
 
 
-#
-"Firmware [strict]"
-"Firmware [strikt]"
+#MSG_STRICT
+"Strict"
+"Strikt"
 
 
-#
-"Firmware   [warn]"
-"Firmware [warnen]"
+#MSG_WARN
+"Warn"
+"Warnen"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -1278,25 +1238,13 @@
 "IR:"
 "IR:"
 "\x00"
 "\x00"
 
 
-#
-"Magnets comp.[N/A]"
-"Magnet Komp.  [nv]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
+"Magnet Komp."
 
 
-#
-"Magnets comp.[Off]"
-"Magnet Komp. [Aus]"
-
-#
-"Magnets comp. [On]"
-"Magnet Komp.  [An]"
-
-#
-"Mesh         [3x3]"
-"Gitter       [3x3]"
-
-#
-"Mesh         [7x7]"
-"Gitter       [7x7]"
+#MSG_MESH
+"Mesh"
+"Gitter"
 
 
 #
 #
 "Mesh bed leveling"
 "Mesh bed leveling"
@@ -1306,53 +1254,21 @@
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 "MK3S-Firmware auf MK3-Drucker erkannt"
 "MK3S-Firmware auf MK3-Drucker erkannt"
 
 
-#
-"MMU Mode [Normal]"
-"MMU Modus[Normal]"
-
-#
-"MMU Mode[Stealth]"
-"MMU Mod.[Stealth]"
+#MSG_MMU_MODE
+"MMU Mode"
+"MMU Modus"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 "Moduswechsel erfolgt..."
 "Moduswechsel erfolgt..."
 
 
-#
-"Model      [none]"
-"Modell     [ohne]"
-
-#
-"Model    [strict]"
-"Modell   [strikt]"
-
-#
-"Model      [warn]"
-"Modell   [warnen]"
-
-#
-"Nozzle d.  [0.25]"
-"Duese D.   [0.25]"
+#MSG_MODEL
+"Model"
+"Modell"
 
 
-#
-"Nozzle d.  [0.40]"
-"Duese D.   [0.40]"
-
-#
-"Nozzle d.  [0.60]"
-"Duese D.   [0.60]"
-
-#
-"Nozzle     [none]"
-"Duese      [ohne]"
-
-#
-"Nozzle   [strict]"
-"Duese    [strikt]"
-
-#
-"Nozzle     [warn]"
-"Duese    [warnen]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
+"Duese D."
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1414,9 +1330,9 @@
 "Sheet"
 "Sheet"
 "Blech"
 "Blech"
 
 
-#
-"Sound    [assist]"
-"Sound    [Assist]"
+#MSG_SOUND_BLIND
+"Assist"
+"\x00"
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1426,14 +1342,6 @@
 "Z-correct:"
 "Z-correct:"
 "Z-Korrektur:"
 "Z-Korrektur:"
 
 
-#
-"Z-probe nr.    [1]"
-"Z-Probe Nr.    [1]"
-
-#
-"Z-probe nr.    [3]"
-"Z-Probe Nr.    [3]"
-
-#
-"Z-probe nr.    [5]"
-"Z-Probe Nr.    [5]"
+#MSG_Z_PROBE_NR
+"Z-probe nr."
+"\x00"

+ 105 - 197
lang/lang_en_es.txt

@@ -50,16 +50,8 @@
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 "Carros Z izq./der. estan arriba maximo?"
 "Carros Z izq./der. estan arriba maximo?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-"\x00"
-
-#
-"SpoolJoin   [N/A]"
-"\x00"
-
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
 "\x00"
 "\x00"
 
 
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
@@ -174,22 +166,14 @@
 "Copy selected language?"
 "Copy selected language?"
 "Copiar idioma seleccionado?"
 "Copiar idioma seleccionado?"
 
 
-#MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-"Det. choque [act]"
+#MSG_CRASHDETECT
+"Crash det."
+"Det. choque"
 
 
 #
 #
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Escoge un filamento para la Calibracion de la Primera Capa y seleccionalo en el menu en pantalla."
 "Escoge un filamento para la Calibracion de la Primera Capa y seleccionalo en el menu en pantalla."
 
 
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-"Dec. choque [N/D]"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-"Det. choque [ina]"
-
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
 "Choque detectado."
 "Choque detectado."
@@ -274,17 +258,9 @@
 "Fail stats MMU"
 "Fail stats MMU"
 "Estadistica de fallos MMU"
 "Estadistica de fallos MMU"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-"Autocarg.Fil[act]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-"Autocarg.Fil[N/D]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
-"Autocarg.Fil[ina]"
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
+"Autocarg.fil."
 
 
 #
 #
 "Fail stats"
 "Fail stats"
@@ -298,25 +274,13 @@
 "Fan test"
 "Fan test"
 "Test ventiladores"
 "Test ventiladores"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-"Comprob.vent[act]"
-
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-"Comprob.vent[ina]"
-
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-"Sensor Fil. [act]"
-
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
-"Sensor Fil. [N/D]"
+#MSG_FANS_CHECK
+"Fans check"
+"Comprob.vent"
 
 
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
-"Sensor Fil. [ina]"
+#MSG_FSENSOR
+"Fil. sensor"
+"Sensor Fil."
 
 
 #
 #
 "Filam. runouts"
 "Filam. runouts"
@@ -578,13 +542,17 @@
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 "MMU OK. Resumiendo..."
 "MMU OK. Resumiendo..."
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
-"Modo     [Normal]"
+#MSG_MODE
+"Mode"
+"Modo"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
-"Modo   [silencio]"
+#MSG_NORMAL
+"Normal"
+"\x00"
+
+#MSG_SILENT
+"Silent"
+"Silencio"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -594,17 +562,17 @@
 "MMU power fails"
 "MMU power fails"
 "Fallo de energia en MMU"
 "Fallo de energia en MMU"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
-"Modo   [Silencio]"
+#MSG_STEALTH
+"Stealth"
+"Silencio"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
-"Modo[fuerza auto]"
+#MSG_AUTO_POWER
+"Auto power"
+"Fuerza auto"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
-"Modo [rend.pleno]"
+#MSG_HIGH_POWER
+"High power"
+"Rend.pleno"
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -638,7 +606,7 @@
 "No SD card"
 "No SD card"
 "No hay tarjeta SD"
 "No hay tarjeta SD"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
 "N/A"
 "N/A"
 
 
@@ -878,25 +846,21 @@
 "Right side[um]"
 "Right side[um]"
 "Derecha [um]"
 "Derecha [um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-"Puerto RPi  [act]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
-"Puerto RPi  [ina]"
+#MSG_RPI_PORT
+"RPi port"
+"Puerto RPi"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Ejecutar el Wizard borrara los valores de calibracion actuales y comenzara de nuevo. Continuar?"
 "Ejecutar el Wizard borrara los valores de calibracion actuales y comenzara de nuevo. Continuar?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
-"Tarj. SD [normal]"
+#MSG_SD_CARD
+"SD card"
+"Tarj. SD"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
-"Tarj. SD[FlshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
+"\x00"
 
 
 #
 #
 "Right"
 "Right"
@@ -958,49 +922,49 @@
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Algunos archivos no se ordenaran. Maximo 100 archivos por carpeta para ordenar. "
 "Algunos archivos no se ordenaran. Maximo 100 archivos por carpeta para ordenar. "
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
-"Ordenar [ninguno]"
+#MSG_SORT
+"Sort"
+"Ordenar"
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
-"Ordenar   [fecha]"
+#MSG_NONE
+"None"
+"Ninguno"
+
+#MSG_SORT_TIME
+"Time"
+"Fecha"
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 "Incl.severa:"
 "Incl.severa:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
-"Ordenar [alfabet]"
+#MSG_SORT_ALPHA
+"Alphabet"
+"Alfabet"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 "Ordenando archivos"
 "Ordenando archivos"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
-"Sonido     [alto]"
+#MSG_SOUND_LOUD
+"Loud"
+"Alto"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 "Liger.incl.:"
 "Liger.incl.:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
-"Sonido[silenciad]"
+#MSG_SOUND
+"Sound"
+"Sonido"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 "Problema encontrado, nivelacion Z forzosa ..."
 "Problema encontrado, nivelacion Z forzosa ..."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-"Sonido  [una vez]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
-"Sonido[silencios]"
+#MSG_SOUND_ONCE
+"Once"
+"Una vez"
 
 
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
@@ -1038,22 +1002,14 @@
 "Select filament:"
 "Select filament:"
 "Selecciona filamento:"
 "Selecciona filamento:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
-"Cal. temp. "
-
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
-"Cal. temp.   [on]"
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
+"Cal. temp."
 
 
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 "Selecciona la temperatura adecuada a tu material."
 "Selecciona la temperatura adecuada a tu material."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-"Cal. temp.  [off]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 "Calibracion temp."
 "Calibracion temp."
@@ -1232,15 +1188,19 @@
 
 
 #
 #
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
-"\x00"
+"La impresora comenzara a imprimir una linea en zig-zag. Gira el dial hasta que la linea alcance la altura optima. Mira las fotos del manual (Capitulo de calibracion)."
 
 
 #
 #
 "Y-correct:"
 "Y-correct:"
 "Corregir-Y:"
 "Corregir-Y:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
-"[apag]"
+"Off"
+"Ina"
+
+#MSG_ON
+"On"
+"Act"
 
 
 #
 #
 "Back"
 "Back"
@@ -1258,17 +1218,17 @@
 "FINDA:"
 "FINDA:"
 "FINDA:"
 "FINDA:"
 
 
-#
-"Firmware   [none]"
-"Firmware[ninguno]"
+#MSG_FIRMWARE
+"Firmware"
+"\x00"
 
 
-#
-"Firmware [strict]"
-"Firmware[estrict]"
+#MSG_STRICT
+"Strict"
+"Estrict"
 
 
-#
-"Firmware   [warn]"
-"Firmware  [aviso]"
+#MSG_WARN
+"Warn"
+"Aviso"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -1278,25 +1238,13 @@
 "IR:"
 "IR:"
 "\x00"
 "\x00"
 
 
-#
-"Magnets comp.[N/A]"
-"Comp. imanes [N/A]"
-
-#
-"Magnets comp.[Off]"
-"Comp. imanes [Off]"
-
-#
-"Magnets comp. [On]"
-"Comp. imanes  [On]"
-
-#
-"Mesh         [3x3]"
-"Malla        [3x3]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
+"Comp. imanes"
 
 
-#
-"Mesh         [7x7]"
-"Malla        [7x7]"
+#MSG_MESH
+"Mesh"
+"Malla"
 
 
 #
 #
 "Mesh bed leveling"
 "Mesh bed leveling"
@@ -1306,53 +1254,21 @@
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 "Firmware MK3S detectado en impresora MK3"
 "Firmware MK3S detectado en impresora MK3"
 
 
-#
-"MMU Mode [Normal]"
-"Modo MMU [Normal]"
-
-#
-"MMU Mode[Stealth]"
-"Modo MMU[Silenci]"
+#MSG_MMU_MODE
+"MMU Mode"
+"Modo MMU"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 "Cambio de modo progresando ..."
 "Cambio de modo progresando ..."
 
 
-#
-"Model      [none]"
-"Modelo  [ninguno]"
-
-#
-"Model    [strict]"
-"Modelo [estricto]"
-
-#
-"Model      [warn]"
-"Modelo    [aviso]"
-
-#
-"Nozzle d.  [0.25]"
-"Diam. nozzl[0.25]"
-
-#
-"Nozzle d.  [0.40]"
-"Diam. nozzl[0.40]"
-
-#
-"Nozzle d.  [0.60]"
-"Diam. nozzl[0.60]"
-
-#
-"Nozzle     [none]"
-"Nozzle  [ninguno]"
+#MSG_MODEL
+"Model"
+"Modelo"
 
 
-#
-"Nozzle   [strict]"
-"Nozzle [estricto]"
-
-#
-"Nozzle     [warn]"
-"Nozzle    [aviso]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
+"Diam. nozzl"
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1414,9 +1330,9 @@
 "Sheet"
 "Sheet"
 "Lamina"
 "Lamina"
 
 
-#
-"Sound    [assist]"
-"Sonido [asistido]"
+#MSG_SOUND_BLIND
+"Assist"
+"Asistido"
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1426,14 +1342,6 @@
 "Z-correct:"
 "Z-correct:"
 "Corregir-Z:"
 "Corregir-Z:"
 
 
-#
-"Z-probe nr.    [1]"
-"Z-sensor nr.   [1]"
-
-#
-"Z-probe nr.    [3]"
-"Z-sensor nr.   [3]"
-
-#
-"Z-probe nr.    [5]"
-"Z-sensor nr.   [5]"
+#MSG_Z_PROBE_NR
+"Z-probe nr."
+"Z-sensor nr."

+ 102 - 198
lang/lang_en_fr.txt

@@ -50,16 +50,8 @@
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 "Z~carriages gauche + droite tout en haut?"
 "Z~carriages gauche + droite tout en haut?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-"\x00"
-
-#
-"SpoolJoin   [N/A]"
-"\x00"
-
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
 "\x00"
 "\x00"
 
 
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
@@ -174,22 +166,14 @@
 "Copy selected language?"
 "Copy selected language?"
 "Copier la langue selectionne?"
 "Copier la langue selectionne?"
 
 
-#MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-"Detect.crash [on]"
+#MSG_CRASHDETECT
+"Crash det."
+"Detect.crash"
 
 
 #
 #
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choisissez un filament pour la Calibration de la Premiere Couche et selectionnez-le depuis le menu a l'ecran."
 "Choisissez un filament pour la Calibration de la Premiere Couche et selectionnez-le depuis le menu a l'ecran."
 
 
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-"Detect.crash[N/A]"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-"Detect.crash[off]"
-
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
 "Crash detecte."
 "Crash detecte."
@@ -274,18 +258,9 @@
 "Fail stats MMU"
 "Fail stats MMU"
 "Stat. d'echec MMU"
 "Stat. d'echec MMU"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-"Autochargeur [on]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-"Autochargeur[N/A]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
-"Autochargeur[off]"
-
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
+"Autochargeur"
 #
 #
 "Fail stats"
 "Fail stats"
 "Stat. d'echec"
 "Stat. d'echec"
@@ -298,26 +273,13 @@
 "Fan test"
 "Fan test"
 "Test du ventilateur"
 "Test du ventilateur"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-"Verif vent.  [on]"
-
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-"Verif vent. [off]"
-
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-"Capteur Fil. [on]"
-
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
-"Capteur Fil.[N/A]"
-
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
-"Capteur Fil.[off]"
+#MSG_FANS_CHECK
+"Fans check"
+"Verif vent."
 
 
+#MSG_FSENSOR
+"Fil. sensor"
+"Capteur Fil."
 #
 #
 "Filam. runouts"
 "Filam. runouts"
 "Fins de filament"
 "Fins de filament"
@@ -578,13 +540,17 @@
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 "MMU OK. Reprise ..."
 "MMU OK. Reprise ..."
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
+#MSG_MODE
+"Mode"
+"\x00"
+
+#MSG_NORMAL
+"Normal"
 "\x00"
 "\x00"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
-"Mode     [feutre]"
+#MSG_SILENT
+"Silent"
+"Feutre"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -594,17 +560,17 @@
 "MMU power fails"
 "MMU power fails"
 "Echecs alim. MMU"
 "Echecs alim. MMU"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
-"Mode     [furtif]"
+#MSG_STEALTH
+"Stealth"
+"Furtif"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
-"Mode [puiss.auto]"
+#MSG_AUTO_POWER
+"Auto power"
+"Puiss.auto"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
-"Mode[haute puiss]"
+#MSG_HIGH_POWER
+"High power"
+"Haute puiss"
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -638,7 +604,7 @@
 "No SD card"
 "No SD card"
 "Pas de carte SD"
 "Pas de carte SD"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
 "\x00"
 "\x00"
 
 
@@ -878,25 +844,21 @@
 "Right side[um]"
 "Right side[um]"
 "Droite [um]"
 "Droite [um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-"Port RPi     [on]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
-"Port RPi    [off]"
+#MSG_RPI_PORT
+"RPi port"
+"Port RPi"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Lancement de l'Assistant supprimera les resultats actuels de calibration et commencera du debut. Continuer?"
 "Lancement de l'Assistant supprimera les resultats actuels de calibration et commencera du debut. Continuer?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
-"Carte SD [normal]"
+#MSG_SD_CARD
+"SD card"
+"Carte SD"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
-"Carte SD[flshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
+"FlshAir"
 
 
 #
 #
 "Right"
 "Right"
@@ -958,50 +920,49 @@
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Certains fichiers ne seront pas tries. Max 100 fichiers tries par dossier."
 "Certains fichiers ne seront pas tries. Max 100 fichiers tries par dossier."
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
-"Tri       [aucun]"
+#MSG_SORT
+"Sort"
+"Tri"
+
+#MSG_NONE
+"None"
+"Aucun"
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
-"Tri       [heure]"
+#MSG_SORT_TIME
+"Time"
+"Heure"
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 "Deviat.sev.:"
 "Deviat.sev.:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
-"Tri    [alphabet]"
+#MSG_SORT_ALPHA
+"Alphabet"
+"\x00"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 "Tri des fichiers"
 "Tri des fichiers"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
-"Son        [fort]"
+#MSG_SOUND_LOUD
+"Loud"
+"Fort"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 "Deviat.leg.:"
 "Deviat.leg.:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
-"Son        [muet]"
+#MSG_SOUND
+"Sound"
+"Son"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 "Probleme rencontre, cliquez sur le bouton pour niveller l'axe Z..."
 "Probleme rencontre, cliquez sur le bouton pour niveller l'axe Z..."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-"Son    [une fois]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
-"Son      [feutre]"
-
+#MSG_SOUND_ONCE
+"Once"
+"Une fois"
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
 "Vitesse"
 "Vitesse"
@@ -1038,22 +999,14 @@
 "Select filament:"
 "Select filament:"
 "Selectionnez le filament:"
 "Selectionnez le filament:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
 "Calib. Temp."
 "Calib. Temp."
 
 
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
-"Calib. Temp. [on]"
-
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 "Selectionnez la temperature qui correspond a votre materiau."
 "Selectionnez la temperature qui correspond a votre materiau."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-"Calib. Temp.[off]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 "Calibration temp."
 "Calibration temp."
@@ -1232,15 +1185,19 @@
 
 
 #
 #
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
-"\x00"
+"L'imprimante commencera a  imprimer une ligne en zig-zag. Tournez le bouton jusqu'a atteindre la hauteur optimale. Consultez les photos dans le manuel (chapitre Calibration)."
 
 
 #
 #
 "Y-correct:"
 "Y-correct:"
 "Correct-Y:"
 "Correct-Y:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
-" [off]"
+"Off"
+"\x00"
+
+#MSG_ON
+"On"
+"\x00"
 
 
 #
 #
 "Back"
 "Back"
@@ -1258,17 +1215,17 @@
 "FINDA:"
 "FINDA:"
 "FINDA:"
 "FINDA:"
 
 
-#
-"Firmware   [none]"
-"Firmware [aucune]"
+#MSG_FIRMWARE
+"Firmware"
+"\x00"
 
 
-#
-"Firmware [strict]"
-"Firmware[stricte]"
+#MSG_STRICT
+"Strict"
+"Stricte"
 
 
-#
-"Firmware   [warn]"
-"Firmware  [avert]"
+#MSG_WARN
+"Warn"
+"Avert"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -1278,24 +1235,12 @@
 "IR:"
 "IR:"
 "IR:"
 "IR:"
 
 
-#
-"Magnets comp.[N/A]"
-"Compens. aim.[N/A]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
+"Compens. aim."
 
 
-#
-"Magnets comp.[Off]"
-"Compens. aim.[off]"
-
-#
-"Magnets comp. [On]"
-"Compens. aim. [on]"
-
-#
-"Mesh         [3x3]"
-"\x00"
-
-#
-"Mesh         [7x7]"
+#MSG_MESH
+"Mesh"
 "\x00"
 "\x00"
 
 
 #
 #
@@ -1306,53 +1251,21 @@
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 "Firmware MK3S detecte sur imprimante MK3"
 "Firmware MK3S detecte sur imprimante MK3"
 
 
-#
-"MMU Mode [Normal]"
-"Mode MMU [normal]"
-
-#
-"MMU Mode[Stealth]"
-"Mode MMU [feutre]"
+#MSG_MMU_MODE
+"MMU Mode"
+"Mode MMU"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 "Changement de mode en cours..."
 "Changement de mode en cours..."
 
 
-#
-"Model      [none]"
-"Modele   [aucune]"
-
-#
-"Model    [strict]"
-"Modele  [stricte]"
-
-#
-"Model      [warn]"
-"Modele    [avert]"
+#MSG_MODEL
+"Model"
+"Modele"
 
 
-#
-"Nozzle d.  [0.25]"
-"Diam. buse [0.25]"
-
-#
-"Nozzle d.  [0.40]"
-"Diam. buse [0.40]"
-
-#
-"Nozzle d.  [0.60]"
-"Diam. buse [0.60]"
-
-#
-"Nozzle     [none]"
-"Buse     [aucune]"
-
-#
-"Nozzle   [strict]"
-"Buse    [stricte]"
-
-#
-"Nozzle     [warn]"
-"Buse      [avert]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
+"Diam. buse"
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1414,9 +1327,9 @@
 "Sheet"
 "Sheet"
 "Plaque"
 "Plaque"
 
 
-#
-"Sound    [assist]"
-"Son      [assist]"
+#MSG_SOUND_BLIND
+"Assist"
+"\x00"
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1426,15 +1339,6 @@
 "Z-correct:"
 "Z-correct:"
 "Correct-Z:"
 "Correct-Z:"
 
 
-#
-"Z-probe nr.    [1]"
-"Mesurer x-fois [1]"
-
-#
-"Z-probe nr.    [3]"
-"Mesurer x-fois [3]"
-
-#
-"Z-probe nr.    [5]"
-"Mesurer x-fois [5]"
- 
+#MSG_Z_PROBE_NR
+"Z-probe nr."
+"Mesurer x-fois"

+ 104 - 197
lang/lang_en_it.txt

@@ -50,16 +50,8 @@
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 "I carrelli Z sin/des sono altezza max?"
 "I carrelli Z sin/des sono altezza max?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-"\x00"
-
-#
-"SpoolJoin   [N/A]"
-"\x00"
-
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
 "\x00"
 "\x00"
 
 
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
@@ -174,22 +166,14 @@
 "Copy selected language?"
 "Copy selected language?"
 "Copiare la lingua selezionata?"
 "Copiare la lingua selezionata?"
 
 
-#MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-"Rileva.crash [on]"
+#MSG_CRASHDETECT
+"Crash det."
+"Rileva.crash"
 
 
 #
 #
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Scegli un filamento per la calibrazione del primo strato e selezionalo nel menu sullo schermo."
 "Scegli un filamento per la calibrazione del primo strato e selezionalo nel menu sullo schermo."
 
 
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-"Rileva.crash[N/A]"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-"Rileva.crash[off]"
-
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
 "Rilevato impatto."
 "Rilevato impatto."
@@ -274,17 +258,9 @@
 "Fail stats MMU"
 "Fail stats MMU"
 "Stat.fall. MMU"
 "Stat.fall. MMU"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-"Autocar.fil. [on]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-"Autocar.fil.[N/A]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
-"Autocar.fil.[off]"
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
+"Autocar.fil."
 
 
 #
 #
 "Fail stats"
 "Fail stats"
@@ -298,26 +274,13 @@
 "Fan test"
 "Fan test"
 "Test ventola"
 "Test ventola"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-"Control.vent [on]"
-
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-"Control.vent[off]"
-
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-"Sensore fil. [on]"
-
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
-"Sensore fil.[N/A]"
-
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
-"Sensore fil.[off]"
+#MSG_FANS_CHECK
+"Fans check"
+"Control.vent"
 
 
+#MSG_FSENSOR
+"Fil. sensor"
+"Sensore fil."
 #
 #
 "Filam. runouts"
 "Filam. runouts"
 "Filam. esauriti"
 "Filam. esauriti"
@@ -578,13 +541,17 @@
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 "MMU OK. Riprendendo... "
 "MMU OK. Riprendendo... "
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
-"Mod.    [normale]"
+#MSG_MODE
+"Mode"
+"Mod."
+
+#MSG_NORMAL
+"Normal"
+"Normale"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
-"Mod. [silenziosa]"
+#MSG_SILENT
+"Silent"
+"Silenzioso"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -594,17 +561,17 @@
 "MMU power fails"
 "MMU power fails"
 "Manc. corr. MMU"
 "Manc. corr. MMU"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
-"Mod. [silenziosa]"
+#MSG_STEALTH
+"Stealth"
+"Silenziosa"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
-"Mod.       [auto]"
+#MSG_AUTO_POWER
+"Auto power"
+"Auto"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
-"Mod.      [forte]"
+#MSG_HIGH_POWER
+"High power"
+"Forte"
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -638,7 +605,7 @@
 "No SD card"
 "No SD card"
 "Nessuna SD"
 "Nessuna SD"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
 "\x00"
 "\x00"
 
 
@@ -878,25 +845,21 @@
 "Right side[um]"
 "Right side[um]"
 "Destra [um]"
 "Destra [um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-"Porta RPi    [on]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
-"Porta RPi   [off]"
+#MSG_RPI_PORT
+"RPi port"
+"Porta RPi"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Se avvi il Wizard perderai la calibrazione preesistente e dovrai ricominciare dall'inizio. Continuare?"
 "Se avvi il Wizard perderai la calibrazione preesistente e dovrai ricominciare dall'inizio. Continuare?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
-"Mem. SD [normale]"
+#MSG_SD_CARD
+"SD card"
+"Mem. SD"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
-"Mem. SD [flshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
+"\x00"
 
 
 #
 #
 "Right"
 "Right"
@@ -958,49 +921,49 @@
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Alcuni file non saranno ordinati. Il numero massimo di file in una cartella e 100 perche siano ordinati."
 "Alcuni file non saranno ordinati. Il numero massimo di file in una cartella e 100 perche siano ordinati."
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
-"Ordina  [nessuno]"
+#MSG_SORT
+"Sort"
+"Ordina"
+
+#MSG_NONE
+"None"
+"Nessuno"
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
-"Ordina    [cron.]"
+#MSG_SORT_TIME
+"Time"
+"Cron."
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 "Devia.grave:"
 "Devia.grave:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
-"Ordine [alfabeti]"
+#MSG_SORT_ALPHA
+"Alphabet"
+"Alfabeti"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 "Ordinando i file"
 "Ordinando i file"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
-"Suono     [forte]"
+#MSG_SOUND_LOUD
+"Loud"
+"Forte"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 "Devia.lieve:"
 "Devia.lieve:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
-"Suono      [mute]"
+#MSG_SOUND
+"Sound"
+"Suono"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 "Sono stati rilevati problemi, avviato livellamento Z ..."
 "Sono stati rilevati problemi, avviato livellamento Z ..."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-"Suono   [singolo]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
-"Suono[silenzioso]"
+#MSG_SOUND_ONCE
+"Once"
+"Singolo"
 
 
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
@@ -1038,22 +1001,14 @@
 "Select filament:"
 "Select filament:"
 "Seleziona il filamento:"
 "Seleziona il filamento:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
-"Calib. temp. "
-
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
-"Calib. temp. [on]"
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
+"Calib. temp."
 
 
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 "Seleziona la temperatura appropriata per il tuo materiale."
 "Seleziona la temperatura appropriata per il tuo materiale."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-"Calib. temp.[off]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 "Calib. Temp."
 "Calib. Temp."
@@ -1232,14 +1187,18 @@
 
 
 #
 #
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
-"\x00"
+"La stampante iniziera a stampare una linea a zig-zag. Gira la manopola fino a che non hai raggiungo l'altezza ottimale. Verifica con le immagini nel manuale (capitolo sulla calibrazione):"
 
 
 #
 #
 "Y-correct:"
 "Y-correct:"
 "Correzione-Y:"
 "Correzione-Y:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
+"Off"
+"\x00"
+
+#MSG_ON
+"On"
 "\x00"
 "\x00"
 
 
 #
 #
@@ -1258,17 +1217,17 @@
 "FINDA:"
 "FINDA:"
 "\x00"
 "\x00"
 
 
-#
-"Firmware   [none]"
-"Firmware[nessuno]"
+#MSG_FIRMWARE
+"Firmware"
+"\x00"
 
 
-#
-"Firmware [strict]"
-"Firmware [esatto]"
+#MSG_STRICT
+"Strict"
+"Esatto"
 
 
-#
-"Firmware   [warn]"
-"Firmware [avviso]"
+#MSG_WARN
+"Warn"
+"Avviso"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -1278,25 +1237,13 @@
 "IR:"
 "IR:"
 "\x00"
 "\x00"
 
 
-#
-"Magnets comp.[N/A]"
-"Comp. Magneti[N/A]"
-
-#
-"Magnets comp.[Off]"
-"Comp. Magneti[off]"
-
-#
-"Magnets comp. [On]"
-"Comp. Magneti [on]"
-
-#
-"Mesh         [3x3]"
-"Griglia      [3x3]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
+"Comp. Magneti"
 
 
-#
-"Mesh         [7x7]"
-"Griglia      [7x7]"
+#MSG_MESH
+"Mesh"
+"Griglia"
 
 
 #
 #
 "Mesh bed leveling"
 "Mesh bed leveling"
@@ -1306,53 +1253,21 @@
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 "Firmware MK3S rilevato su stampante MK3"
 "Firmware MK3S rilevato su stampante MK3"
 
 
-#
-"MMU Mode [Normal]"
-"Modalita MMU [Normale]"
-
-#
-"MMU Mode[Stealth]"
-"Modalita MMU [Silenziosa]"
+#MSG_MMU_MODE
+"MMU Mode"
+"Mod. MMU"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 "Cambio modalita in corso ..."
 "Cambio modalita in corso ..."
 
 
-#
-"Model      [none]"
-"Modello [nessuno]"
-
-#
-"Model    [strict]"
-"Modello  [esatto]"
-
-#
-"Model      [warn]"
-"Modello  [avviso]"
-
-#
-"Nozzle d.  [0.25]"
-"Diam.Ugello[0.25]"
+#MSG_MODEL
+"Model"
+"Modello"
 
 
-#
-"Nozzle d.  [0.40]"
-"Diam.Ugello[0.40]"
-
-#
-"Nozzle d.  [0.60]"
-"Diam.Ugello[0.60]"
-
-#
-"Nozzle     [none]"
-"Ugello  [nessuno]"
-
-#
-"Nozzle   [strict]"
-"Ugello   [esatto]"
-
-#
-"Nozzle     [warn]"
-"Ugello   [avviso]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
+"Diam.Ugello"
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1414,9 +1329,9 @@
 "Sheet"
 "Sheet"
 "Piano"
 "Piano"
 
 
-#
-"Sound    [assist]"
-"Suono   [assist.]"
+#MSG_SOUND_BLIND
+"Assist"
+"Assist."
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1426,14 +1341,6 @@
 "Z-correct:"
 "Z-correct:"
 "Correzione-Z:"
 "Correzione-Z:"
 
 
-#
-"Z-probe nr.    [1]"
-"Z-probe nr.    [1]"
-
-#
-"Z-probe nr.    [3]"
-"Z-probe nr.    [3]"
-
-#
-"Z-probe nr.    [5]"
-"Z-probe nr.    [5]"
+#MSG_Z_PROBE_NR
+"Z-probe nr."
+"\x00"

+ 104 - 197
lang/lang_en_pl.txt

@@ -50,17 +50,9 @@
 "Are left and right Z~carriages all up?"
 "Are left and right Z~carriages all up?"
 "Obydwa konce osi sa na szczycie?"
 "Obydwa konce osi sa na szczycie?"
 
 
-#MSG_AUTO_DEPLETE_ON c=17 r=1
-"SpoolJoin    [on]"
-"SpoolJoin    [wl]"
-
-#
-"SpoolJoin   [N/A]"
-"SpoolJoin   [N/D]"
-
-#MSG_AUTO_DEPLETE_OFF c=17 r=1
-"SpoolJoin   [off]"
-"SpoolJoin   [wyl]"
+#MSG_AUTO_DEPLETE c=17 r=1
+"SpoolJoin"
+"\x00"
 
 
 #MSG_AUTO_HOME
 #MSG_AUTO_HOME
 "Auto home"
 "Auto home"
@@ -175,21 +167,13 @@
 "Skopiowac wybrany jezyk?"
 "Skopiowac wybrany jezyk?"
 
 
 #MSG_CRASHDETECT_ON
 #MSG_CRASHDETECT_ON
-"Crash det.   [on]"
-"Wykr.zderzen [wl]"
+"Crash det."
+"Wykr.zderzen"
 
 
 #
 #
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Choose a filament for the First Layer Calibration and select it in the on-screen menu."
 "Wybierz filament do Kalibracji Pierwszej Warstwy i potwierdz w menu ekranowym."
 "Wybierz filament do Kalibracji Pierwszej Warstwy i potwierdz w menu ekranowym."
 
 
-#MSG_CRASHDETECT_NA
-"Crash det.  [N/A]"
-"Wykr.zderzen[N/D]"
-
-#MSG_CRASHDETECT_OFF
-"Crash det.  [off]"
-"Wykr.zderzen[wyl]"
-
 #MSG_CRASH_DETECTED c=20 r=1
 #MSG_CRASH_DETECTED c=20 r=1
 "Crash detected."
 "Crash detected."
 "Zderzenie wykryte"
 "Zderzenie wykryte"
@@ -274,17 +258,9 @@
 "Fail stats MMU"
 "Fail stats MMU"
 "Bledy MMU"
 "Bledy MMU"
 
 
-#MSG_FSENS_AUTOLOAD_ON c=17 r=1
-"F. autoload  [on]"
-"Autolad.fil. [wl]"
-
-#MSG_FSENS_AUTOLOAD_NA c=17 r=1
-"F. autoload [N/A]"
-"Autolad.fil.[N/D]"
-
-#MSG_FSENS_AUTOLOAD_OFF c=17 r=1
-"F. autoload [off]"
-"Autolad.fil.[wyl]"
+#MSG_FSENSOR_AUTOLOAD
+"F. autoload"
+"Autolad. fil."
 
 
 #
 #
 "Fail stats"
 "Fail stats"
@@ -298,25 +274,13 @@
 "Fan test"
 "Fan test"
 "Test wentylatora"
 "Test wentylatora"
 
 
-#MSG_FANS_CHECK_ON c=17 r=1
-"Fans check   [on]"
-"Sprawd.went. [wl]"
+#MSG_FANS_CHECK
+"Fans check"
+"Sprawd.went."
 
 
-#MSG_FANS_CHECK_OFF c=17 r=1
-"Fans check  [off]"
-"Sprawd.went.[wyl]"
-
-#MSG_FSENSOR_ON
-"Fil. sensor  [on]"
-"Czuj. filam. [wl]"
-
-#MSG_FSENSOR_NA
-"Fil. sensor [N/A]"
-"Czuj. filam.[N/D]"
-
-#MSG_FSENSOR_OFF
-"Fil. sensor [off]"
-"Czuj. filam.[wyl]"
+#MSG_FSENSOR
+"Fil. sensor"
+"Czuj. filam."
 
 
 #
 #
 "Filam. runouts"
 "Filam. runouts"
@@ -578,13 +542,17 @@
 "MMU OK. Resuming..."
 "MMU OK. Resuming..."
 "MMU OK. Wznawianie..."
 "MMU OK. Wznawianie..."
 
 
-#MSG_STEALTH_MODE_OFF
-"Mode     [Normal]"
-"Tryb   [normalny]"
+#MSG_MODE
+"Mode"
+"Tryb"
+
+#MSG_NORMAL
+"Normal"
+"Normalny"
 
 
-#MSG_SILENT_MODE_ON
-"Mode     [silent]"
-"Tryb      [cichy]"
+#MSG_SILENT
+"Silent"
+"Cichy"
 
 
 #
 #
 "MMU needs user attention."
 "MMU needs user attention."
@@ -594,17 +562,17 @@
 "MMU power fails"
 "MMU power fails"
 "Zaniki zasil. MMU"
 "Zaniki zasil. MMU"
 
 
-#MSG_STEALTH_MODE_ON
-"Mode    [Stealth]"
-"Tryb      [cichy]"
+#MSG_STEALTH
+"Stealth"
+"Cichy"
 
 
-#MSG_AUTO_MODE_ON
-"Mode [auto power]"
-"Tryb [automatycz]"
+#MSG_AUTO_POWER
+"Auto power"
+"Automatycz"
 
 
-#MSG_SILENT_MODE_OFF
-"Mode [high power]"
-"Tryb[wysoka wyd.]"
+#MSG_HIGH_POWER
+"High power"
+"Wysoka wyd."
 
 
 #
 #
 "MMU2 connected"
 "MMU2 connected"
@@ -638,7 +606,7 @@
 "No SD card"
 "No SD card"
 "Brak karty SD"
 "Brak karty SD"
 
 
-#
+#MSG_NA
 "N/A"
 "N/A"
 "N/D"
 "N/D"
 
 
@@ -878,25 +846,21 @@
 "Right side[um]"
 "Right side[um]"
 "Prawo [um]"
 "Prawo [um]"
 
 
-#MSG_SECOND_SERIAL_ON c=17 r=1
-"RPi port     [on]"
-"Port RPi     [wl]"
-
-#MSG_SECOND_SERIAL_OFF c=17 r=1
-"RPi port    [off]"
-"Port RPi    [wyl]"
+#MSG_RPI_PORT
+"RPi port"
+"Port RPi"
 
 
 #MSG_WIZARD_RERUN c=20 r=7
 #MSG_WIZARD_RERUN c=20 r=7
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Running Wizard will delete current calibration results and start from the beginning. Continue?"
 "Wlaczenie Asystenta usunie obecne dane kalibracyjne i zacznie od poczatku. Kontynuowac?"
 "Wlaczenie Asystenta usunie obecne dane kalibracyjne i zacznie od poczatku. Kontynuowac?"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_OFF c=19 r=1
-"SD card  [normal]"
-"Karta SD [normal]"
+#MSG_SD_CARD
+"SD card"
+"Karta SD"
 
 
-#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY_ON c=19 r=1
-"SD card [flshAir]"
-"Karta SD[FlshAir]"
+#MSG_TOSHIBA_FLASH_AIR_COMPATIBILITY
+"FlashAir"
+"\x00"
 
 
 #
 #
 "Right"
 "Right"
@@ -958,50 +922,49 @@
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Some files will not be sorted. Max. No. of files in 1 folder for sorting is 100."
 "Niektore pliki nie zostana posortowane. Max. liczba plikow w 1 folderze = 100."
 "Niektore pliki nie zostana posortowane. Max. liczba plikow w 1 folderze = 100."
 
 
-#MSG_SORT_NONE c=17 r=1
-"Sort       [none]"
-"Sortowanie [brak]"
+#MSG_SORT
+"Sort"
+"Sortowanie"
 
 
-#MSG_SORT_TIME c=17 r=1
-"Sort       [time]"
-"Sortowanie [czas]"
+#MSG_NONE
+"None"
+"Brak"
+
+#MSG_SORT_TIME
+"Time"
+"Czas"
 
 
 #
 #
 "Severe skew:"
 "Severe skew:"
 "Znaczny skos:"
 "Znaczny skos:"
 
 
-#MSG_SORT_ALPHA c=17 r=1
-"Sort   [alphabet]"
-"Sortowanie[alfab]"
+#MSG_SORT_ALPHA
+"Alphabet"
+"Alfab"
 
 
 #MSG_SORTING c=20 r=1
 #MSG_SORTING c=20 r=1
 "Sorting files"
 "Sorting files"
 "Sortowanie plikow"
 "Sortowanie plikow"
 
 
-#MSG_SOUND_LOUD c=17 r=1
-"Sound      [loud]"
-"Dzwiek   [glosny]"
+#MSG_SOUND_LOUD
+"Loud"
+"Glosny"
 
 
 #
 #
 "Slight skew:"
 "Slight skew:"
 "Lekki skos:"
 "Lekki skos:"
 
 
-#MSG_SOUND_MUTE c=17 r=1
-"Sound      [mute]"
-"Dzwiek[wylaczony]"
+#MSG_SOUND
+"Sound"
+"Dzwiek"
 
 
 #
 #
 "Some problem encountered, Z-leveling enforced ..."
 "Some problem encountered, Z-leveling enforced ..."
 "Wykryto problem, wymuszono poziomowanie osi Z."
 "Wykryto problem, wymuszono poziomowanie osi Z."
 
 
-#MSG_SOUND_ONCE c=17 r=1
-"Sound      [once]"
-"Dzwiek    [1-raz]"
-
-#MSG_SOUND_SILENT c=17 r=1
-"Sound    [silent]"
-"Dzwiek    [cichy]"
-
+#MSG_SOUND_ONCE
+"Once"
+"1-raz"
 #MSG_SPEED
 #MSG_SPEED
 "Speed"
 "Speed"
 "Predkosc"
 "Predkosc"
@@ -1038,22 +1001,14 @@
 "Select filament:"
 "Select filament:"
 "Wybierz filament:"
 "Wybierz filament:"
 
 
-#MSG_TEMP_CALIBRATION c=20 r=1
-"Temp. cal.          "
+#MSG_TEMP_CALIBRATION c=12 r=1
+"Temp. cal."
 "Kalibracja temp."
 "Kalibracja temp."
 
 
-#MSG_TEMP_CALIBRATION_ON c=20 r=1
-"Temp. cal.   [on]"
-"Kalibr.temp. [wl]"
-
 #
 #
 "Select temperature which matches your material."
 "Select temperature which matches your material."
 "Wybierz temperature, ktora odpowiada Twojemu filamentowi."
 "Wybierz temperature, ktora odpowiada Twojemu filamentowi."
 
 
-#MSG_TEMP_CALIBRATION_OFF c=20 r=1
-"Temp. cal.  [off]"
-"Kalibr.temp.[wyl]"
-
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 #MSG_CALIBRATION_PINDA_MENU c=17 r=1
 "Temp. calibration"
 "Temp. calibration"
 "Kalibracja temp."
 "Kalibracja temp."
@@ -1232,15 +1187,19 @@
 
 
 #
 #
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
 "The printer will start printing a zig-zag line. Rotate the knob until you reach the optimal height. Check the pictures in the handbook (Calibration chapter)."
-"\x00"
+"Drukarka zacznie drukowanie linii w ksztalcie zygzaka. Ustaw optymalna wysokosc obracajac pokretlo. Porownaj z ilustracjami w Podreczniku (rozdzial Kalibracja)."
 
 
 #
 #
 "Y-correct:"
 "Y-correct:"
 "Korekcja-Y:"
 "Korekcja-Y:"
 
 
 #MSG_OFF
 #MSG_OFF
-" [off]"
-" [wyl]"
+"Off"
+"Wyl"
+
+#MSG_ON
+"On"
+"Wl"
 
 
 #
 #
 "Back"
 "Back"
@@ -1258,17 +1217,17 @@
 "FINDA:"
 "FINDA:"
 "\x00"
 "\x00"
 
 
-#
-"Firmware   [none]"
-"Firmware   [brak]"
+#MSG_FIRMWARE
+"Firmware"
+"\x00"
 
 
-#
-"Firmware [strict]"
-"Firmware [restr.]"
+#MSG_STRICT
+"Strict"
+"Restr."
 
 
-#
-"Firmware   [warn]"
-"Firmware[ostrzez]"
+#MSG_WARN
+"Warn"
+"Ostrzez"
 
 
 #
 #
 "HW Setup"
 "HW Setup"
@@ -1278,25 +1237,13 @@
 "IR:"
 "IR:"
 "\x00"
 "\x00"
 
 
-#
-"Magnets comp.[N/A]"
-"Kor. magnesow[N/D]"
-
-#
-"Magnets comp.[Off]"
-"Kor. magnesow[wyl]"
-
-#
-"Magnets comp. [On]"
-"Kor. magnesow [wl]"
-
-#
-"Mesh         [3x3]"
-"Siatka       [3x3]"
+#MSG_MAGNETS_COMP
+"Magnets comp."
+"Kor. magnesow"
 
 
-#
-"Mesh         [7x7]"
-"Siatka       [7x7]"
+#MSG_MESH
+"Mesh"
+"Siatka"
 
 
 #
 #
 "Mesh bed leveling"
 "Mesh bed leveling"
@@ -1306,53 +1253,21 @@
 "MK3S firmware detected on MK3 printer"
 "MK3S firmware detected on MK3 printer"
 "Wykryto firmware MK3S w drukarce MK3"
 "Wykryto firmware MK3S w drukarce MK3"
 
 
-#
-"MMU Mode [Normal]"
-"Tryb MMU[Normaln]"
-
-#
-"MMU Mode[Stealth]"
-"Tryb MMU[Stealth]"
+#MSG_MMU_MODE
+"MMU Mode"
+"Tryb MMU"
 
 
 #
 #
 "Mode change in progress ..."
 "Mode change in progress ..."
 "Trwa zmiana trybu..."
 "Trwa zmiana trybu..."
 
 
-#
-"Model      [none]"
-"Model      [brak]"
-
-#
-"Model    [strict]"
-"Model [restrykc.]"
-
-#
-"Model      [warn]"
-"Model  [ostrzez.]"
-
-#
-"Nozzle d.  [0.25]"
-"Sr. dyszy  [0,25]"
-
-#
-"Nozzle d.  [0.40]"
-"Sr. dyszy  [0,40]"
-
-#
-"Nozzle d.  [0.60]"
-"Sr. dyszy  [0,60]"
-
-#
-"Nozzle     [none]"
-"Dysza      [brak]"
+#MSG_MODEL
+"Model"
+"\x00"
 
 
-#
-"Nozzle   [strict]"
-"Dysza [restrykc.]"
-
-#
-"Nozzle     [warn]"
-"Dysza  [ostrzez.]"
+#MSG_NOZZLE_DIAMETER
+"Nozzle d."
+"Sr. dyszy"
 
 
 #
 #
 "G-code sliced for a different level. Continue?"
 "G-code sliced for a different level. Continue?"
@@ -1414,9 +1329,9 @@
 "Sheet"
 "Sheet"
 "Plyta"
 "Plyta"
 
 
-#
-"Sound    [assist]"
-"Dzwiek   [asyst.]"
+#MSG_SOUND_BLIND
+"Assist"
+"Asyst."
 
 
 #
 #
 "Steel sheets"
 "Steel sheets"
@@ -1426,14 +1341,6 @@
 "Z-correct:"
 "Z-correct:"
 "Korekcja-Z:"
 "Korekcja-Z:"
 
 
-#
-"Z-probe nr.    [1]"
-"Ilosc Pomiarow [1]"
-
-#
-"Z-probe nr.    [3]"
-"Ilosc Pomiarow [3]"
-
-#
-"Z-probe nr.    [5]"
-"Ilosc Pomiarow [5]"
+#MSG_Z_PROBE_NR
+"Z-probe nr."
+"Ilosc Pomiarow"