diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 799e5e9d..c8558b8a 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -9451,7 +9451,32 @@ static void handleSafetyTimer() } #endif //SAFETYTIMER -#define FS_CHECK_COUNT 250 +#ifdef IR_SENSOR_ANALOG +#define FS_CHECK_COUNT 16 +/// Switching mechanism of the fsensor type. +/// Called from 2 spots which have a very similar behavior +/// 1: ClFsensorPCB::_Old -> ClFsensorPCB::_Rev04 and print _i("FS v0.4 or newer") +/// 2: ClFsensorPCB::_Rev04 -> oFsensorPCB=ClFsensorPCB::_Old and print _i("FS v0.3 or older") +void manage_inactivity_IR_ANALOG_Check(uint16_t &nFSCheckCount, ClFsensorPCB isVersion, ClFsensorPCB switchTo, const char *statusLineTxt_P) { + bool bTemp = (!CHECK_ALL_HEATERS); + bTemp = bTemp && (menu_menu == lcd_status_screen); + bTemp = bTemp && ((oFsensorPCB == isVersion) || (oFsensorPCB == ClFsensorPCB::_Undef)); + bTemp = bTemp && fsensor_enabled; + if (bTemp) { + nFSCheckCount++; + if (nFSCheckCount > FS_CHECK_COUNT) { + nFSCheckCount = 0; // not necessary + oFsensorPCB = switchTo; + eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_PCB, (uint8_t)oFsensorPCB); + printf_IRSensorAnalogBoardChange(); + lcd_setstatuspgm(statusLineTxt_P); + } + } else { + nFSCheckCount = 0; + } +} +#endif + void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h { #ifdef FILAMENT_SENSOR @@ -9464,15 +9489,15 @@ static uint16_t nFSCheckCount=0; { //-// if (mcode_in_progress != 600) //M600 not in progress #ifdef PAT9125 - bInhibitFlag=(menu_menu==lcd_menu_extruder_info); // Support::ExtruderInfo menu active + bInhibitFlag=(menu_menu==lcd_menu_extruder_info); // Support::ExtruderInfo menu active #endif // PAT9125 #ifdef IR_SENSOR - bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active + bInhibitFlag=(menu_menu==lcd_menu_show_sensors_state); // Support::SensorInfo menu active #ifdef IR_SENSOR_ANALOG - bInhibitFlag=bInhibitFlag||bMenuFSDetect; // Settings::HWsetup::FSdetect menu active + bInhibitFlag=bInhibitFlag||bMenuFSDetect; // Settings::HWsetup::FSdetect menu active #endif // IR_SENSOR_ANALOG #endif // IR_SENSOR - if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active + if ((mcode_in_progress != 600) && (eFilamentAction != FilamentAction::AutoLoad) && (!bInhibitFlag)) //M600 not in progress, preHeat @ autoLoad menu not active, Support::ExtruderInfo/SensorInfo menu not active { if (!moves_planned() && !IS_SD_PRINTING && !is_usb_printing && (lcd_commands_type != LcdCommands::Layer1Cal) && ! eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)) { @@ -9483,7 +9508,7 @@ static uint16_t nFSCheckCount=0; if( current_voltage_raw_IR > maxVolt )maxVolt = current_voltage_raw_IR; if( current_voltage_raw_IR < minVolt )minVolt = current_voltage_raw_IR; -#if 0 +#if 0 // Start: IR Sensor debug info { // debug print static uint16_t lastVolt = ~0U; if( current_voltage_raw_IR != lastVolt ){ @@ -9491,38 +9516,29 @@ static uint16_t nFSCheckCount=0; lastVolt = current_voltage_raw_IR; } } -#endif - // the trouble is, I can hold the filament in the hole in such a way, that it creates the exact voltage - // to be detected as the new fsensor - // We can either fake it by extending the detection window to a looooong time - // or do some other countermeasures +#endif // End: IR Sensor debug info + //! The trouble is, I can hold the filament in the hole in such a way, that it creates the exact voltage + //! to be detected as the new fsensor + //! We can either fake it by extending the detection window to a looooong time + //! or do some other countermeasures - // what we want to detect: - // if minvolt gets below ~0.6V, it means there is an old fsensor - // if maxvolt gets above 4.6V, it means we either have an old fsensor or broken cables/fsensor - // So I'm waiting for a situation, when minVolt gets to range <0, 0.7> and maxVolt gets into range <4.4, 5> - // If and only if minVolt is in range <0.6, 0.7> and maxVolt is in range <4.4, 4.5>, I'm considering a situation with the new fsensor - // otherwise, I don't care - - if( minVolt >= Voltage2Raw(0.3F) && minVolt <= Voltage2Raw(0.5F) - && maxVolt >= Voltage2Raw(4.2F) && maxVolt <= Voltage2Raw(4.6F) + //! what we want to detect: + //! if minvolt gets below ~0.3V, it means there is an old fsensor + //! if maxvolt gets above 4.6V, it means we either have an old fsensor or broken cables/fsensor + //! So I'm waiting for a situation, when minVolt gets to range <0, 1.5> and maxVolt gets into range <3.0, 5> + //! If and only if minVolt is in range <0.3, 1.5> and maxVolt is in range <3.0, 4.6>, I'm considering a situation with the new fsensor + if( minVolt >= IRsensor_Ldiode_TRESHOLD && minVolt <= IRsensor_Lmax_TRESHOLD + && maxVolt >= IRsensor_Hmin_TRESHOLD && maxVolt <= IRsensor_Hopen_TRESHOLD ){ - bool bTemp = (!CHECK_ALL_HEATERS); - bTemp = bTemp && (menu_menu==lcd_status_screen); - bTemp = bTemp && ((oFsensorPCB==ClFsensorPCB::_Old)||(oFsensorPCB==ClFsensorPCB::_Undef)); - bTemp = bTemp && fsensor_enabled; - if(bTemp){ - nFSCheckCount++; - if(nFSCheckCount>FS_CHECK_COUNT){ - nFSCheckCount=0; // not necessary - oFsensorPCB=ClFsensorPCB::_Rev04; - eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB); - printf_IRSensorAnalogBoardChange(true); - lcd_setstatuspgm(_i("FS v0.4 or newer"));////c=18 - } - } else { - nFSCheckCount=0; - } + manage_inactivity_IR_ANALOG_Check(nFSCheckCount, ClFsensorPCB::_Old, ClFsensorPCB::_Rev04, _i("FS v0.4 or newer") ); ////c=18 + } + //! If and only if minVolt is in range <0.0, 0.3> and maxVolt is in range <4.6, 5.0V>, I'm considering a situation with the old fsensor + //! Note, we are not relying on one voltage here - getting just +5V can mean an old fsensor or a broken new sensor - that's why + //! we need to have both voltages detected correctly to allow switching back to the old fsensor. + else if( minVolt < IRsensor_Ldiode_TRESHOLD + && maxVolt > IRsensor_Hopen_TRESHOLD && maxVolt <= IRsensor_VMax_TRESHOLD + ){ + manage_inactivity_IR_ANALOG_Check(nFSCheckCount, ClFsensorPCB::_Rev04, oFsensorPCB=ClFsensorPCB::_Old, _i("FS v0.3 or older")); ////c=18 } #endif // IR_SENSOR_ANALOG if (fsensor_check_autoload()) @@ -9533,7 +9549,7 @@ static uint16_t nFSCheckCount=0; //-// if (degHotend0() > EXTRUDE_MINTEMP) if(0) { - Sound_MakeCustom(50,1000,false); + Sound_MakeCustom(50,1000,false); loading_flag = true; enquecommand_front_P((PSTR("M701"))); } @@ -9544,20 +9560,17 @@ if(0) show_preheat_nozzle_warning(); lcd_update_enable(true); */ - eFilamentAction=FilamentAction::AutoLoad; - bFilamentFirstRun=false; - if(target_temperature[0]>=EXTRUDE_MINTEMP) - { - bFilamentPreheatState=true; -// mFilamentItem(target_temperature[0],target_temperature_bed); - menu_submenu(mFilamentItemForce); - } - else - { - menu_submenu(lcd_generic_preheat_menu); - lcd_timeoutToStatus.start(); - } - } + eFilamentAction=FilamentAction::AutoLoad; + bFilamentFirstRun=false; + if(target_temperature[0]>=EXTRUDE_MINTEMP){ + bFilamentPreheatState=true; +// mFilamentItem(target_temperature[0],target_temperature_bed); + menu_submenu(mFilamentItemForce); + } else { + menu_submenu(lcd_generic_preheat_menu); + lcd_timeoutToStatus.start(); + } + } } } else diff --git a/Firmware/eeprom.h b/Firmware/eeprom.h index 61e078fc..89d7e7f9 100644 --- a/Firmware/eeprom.h +++ b/Firmware/eeprom.h @@ -341,8 +341,9 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP | 0x0D9F 3487 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - bed temp | ^ | D3 Ax0d9f C1 | 0x0DA0 3488 | uint8 | ^ | 00h 0 | ffh 255 | 8th sheet - PINDA temp | ^ | D3 Ax0da0 C1 | 0x0DA1 3489 | uint8 | ??? | 00h 0 | ffh 255 | ??? | ??? | D3 Ax0da1 C1 -| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ??? | ffh 255 | Filament Sensor type old vs new | ??? | D3 Ax0d48 C1 -| ^ | ^ | ^ | ??? | ^ | Filament Sensor type ??? | ^ | ^ +| 0x0D48 3400 | uint8 | EEPROM_FSENSOR_PCB | ffh 255 | ffh 255 | Filament Sensor type IR unknown | LCD Support | D3 Ax0d48 C1 +| ^ | ^ | ^ | 00h 0 | ^ | Filament Sensor type IR 0.3 or older | ^ | ^ +| ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor type IR 0.4 or newer | ^ | ^ | 0x0D47 3399 | uint8 | EEPROM_FSENSOR_ACTION_NA | 00h 0 | ffh 255 | Filament Sensor action: __Continue__ | LCD menu | D3 Ax0d47 C1 | ^ | ^ | ^ | 01h 1 | ^ | Filament Sensor action: __Pause__ | ^ | ^ | 0x0D37 3383 | float | EEPROM_UVLO_SAVED_TARGET | ??? | ff ff ff ffh | Power panic saved target all-axis | ??? | D3 Ax0d37 C16 diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp index f5fc768a..2753ede0 100755 --- a/Firmware/fsensor.cpp +++ b/Firmware/fsensor.cpp @@ -170,6 +170,21 @@ void fsensor_checkpoint_print(void) restore_print_from_ram_and_continue(0); } +#ifdef IR_SENSOR_ANALOG +const char* FsensorIRVersionText() +{ + switch(oFsensorPCB) + { + case ClFsensorPCB::_Old: + return _T(MSG_IR_03_OR_OLDER); + case ClFsensorPCB::_Rev04: + return _T(MSG_IR_04_OR_NEWER); + default: + return _T(MSG_IR_UNKNOWN); + } +} +#endif //IR_SENSOR_ANALOG + void fsensor_init(void) { #ifdef PAT9125 @@ -207,9 +222,9 @@ void fsensor_init(void) } printf_P(PSTR("FSensor %S"), (fsensor_enabled?PSTR("ENABLED"):PSTR("DISABLED"))); #ifdef IR_SENSOR_ANALOG - printf_P(PSTR(" (sensor board revision:%S)\n"), (oFsensorPCB==ClFsensorPCB::_Rev04) ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER)); + printf_P(PSTR(" (sensor board revision:%S)\n"), FsensorIRVersionText()); #else //IR_SENSOR_ANALOG - printf_P(PSTR("\n")); + MYSERIAL.println(); #endif //IR_SENSOR_ANALOG if (check_for_ir_sensor()){ ir_sensor_detected = true; @@ -611,15 +626,15 @@ void fsensor_enque_M600(){ void fsensor_update(void) { #ifdef PAT9125 - if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX)) - { - fsensor_stop_and_save_print(); + if (fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX)) + { + fsensor_stop_and_save_print(); KEEPALIVE_STATE(IN_HANDLER); - bool autoload_enabled_tmp = fsensor_autoload_enabled; - fsensor_autoload_enabled = false; - bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled; - fsensor_oq_meassure_enabled = true; + bool autoload_enabled_tmp = fsensor_autoload_enabled; + fsensor_autoload_enabled = false; + bool oq_meassure_enabled_tmp = fsensor_oq_meassure_enabled; + fsensor_oq_meassure_enabled = true; // move the nozzle away while checking the filament current_position[Z_AXIS] += 0.8; @@ -629,24 +644,23 @@ void fsensor_update(void) // check the filament in isolation fsensor_reset_err_cnt(); - fsensor_oq_meassure_start(0); + fsensor_oq_meassure_start(0); float e_tmp = current_position[E_AXIS]; current_position[E_AXIS] -= 3; plan_buffer_line_curposXYZE(250/60); current_position[E_AXIS] = e_tmp; plan_buffer_line_curposXYZE(200/60); st_synchronize(); - fsensor_oq_meassure_stop(); + fsensor_oq_meassure_stop(); - bool err = false; - err |= (fsensor_err_cnt > 0); // final error count is non-zero - err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit - err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit + bool err = false; + err |= (fsensor_err_cnt > 0); // final error count is non-zero + err |= (fsensor_oq_er_sum > FSENSOR_OQ_MAX_ES); // total error count is above limit + err |= (fsensor_oq_yd_sum < FSENSOR_OQ_MIN_YD); // total measured distance is below limit fsensor_restore_print_and_continue(); fsensor_autoload_enabled = autoload_enabled_tmp; fsensor_oq_meassure_enabled = oq_meassure_enabled_tmp; - unsigned long now = _millis(); if (!err && (now - fsensor_softfail_last) > FSENSOR_SOFTERR_DELTA) fsensor_softfail_ccnt = 0; @@ -663,70 +677,70 @@ void fsensor_update(void) fsensor_softfail_last = 0; fsensor_enque_M600(); } - } + } #else //PAT9125 - if (CHECK_FSENSOR && ir_sensor_detected) + if (CHECK_FSENSOR && ir_sensor_detected) { - if(digitalRead(IR_SENSOR_PIN)) - { // IR_SENSOR_PIN ~ H + if(digitalRead(IR_SENSOR_PIN)) + { // IR_SENSOR_PIN ~ H #ifdef IR_SENSOR_ANALOG - if(!bIRsensorStateFlag) + if(!bIRsensorStateFlag) + { + bIRsensorStateFlag=true; + nIRsensorLastTime=_millis(); + } + else + { + if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY) { - bIRsensorStateFlag=true; - nIRsensorLastTime=_millis(); - } - else - { - if((_millis()-nIRsensorLastTime)>IR_SENSOR_STEADY) - { - uint8_t nMUX1,nMUX2; - uint16_t nADC; - bIRsensorStateFlag=false; - // sequence for direct data reading from AD converter - DISABLE_TEMPERATURE_INTERRUPT(); - nMUX1=ADMUX; // ADMUX saving - nMUX2=ADCSRB; - adc_setmux(VOLT_IR_PIN); - ADCSRA|=(1<4.6V - // If it does, it means a disconnected cables or faulty board - if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) ) - { - fsensor_disable(); - fsensor_not_responding = true; - printf_P(PSTR("IR sensor not responding (%d)!\n"),1); - if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause) + uint8_t nMUX1,nMUX2; + uint16_t nADC; + bIRsensorStateFlag=false; + // sequence for direct data reading from AD converter + DISABLE_TEMPERATURE_INTERRUPT(); + nMUX1=ADMUX; // ADMUX saving + nMUX2=ADCSRB; + adc_setmux(VOLT_IR_PIN); + ADCSRA|=(1<4.6V + // If it does, it means a disconnected cables or faulty board + if( (oFsensorPCB == ClFsensorPCB::_Rev04) && ( (nADC*OVERSAMPLENR) > IRsensor_Hopen_TRESHOLD ) ) + { + fsensor_disable(); + fsensor_not_responding = true; + printf_P(PSTR("IR sensor not responding (%d)!\n"),1); + if((ClFsensorActionNA)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA)==ClFsensorActionNA::_Pause) - // if we are printing and FS action is set to "Pause", force pause the print - if(oFsensorActionNA==ClFsensorActionNA::_Pause) - lcd_pause_print(); - } - else - { + // if we are printing and FS action is set to "Pause", force pause the print + if(oFsensorActionNA==ClFsensorActionNA::_Pause) + lcd_pause_print(); + } + else + { #endif //IR_SENSOR_ANALOG - fsensor_checkpoint_print(); - fsensor_enque_M600(); + fsensor_checkpoint_print(); + fsensor_enque_M600(); #ifdef IR_SENSOR_ANALOG - } - } + } } - } - else - { // IR_SENSOR_PIN ~ L - bIRsensorStateFlag=false; + } + } + else + { // IR_SENSOR_PIN ~ L + bIRsensorStateFlag=false; #endif //IR_SENSOR_ANALOG - } - } + } + } #endif //PAT9125 } @@ -734,24 +748,36 @@ void fsensor_update(void) /// This is called only upon start of the printer or when switching the fsensor ON in the menu /// We cannot do temporal window checks here (aka the voltage has been in some range for a period of time) bool fsensor_IR_check(){ - if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){ - // If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly. - // Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way, - // that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual - // and would have been considered more like a sabotage than normal printer operation - printf_P(PSTR("fsensor in forbidden range 1.5-3V - bad lever\n")); - return false; - } - - if( oFsensorPCB == ClFsensorPCB::_Rev04 ){ - // newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount - if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){ - printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n")); - return false; - } - } - - // otherwise the IR fsensor is considered working correctly - return true; + if( IRsensor_Lmax_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_Hmin_TRESHOLD ){ + /// If the voltage is in forbidden range, the fsensor is ok, but the lever is mounted improperly. + /// Or the user is so creative so that he can hold a piece of fillament in the hole in such a genius way, + /// that the IR fsensor reading is within 1.5 and 3V ... this would have been highly unusual + /// and would have been considered more like a sabotage than normal printer operation + printf_P(PSTR("fsensor in forbidden range 1.5-3V - check sensor\n")); + return false; + } + if( oFsensorPCB == ClFsensorPCB::_Rev04 ){ + /// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount + if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){ + printf_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected\n")); + return false; + } + /// newer IR sensor cannot normally produce 0-0.3V, this is considered a failure +#if 0 //Disabled as it has to be decided if we gonna use this or not. + if( IRsensor_Hopen_TRESHOLD <= current_voltage_raw_IR && current_voltage_raw_IR <= IRsensor_VMax_TRESHOLD ){ + printf_P(PSTR("fsensor v0.4 in fault range 0.0-0.3V - wrong IR sensor\n")); + return false; + } +#endif + } + /// If IR sensor is "uknown state" and filament is not loaded > 1.5V return false +#if 0 + if( (oFsensorPCB == ClFsensorPCB::_Undef) && ( current_voltage_raw_IR > IRsensor_Lmax_TRESHOLD ) ){ + printf_P(PSTR("Unknown IR sensor version and no filament loaded detected.\n")); + return false; + } +#endif + // otherwise the IR fsensor is considered working correctly + return true; } #endif //IR_SENSOR_ANALOG diff --git a/Firmware/fsensor.h b/Firmware/fsensor.h index 4038d6b6..7eb09ab8 100755 --- a/Firmware/fsensor.h +++ b/Firmware/fsensor.h @@ -83,6 +83,7 @@ extern uint8_t fsensor_log; //! @} #endif //PAT9125 +#define VOLT_DIV_REF 5 #ifdef IR_SENSOR_ANALOG #define IR_SENSOR_STEADY 10 // [ms] @@ -103,8 +104,21 @@ enum class ClFsensorActionNA:uint_least8_t extern ClFsensorPCB oFsensorPCB; extern ClFsensorActionNA oFsensorActionNA; +extern const char* FsensorIRVersionText(); extern bool fsensor_IR_check(); +constexpr uint16_t Voltage2Raw(float V){ + return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F; +} +constexpr float Raw2Voltage(uint16_t raw){ + return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) ); +} +constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982 +constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910 +constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821 +constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059 +constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368 + #endif //IR_SENSOR_ANALOG #endif //FSENSOR_H diff --git a/Firmware/messages.c b/Firmware/messages.c index 9c31c126..be613cab 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -140,8 +140,9 @@ const char MSG_DIM[] PROGMEM_I1 = ISTR("Dim"); ////c=6 const char MSG_AUTO[] PROGMEM_I1 = ISTR("Auto"); ////c=6 #ifdef IR_SENSOR_ANALOG // Beware - the space at the beginning is necessary since it is reused in LCD menu items which are to be with a space -const char MSG_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");////c=18 -const char MSG_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////c=18 +const char MSG_IR_04_OR_NEWER[] PROGMEM_I1 = ISTR(" 0.4 or newer");////c=18 +const char MSG_IR_03_OR_OLDER[] PROGMEM_I1 = ISTR(" 0.3 or older");////c=18 +const char MSG_IR_UNKNOWN[] PROGMEM_I1 = ISTR("unknown state");////c=18 #endif //not internationalized messages diff --git a/Firmware/messages.h b/Firmware/messages.h index 599f1d1f..4653c869 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -139,8 +139,9 @@ extern const char MSG_BRIGHT[]; extern const char MSG_DIM[]; extern const char MSG_AUTO[]; #ifdef IR_SENSOR_ANALOG -extern const char MSG_04_OR_NEWER[]; -extern const char MSG_03_OR_OLDER[]; +extern const char MSG_IR_04_OR_NEWER[]; +extern const char MSG_IR_03_OR_OLDER[]; +extern const char MSG_IR_UNKNOWN[]; #endif //not internationalized messages diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index e32b6ad1..ce312389 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -2166,18 +2166,7 @@ static void lcd_support_menu() #ifdef IR_SENSOR_ANALOG MENU_ITEM_BACK_P(STR_SEPARATOR); MENU_ITEM_BACK_P(PSTR("Fil. sensor v.:")); - switch(oFsensorPCB) - { - case ClFsensorPCB::_Old: - MENU_ITEM_BACK_P(_T(MSG_03_OR_OLDER)); - break; - case ClFsensorPCB::_Rev04: - MENU_ITEM_BACK_P(_T(MSG_04_OR_NEWER)); - break; - case ClFsensorPCB::_Undef: - default: - MENU_ITEM_BACK_P(PSTR(" unknown state")); - } + MENU_ITEM_BACK_P(FsensorIRVersionText()); #endif // IR_SENSOR_ANALOG MENU_ITEM_BACK_P(STR_SEPARATOR); @@ -5725,7 +5714,9 @@ void lcd_hw_setup_menu(void) // can not be "static" #ifdef IR_SENSOR_ANALOG FSENSOR_ACTION_NA; - MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor); + //! Fsensor Detection isn't ready for mmu yet it is temporarily disabled. + //! @todo Don't forget to remove this as soon Fsensor Detection works with mmu + if(!mmu_enabled) MENU_ITEM_FUNCTION_P(PSTR("Fsensor Detection"), lcd_detect_IRsensor); #endif //IR_SENSOR_ANALOG MENU_END(); } @@ -7508,8 +7499,8 @@ void lcd_belttest() #ifdef IR_SENSOR_ANALOG // called also from marlin_main.cpp -void printf_IRSensorAnalogBoardChange(bool bPCBrev04){ - printf_P(PSTR("Filament sensor board change detected: revision%S\n"), bPCBrev04 ? _T(MSG_04_OR_NEWER) : _T(MSG_03_OR_OLDER)); +void printf_IRSensorAnalogBoardChange(){ + printf_P(PSTR("Filament sensor board change detected: revision%S\n"), FsensorIRVersionText()); } static bool lcd_selftest_IRsensor(bool bStandalone) @@ -7534,8 +7525,8 @@ static bool lcd_selftest_IRsensor(bool bStandalone) return(false); } if((bPCBrev04 ? 1 : 0) != (uint8_t)oFsensorPCB){ // safer then "(uint8_t)bPCBrev04" - printf_IRSensorAnalogBoardChange(bPCBrev04); oFsensorPCB=bPCBrev04 ? ClFsensorPCB::_Rev04 : ClFsensorPCB::_Old; + printf_IRSensorAnalogBoardChange(); eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,(uint8_t)oFsensorPCB); } return(true); @@ -7543,22 +7534,26 @@ static bool lcd_selftest_IRsensor(bool bStandalone) static void lcd_detect_IRsensor(){ bool bAction; - + bool loaded; bMenuFSDetect = true; // inhibits some code inside "manage_inactivity()" - bAction = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Is filament loaded?"), false, false); - if(bAction){ - lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action."));////c=20 r=4 + /// Check if filament is loaded. If it is loaded stop detection. + /// @todo Add autodetection with MMU2s + loaded = ! READ(IR_SENSOR_PIN); + if(loaded ){ + lcd_show_fullscreen_message_and_wait_P(_i("Please unload the filament first, then repeat this action.")); return; + } else { + lcd_show_fullscreen_message_and_wait_P(_i("Please check the IR sensor connections and filament is unloaded.")); + bAction = lcd_selftest_IRsensor(true); } - bAction = lcd_selftest_IRsensor(true); - if(bAction){ + if(bAction){ lcd_show_fullscreen_message_and_wait_P(_i("Sensor verified, remove the filament now."));////c=20 r=3 - // the fsensor board has been successfully identified, any previous "not responding" may be cleared now - fsensor_not_responding = false; + // the fsensor board has been successfully identified, any previous "not responding" may be cleared now + fsensor_not_responding = false; } else { lcd_show_fullscreen_message_and_wait_P(_i("Verification failed, remove the filament and try again."));////c=20 r=5 - // here it is unclear what to to with the fsensor_not_responding flag - } + // here it is unclear what to to with the fsensor_not_responding flag + } bMenuFSDetect=false; // de-inhibits some code inside "manage_inactivity()" } #endif //IR_SENSOR_ANALOG @@ -7574,9 +7569,17 @@ bool lcd_selftest() bool _result = true; bool _swapped_fan = false; #ifdef IR_SENSOR_ANALOG - //! Check if IR sensor is in unknown state, set it temporarily to 0.3 or older - //! @todo This has to be improved - if( oFsensorPCB == ClFsensorPCB::_Undef) eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,0); + //! Check if IR sensor is in unknown state, if so run Fsensor Detection + //! As the Fsensor Detection isn't yet ready for the mmu2s we set temporarily the IR sensor 0.3 or older for mmu2s + //! @todo Don't forget to remove this as soon Fsensor Detection works with mmu + if( oFsensorPCB == ClFsensorPCB::_Undef) { + if (!mmu_enabled) { + lcd_detect_IRsensor(); + } + else { + eeprom_update_byte((uint8_t*)EEPROM_FSENSOR_PCB,0); + } + } #endif //IR_SENSOR_ANALOG lcd_wait_for_cool_down(); lcd_clear(); @@ -7784,10 +7787,12 @@ bool lcd_selftest() _progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //fil sensor OK } #endif //PAT9125 -//#ifdef IR_SENSOR_ANALOG -#if (0) +#if 0 + // Intentionally disabled - that's why we moved the detection to runtime by just checking the two voltages. + // The idea is not to force the user to remove and insert the filament on an assembled printer. +//def IR_SENSOR_ANALOG _progress = lcd_selftest_screen(TestScreen::Fsensor, _progress, 3, true, 2000); //check filament sensor - _result = lcd_selftest_IRsensor(); + _result = lcd_selftest_IRsensor(); if (_result) { _progress = lcd_selftest_screen(TestScreen::FsensorOk, _progress, 3, true, 2000); //filament sensor OK diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index d68ab14b..844c7c7d 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -142,7 +142,7 @@ extern uint8_t farm_status; #ifdef IR_SENSOR_ANALOG extern bool bMenuFSDetect; -void printf_IRSensorAnalogBoardChange(bool bPCBrev04); +void printf_IRSensorAnalogBoardChange(); #endif //IR_SENSOR_ANALOG extern int8_t SilentModeMenu; @@ -257,21 +257,4 @@ enum class WizState : uint8_t void lcd_wizard(WizState state); -#define VOLT_DIV_REF 5 -#ifdef IR_SENSOR_ANALOG -constexpr uint16_t Voltage2Raw(float V){ - return ( V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F; -} -constexpr float Raw2Voltage(uint16_t raw){ - return VOLT_DIV_REF*(raw / (1023.F * OVERSAMPLENR) ); -} -constexpr uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821 -constexpr uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910 -constexpr uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059 -constexpr uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982 -constexpr uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368 - - -#endif //IR_SENSOR_ANALOG - #endif //ULTRALCD_H