Browse Source

Fsensor error state

Alex Voinea 3 years ago
parent
commit
b741707c0e
2 changed files with 84 additions and 58 deletions
  1. 81 55
      Firmware/Filament_sensor.h
  2. 3 3
      Firmware/ultralcd.cpp

+ 81 - 55
Firmware/Filament_sensor.h

@@ -136,6 +136,15 @@ protected:
         }
     }
     
+    void triggerError() {
+        state = State::error;
+        autoLoadEnabled = false;
+        runoutEnabled = false;
+        
+        /// some message, idk
+        ;//
+    }
+    
     State state;
     bool autoLoadEnabled;
     bool runoutEnabled;
@@ -154,15 +163,24 @@ public:
     }
     
     bool update() {
-        if (state == State::initializing) {
-            state = State::ready; //the IR sensor gets ready instantly as it's just a gpio read operation.
-            oldFilamentPresent = getFilamentPresent(); //initialize the current filament state so that we don't create a switching event right after the sensor is ready.
+        switch (state) {
+            case State::initializing:
+                state = State::ready; //the IR sensor gets ready instantly as it's just a gpio read operation.
+                oldFilamentPresent = getFilamentPresent(); //initialize the current filament state so that we don't create a switching event right after the sensor is ready.
+                // fallthru
+            case State::ready: {
+                postponedLoadEvent = false;
+                bool event = checkFilamentEvents();
+                
+                ;//
+                
+                return event;
+            } break;
+            case State::disabled:
+            case State::error:
+            default:
+                return false;
         }
-        
-        postponedLoadEvent = false;
-        bool event = checkFilamentEvents();
-        
-        return event;
     }
     
     bool getFilamentPresent() {
@@ -184,41 +202,44 @@ public:
     
     bool update() {
         bool event = IR_sensor::update();
-        if (voltReady) {
-            voltReady = false;
-            uint16_t volt = getVoltRaw();
-            printf_P(PSTR("newVoltRaw:%u\n"), volt / OVERSAMPLENR);
-            
-            // detect min-max, some long term sliding window for filtration may be added
-            // avoiding floating point operations, thus computing in raw
-            if(volt > maxVolt) {
-                maxVolt = volt;
-            }
-            else if(volt < minVolt) {
-                minVolt = volt;
-            }
-            //! 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.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) {
-                IR_ANALOG_Check(SensorRevision::_Old, SensorRevision::_Rev04);
-            }
-            //! 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) {
-                IR_ANALOG_Check(SensorRevision::_Rev04, SensorRevision::_Old);
+        if (state == State::ready) {
+            if (voltReady) {
+                voltReady = false;
+                uint16_t volt = getVoltRaw();
+                printf_P(PSTR("newVoltRaw:%u\n"), volt / OVERSAMPLENR);
+                
+                // detect min-max, some long term sliding window for filtration may be added
+                // avoiding floating point operations, thus computing in raw
+                if(volt > maxVolt) {
+                    maxVolt = volt;
+                }
+                else if(volt < minVolt) {
+                    minVolt = volt;
+                }
+                //! 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.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) {
+                    IR_ANALOG_Check(SensorRevision::_Old, SensorRevision::_Rev04);
+                }
+                //! 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) {
+                    IR_ANALOG_Check(SensorRevision::_Rev04, SensorRevision::_Old);
+                }
+                
+                if (!checkVoltage(volt)) {
+                    triggerError();
+                }
             }
-            
-            
-            ;//
         }
         
         ;//
@@ -279,16 +300,19 @@ public:
         return VOLT_DIV_REF * (raw / (1023.F * OVERSAMPLENR));
     }
     
-    /// 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 checkVoltage(uint16_t raw){
+    bool checkVoltage(uint16_t raw) {
         if(IRsensor_Lmax_TRESHOLD <= raw && raw <= 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
-            puts_P(PSTR("fsensor in forbidden range 1.5-3V - check sensor"));
-            return false; 
+            if (voltageErrorCnt++ > 4) {
+                puts_P(PSTR("fsensor in forbidden range 1.5-3V - check sensor"));
+                return false;
+            }
+        }
+        else {
+            voltageErrorCnt = 0;
         }
         if(sensorRevision == SensorRevision::_Rev04) {
             /// newer IR sensor cannot normally produce 4.6-5V, this is considered a failure/bad mount
@@ -306,6 +330,7 @@ public:
         }
         /// If IR sensor is "uknown state" and filament is not loaded > 1.5V return false
     #if 0
+    #error "I really think this code can't be enabled anymore because we are constantly checking this voltage."
         if((sensorRevision == SensorRevision::_Undef) && (raw > IRsensor_Lmax_TRESHOLD)) {
             puts_P(PSTR("Unknown IR sensor version and no filament loaded detected."));
             return false;
@@ -329,6 +354,7 @@ private:
     uint16_t minVolt = Voltage2Raw(6.f);
     uint16_t maxVolt = 0;
     uint16_t nFSCheckCount;
+    uint8_t voltageErrorCnt;
 
     static constexpr uint16_t FS_CHECK_COUNT = 4;
     /// Switching mechanism of the fsensor type.
@@ -347,14 +373,14 @@ private:
                 setSensorRevision(switchTo, true);
                 printf_IRSensorAnalogBoardChange();
                 switch (switchTo) {
-                case SensorRevision::_Old:
-                    lcd_setstatuspgm(_T(MSG_FS_V_03_OR_OLDER)); ////MSG_FS_V_03_OR_OLDER c=18
-                    break;
-                case SensorRevision::_Rev04:
-                    lcd_setstatuspgm(_T(MSG_FS_V_04_OR_NEWER)); ////MSG_FS_V_04_OR_NEWER c=18
-                    break;
-                default:
-                    break;
+                    case SensorRevision::_Old:
+                        lcd_setstatuspgm(_T(MSG_FS_V_03_OR_OLDER)); ////MSG_FS_V_03_OR_OLDER c=18
+                        break;
+                    case SensorRevision::_Rev04:
+                        lcd_setstatuspgm(_T(MSG_FS_V_04_OR_NEWER)); ////MSG_FS_V_04_OR_NEWER c=18
+                        break;
+                    default:
+                        break;
                 }
             }
         }

+ 3 - 3
Firmware/ultralcd.cpp

@@ -4183,8 +4183,8 @@ void fsensor_reinit() {
 #define SETTINGS_FILAMENT_SENSOR \
 do {\
     if (fsensor.isError()) {\
-        MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), NULL, fsensor_reinit);\
-        MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), NULL, fsensor_reinit);\
+        MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), _T(MSG_NA), fsensor_reinit);\
+        MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR_AUTOLOAD), _T(MSG_NA), fsensor_reinit);\
     }\
     else {\
         MENU_ITEM_TOGGLE_P(_T(MSG_FSENSOR), fsensor.getRunoutEnabled() ? _T(MSG_ON) : _T(MSG_OFF), lcd_fsensor_runout_set);\
@@ -4204,7 +4204,7 @@ static void settingsAutoDeplete()
     if (mmu_enabled)
     {
         if (fsensor.isError()) {
-            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), NULL, fsensor_reinit);
+            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), _T(MSG_NA), fsensor_reinit);
         }
         else {
             MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), lcd_autoDeplete ? _T(MSG_ON) : _T(MSG_OFF), auto_deplete_switch);