Browse Source

Merge branch 'MK3' into MK3_ShellSort

Alex Voinea 4 years ago
parent
commit
103e29d38a

+ 2 - 1
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
@@ -395,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

+ 123 - 61
Firmware/Marlin_main.cpp

@@ -309,6 +309,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,7 +331,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;
+
+// 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;
 
 
 // Determines Absolute or Relative Coordinates.
 // Determines Absolute or Relative Coordinates.
 // Also there is bool axis_relative_modes[] per axis flag.
 // Also there is bool axis_relative_modes[] per axis flag.
@@ -373,8 +383,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;
@@ -3655,7 +3665,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
@@ -3663,7 +3673,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`  - ?
@@ -3713,12 +3722,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();
@@ -4043,8 +4046,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);
 		}
 		}
@@ -5363,21 +5377,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.
@@ -7232,27 +7244,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: {
-		lcd_print_stop();
+	case 603: {
+		Stop();
 	}
 	}
+	break;
 
 
 #ifdef PINDA_THERMISTOR
 #ifdef PINDA_THERMISTOR
   //! ### M860 - Wait for extruder temperature (PINDA)
   //! ### M860 - Wait for extruder temperature (PINDA)
@@ -8338,38 +8359,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
     
     
@@ -8389,10 +8415,10 @@ void prepare_move()
      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder);
      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply*(1./(60.f*100.f)), active_extruder);
 #endif
 #endif
   }
   }
+  if (waiting_inside_plan_buffer_line_print_aborted)
+      return;
 
 
-  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) {
@@ -9113,10 +9139,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]);
@@ -9602,8 +9626,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
@@ -9670,7 +9704,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);
@@ -9682,6 +9717,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);
@@ -9930,10 +9970,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];
@@ -9941,9 +9988,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);
 	
 	
@@ -9984,9 +10034,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
@@ -10138,16 +10190,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);
 
 
@@ -10225,7 +10282,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);
@@ -10248,6 +10304,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
@@ -10263,10 +10323,12 @@ 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
 }
 }
 
 
 void print_world_coordinates()
 void print_world_coordinates()

+ 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;

+ 23 - 34
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;
@@ -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;
@@ -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");

+ 0 - 2
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,7 +74,6 @@ public:
   bool logging;
   bool logging;
   bool sdprinting ;  
   bool sdprinting ;  
   bool cardOK ;
   bool cardOK ;
-  bool paused ;
   char filename[13];
   char filename[13];
   uint16_t modificationTime, modificationDate;
   uint16_t modificationTime, modificationDate;
   uint32_t cluster, position;
   uint32_t cluster, position;

+ 32 - 23
Firmware/cmdqueue.cpp

@@ -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)

+ 7 - 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,14 @@ 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
 
 
 //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_UVLO_FEEDMULTIPLY
 // !!!!!
 // !!!!!
 // !!!!! 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 - 0
Firmware/messages.c

@@ -128,6 +128,9 @@ const char MSG_SOUND_BLIND[] PROGMEM_I1 = ISTR("Assist"); ////
 const char MSG_MESH[] PROGMEM_I1 = ISTR("Mesh"); ////
 const char MSG_MESH[] PROGMEM_I1 = ISTR("Mesh"); ////
 const char MSG_Z_PROBE_NR[] PROGMEM_I1 = ISTR("Z-probe nr."); ////
 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_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"); ////
 
 
 //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"; ////

+ 3 - 0
Firmware/messages.h

@@ -128,6 +128,9 @@ extern const char MSG_SOUND_BLIND[];
 extern const char MSG_MESH[];
 extern const char MSG_MESH[];
 extern const char MSG_Z_PROBE_NR[];
 extern const char MSG_Z_PROBE_NR[];
 extern const char MSG_MAGNETS_COMP[];
 extern const char MSG_MAGNETS_COMP[];
+extern const char MSG_FS_ACTION[];
+extern const char MSG_FS_CONTINUE[];
+extern const char MSG_FS_PAUSE[];
 
 
 //not internationalized messages
 //not internationalized messages
 extern const char MSG_BROWNOUT_RESET[];
 extern const char MSG_BROWNOUT_RESET[];

+ 1 - 2
Firmware/mmu.cpp

@@ -382,8 +382,7 @@ void mmu_loop(void)
 			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())
 				{
 				{

+ 2 - 1
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

+ 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);

+ 10 - 1
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;
   
   
@@ -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;

+ 2 - 2
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;

+ 135 - 17
Firmware/ultralcd.cpp

@@ -45,6 +45,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];
@@ -61,9 +65,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;
@@ -197,6 +198,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);
@@ -228,6 +230,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
@@ -2018,11 +2023,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}
@@ -2040,10 +2045,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
@@ -4096,7 +4108,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);
 		}
 		}
@@ -5684,6 +5696,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()
 {
 {
@@ -5715,6 +5762,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();
 }
 }
 
 
@@ -7048,11 +7098,21 @@ static void lcd_tune_menu()
 
 
 #ifdef FILAMENT_SENSOR
 #ifdef FILAMENT_SENSOR
 	if (FSensorStateMenu == 0) {
 	if (FSensorStateMenu == 0) {
-		MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_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_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_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;
@@ -7370,6 +7430,42 @@ void lcd_belttest()
 }
 }
 #endif //TMC2130
 #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()
 {
 {
 	(void)lcd_selftest();
 	(void)lcd_selftest();
@@ -7386,8 +7482,16 @@ bool lcd_selftest()
 	#ifdef TMC2130
 	#ifdef TMC2130
 	  FORCE_HIGH_POWER_START;
 	  FORCE_HIGH_POWER_START;
 	#endif // TMC2130
 	#endif // TMC2130
-	_delay(2000);
+#if !IR_SENSOR_ANALOG
+     _delay(2000);
+#endif //!IR_SENSOR_ANALOG
 	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))
@@ -7573,12 +7677,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
@@ -8114,11 +8226,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);

+ 10 - 0
Firmware/ultralcd.h

@@ -7,6 +7,8 @@
 #include "menu.h"
 #include "menu.h"
 #include "mesh_bed_calibration.h"
 #include "mesh_bed_calibration.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);
 extern void menu_lcd_lcdupdate_func(void);
 extern void menu_lcd_lcdupdate_func(void);
@@ -242,4 +244,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

+ 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);