Explorar o código

Merge pull request #1506 from PavelSindler/dev2

sw pwm for print fan, bed hw pwm, fsensor changes...
PavelSindler %!s(int64=5) %!d(string=hai) anos
pai
achega
166f886203

+ 20 - 0
.gitignore

@@ -16,6 +16,25 @@ Firmware/Doc
 /html
 /latex
 /Doxyfile
+/Firmware/builds/1_75mm_MK3-EINY04-E3Dv6full
+/Firmware/Configuration_prusa.h.bak
+/Firmware/Configuration_prusa_backup.h
+/Firmware/ultralcd_implementation_hitachi_HD44780.h.bak
+/Firmware/ultralcd.cpp.bak
+/Firmware/temperature.cpp.bak
+/Firmware/pins.h.bak
+/Firmware/Marlin_main.cpp.bak
+/Firmware/language_pl.h.bak
+/Firmware/language_it.h.bak
+/Firmware/language_es.h.bak
+/Firmware/language_en.h.bak
+/Firmware/language_de.h.bak
+/Firmware/language_cz.h.bak
+/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h
+/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h
+/Firmware/variants/1_75mm_MK2-EINY01-E3Dv6full.h.bak
+/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h
+/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h
 /lang/*.bin
 /lang/*.hex
 /lang/*.dat
@@ -30,3 +49,4 @@ Firmware/Doc
 /lang/text.sym
 /lang/textaddr.txt
 /build-env/
+/Firmware/Firmware.vcxproj

+ 2 - 1
Firmware/Configuration.h

@@ -475,7 +475,8 @@ your extruder heater takes 2 minutes to hit the target on heating.
 // Use software PWM to drive the fan, as for the heaters. This uses a very low frequency
 // which is not ass annoying as with the hardware PWM. On the other hand, if this frequency
 // is too low, you should also increment SOFT_PWM_SCALE.
-//#define FAN_SOFT_PWM
+#define FAN_SOFT_PWM
+#define FAN_SOFT_PWM_BITS 4 //PWM bit resolution = 4bits, freq = 62.5Hz
 
 // Incrementing this by 1 will double the software PWM frequency,
 // affecting heaters, and the fan if FAN_SOFT_PWM is enabled.

+ 1 - 0
Firmware/Marlin.h

@@ -383,6 +383,7 @@ extern LongTimer safetyTimer;
 
 #define PRINT_PERCENT_DONE_INIT   0xff
 #define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == CUSTOM_MSG_TYPE_TEMCAL) || saved_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL) || card.paused || mmu_print_saved)
+#define CHECK_FSENSOR ((IS_SD_PRINTING || is_usb_printing) && (mcode_in_progress != 600) && !saved_printing && e_active())
 
 extern void calculate_extruder_multipliers();
 

+ 70 - 46
Firmware/Marlin_main.cpp

@@ -142,6 +142,7 @@
 
 #define PRINTING_TYPE_SD 0
 #define PRINTING_TYPE_USB 1
+#define PRINTING_TYPE_NONE 2
 
 //filament types 
 #define FILAMENT_DEFAULT 0
@@ -991,6 +992,10 @@ void setup()
 	
 	ultralcd_init();
 
+#if (LCD_BL_PIN != -1) && defined (LCD_BL_PIN)
+	analogWrite(LCD_BL_PIN, 255); //set full brightnes
+#endif //(LCD_BL_PIN != -1) && defined (LCD_BL_PIN)
+
 	spi_init();
 
 	lcd_splash();
@@ -1478,9 +1483,9 @@ void setup()
 	setup_fan_interrupt();
 #endif //DEBUG_DISABLE_FANCHECK
 
-#ifdef FILAMENT_SENSOR
+#ifdef PAT9125
 	fsensor_setup_interrupt();
-#endif //FILAMENT_SENSOR
+#endif //PAT9125
 	for (int i = 0; i<4; i++) EEPROM_read_B(EEPROM_BOWDEN_LENGTH + i * 2, &bowden_length[i]); 
 	
 #ifndef DEBUG_DISABLE_STARTMSGS
@@ -1612,7 +1617,6 @@ void setup()
 	   
   }
 #endif //UVLO_SUPPORT
-
   KEEPALIVE_STATE(NOT_BUSY);
 #ifdef WATCHDOG
   wdt_enable(WDTO_4S);
@@ -2089,8 +2093,8 @@ bool calibrate_z_auto()
 {
 	//lcd_display_message_fullscreen_P(_T(MSG_CALIBRATE_Z_AUTO));
 	lcd_clear();
-	lcd_puts_at_P(0,1, _T(MSG_CALIBRATE_Z_AUTO));
-	bool endstops_enabled  = enable_endstops(true);
+	lcd_puts_at_P(0, 1, _T(MSG_CALIBRATE_Z_AUTO));
+	bool endstops_enabled = enable_endstops(true);
 	int axis_up_dir = -home_dir(Z_AXIS);
 	tmc2130_home_enter(Z_AXIS_MASK);
 	current_position[Z_AXIS] = 0;
@@ -2098,21 +2102,26 @@ bool calibrate_z_auto()
 	set_destination_to_current();
 	destination[Z_AXIS] += (1.1 * max_length(Z_AXIS) * axis_up_dir);
 	feedrate = homing_feedrate[Z_AXIS];
-	plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+	plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate / 60, active_extruder);
 	st_synchronize();
-//	current_position[axis] = 0;
-//	plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
+	//	current_position[axis] = 0;
+	//	plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 	tmc2130_home_exit();
-    enable_endstops(false);
+	enable_endstops(false);
 	current_position[Z_AXIS] = 0;
 	plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 	set_destination_to_current();
 	destination[Z_AXIS] += 10 * axis_up_dir; //10mm up
 	feedrate = homing_feedrate[Z_AXIS] / 2;
-	plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+	plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate / 60, active_extruder);
 	st_synchronize();
-    enable_endstops(endstops_enabled);
-    current_position[Z_AXIS] = Z_MAX_POS+2.0;
+	enable_endstops(endstops_enabled);
+	if (PRINTER_TYPE == PRINTER_MK3) {
+		current_position[Z_AXIS] = Z_MAX_POS + 2.0;
+	}
+	else {
+		current_position[Z_AXIS] = Z_MAX_POS + 9.0;
+	}
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 	return true;
 }
@@ -2316,9 +2325,9 @@ void refresh_cmd_timeout(void)
 
 void trace() {
 //if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
-    tone(BEEPER, 440);
+    _tone(BEEPER, 440);
     _delay(25);
-    noTone(BEEPER);
+    _noTone(BEEPER);
     _delay(20);
 }
 /*
@@ -3073,6 +3082,11 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     sprintf_P(cmd, PSTR("M220 S%i"), feedmultiplyBckp);
     enquecommand(cmd);
 
+#ifdef IR_SENSOR
+	//this will set fsensor_watch_autoload to correct value and prevent possible M701 gcode enqueuing when M600 is finished
+	fsensor_check_autoload();
+#endif //IR_SENSOR
+
     lcd_setstatuspgm(_T(WELCOME_MSG));
     custom_message_type = CUSTOM_MSG_TYPE_STATUS;
 }
@@ -3110,9 +3124,9 @@ void gcode_M701()
 		load_filament_final_feed(); //slow sequence
 		st_synchronize();
 
-		if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) tone(BEEPER, 500);
+		if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) _tone(BEEPER, 500);
 		delay_keep_alive(50);
-		noTone(BEEPER);
+		_noTone(BEEPER);
 
 		if (!farm_mode && loading_flag) {
 			lcd_load_filament_color_check();
@@ -3175,9 +3189,9 @@ static void gcode_PRUSA_SN()
         putchar('\n');
 #if 0
         for (int b = 0; b < 3; b++) {
-            tone(BEEPER, 110);
+            _tone(BEEPER, 110);
             _delay(50);
-            noTone(BEEPER);
+            _noTone(BEEPER);
             _delay(50);
         }
 #endif
@@ -3450,11 +3464,11 @@ void process_commands()
 	}
 #endif //BACKLASH_Y
 #endif //TMC2130
-#ifdef PAT9125
+#ifdef FILAMENT_SENSOR
 	else if (code_seen("FSENSOR_RECOVER")) { //! FSENSOR_RECOVER
 		fsensor_restore_print_and_continue();
   }
-#endif //PAT9125
+#endif //FILAMENT_SENSOR
   else if(code_seen("PRUSA")){
 		if (code_seen("Ping")) {  //! PRUSA Ping
 			if (farm_mode) {
@@ -4606,14 +4620,15 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 			}
 			if (correction == 0)
 				continue;
-			float offset = float(correction) * 0.001f;
-			if (fabs(offset) > 0.101f) {
+			
+			if (labs(correction) > BED_ADJUSTMENT_UM_MAX) {
 				SERIAL_ERROR_START;
 				SERIAL_ECHOPGM("Excessive bed leveling correction: ");
-				SERIAL_ECHO(offset);
+				SERIAL_ECHO(correction);
 				SERIAL_ECHOLNPGM(" microns");
 			}
 			else {
+				float offset = float(correction) * 0.001f;
 				switch (i) {
 				case 0:
 					for (uint8_t row = 0; row < 3; ++row) {
@@ -6253,9 +6268,9 @@ Sigma_Exit:
       {
         #if BEEPER > 0
 if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
-          tone(BEEPER, beepS);
+          _tone(BEEPER, beepS);
           _delay(beepP);
-          noTone(BEEPER);
+          _noTone(BEEPER);
         #endif
       }
       else
@@ -7105,7 +7120,6 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 		dcode_8(); break;
 	case 9: //! D9 - Read/Write ADC
 		dcode_9(); break;
-
 	case 10: //! D10 - XYZ calibration = OK
 		dcode_10(); break;
     
@@ -7474,13 +7488,15 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s
 			{
 				if (fsensor_check_autoload())
 				{
+#ifdef PAT9125
 					fsensor_autoload_check_stop();
+#endif //PAT9125
 					if (degHotend0() > EXTRUDE_MINTEMP)
 					{
 						if ((eSoundMode == e_SOUND_MODE_LOUD) || (eSoundMode == e_SOUND_MODE_ONCE))
-							tone(BEEPER, 1000);
+							_tone(BEEPER, 1000);
 						delay_keep_alive(50);
-						noTone(BEEPER);
+						_noTone(BEEPER);
 						loading_flag = true;
 						enquecommand_front_P((PSTR("M701")));
 					}
@@ -7504,7 +7520,9 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s
 			}
 			else
 			{
+#ifdef PAT9125
 				fsensor_autoload_check_stop();
+#endif //PAT9125
 				fsensor_update();
 			}
 		}
@@ -8339,8 +8357,8 @@ void uvlo_()
     // are in action.
     planner_abort_hard();
 
-    // Store the current extruder position.
-    eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E), st_get_position_mm(E_AXIS));
+	// Store the current extruder position.
+	eeprom_update_float((float*)(EEPROM_UVLO_CURRENT_POSITION_E), st_get_position_mm(E_AXIS));
 	eeprom_update_byte((uint8_t*)EEPROM_UVLO_E_ABS, axis_relative_modes[3]?0:1);
 
     // Clean the input command queue.
@@ -8511,8 +8529,12 @@ void setup_fan_interrupt() {
 // and it takes 4.24 us to process (the interrupt invocation overhead not taken into account).
 ISR(INT7_vect) {
 	//measuring speed now works for fanSpeed > 18 (approximately), which is sufficient because MIN_PRINT_FAN_SPEED is higher
-
+#ifdef FAN_SOFT_PWM
+	if (!fan_measuring || (fanSpeedSoftPwm < MIN_PRINT_FAN_SPEED)) return;
+#else //FAN_SOFT_PWM
 	if (fanSpeed < MIN_PRINT_FAN_SPEED) return;
+#endif //FAN_SOFT_PWM
+
 	if ((1 << 6) & EICRB) { //interrupt was triggered by rising edge
 		t_fan_rising_edge = millis_nc();
 	}
@@ -8696,8 +8718,7 @@ void restore_print_from_eeprom() {
 	enquecommand(cmd);
 	uint32_t position = eeprom_read_dword((uint32_t*)(EEPROM_FILE_POSITION));
 	SERIAL_ECHOPGM("Position read from eeprom:");
-	MYSERIAL.println(position);
-
+	MYSERIAL.println(position);	
   // E axis relative mode.
 	enquecommand_P(PSTR("M83"));
   // Move to the XY print position in logical coordinates, where the print has been killed.
@@ -8772,7 +8793,8 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
 		 saved_printing_type = PRINTING_TYPE_USB;
 	}
 	else {
-		//not sd printing nor usb printing
+		 saved_printing_type = PRINTING_TYPE_NONE;
+		 //not sd printing nor usb printing
 	}
 
 #if 0
@@ -8937,10 +8959,12 @@ void restore_print_from_ram_and_continue(float e_move)
 //	for (int axis = X_AXIS; axis <= E_AXIS; axis++)
 //	    current_position[axis] = st_get_position_mm(axis);
 	active_extruder = saved_active_extruder; //restore active_extruder
-	setTargetHotendSafe(saved_extruder_temperature,saved_active_extruder);
-	heating_status = 1;
-	wait_for_heater(_millis(),saved_active_extruder);
-	heating_status = 2;
+	if (saved_extruder_temperature) {
+		setTargetHotendSafe(saved_extruder_temperature, saved_active_extruder);
+		heating_status = 1;
+		wait_for_heater(_millis(), saved_active_extruder);
+		heating_status = 2;
+	}
 	feedrate = saved_feedrate2; //restore feedrate
 	axis_relative_modes[E_AXIS] = saved_extruder_relative_mode;
 	fanSpeed = saved_fanSpeed;
@@ -9198,9 +9222,9 @@ void M600_load_filament() {
 	//load_filament_time = _millis();
 	KEEPALIVE_STATE(PAUSED_FOR_USER);
 
-#ifdef FILAMENT_SENSOR
+#ifdef PAT9125
 	fsensor_autoload_check_start();
-#endif //FILAMENT_SENSOR
+#endif //PAT9125
 	while(!lcd_clicked())
 	{
 		manage_heater();
@@ -9209,16 +9233,16 @@ void M600_load_filament() {
 		if (fsensor_check_autoload())
 		{
 if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
-			tone(BEEPER, 1000);
+			_tone(BEEPER, 1000);
 			delay_keep_alive(50);
-			noTone(BEEPER);
+			_noTone(BEEPER);
 			break;
 		}
 #endif //FILAMENT_SENSOR
 	}
-#ifdef FILAMENT_SENSOR
+#ifdef PAT9125
 	fsensor_autoload_check_stop();
-#endif //FILAMENT_SENSOR
+#endif //PAT9125
 	KEEPALIVE_STATE(IN_HANDLER);
 
 #ifdef FSENSOR_QUALITY
@@ -9228,9 +9252,9 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 	M600_load_filament_movements();
 
 if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
-	tone(BEEPER, 500);
+	_tone(BEEPER, 500);
 	delay_keep_alive(50);
-	noTone(BEEPER);
+	_noTone(BEEPER);
 
 #ifdef FSENSOR_QUALITY
 	fsensor_oq_meassure_stop();

+ 100 - 57
Firmware/fsensor.cpp

@@ -13,6 +13,7 @@
 #include "ultralcd.h"
 #include "ConfigurationStore.h"
 #include "mmu.h"
+#include "cardreader.h"
 
 //! @name Basic parameters
 //! @{
@@ -120,17 +121,20 @@ void fsensor_stop_and_save_print(void)
 void fsensor_restore_print_and_continue(void)
 {
     printf_P(PSTR("fsensor_restore_print_and_continue\n"));
-    fsensor_watch_runout = true;
-    fsensor_err_cnt = 0;
+	fsensor_watch_runout = true;
+	fsensor_err_cnt = 0;
     restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change
 }
 
 void fsensor_init(void)
 {
+#ifdef PAT9125
 	uint8_t pat9125 = pat9125_init();
     printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
+#endif //PAT9125
 	uint8_t fsensor = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
+#ifdef PAT9125
 	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_chunk_len = (int16_t)(FSENSOR_CHUNK_LEN * cs.axis_steps_per_unit[E_AXIS]);
@@ -142,15 +146,19 @@ void fsensor_init(void)
 	}
 	else
 		fsensor_not_responding = false;
+#endif //PAT9125
 	if (fsensor)
 		fsensor_enable();
 	else
 		fsensor_disable();
 	printf_P(PSTR("FSensor %S\n"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED\n")));
+	if (check_for_ir_sensor()) ir_sensor_detected = true;
+
 }
 
 bool fsensor_enable(void)
 {
+#ifdef PAT9125
 	if (mmu_enabled == false) { //filament sensor is pat9125, enable only if it is working
 		uint8_t pat9125 = pat9125_init();
 		printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
@@ -172,6 +180,11 @@ bool fsensor_enable(void)
 		eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x01);
 		FSensorStateMenu = 1;
 	}
+#else // PAT9125
+	fsensor_enabled = true;
+	eeprom_update_byte((uint8_t*)EEPROM_FSENSOR, 0x01);
+	FSensorStateMenu = 1;
+#endif // PAT9125
 	return fsensor_enabled;
 }
 
@@ -184,7 +197,9 @@ void fsensor_disable(void)
 
 void fsensor_autoload_set(bool State)
 {
+#ifdef PAT9125
 	if (!State) fsensor_autoload_check_stop();
+#endif //PAT9125
 	fsensor_autoload_enabled = State;
 	eeprom_update_byte((unsigned char *)EEPROM_FSENS_AUTOLOAD_ENABLED, fsensor_autoload_enabled);
 }
@@ -197,6 +212,7 @@ void pciSetup(byte pin)
 	PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group 
 }
 
+#ifdef PAT9125
 void fsensor_autoload_check_start(void)
 {
 //	puts_P(_N("fsensor_autoload_check_start\n"));
@@ -223,6 +239,7 @@ void fsensor_autoload_check_start(void)
 
 void fsensor_autoload_check_stop(void)
 {
+
 //	puts_P(_N("fsensor_autoload_check_stop\n"));
 	if (!fsensor_enabled) return;
 //	puts_P(_N("fsensor_autoload_check_stop 1\n"));
@@ -235,11 +252,22 @@ void fsensor_autoload_check_stop(void)
 	fsensor_watch_runout = true;
 	fsensor_err_cnt = 0;
 }
+#endif //PAT9125
 
 bool fsensor_check_autoload(void)
 {
 	if (!fsensor_enabled) return false;
 	if (!fsensor_autoload_enabled) return false;
+	if (ir_sensor_detected) {
+		if (digitalRead(IR_SENSOR_PIN) == 1) {
+			fsensor_watch_autoload = true;
+		}
+		else if (fsensor_watch_autoload == true) {
+			fsensor_watch_autoload = false;
+			return true;
+		}
+	}
+#ifdef PAT9125
 	if (!fsensor_watch_autoload)
 	{
 		fsensor_autoload_check_start();
@@ -283,6 +311,7 @@ bool fsensor_check_autoload(void)
 //		puts_P(_N("fsensor_check_autoload = true !!!\n"));
 		return true;
 	}
+#endif //PAT9125
 	return false;
 }
 
@@ -359,10 +388,10 @@ bool fsensor_oq_result(void)
 	printf_P(_N("fsensor_oq_result %S\n"), (res?_OK:_NG));
 	return res;
 }
-
+#ifdef PAT9125
 ISR(FSENSOR_INT_PIN_VECT)
 {
-	if (mmu_enabled) return;
+	if (mmu_enabled || ir_sensor_detected) return;
 	if (!((fsensor_int_pin_old ^ FSENSOR_INT_PIN_PIN_REG) & FSENSOR_INT_PIN_MASK)) return;
 	fsensor_int_pin_old = FSENSOR_INT_PIN_PIN_REG;
 	static bool _lock = false;
@@ -446,6 +475,23 @@ ISR(FSENSOR_INT_PIN_VECT)
 	return;
 }
 
+void fsensor_setup_interrupt(void)
+{
+
+	pinMode(FSENSOR_INT_PIN, OUTPUT);
+	digitalWrite(FSENSOR_INT_PIN, LOW);
+	fsensor_int_pin_old = 0;
+
+	//pciSetup(FSENSOR_INT_PIN);
+// !!! "pciSetup()" does not provide the correct results for some MCU pins
+// so interrupt registers settings:
+     FSENSOR_INT_PIN_PCMSK_REG |= bit(FSENSOR_INT_PIN_PCMSK_BIT); // enable corresponding PinChangeInterrupt (individual pin)
+     PCIFR |= bit(FSENSOR_INT_PIN_PCICR_BIT);     // clear previous occasional interrupt (set of pins)
+     PCICR |= bit(FSENSOR_INT_PIN_PCICR_BIT);     // enable corresponding PinChangeInterrupt (set of pins)
+}
+
+#endif //PAT9125
+
 void fsensor_st_block_begin(block_t* bl)
 {
 	if (!fsensor_enabled) return;
@@ -477,17 +523,18 @@ void fsensor_st_block_chunk(block_t* bl, int cnt)
 //! If there is still no plausible signal from filament sensor plans M600 (Filament change).
 void fsensor_update(void)
 {
-	if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
-	{
-        bool autoload_enabled_tmp = fsensor_autoload_enabled;
-        fsensor_autoload_enabled = false;
-        bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
-		fsensor_oq_meassure_enabled = true;
+#ifdef PAT9125
+		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
+		{
+			bool autoload_enabled_tmp = fsensor_autoload_enabled;
+			fsensor_autoload_enabled = false;
+			bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled;
+			fsensor_oq_meassure_enabled = true;
 
-        fsensor_stop_and_save_print();
+			fsensor_stop_and_save_print();
 
-        fsensor_err_cnt = 0;
-        fsensor_oq_meassure_start(0);
+			fsensor_err_cnt = 0;
+			fsensor_oq_meassure_start(0);
 
 			enquecommand_front_P((PSTR("G1 E-3 F200")));
 			process_commands();
@@ -495,51 +542,47 @@ void fsensor_update(void)
 			cmdqueue_pop_front();
 			st_synchronize();
 
-        enquecommand_front_P((PSTR("G1 E3 F200")));
-        process_commands();
-		KEEPALIVE_STATE(IN_HANDLER);
-        cmdqueue_pop_front();
-        st_synchronize();
-
-		uint8_t err_cnt = fsensor_err_cnt;
-        fsensor_oq_meassure_stop();
-
-        bool err = false;
-        err |= (err_cnt > 1);
-
-		err |= (fsensor_oq_er_sum > 2);
-		err |= (fsensor_oq_yd_sum < (4 * FSENSOR_OQ_MIN_YD));
-
-		if (!err)
-        {
-            printf_P(PSTR("fsensor_err_cnt = 0\n"));
-            fsensor_restore_print_and_continue();
-        }
-        else
-        {
-            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_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
-            enquecommand_front_P(PSTR("FSENSOR_RECOVER"));
-            enquecommand_front_P((PSTR("M600")));
-            fsensor_watch_runout = false;
-        }
-        fsensor_autoload_enabled = autoload_enabled_tmp;
-		fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
-	}
-}
+			enquecommand_front_P((PSTR("G1 E3 F200")));
+			process_commands();
+			KEEPALIVE_STATE(IN_HANDLER);
+			cmdqueue_pop_front();
+			st_synchronize();
 
-void fsensor_setup_interrupt(void)
-{
+			uint8_t err_cnt = fsensor_err_cnt;
+			fsensor_oq_meassure_stop();
 
-	pinMode(FSENSOR_INT_PIN, OUTPUT);
-	digitalWrite(FSENSOR_INT_PIN, LOW);
-	fsensor_int_pin_old = 0;
+			bool err = false;
+			err |= (err_cnt > 1);
 
-	//pciSetup(FSENSOR_INT_PIN);
-// !!! "pciSetup()" does not provide the correct results for some MCU pins
-// so interrupt registers settings:
-     FSENSOR_INT_PIN_PCMSK_REG |= bit(FSENSOR_INT_PIN_PCMSK_BIT); // enable corresponding PinChangeInterrupt (individual pin)
-     PCIFR |= bit(FSENSOR_INT_PIN_PCICR_BIT);     // clear previous occasional interrupt (set of pins)
-     PCICR |= bit(FSENSOR_INT_PIN_PCICR_BIT);     // enable corresponding PinChangeInterrupt (set of pins)
+			err |= (fsensor_oq_er_sum > 2);
+			err |= (fsensor_oq_yd_sum < (4 * FSENSOR_OQ_MIN_YD));
+
+			if (!err)
+			{
+				printf_P(PSTR("fsensor_err_cnt = 0\n"));
+				fsensor_restore_print_and_continue();
+			}
+			else
+			{
+				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_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
+				enquecommand_front_P(PSTR("FSENSOR_RECOVER"));
+				enquecommand_front_P((PSTR("M600")));
+				fsensor_watch_runout = false;
+			}
+			fsensor_autoload_enabled = autoload_enabled_tmp;
+			fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp;
+		}
+#else //PAT9125
+		if ((digitalRead(IR_SENSOR_PIN) == 1) && CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected)
+		{
+			fsensor_stop_and_save_print();
+			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_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
+			enquecommand_front_P(PSTR("FSENSOR_RECOVER"));
+			enquecommand_front_P((PSTR("M600")));
+		}
+#endif //PAT9125
 }

+ 3 - 1
Firmware/fsensor.h

@@ -35,14 +35,16 @@ extern bool fsensor_autoload_enabled;
 extern void fsensor_autoload_set(bool State);
 
 extern void fsensor_update(void);
-
+#ifdef PAT9125
 //! setup pin-change interrupt
 extern void fsensor_setup_interrupt(void);
 
 //! @name autoload support
 //! @{
+
 extern void fsensor_autoload_check_start(void);
 extern void fsensor_autoload_check_stop(void);
+#endif //PAT9125
 extern bool fsensor_check_autoload(void);
 //! @}
 

+ 2 - 1
Firmware/menu.cpp

@@ -284,7 +284,8 @@ void menu_draw_P<int16_t*>(char chr, const char* str, int16_t val)
 	if (text_len > 15) text_len = 15;
 	char spaces[21];
 	strcpy_P(spaces, menu_20x_space);
-	spaces[15 - text_len] = 0;
+	if (val <= -100) spaces[15 - text_len - 1] = 0;
+	else spaces[15 - text_len] = 0;
 	lcd_printf_P(menu_fmt_int3, chr, str, spaces, val);
 }
 

+ 1 - 1
Firmware/messages.c

@@ -96,7 +96,7 @@ const char MSG_WIZARD_DONE[] PROGMEM_I1 = ISTR("All is done. Happy printing!");
 const char MSG_WIZARD_HEATING[] PROGMEM_I1 = ISTR("Preheating nozzle. Please wait."); ////c=20 r=3
 const char MSG_WIZARD_QUIT[] PROGMEM_I1 = ISTR("You can always resume the Wizard from Calibration -> Wizard."); ////c=20 r=8
 const char MSG_YES[] PROGMEM_I1 = ISTR("Yes"); ////c=0 r=0
-const char WELCOME_MSG[] PROGMEM_I1 = ISTR(CUSTOM_MENDEL_NAME " ready."); ////c=20 r=0
+const char WELCOME_MSG[] PROGMEM_I1 = ISTR(CUSTOM_MENDEL_NAME " OK."); ////c=20 r=0
 //not internationalized messages
 const char MSG_SD_WORKDIR_FAIL[] PROGMEM_N1 = "workDir open failed"; ////c=0 r=0
 const char MSG_BROWNOUT_RESET[] PROGMEM_N1 = " Brown out Reset"; ////c=0 r=0

+ 36 - 27
Firmware/mmu.cpp

@@ -20,8 +20,6 @@
 #include "tmc2130.h"
 #endif //TMC2130
 
-#define CHECK_FINDA ((IS_SD_PRINTING || is_usb_printing) && (mcode_in_progress != 600) && !saved_printing && e_active())
-
 #define MMU_TODELAY 100
 #define MMU_TIMEOUT 10
 #define MMU_CMD_TIMEOUT 45000ul //5min timeout for mmu commands (except P0)
@@ -42,7 +40,7 @@ uint8_t mmu_cmd = 0;
 
 //idler ir sensor
 uint8_t mmu_idl_sens = 0;
-bool mmu_idler_sensor_detected = false; 
+bool ir_sensor_detected = false; 
 bool mmu_loading_flag = false;
 
 uint8_t mmu_extruder = MMU_FILAMENT_UNKNOWN;
@@ -117,25 +115,36 @@ void mmu_init(void)
 	_delay_ms(10);                             //wait 10ms for sure
 	mmu_reset();                               //reset mmu (HW or SW), do not wait for response
 	mmu_state = -1;
-	PIN_INP(MMU_IDLER_SENSOR_PIN); //input mode
-	PIN_SET(MMU_IDLER_SENSOR_PIN); //pullup
+	PIN_INP(IR_SENSOR_PIN); //input mode
+	PIN_SET(IR_SENSOR_PIN); //pullup
 }
 
-//returns true if idler IR sensor was detected, otherwise returns false
-bool check_for_idler_sensor() 
+
+//if IR_SENSOR defined, always returns true
+//otherwise check for ir sensor and returns true if idler IR sensor was detected, otherwise returns false
+bool check_for_ir_sensor() 
 {
+#ifdef IR_SENSOR
+	return true;
+#else //IR_SENSOR
+
 	bool detected = false;
-	//if MMU_IDLER_SENSOR_PIN input is low and pat9125sensor is not present we detected idler sensor
-	if ((PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) && fsensor_not_responding) 
-	{
-		  detected = true;
-		  //printf_P(PSTR("Idler IR sensor detected\n"));
+	//if IR_SENSOR_PIN input is low and pat9125sensor is not present we detected idler sensor
+	if ((PIN_GET(IR_SENSOR_PIN) == 0) 
+#ifdef PAT9125
+		&& fsensor_not_responding
+#endif //PAT9125
+	) 
+	{		
+		detected = true;
+		//printf_P(PSTR("Idler IR sensor detected\n"));
 	}
 	else
 	{
-		  //printf_P(PSTR("Idler IR sensor not detected\n"));
+		//printf_P(PSTR("Idler IR sensor not detected\n"));
 	}
 	return detected;
+#endif //IR_SENSOR
 }
 
 //mmu main loop - state machine processing
@@ -225,8 +234,6 @@ void mmu_loop(void)
 #endif //MMU_DEBUG && MMU_FINDA_DEBUG
 			puts_P(PSTR("MMU - ENABLED"));
 			mmu_enabled = true;
-			//if we have filament loaded into the nozzle, we can decide if printer has idler sensor right now; otherwise we will will wait till start of T-code so it will be detected on beginning of second T-code
-			if(check_for_idler_sensor()) mmu_idler_sensor_detected = true;
 			mmu_state = 1;
 		}
 		return;
@@ -302,7 +309,9 @@ void mmu_loop(void)
 		}
 		else if ((mmu_last_response + 300) < _millis()) //request every 300ms
 		{
-			if(check_for_idler_sensor()) mmu_idler_sensor_detected = true;
+#ifndef IR_SENSOR
+			if(check_for_ir_sensor()) ir_sensor_detected = true;
+#endif //IR_SENSOR not defined
 #if defined MMU_DEBUG && defined MMU_FINDA_DEBUG
 			puts_P(PSTR("MMU <= 'P0'"));
 #endif //MMU_DEBUG && MMU_FINDA_DEBUG
@@ -318,7 +327,7 @@ void mmu_loop(void)
 			printf_P(PSTR("MMU => '%dok'\n"), mmu_finda);
 #endif //MMU_DEBUG && MMU_FINDA_DEBUG
 			//printf_P(PSTR("Eact: %d\n"), int(e_active()));
-			if (!mmu_finda && CHECK_FINDA && fsensor_enabled) {
+			if (!mmu_finda && CHECK_FSENSOR && fsensor_enabled) {
 				fsensor_stop_and_save_print();
 				enquecommand_front_P(PSTR("FSENSOR_RECOVER")); //then recover
 				ad_markDepleted(mmu_extruder);
@@ -343,7 +352,7 @@ void mmu_loop(void)
 	case 3: //response to mmu commands
         if (mmu_idl_sens)
         {
-            if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0 && mmu_loading_flag)
+            if (PIN_GET(IR_SENSOR_PIN) == 0 && mmu_loading_flag)
             {
 #ifdef MMU_DEBUG
                 printf_P(PSTR("MMU <= 'A'\n"));
@@ -471,7 +480,7 @@ void mmu_load_step(bool synchronize)
 //!         off E-stepper to prevent over-heating and allow filament pull-out if necessary
 bool can_extrude()
 {
-    if ((degHotend(active_extruder) < EXTRUDE_MINTEMP) || !mmu_idler_sensor_detected)
+    if ((degHotend(active_extruder) < EXTRUDE_MINTEMP) || !ir_sensor_detected)
     {
         disable_e0();
         delay_keep_alive(100);
@@ -501,10 +510,10 @@ bool mmu_get_response(uint8_t move)
 			    mmu_loading_flag = true;
 				if (can_extrude()) mmu_load_step();
 				//don't rely on "ok" signal from mmu unit; if filament detected by idler sensor during loading stop loading movements to prevent infinite loading
-				if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
+				if (PIN_GET(IR_SENSOR_PIN) == 0) move = MMU_NO_MOVE;
 				break;
 			case MMU_UNLOAD_MOVE:
-				if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading 
+				if (PIN_GET(IR_SENSOR_PIN) == 0) //filament is still detected by idler sensor, printer helps with unlading 
 				{
 				    if (can_extrude())
 				    {
@@ -522,7 +531,7 @@ bool mmu_get_response(uint8_t move)
 				}
 				break;
 			case MMU_TCODE_MOVE: //first do unload and then continue with infinite loading movements
-				if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first 
+				if (PIN_GET(IR_SENSOR_PIN) == 0) //filament detected by idler sensor, we must unload first 
 				{
                     if (can_extrude())
                     {
@@ -700,7 +709,7 @@ void mmu_load_to_nozzle()
 	
 	bool saved_e_relative_mode = axis_relative_modes[E_AXIS];
 	if (!saved_e_relative_mode) axis_relative_modes[E_AXIS] = true;
-	if (mmu_idler_sensor_detected)
+	if (ir_sensor_detected)
 	{
 		current_position[E_AXIS] += 3.0f;
 	}
@@ -1356,16 +1365,16 @@ void mmu_eject_filament(uint8_t filament, bool recover)
 void mmu_continue_loading() 
 {
 
-	if (mmu_idler_sensor_detected) {
+	if (ir_sensor_detected) {
 		for (uint8_t i = 0; i < MMU_IDLER_SENSOR_ATTEMPTS_NR; i++) {
-			if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) return;
+			if (PIN_GET(IR_SENSOR_PIN) == 0) return;
 #ifdef MMU_DEBUG
 			printf_P(PSTR("Additional load attempt nr. %d\n"), i);
 #endif // MMU_DEBUG
 			mmu_command(MMU_CMD_C0);
 			manage_response(true, true, MMU_LOAD_MOVE);
 		}
-		if (PIN_GET(MMU_IDLER_SENSOR_PIN) != 0) {
+		if (PIN_GET(IR_SENSOR_PIN) != 0) {
 			uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL);
 			uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT);
 			if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1);
@@ -1392,7 +1401,7 @@ void mmu_continue_loading()
 			isPrintPaused = true;
 		}
 	}
-	else { //mmu_idler_sensor_detected == false
+	else { //mmu_ir_sensor_detected == false
 		mmu_command(MMU_CMD_C0);
 	}
 }

+ 2 - 2
Firmware/mmu.h

@@ -14,7 +14,7 @@ extern uint8_t mmu_extruder;
 extern uint8_t tmp_extruder;
 
 extern int8_t mmu_finda;
-extern bool mmu_idler_sensor_detected;
+extern bool ir_sensor_detected;
 extern bool mmu_loading_flag;
 
 extern int16_t mmu_version;
@@ -59,7 +59,7 @@ extern int mmu_printf_P(const char* format, ...);
 
 extern int8_t mmu_rx_ok(void);
 
-extern bool check_for_idler_sensor();
+extern bool check_for_ir_sensor();
 
 extern void mmu_init(void);
 

+ 2 - 5
Firmware/pins_Einsy_1_0.h

@@ -99,10 +99,7 @@
 
 //#define KILL_PIN            32
 
-
-//#define LCD_PWM_PIN         -1//32  // lcd backlight brightnes pwm control pin
-//#define LCD_PWM_MAX       0x0f  // lcd pwm maximum value (0x07=64Hz, 0x0f=32Hz, 0x1f=16Hz)
-
+//#define LCD_BL_PIN          5   //backlight control pin
 #define BEEPER              84  // Beeper on AUX-4
 #define LCD_PINS_RS         82
 #define LCD_PINS_ENABLE     61 // !!! changed from 18 (EINY03)
@@ -121,7 +118,7 @@
 #define TACH_0                 79 // !!! changed from 81 (EINY03)
 #define TACH_1                 80 
 
-#define MMU_IDLER_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
+#define IR_SENSOR_PIN 62 //idler sensor @PK0 (digital pin 62/A8)
 
 // Support for an 8 bit logic analyzer, for example the Saleae.
 // Channels 0-2 are fast, they could generate 2.667Mhz waveform with a software loop.

+ 1 - 1
Firmware/pins_Rambo_1_0.h

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

+ 1 - 1
Firmware/pins_Rambo_1_3.h

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

+ 7 - 1
Firmware/planner.cpp

@@ -545,7 +545,13 @@ void check_axes_activity()
     }
   #endif//FAN_KICKSTART_TIME
   #ifdef FAN_SOFT_PWM
-  fanSpeedSoftPwm = tail_fan_speed;
+	if (fan_measuring) { //if measurement is currently in process, fanSpeedSoftPwm must remain set to 255, but we must update fanSpeedBckp value
+		fanSpeedBckp = tail_fan_speed;
+	}
+	else {
+		fanSpeedSoftPwm = tail_fan_speed;
+	}
+  //printf_P(PSTR("fanspeedsoftPWM %d \n"), fanSpeedSoftPwm);
   #else
   analogWrite(FAN_PIN,tail_fan_speed);
   #endif//!FAN_SOFT_PWM

+ 2 - 0
Firmware/printers.h

@@ -8,7 +8,9 @@
 #define PRINTER_MK2_SNMM    201
 #define PRINTER_MK25        250
 #define PRINTER_MK25_SNMM   251
+#define PRINTER_MK25S		252
 #define PRINTER_MK3         300
 #define PRINTER_MK3_SNMM    301
+#define PRINTER_MK3S		302
 
 #endif //PRINTERS_H

+ 4 - 0
Firmware/system_timer.h

@@ -11,10 +11,14 @@
 #define _millis millis2
 #define _micros micros2
 #define _delay delay2
+#define _tone tone2
+#define _noTone noTone2
 #else //SYSTEM_TIMER_2
 #define _millis millis
 #define _micros micros
 #define _delay delay
+#define _tone tone
+#define _noTone noTone
 #define timer02_set_pwm0(pwm0)
 #endif //SYSTEM_TIMER_2
 

+ 63 - 12
Firmware/temperature.cpp

@@ -142,7 +142,10 @@ static volatile bool temp_meas_ready = false;
 #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
     (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
     (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
-  static unsigned long extruder_autofan_last_check;
+  unsigned long extruder_autofan_last_check = _millis();
+  uint8_t fanSpeedBckp = 255;
+  bool fan_measuring = false;
+
 #endif  
 
 
@@ -462,7 +465,7 @@ void setExtruderAutoFanState(int pin, bool state)
   // this idiom allows both digital and PWM fan outputs (see M42 handling).
   pinMode(pin, OUTPUT);
   digitalWrite(pin, newFanSpeed);
-  analogWrite(pin, newFanSpeed);
+  //analogWrite(pin, newFanSpeed);
 }
 
 #if (defined(FANCHECK) && (((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1)))))
@@ -484,6 +487,16 @@ extern bool fans_check_enabled;
 
 void checkFanSpeed()
 {
+	uint8_t max_print_fan_errors = 0;
+	uint8_t max_extruder_fan_errors = 0;
+#ifdef FAN_SOFT_PWM
+	max_print_fan_errors = 3; //15 seconds
+	max_extruder_fan_errors = 2; //10seconds
+#else //FAN_SOFT_PWM
+	max_print_fan_errors = 15; //15 seconds
+	max_extruder_fan_errors = 5; //5 seconds
+#endif //FAN_SOFT_PWM
+
 	fans_check_enabled = (eeprom_read_byte((uint8_t*)EEPROM_FAN_CHECK_ENABLED) > 0);
 	static unsigned char fan_speed_errors[2] = { 0,0 };
 #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 >-1))
@@ -491,15 +504,15 @@ void checkFanSpeed()
 	else fan_speed_errors[0] = 0;
 #endif
 #if (defined(FANCHECK) && defined(TACH_1) && (TACH_1 >-1))
-	if ((fan_speed[1] == 0) && ((blocks_queued() ? block_buffer[block_buffer_tail].fan_speed : fanSpeed) > MIN_PRINT_FAN_SPEED)) fan_speed_errors[1]++;
+	if ((fan_speed[1] < 5) && ((blocks_queued() ? block_buffer[block_buffer_tail].fan_speed : fanSpeed) > MIN_PRINT_FAN_SPEED)) fan_speed_errors[1]++;
 	else fan_speed_errors[1] = 0;
 #endif
 
-	if ((fan_speed_errors[0] > 5) && fans_check_enabled) {
+	if ((fan_speed_errors[0] > max_extruder_fan_errors) && fans_check_enabled) {
 		fan_speed_errors[0] = 0;
 		fanSpeedError(0); //extruder fan
 	}
-	if ((fan_speed_errors[1] > 15) && fans_check_enabled) {
+	if ((fan_speed_errors[1] > max_print_fan_errors) && fans_check_enabled) {
 		fan_speed_errors[1] = 0;
 		fanSpeedError(1); //print fan
 	}
@@ -734,10 +747,38 @@ void manage_heater()
     #endif
   } // End extruder for loop
 
+#define FAN_CHECK_PERIOD 5000 //5s
+#define FAN_CHECK_DURATION 100 //100ms
+
 #ifndef DEBUG_DISABLE_FANCHECK
   #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
       (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
       (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
+
+#ifdef FAN_SOFT_PWM
+#ifdef FANCHECK
+  if ((_millis() - extruder_autofan_last_check > FAN_CHECK_PERIOD) && (!fan_measuring)) {
+	  extruder_autofan_last_check = _millis();
+	  fanSpeedBckp = fanSpeedSoftPwm;
+	  
+	  if (fanSpeedSoftPwm >= MIN_PRINT_FAN_SPEED) { //if we are in rage where we are doing fan check, set full PWM range for a short time to measure fan RPM by reading tacho signal without modulation by PWM signal
+		//  printf_P(PSTR("fanSpeedSoftPwm 1: %d\n"), fanSpeedSoftPwm);
+		  fanSpeedSoftPwm = 255;
+	  }
+	  fan_measuring = true;
+  }
+  if ((_millis() - extruder_autofan_last_check > FAN_CHECK_DURATION) && (fan_measuring)) {
+	  countFanSpeed();
+	  checkFanSpeed();
+	  //printf_P(PSTR("fanSpeedSoftPwm 1: %d\n"), fanSpeedSoftPwm);
+	  fanSpeedSoftPwm = fanSpeedBckp;
+	  //printf_P(PSTR("fan PWM: %d; extr fanSpeed measured: %d; print fan speed measured: %d \n"), fanSpeedBckp, fan_speed[0], fan_speed[1]);
+	  extruder_autofan_last_check = _millis();
+	  fan_measuring = false;
+  }
+#endif //FANCHECK
+  checkExtruderAutoFans();
+#else //FAN_SOFT_PWM
   if(_millis() - extruder_autofan_last_check > 1000)  // only need to check fan state very infrequently
   {
 #if (defined(FANCHECK) && ((defined(TACH_0) && (TACH_0 >-1)) || (defined(TACH_1) && (TACH_1 > -1))))
@@ -747,7 +788,9 @@ void manage_heater()
     checkExtruderAutoFans();
     extruder_autofan_last_check = _millis();
   }  
-  #endif       
+#endif //FAN_SOFT_PWM
+
+  #endif  
 #endif //DEBUG_DISABLE_FANCHECK
   
   #ifndef PIDTEMPBED
@@ -1055,7 +1098,7 @@ void tp_init()
     setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
     #endif
     #ifdef FAN_SOFT_PWM
-    soft_pwm_fan = fanSpeedSoftPwm / 2;
+    soft_pwm_fan = fanSpeedSoftPwm / (1 << (8 - FAN_SOFT_PWM_BITS));
     #endif
   #endif
 
@@ -1355,7 +1398,12 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode
 		SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
 		SET_OUTPUT(FAN_PIN);
 		WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
+#ifdef FAN_SOFT_PWM
+		fanSpeedSoftPwm = 255;
+#else //FAN_SOFT_PWM
 		analogWrite(FAN_PIN, 255);
+#endif //FAN_SOFT_PWM
+
 		fanSpeed = 255;
 		delayMicroseconds(2000);
 	}
@@ -1641,11 +1689,14 @@ ISR(TIMER0_COMPB_vect)
 	if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
 #endif //SYSTEM_TIMER_2
 #endif
+  }
 #ifdef FAN_SOFT_PWM
-    soft_pwm_fan = fanSpeedSoftPwm / 2;
+  if ((pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1)) == 0)
+  {
+    soft_pwm_fan = fanSpeedSoftPwm / (1 << (8 - FAN_SOFT_PWM_BITS));
     if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
-#endif
   }
+#endif
   if(soft_pwm_0 < pwm_count)
   { 
     WRITE(HEATER_0_PIN,0);
@@ -1664,7 +1715,7 @@ ISR(TIMER0_COMPB_vect)
   if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
 #endif
 #ifdef FAN_SOFT_PWM
-  if(soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
+  if (soft_pwm_fan < (pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1))) WRITE(FAN_PIN,0);
 #endif
   
   pwm_count += (1 << SOFT_PWM_SCALE);
@@ -1851,8 +1902,8 @@ ISR(TIMER0_COMPB_vect)
 #endif
   
 #ifdef FAN_SOFT_PWM
-  if (pwm_count == 0){
-    soft_pwm_fan = fanSpeedSoftPwm / 2;
+  if ((pwm_count & ((1 << FAN_SOFT_PWM_BITS) - 1)) == 0)
+    soft_pwm_fan = fanSpeedSoftPwm / (1 << (8 - FAN_SOFT_PWM_BITS));
     if (soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
   }
   if (soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);

+ 4 - 0
Firmware/temperature.h

@@ -252,3 +252,7 @@ void check_max_temp();
 
 #endif
 
+extern unsigned long extruder_autofan_last_check;
+extern uint8_t fanSpeedBckp;
+extern bool fan_measuring;
+

+ 13 - 1
Firmware/timer02.c

@@ -4,8 +4,10 @@
 // original OVF handler is disabled
 #include <avr/io.h>
 #include <avr/interrupt.h>
-#include <Arduino.h>
+#include "Arduino.h"
+#include "io_atmega2560.h"
 
+#define BEEPER              84
 
 uint8_t timer02_pwm0 = 0;
 
@@ -154,3 +156,13 @@ void delay2(unsigned long ms)
 		}
 	}
 }
+
+void tone2(uint8_t _pin, unsigned int frequency/*, unsigned long duration*/)
+{
+	PIN_SET(BEEPER);
+}
+
+void noTone2(uint8_t _pin)
+{
+	PIN_CLR(BEEPER);
+}

+ 4 - 0
Firmware/timer02.h

@@ -24,6 +24,10 @@ extern unsigned long micros2(void);
 
 extern void delay2(unsigned long ms);
 
+extern void tone2(uint8_t _pin, unsigned int frequency/*, unsigned long duration*/);
+
+extern void noTone2(uint8_t _pin);
+
 
 #if defined(__cplusplus)
 }

+ 84 - 28
Firmware/ultralcd.cpp

@@ -9,6 +9,7 @@
 #include "temperature.h"
 #include "stepper.h"
 #include "ConfigurationStore.h"
+#include "printers.h"
 #include <string.h>
 
 
@@ -180,7 +181,9 @@ enum class testScreen
 static int  lcd_selftest_screen(testScreen screen, int _progress, int _progress_scale, bool _clear, int _delay);
 static void lcd_selftest_screen_step(int _row, int _col, int _state, const char *_name, const char *_indicator);
 static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite);
+#ifdef FANCHECK
 static bool lcd_selftest_fan_dialog(int _fan);
+#endif //FANCHECK
 static bool lcd_selftest_fsensor();
 static bool selftest_irsensor();
 static void lcd_selftest_error(int _error_no, const char *_error_1, const char *_error_2);
@@ -300,8 +303,8 @@ static void lcd_implementation_drawmenu_sdfile_selected(uint8_t row, char* longF
 				j = 0;
 				break;
             }else{
-				if (j == 1) _delay(3);	//wait around 1.2 s to start scrolling text
-				_delay(1);				//then scroll with redrawing every 300 ms 
+				if (j == 1) _delay_ms(3);	//wait around 1.2 s to start scrolling text
+				_delay_ms(1);				//then scroll with redrawing every 300 ms 
             }
 
           }
@@ -1919,7 +1922,7 @@ static void lcd_menu_extruder_info()
 	 fan_speed_RPM[1]
 	);
 
-#ifdef FILAMENT_SENSOR
+#ifdef PAT9125
 	// Display X and Y difference from Filament sensor    
     // Display Light intensity from Filament sensor
     //  Frame_Avg register represents the average brightness of all pixels within a frame (324 pixels). This
@@ -1945,7 +1948,7 @@ static void lcd_menu_extruder_info()
 			);
 		}
 	}
-#endif //FILAMENT_SENSOR
+#endif //PAT9125
     
     menu_back_if_clicked();
 }
@@ -2261,7 +2264,7 @@ static void lcd_support_menu()
   MENU_ITEM_BACK_P(STR_SEPARATOR);
   MENU_ITEM_SUBMENU_P(_i("XYZ cal. details"), lcd_menu_xyz_y_min);////MSG_XYZ_DETAILS c=19 r=1
   MENU_ITEM_SUBMENU_P(_i("Extruder info"), lcd_menu_extruder_info);////MSG_INFO_EXTRUDER c=18 r=1
-  MENU_ITEM_SUBMENU_P(_i("Show sensors"), lcd_menu_show_sensors_state);////MSG_INFO_SENSORS c=18 r=1
+  MENU_ITEM_SUBMENU_P(_i("Sensors info"), lcd_menu_show_sensors_state);////MSG_INFO_SENSORS c=18 r=1
 
 #ifdef TMC2130
   MENU_ITEM_SUBMENU_P(_i("Belt status"), lcd_menu_belt_status);////MSG_MENU_BELT_STATUS c=18 r=1
@@ -2455,9 +2458,10 @@ void lcd_wait_interact() {
 #else
   lcd_puts_P(_i("Insert filament"));////MSG_INSERT_FILAMENT c=20 r=0
 #endif
-  lcd_set_cursor(0, 2);
-  lcd_puts_P(_i("and press the knob"));////MSG_PRESS c=20 r=0
-
+  if (!fsensor_autoload_enabled) {
+	  lcd_set_cursor(0, 2);
+	  lcd_puts_P(_i("and press the knob"));////MSG_PRESS c=20 r=0
+  }
 }
 
 
@@ -3062,8 +3066,6 @@ void lcd_adjust_bed_reset(void)
 	_md->status = 0;
 }
 
-#define BED_ADJUSTMENT_UM_MAX 50
-
 void lcd_adjust_bed(void)
 {
 	_menu_data_adjust_bed_t* _md = (_menu_data_adjust_bed_t*)&(menu_data[0]);
@@ -3336,7 +3338,12 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z)
 calibrated:
     // Let the machine think the Z axis is a bit higher than it is, so it will not home into the bed
     // during the search for the induction points.
-    current_position[Z_AXIS] = Z_MAX_POS-3.f;
+	if ((PRINTER_TYPE == PRINTER_MK25) || (PRINTER_TYPE == PRINTER_MK2) || (PRINTER_TYPE == PRINTER_MK2_SNMM)) {
+		current_position[Z_AXIS] = Z_MAX_POS-3.f;
+	}
+	else {
+		current_position[Z_AXIS] = Z_MAX_POS+4.f;
+	}
     plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
     return true;
 
@@ -3806,8 +3813,8 @@ static void lcd_show_sensors_state()
 	if (mmu_enabled) {
 		finda_state = mmu_finda;
 	}
-	if (mmu_idler_sensor_detected) {
-		idler_state = !PIN_GET(MMU_IDLER_SENSOR_PIN);
+	if (ir_sensor_detected) {
+		idler_state = !PIN_GET(IR_SENSOR_PIN);
 	}
 	lcd_puts_at_P(0, 0, _i("Sensor state"));
 	lcd_puts_at_P(1, 1, _i("PINDA:"));
@@ -6582,25 +6589,31 @@ bool lcd_selftest()
 	{
 		_progress = lcd_selftest_screen(testScreen::hotendOk, _progress, 3, true, 2000); //nozzle ok
 	}
-
 #ifdef FILAMENT_SENSOR
     if (_result)
     {
-        _progress = lcd_selftest_screen(testScreen::fsensor, _progress, 3, true, 2000); //check filaments sensor
+
         if (mmu_enabled)
-        {
+        {        
+			_progress = lcd_selftest_screen(testScreen::fsensor, _progress, 3, true, 2000); //check filaments sensor
             _result = selftest_irsensor();
+		    if (_result)
+			{
+				_progress = lcd_selftest_screen(testScreen::fsensorOk, _progress, 3, true, 2000); //fil sensor OK
+			}
         } else
         {
+#ifdef PAT9125
+			_progress = lcd_selftest_screen(testScreen::fsensor, _progress, 3, true, 2000); //check filaments sensor
             _result = lcd_selftest_fsensor();
+			if (_result)
+			{
+				_progress = lcd_selftest_screen(testScreen::fsensorOk, _progress, 3, true, 2000); //fil sensor OK
+			}
+#endif //PAT9125
         }
     }
-    if (_result)
-    {
-        _progress = lcd_selftest_screen(testScreen::fsensorOk, _progress, 3, true, 2000); //fil sensor OK
-    }
-#endif // FILAMENT_SENSOR
-
+#endif //FILAMENT_SENSOR
 	if (_result)
 	{
 		_progress = lcd_selftest_screen(testScreen::allCorrect, _progress, 3, true, 5000); //all correct
@@ -7168,7 +7181,7 @@ static bool lcd_selftest_fsensor(void)
 //!  * Pre-heat to PLA extrude temperature.
 //!  * Unload filament possibly present.
 //!  * Move extruder idler same way as during filament load
-//!    and sample MMU_IDLER_SENSOR_PIN.
+//!    and sample IR_SENSOR_PIN.
 //!  * Check that pin doesn't go low.
 //!
 //! @retval true passed
@@ -7205,7 +7218,7 @@ static bool selftest_irsensor()
         mmu_load_step(false);
         while (blocks_queued())
         {
-            if (PIN_GET(MMU_IDLER_SENSOR_PIN) == 0) return false;
+            if (PIN_GET(IR_SENSOR_PIN) == 0) return false;
 #ifdef TMC2130
             manage_heater();
             // Vojtech: Don't disable motors inside the planner!
@@ -7248,7 +7261,12 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite)
 		if (check_opposite == true) lcd_puts_P(_T(MSG_SELFTEST_EXTRUDER_FAN));
 		else lcd_puts_P(_T(MSG_SELFTEST_COOLING_FAN));
 		SET_OUTPUT(FAN_PIN);
+#ifdef FAN_SOFT_PWM
+		fanSpeedSoftPwm = 255;
+#else //FAN_SOFT_PWM
 		analogWrite(FAN_PIN, 255);
+#endif //FAN_SOFT_PWM
+
 		break;
 	}
 	_delay(500);
@@ -7273,7 +7291,11 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite)
 		case 1:
 			// object cooling fan
 			SET_OUTPUT(FAN_PIN);
+#ifdef FAN_SOFT_PWM
+			fanSpeedSoftPwm = 255;
+#else //FAN_SOFT_PWM
 			analogWrite(FAN_PIN, 255);
+#endif //FAN_SOFT_PWM
 			break;
 		}
 
@@ -7306,8 +7328,11 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite)
 	SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
 	WRITE(EXTRUDER_0_AUTO_FAN_PIN, 0);
 	SET_OUTPUT(FAN_PIN);
+#ifdef FAN_SOFT_PWM
+	fanSpeedSoftPwm = 0;
+#else //FAN_SOFT_PWM
 	analogWrite(FAN_PIN, 0);
-
+#endif //FAN_SOFT_PWM
 	fanSpeed = 0;
 	manage_heater();
 
@@ -7315,20 +7340,31 @@ static bool lcd_selftest_manual_fan_check(int _fan, bool check_opposite)
 
 }
 
-
+#ifdef FANCHECK
 static bool lcd_selftest_fan_dialog(int _fan)
 {
 	bool _result = true;
 	int _errno = 7;
-
 	switch (_fan) {
 	case 0:
 		fanSpeed = 0;
 		manage_heater();			//turn off fan
 		setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, 1); //extruder fan
+#ifdef FAN_SOFT_PWM
+		extruder_autofan_last_check = _millis();
+#endif //FAN_SOFT_PWM
 		_delay(2000);				//delay_keep_alive would turn off extruder fan, because temerature is too low
+#ifdef FAN_SOFT_PWM
+		countFanSpeed();
+		if (!fan_speed[0]) _result = false;
+#else //FAN_SOFT_PWM
 		manage_heater();			//count average fan speed from 2s delay and turn off fans
 		if (!fan_speed[0]) _result = false;
+#endif //FAN_SOFT_PWM
+		
+		printf_P(PSTR("Test 1:\n"));
+		printf_P(PSTR("Print fan speed: %d \n"), fan_speed[1]);
+		printf_P(PSTR("Extr fan speed: %d \n"), fan_speed[0]);
 		//SERIAL_ECHOPGM("Extruder fan speed: ");
 		//MYSERIAL.println(fan_speed[0]);
 		//SERIAL_ECHOPGM("Print fan speed: ");
@@ -7337,7 +7373,14 @@ static bool lcd_selftest_fan_dialog(int _fan)
 
 	case 1:
 		//will it work with Thotend > 50 C ?
+#ifdef FAN_SOFT_PWM		
+		fanSpeed = 255;	
+		fanSpeedSoftPwm = 255;	
+		extruder_autofan_last_check = _millis(); //store time when measurement starts
+		fan_measuring = true; //start fan measuring, rest is on manage_heater
+#else //FAN_SOFT_PWM
 		fanSpeed = 150;				//print fan
+#endif //FAN_SOFT_PWM
 		for (uint8_t i = 0; i < 5; i++) {
 			delay_keep_alive(1000);
 			lcd_set_cursor(18, 3);
@@ -7346,15 +7389,26 @@ static bool lcd_selftest_fan_dialog(int _fan)
 			lcd_set_cursor(18, 3);
 			lcd_print("|");
 		}
+#ifdef FAN_SOFT_PWM
+		fanSpeed = 0;
+		fanSpeedSoftPwm = 0;	
+#else //FAN_SOFT_PWM
 		fanSpeed = 0;
 		manage_heater();			//turn off fan
 		manage_inactivity(true);	//to turn off print fan
+#endif //FAN_SOFT_PWM
+		printf_P(PSTR("Test 2:\n"));
+		printf_P(PSTR("Print fan speed: %d \n"), fan_speed[1]);
+		printf_P(PSTR("Extr fan speed: %d \n"), fan_speed[0]);
 		if (!fan_speed[1]) {
 			_result = false; _errno = 6; //print fan not spinning
 		}
+#ifdef FAN_SOFT_PWM 
+		else {
+#else //FAN_SOFT_PWM
 		else if (fan_speed[1] < 34) { //fan is spinning, but measured RPM are too low for print fan, it must be left extruder fan
+#endif //FAN_SOFT_PWM
 			//check fans manually
-
 			_result = lcd_selftest_manual_fan_check(1, true); //turn on print fan and check that left extruder fan is not spinning
 			if (_result) {
 				_result = lcd_selftest_manual_fan_check(1, false); //print fan is stil turned on; check that it is spinning
@@ -7378,6 +7432,8 @@ static bool lcd_selftest_fan_dialog(int _fan)
 	return _result;
 }
 
+#endif //FANCHECK
+
 static int lcd_selftest_screen(testScreen screen, int _progress, int _progress_scale, bool _clear, int _delay)
 {
 

+ 4 - 4
Firmware/util.cpp

@@ -296,14 +296,14 @@ bool show_upgrade_dialog_if_version_newer(const char *version_string)
             lcd_putc(*c);
         lcd_puts_at_P(0, 3, _i("Please upgrade."));////MSG_NEW_FIRMWARE_PLEASE_UPGRADE c=20 r=0
 if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
-        tone(BEEPER, 1000);
+        _tone(BEEPER, 1000);
         delay_keep_alive(50);
-        noTone(BEEPER);
+        _noTone(BEEPER);
         delay_keep_alive(500);
 if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
-        tone(BEEPER, 1000);
+        _tone(BEEPER, 1000);
         delay_keep_alive(50);
-        noTone(BEEPER);
+        _noTone(BEEPER);
         lcd_wait_for_click();
         lcd_update_enable(true);
         lcd_clear();

+ 3 - 0
Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h

@@ -246,6 +246,9 @@ BED SETTINGS
 #define MESH_MEAS_NUM_X_POINTS 3
 #define MESH_MEAS_NUM_Y_POINTS 3
 
+// Maximum bed level correction value
+#define BED_ADJUSTMENT_UM_MAX 100
+
 #define MESH_HOME_Z_CALIB 0.2
 #define MESH_HOME_Z_SEARCH 5 //Z lift for homing, mesh bed leveling etc.
 

+ 3 - 0
Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h

@@ -246,6 +246,9 @@ BED SETTINGS
 #define MESH_MEAS_NUM_X_POINTS 3
 #define MESH_MEAS_NUM_Y_POINTS 3
 
+// Maximum bed level correction value
+#define BED_ADJUSTMENT_UM_MAX 100
+
 #define MESH_HOME_Z_CALIB 0.2
 #define MESH_HOME_Z_SEARCH 5 //Z lift for homing, mesh bed leveling etc.
 

+ 5 - 1
Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h

@@ -111,8 +111,9 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 
 // Filament sensor
-#define PAT9125
 #define FILAMENT_SENSOR
+#define PAT9125
+
 
 #define DEBUG_DCODE3
 
@@ -301,6 +302,9 @@
 #define MESH_MEAS_NUM_X_POINTS 3
 #define MESH_MEAS_NUM_Y_POINTS 3
 
+// Maximum bed level correction value
+#define BED_ADJUSTMENT_UM_MAX 100
+
 #define MESH_HOME_Z_CALIB 0.2
 #define MESH_HOME_Z_SEARCH 5 //Z lift for homing, mesh bed leveling etc.
 

+ 5 - 1
Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h

@@ -112,8 +112,9 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 
 // Filament sensor
-#define PAT9125
 #define FILAMENT_SENSOR
+#define PAT9125
+
 
 #define DEBUG_DCODE3
 
@@ -302,6 +303,9 @@
 #define MESH_MEAS_NUM_X_POINTS 3
 #define MESH_MEAS_NUM_Y_POINTS 3
 
+// Maximum bed level correction value
+#define BED_ADJUSTMENT_UM_MAX 100
+
 #define MESH_HOME_Z_CALIB 0.2
 #define MESH_HOME_Z_SEARCH 5 //Z lift for homing, mesh bed leveling etc.
 

+ 4 - 2
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -133,8 +133,8 @@
 #define DEFAULT_SAFETYTIMER_TIME_MINS 30
 
 // Filament sensor
-#define PAT9125
 #define FILAMENT_SENSOR
+#define PAT9125
 
 // Backlash - 
 //#define BACKLASH_X
@@ -412,6 +412,9 @@
 #define MESH_MEAS_NUM_X_POINTS 3
 #define MESH_MEAS_NUM_Y_POINTS 3
 
+// Maximum bed level correction value
+#define BED_ADJUSTMENT_UM_MAX 100
+
 #define MESH_HOME_Z_CALIB 0.2
 #define MESH_HOME_Z_SEARCH 5 //Z lift for homing, mesh bed leveling etc.
 
@@ -623,7 +626,6 @@
 #define MMU_REQUIRED_FW_BUILDNR 83
 #define MMU_HWRESET
 #define MMU_DEBUG //print communication between MMU2 and printer on serial
-
 #define MMU_IDLER_SENSOR_ATTEMPTS_NR 21 //max. number of attempts to load filament if first load failed; value for max bowden length and case when loading fails right at the beginning
 
 #endif //__CONFIGURATION_PRUSA_H