MK3s IR sensor improvement (#2698)

* Update EEPROM_FSENSOR_PCB documentation

* Update IR sensor check

* Rename IR messags and add UNKNOWN state

* Update code to use new messages

* To be continued

* Move fsensor related things from ultralcd.h to fsensor.h

* Use defined Thresholds

* IR sensor auto detection "0.3 or older" and "0.4 or newer" when trigger status changes.
Typo fixes
Doxygen documentation

* Cleanup spaces

* Revert PF-build.sh changes

* re-add space in messages

* revert doxygen snytax

* Remove double _Undef

* Fix indentation and doxygen syntax

* Fix indentation

* Better message handling

* Fix indentation

* Fix indentation

* More indentation fixwa

* Extract common code into manage_inactivity_IR_ANALOG_Check

Saves ~60B of code

* Revert indentation changes on fsensor.cpp

* Keep the selftest IR sensor part disabled

Everything shall happen at runtime

* Fix indentation fsensor_update

* Fix another misleading indentation in fsensor_update

Co-authored-by: Alex Voinea <voinea.dragos.alexandru@gmail.com>
Co-authored-by: D.R.racer <drracer@drracer.eu>
This commit is contained in:
3d-gussner 2020-06-03 16:14:56 +02:00 committed by GitHub
parent 233e66900f
commit d1865fc59a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 241 additions and 197 deletions

View File

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

View File

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

View File

@ -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<<ADSC); // first conversion after ADMUX change discarded (preventively)
while(ADCSRA&(1<<ADSC))
;
ADCSRA|=(1<<ADSC); // second conversion used
while(ADCSRA&(1<<ADSC))
;
nADC=ADC;
ADMUX=nMUX1; // ADMUX restoring
ADCSRB=nMUX2;
ENABLE_TEMPERATURE_INTERRUPT();
// end of sequence for ...
// 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)
uint8_t nMUX1,nMUX2;
uint16_t nADC;
bIRsensorStateFlag=false;
// sequence for direct data reading from AD converter
DISABLE_TEMPERATURE_INTERRUPT();
nMUX1=ADMUX; // ADMUX saving
nMUX2=ADCSRB;
adc_setmux(VOLT_IR_PIN);
ADCSRA|=(1<<ADSC); // first conversion after ADMUX change discarded (preventively)
while(ADCSRA&(1<<ADSC))
;
ADCSRA|=(1<<ADSC); // second conversion used
while(ADCSRA&(1<<ADSC))
;
nADC=ADC;
ADMUX=nMUX1; // ADMUX restoring
ADCSRB=nMUX2;
ENABLE_TEMPERATURE_INTERRUPT();
// end of sequence for ...
// 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 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

View File

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

View File

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

View File

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

View File

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

View File

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