Просмотр исходного кода

Merge branch 'MK3_3.9.0' into flashair_display_ip

odaki 4 лет назад
Родитель
Сommit
a1254b3a3c

+ 2 - 2
Firmware/Configuration.h

@@ -16,8 +16,8 @@ extern uint16_t nPrinterType;
 extern PGM_P sPrinterName;
 
 // Firmware version
-#define FW_VERSION "3.9.0-RC2"
-#define FW_COMMIT_NR   3398
+#define FW_VERSION "3.9.0-RC3"
+#define FW_COMMIT_NR   3401
 // FW_VERSION_UNKNOWN means this is an unofficial build.
 // The firmware should only be checked into github with this symbol.
 #define FW_DEV_VERSION FW_VERSION_UNKNOWN

+ 42 - 14
Firmware/Marlin_main.cpp

@@ -9448,13 +9448,13 @@ static void handleSafetyTimer()
 }
 #endif //SAFETYTIMER
 
-#define FS_CHECK_COUNT 15
+#define FS_CHECK_COUNT 250
 void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h
 {
 #ifdef FILAMENT_SENSOR
 bool bInhibitFlag;
 #ifdef IR_SENSOR_ANALOG
-static uint8_t nFSCheckCount=0;
+static uint16_t nFSCheckCount=0;
 #endif // IR_SENSOR_ANALOG
 
 	if (mmu_enabled == false)
@@ -9474,25 +9474,53 @@ static uint8_t nFSCheckCount=0;
 			if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LcdCommands::Layer1Cal) && ! eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))
 			{
 #ifdef IR_SENSOR_ANALOG
-                    bool bTemp=current_voltage_raw_IR>IRsensor_Hmin_TRESHOLD;
-                    bTemp=bTemp&&current_voltage_raw_IR<IRsensor_Hopen_TRESHOLD;
-                    bTemp=bTemp&&(!CHECK_ALL_HEATERS);
-                    bTemp=bTemp&&(menu_menu==lcd_status_screen);
-                    bTemp=bTemp&&((oFsensorPCB==ClFsensorPCB::_Old)||(oFsensorPCB==ClFsensorPCB::_Undef));
-                    bTemp=bTemp&&fsensor_enabled;
-                    if(bTemp)
-                    {
+				static uint16_t minVolt = Voltage2Raw(6.F), maxVolt = 0;
+				// detect min-max, some long term sliding window for filtration may be added
+				// avoiding floating point operations, thus computing in raw
+				if( current_voltage_raw_IR > maxVolt )maxVolt = current_voltage_raw_IR;
+				if( current_voltage_raw_IR < minVolt )minVolt = current_voltage_raw_IR;
+				
+#if 0
+				{ // debug print
+					static uint16_t lastVolt = ~0U;
+					if( current_voltage_raw_IR != lastVolt ){
+						printf_P(PSTR("fs volt=%4.2fV (min=%4.2f max=%4.2f)\n"), Raw2Voltage(current_voltage_raw_IR), Raw2Voltage(minVolt), Raw2Voltage(maxVolt) );
+						lastVolt = current_voltage_raw_IR;
+					}
+				}
+#endif
+				// the trouble is, I can hold the filament in the hole in such a way, that it creates the exact voltage
+				// to be detected as the new fsensor
+				// We can either fake it by extending the detection window to a looooong time
+				// or do some other countermeasures
+				
+				// what we want to detect:
+				// if minvolt gets below ~0.6V, it means there is an old fsensor
+				// if maxvolt gets above 4.6V, it means we either have an old fsensor or broken cables/fsensor
+				// So I'm waiting for a situation, when minVolt gets to range <0, 0.7> and maxVolt gets into range <4.4, 5>
+				// If and only if minVolt is in range <0.6, 0.7> and maxVolt is in range <4.4, 4.5>, I'm considering a situation with the new fsensor
+				// otherwise, I don't care
+				
+				if( minVolt >= Voltage2Raw(0.3F) && minVolt <= Voltage2Raw(0.5F) 
+				 && maxVolt >= Voltage2Raw(4.2F) && maxVolt <= Voltage2Raw(4.6F)
+				){
+                    bool bTemp = (!CHECK_ALL_HEATERS);
+                    bTemp = bTemp && (menu_menu==lcd_status_screen);
+                    bTemp = bTemp && ((oFsensorPCB==ClFsensorPCB::_Old)||(oFsensorPCB==ClFsensorPCB::_Undef));
+                    bTemp = bTemp && fsensor_enabled;
+                    if(bTemp){
                          nFSCheckCount++;
-                         if(nFSCheckCount>FS_CHECK_COUNT)
-                         {
+                         if(nFSCheckCount>FS_CHECK_COUNT){
                               nFSCheckCount=0;    // not necessary
                               oFsensorPCB=ClFsensorPCB::_Rev04;
                               eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
                               printf_IRSensorAnalogBoardChange(true);
                               lcd_setstatuspgm(_i("FS v0.4 or newer"));
                          }
-                    }
-                    else nFSCheckCount=0;
+                    } else {
+						nFSCheckCount=0;
+					}
+				}
 #endif // IR_SENSOR_ANALOG
 				if (fsensor_check_autoload())
 				{

+ 50 - 26
Firmware/fsensor.cpp

@@ -174,39 +174,46 @@ void fsensor_init(void)
 {
 #ifdef PAT9125
 	uint8_t pat9125 = pat9125_init();
-     printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
+	printf_P(PSTR("PAT9125_init:%hhu\n"), pat9125);
 #endif //PAT9125
-	uint8_t fsensor = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
+	uint8_t fsensor_enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
 	fsensor_autoload_enabled=eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
-     fsensor_not_responding = false;
+	fsensor_not_responding = false;
 #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_set_axis_steps_per_unit(cs.axis_steps_per_unit[E_AXIS]);
-
-	if (!pat9125)
-	{
-		fsensor = 0; //disable sensor
+	fsensor_set_axis_steps_per_unit(cs.axis_steps_per_unit[E_AXIS]);
+	
+	if (!pat9125){
+		fsensor_enabled = 0; //disable sensor
 		fsensor_not_responding = true;
 	}
 #endif //PAT9125
 #ifdef 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);
+	bIRsensorStateFlag=false;
+	oFsensorPCB = (ClFsensorPCB)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_PCB);
+	oFsensorActionNA = (ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA);
+
+	// If the fsensor is not responding even at the start of the printer,
+	// set this flag accordingly to show N/A in Settings->Filament sensor.
+	// This is even valid for both fsensor board revisions (0.3 or older and 0.4).
+	// Must be done after reading what type of fsensor board we have
+	fsensor_not_responding = ! fsensor_IR_check();
 #endif //IR_SENSOR_ANALOG
-	if (fsensor)
+	if (fsensor_enabled){
 		fsensor_enable(false);                  // (in this case) EEPROM update is not necessary
-	else
+	} else {
 		fsensor_disable(false);                 // (in this case) EEPROM update is not necessary
+	}
 	printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED")));
 #ifdef IR_SENSOR_ANALOG
-     printf_P(PSTR(" (sensor board revision: %S)\n"),(oFsensorPCB==ClFsensorPCB::_Rev04) ? MSG_04_OR_NEWER : MSG_03_OR_OLDER);
+     printf_P(PSTR(" (sensor board revision:%S)\n"), (oFsensorPCB==ClFsensorPCB::_Rev04) ? _T(MSG_04_OR_NEWER) : _T(MSG_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(bool bUpdateEEPROM)
@@ -691,12 +698,16 @@ void fsensor_update(void)
                               ADCSRB=nMUX2;
                               ENABLE_TEMPERATURE_INTERRUPT();
                               // end of sequence for ...
-                              if((oFsensorPCB==ClFsensorPCB::_Rev04)&&((nADC*OVERSAMPLENR)>((int)IRsensor_Hopen_TRESHOLD)))
+							  // Detection of correct function of fsensor v04 - it must NOT read >4.6V
+							  // If it does, it means a disconnected cables or faulty board
+                              if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) )
                               {
                                    fsensor_disable();
                                    fsensor_not_responding = true;
                                    printf_P(PSTR("IR sensor not responding (%d)!\n"),1);
-                                   if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause)
+								   if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause)
+
+								   // if we are printing and FS action is set to "Pause", force pause the print
                                    if(oFsensorActionNA==ClFsensorActionNA::_Pause)
                                         lcd_pause_print();
                               }
@@ -720,14 +731,27 @@ void fsensor_update(void)
 }
 
 #ifdef IR_SENSOR_ANALOG
-bool fsensor_IR_check()
-{
-uint16_t volt_IR_int;
-bool bCheckResult;
+/// This is called only upon start of the printer or when switching the fsensor ON in the menu
+/// We cannot do temporal window checks here (aka the voltage has been in some range for a period of time)
+bool fsensor_IR_check(){
+	if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){
+		// If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly.
+		// Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way,
+		// that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual
+		// and would have been considered more like a sabotage than normal printer operation
+		printf_P(PSTR("fsensor in forbidden range 1.5-3V - bad lever\n"));
+		return false; 
+	}
+	
+	if( oFsensorPCB == ClFsensorPCB::_Rev04 ){
+		// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount
+		if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){
+			printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n"));
+			return false;
+		}
+	}
 
-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::_Rev04)&&(volt_IR_int>((int)IRsensor_Hopen_TRESHOLD))));
-return(bCheckResult);
+	// otherwise the IR fsensor is considered working correctly
+	return true;
 }
 #endif //IR_SENSOR_ANALOG

+ 1 - 1
Firmware/temperature.cpp

@@ -74,7 +74,7 @@ int current_voltage_raw_bed = 0;
 #endif
 
 #ifdef IR_SENSOR_ANALOG
-int current_voltage_raw_IR = 0;
+uint16_t current_voltage_raw_IR = 0;
 #endif //IR_SENSOR_ANALOG
 
 int current_temperature_bed_raw = 0;

+ 1 - 1
Firmware/temperature.h

@@ -79,7 +79,7 @@ extern int current_voltage_raw_bed;
 #endif
 
 #ifdef IR_SENSOR_ANALOG
-extern int current_voltage_raw_IR;
+extern uint16_t current_voltage_raw_IR;
 #endif //IR_SENSOR_ANALOG
 
 #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1

+ 19 - 20
Firmware/ultralcd.cpp

@@ -1981,8 +1981,7 @@ static void lcd_menu_voltages()
     lcd_home();
     lcd_printf_P(PSTR(" PWR:      %4.1fV\n" " BED:      %4.1fV"), volt_pwr, volt_bed);
 #ifdef 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);
+    lcd_printf_P(PSTR("\n IR :       %3.1fV"), Raw2Voltage(current_voltage_raw_IR));
 #endif //IR_SENSOR_ANALOG
     menu_back_if_clicked();
 }
@@ -2169,10 +2168,10 @@ static void lcd_support_menu()
   switch(oFsensorPCB)
        {
        case ClFsensorPCB::_Old:
-            MENU_ITEM_BACK_P(MSG_03_OR_OLDER);
+            MENU_ITEM_BACK_P(_T(MSG_03_OR_OLDER));
             break;
        case ClFsensorPCB::_Rev04:
-            MENU_ITEM_BACK_P(MSG_04_OR_NEWER);
+            MENU_ITEM_BACK_P(_T(MSG_04_OR_NEWER));
             break;
        case ClFsensorPCB::_Undef:
        default:
@@ -7512,37 +7511,33 @@ void lcd_belttest()
 #ifdef IR_SENSOR_ANALOG
 // called also from marlin_main.cpp
 void printf_IRSensorAnalogBoardChange(bool bPCBrev04){
-    printf_P(PSTR("Filament sensor board change detected: revision %S\n"), bPCBrev04 ? MSG_04_OR_NEWER : MSG_03_OR_OLDER);
+    printf_P(PSTR("Filament sensor board change detected: revision%S\n"), bPCBrev04 ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER));
 }
 
 static bool lcd_selftest_IRsensor(bool bStandalone)
 {
-    bool bAction;
     bool bPCBrev04;
     uint16_t volt_IR_int;
-    float volt_IR;
 
-    volt_IR_int=current_voltage_raw_IR;
-    bPCBrev04=(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)){
+    volt_IR_int = current_voltage_raw_IR;
+    bPCBrev04=(volt_IR_int < IRsensor_Hopen_TRESHOLD);
+    printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"), Raw2Voltage(volt_IR_int) );
+    if(volt_IR_int < IRsensor_Hmin_TRESHOLD){
         if(!bStandalone)
             lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
         return(false);
     }
     lcd_show_fullscreen_message_and_wait_P(_i("Insert the filament (do not load it) into the 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)){
+    volt_IR_int = current_voltage_raw_IR;
+    printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"), Raw2Voltage(volt_IR_int));
+    if(volt_IR_int > (IRsensor_Lmax_TRESHOLD)){
         if(!bStandalone)
             lcd_selftest_error(TestError::FsensorLevel,"LOW","");
         return(false);
     }
-    if((bPCBrev04?1:0)!=(uint8_t)oFsensorPCB){        // safer then "(uint8_t)bPCBrev04"
+    if((bPCBrev04 ? 1 : 0) != (uint8_t)oFsensorPCB){        // safer then "(uint8_t)bPCBrev04"
         printf_IRSensorAnalogBoardChange(bPCBrev04);
-        oFsensorPCB=bPCBrev04?ClFsensorPCB::_Rev04:ClFsensorPCB::_Old;
+        oFsensorPCB=bPCBrev04 ? ClFsensorPCB::_Rev04 : ClFsensorPCB::_Old;
         eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB);
     }
     return(true);
@@ -7558,10 +7553,14 @@ static void lcd_detect_IRsensor(){
         return;
     }
     bAction = lcd_selftest_IRsensor(true);
-    if(bAction)
+	if(bAction){
         lcd_show_fullscreen_message_and_wait_P(_i("Sensor verified, remove the filament now."));
-    else
+		// the fsensor board has been successfully identified, any previous "not responding" may be cleared now
+		fsensor_not_responding = false;
+    } else {
         lcd_show_fullscreen_message_and_wait_P(_i("Verification failed, remove the filament and try again."));
+		// here it is unclear what to to with the fsensor_not_responding flag
+	}
     bMenuFSDetect=false;                              // de-inhibits some code inside "manage_inactivity()"
 }
 #endif //IR_SENSOR_ANALOG

+ 13 - 4
Firmware/ultralcd.h

@@ -259,10 +259,19 @@ void lcd_wizard(WizState state);
 
 #define VOLT_DIV_REF 5
 #ifdef 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
+constexpr uint16_t Voltage2Raw(float V){
+	return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F;
+}
+constexpr float Raw2Voltage(uint16_t raw){
+	return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) );
+}
+constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821
+constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910
+constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059
+constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982
+constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368
+
+
 #endif //IR_SENSOR_ANALOG
 
 #endif //ULTRALCD_H