Browse Source

This starts to print ;)

Temporarily disabled filament runout as this breaks ToolChange operation
yet for unknown reason.
D.R.racer 2 years ago
parent
commit
0bd3dfdcf7
5 changed files with 554 additions and 492 deletions
  1. 485 1
      Firmware/Filament_sensor.cpp
  2. 52 475
      Firmware/Filament_sensor.h
  3. 11 10
      Firmware/Tcodes.cpp
  4. 4 4
      Firmware/mmu2.cpp
  5. 2 2
      Firmware/ultralcd.cpp

+ 485 - 1
Firmware/Filament_sensor.cpp

@@ -1,4 +1,15 @@
+#include <avr/pgmspace.h>
+#include <stdio.h>
+#include <util/atomic.h>
+
 #include "Filament_sensor.h"
+#include "Timer.h"
+#include "cardreader.h"
+#include "eeprom.h"
+#include "menu.h"
+#include "pat9125.h"
+#include "temperature.h"
+#include "ultralcd.h"
 
 #ifdef FILAMENT_SENSOR
 #if FILAMENT_SENSOR_TYPE == FSENSOR_IR
@@ -8,4 +19,477 @@ IR_sensor_analog fsensor;
 #elif FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125
 PAT9125_sensor fsensor;
 #endif
-#endif //FILAMENT_SENSOR
+#endif // FILAMENT_SENSOR
+
+void Filament_sensor::setEnabled(bool enabled) {
+    eeprom_update_byte((uint8_t *)EEPROM_FSENSOR, enabled);
+    if (enabled) {
+        init();
+    } else {
+        deinit();
+    }
+}
+
+void Filament_sensor::setAutoLoadEnabled(bool state, bool updateEEPROM) {
+    autoLoadEnabled = state;
+    if (updateEEPROM) {
+        eeprom_update_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED, state);
+    }
+}
+
+void Filament_sensor::setRunoutEnabled(bool state, bool updateEEPROM) {
+    runoutEnabled = state;
+    if (updateEEPROM) {
+        eeprom_update_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED, state);
+    }
+}
+
+void Filament_sensor::setActionOnError(SensorActionOnError state, bool updateEEPROM) {
+    sensorActionOnError = state;
+    if (updateEEPROM) {
+        eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_ACTION_NA, (uint8_t)state);
+    }
+}
+
+void Filament_sensor::settings_init_common() {
+    bool enabled = eeprom_read_byte((uint8_t *)EEPROM_FSENSOR);
+    if ((state != State::disabled) != enabled) {
+        state = enabled ? State::initializing : State::disabled;
+    }
+
+    autoLoadEnabled = eeprom_read_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED);
+    runoutEnabled = eeprom_read_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED);
+    sensorActionOnError = (SensorActionOnError)eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_ACTION_NA);
+    if (sensorActionOnError == SensorActionOnError::_Undef) {
+        sensorActionOnError = SensorActionOnError::_Continue;
+    }
+}
+
+bool Filament_sensor::checkFilamentEvents() {
+    if (state != State::ready)
+        return false;
+    if (eventBlankingTimer.running() && !eventBlankingTimer.expired(100)) { // event blanking for 100ms
+        return false;
+    }
+
+    bool newFilamentPresent = getFilamentPresent();
+    if (oldFilamentPresent != newFilamentPresent) {
+        oldFilamentPresent = newFilamentPresent;
+        eventBlankingTimer.start();
+        if (newFilamentPresent) { // filament insertion
+            puts_P(PSTR("filament inserted"));
+            triggerFilamentInserted();
+            postponedLoadEvent = true;
+        } else { // filament removal
+            puts_P(PSTR("filament removed"));
+            triggerFilamentRemoved();
+        }
+        return true;
+    }
+    return false;
+}
+
+void Filament_sensor::triggerFilamentInserted() {
+    if (autoLoadEnabled && (eFilamentAction == FilamentAction::None) &&
+        !(moves_planned() || IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal) ||
+          eeprom_read_byte((uint8_t *)EEPROM_WIZARD_ACTIVE))) {
+        filAutoLoad();
+    }
+}
+
+void Filament_sensor::triggerFilamentRemoved() {
+    if (runoutEnabled
+        && (eFilamentAction == FilamentAction::None)
+        && !saved_printing
+        && (
+            moves_planned()
+            || IS_SD_PRINTING
+            || usb_timer.running()
+            || (lcd_commands_type == LcdCommands::Layer1Cal)
+            || eeprom_read_byte((uint8_t *)EEPROM_WIZARD_ACTIVE)
+        )
+    ){
+//        filRunout();
+    }
+}
+
+void Filament_sensor::filAutoLoad() {
+    eFilamentAction = FilamentAction::AutoLoad;
+    if (target_temperature[0] >= EXTRUDE_MINTEMP) {
+        bFilamentPreheatState = true;
+        menu_submenu(mFilamentItemForce);
+    } else {
+        menu_submenu(lcd_generic_preheat_menu);
+        lcd_timeoutToStatus.start();
+    }
+}
+
+void Filament_sensor::filRunout() {
+    runoutEnabled = false;
+    autoLoadEnabled = false;
+    stop_and_save_print_to_ram(0, 0);
+    restore_print_from_ram_and_continue(0);
+    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("M600")));
+}
+
+void Filament_sensor::triggerError() {
+    state = State::error;
+
+    /// some message, idk
+    ; //
+}
+
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_IR) || (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
+void IR_sensor::init() {
+    if (state == State::error) {
+        deinit(); // deinit first if there was an error.
+    }
+    puts_P(PSTR("fsensor::init()"));
+    SET_INPUT(IR_SENSOR_PIN); // input mode
+    WRITE(IR_SENSOR_PIN, 1);  // pullup
+    settings_init();          // also sets the state to State::initializing
+}
+
+void IR_sensor::deinit() {
+    puts_P(PSTR("fsensor::deinit()"));
+    SET_INPUT(IR_SENSOR_PIN); // input mode
+    WRITE(IR_SENSOR_PIN, 0);  // no pullup
+    state = State::disabled;
+}
+
+bool IR_sensor::update() {
+    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;
+    }
+    return false;
+}
+
+bool IR_sensor::getFilamentPresent() { return !READ(IR_SENSOR_PIN); }
+
+bool IR_sensor::probeOtherType() { return pat9125_probe(); }
+
+void IR_sensor::settings_init() { Filament_sensor::settings_init_common(); }
+
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
+void IR_sensor_analog::init() {
+    IR_sensor::init();
+    settings_init();
+}
+
+void IR_sensor_analog::deinit() { IR_sensor::deinit(); }
+
+bool IR_sensor_analog::update() {
+    bool event = IR_sensor::update();
+    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();
+            }
+        }
+    }
+
+    ; //
+
+    return event;
+}
+
+void IR_sensor_analog::voltUpdate(uint16_t raw) { // to be called from the ADC ISR when a cycle is finished
+    voltRaw = raw;
+    voltReady = true;
+}
+
+uint16_t IR_sensor_analog::getVoltRaw() {
+    uint16_t newVoltRaw;
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { newVoltRaw = voltRaw; }
+    return newVoltRaw;
+}
+
+void IR_sensor_analog::settings_init() {
+    IR_sensor::settings_init();
+    sensorRevision = (SensorRevision)eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_PCB);
+}
+
+const char *IR_sensor_analog::getIRVersionText() {
+    switch (sensorRevision) {
+    case SensorRevision::_Old:
+        return _T(MSG_IR_03_OR_OLDER);
+    case SensorRevision::_Rev04:
+        return _T(MSG_IR_04_OR_NEWER);
+    default:
+        return _T(MSG_IR_UNKNOWN);
+    }
+}
+
+void IR_sensor_analog::setSensorRevision(SensorRevision rev, bool updateEEPROM) {
+    sensorRevision = rev;
+    if (updateEEPROM) {
+        eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_PCB, (uint8_t)rev);
+    }
+}
+
+bool IR_sensor_analog::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
+        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
+        if (IRsensor_Hopen_TRESHOLD <= raw && raw <= IRsensor_VMax_TRESHOLD) {
+            puts_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected"));
+            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 <= raw && raw <= IRsensor_VMax_TRESHOLD) {
+                puts_P(PSTR("fsensor v0.4 in fault range 0.0-0.3V - wrong IR sensor"));
+                return false;
+            }
+#endif
+    }
+    /// 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;
+        }
+#endif
+    // otherwise the IR fsensor is considered working correctly
+    return true;
+}
+
+void IR_sensor_analog::IR_ANALOG_Check(SensorRevision isVersion, SensorRevision switchTo) {
+    bool bTemp = (!CHECK_ALL_HEATERS);
+    bTemp = bTemp && (menu_menu == lcd_status_screen);
+    bTemp = bTemp && ((sensorRevision == isVersion) || (sensorRevision == SensorRevision::_Undef));
+    bTemp = bTemp && (state == State::ready);
+    if (bTemp) {
+        nFSCheckCount++;
+        if (nFSCheckCount > FS_CHECK_COUNT) {
+            nFSCheckCount = 0; // not necessary
+            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;
+            }
+        }
+    } else {
+        nFSCheckCount = 0;
+    }
+}
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
+#endif //(FILAMENT_SENSOR_TYPE == FSENSOR_IR) || (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
+
+#if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
+void PAT9125_sensor::init() {
+    if (state == State::error) {
+        deinit(); // deinit first if there was an error.
+    }
+    puts_P(PSTR("fsensor::init()"));
+
+    settings_init(); // also sets the state to State::initializing
+
+    calcChunkSteps(cs.axis_steps_per_unit[E_AXIS]); // for jam detection
+
+    if (!pat9125_init()) {
+        deinit();
+        triggerError();
+        ; //
+    }
+#ifdef IR_SENSOR_PIN
+    else if (!READ(IR_SENSOR_PIN)) {
+        ; // MK3 fw on MK3S printer
+    }
+#endif // IR_SENSOR_PIN
+}
+
+void PAT9125_sensor::deinit() {
+    puts_P(PSTR("fsensor::deinit()"));
+    ; //
+    state = State::disabled;
+    filter = 0;
+}
+
+bool PAT9125_sensor::update() {
+    switch (state) {
+    case State::initializing:
+        if (!updatePAT9125()) {
+            break; // still not stable. Stay in the initialization state.
+        }
+        oldFilamentPresent =
+            getFilamentPresent(); // initialize the current filament state so that we don't create a switching event right after the sensor is ready.
+        oldPos = pat9125_y;
+        state = State::ready;
+        break;
+    case State::ready: {
+        updatePAT9125();
+        postponedLoadEvent = false;
+        bool event = checkFilamentEvents();
+
+        ; //
+
+        return event;
+    } break;
+    case State::disabled:
+    case State::error:
+    default:
+        return false;
+    }
+    return false;
+}
+
+bool PAT9125_sensor::probeOtherType() {
+    SET_INPUT(IR_SENSOR_PIN); // input mode
+    WRITE(IR_SENSOR_PIN, 1);  // pullup
+    _delay_us(100); // wait for the pullup to pull the line high (might be needed, not really sure. The internal pullups are quite weak and there might be a
+                    // long wire attached).
+    bool fsensorDetected = !READ(IR_SENSOR_PIN);
+    WRITE(IR_SENSOR_PIN, 0); // no pullup
+    return fsensorDetected;
+}
+
+void PAT9125_sensor::setJamDetectionEnabled(bool state, bool updateEEPROM) {
+    jamDetection = state;
+    oldPos = pat9125_y;
+    resetStepCount();
+    jamErrCnt = 0;
+    if (updateEEPROM) {
+        eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_JAM_DETECTION, state);
+    }
+}
+
+void PAT9125_sensor::settings_init() {
+    puts_P(PSTR("settings_init"));
+    Filament_sensor::settings_init_common();
+    setJamDetectionEnabled(eeprom_read_byte((uint8_t *)EEPROM_FSENSOR_JAM_DETECTION));
+}
+
+int16_t PAT9125_sensor::getStepCount() {
+    int16_t st_cnt;
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { st_cnt = stepCount; }
+    return st_cnt;
+}
+
+void PAT9125_sensor::resetStepCount() {
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { stepCount = 0; }
+}
+
+void PAT9125_sensor::filJam() {
+    runoutEnabled = false;
+    autoLoadEnabled = false;
+    jamDetection = false;
+    stop_and_save_print_to_ram(0, 0);
+    restore_print_from_ram_and_continue(0);
+    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("M600")));
+}
+
+bool PAT9125_sensor::updatePAT9125() {
+    if (jamDetection) {
+        int16_t _stepCount = getStepCount();
+        if (abs(_stepCount) >= chunkSteps) { // end of chunk. Check distance
+            resetStepCount();
+            if (!pat9125_update()) { // get up to date data. reinit on error.
+                init();              // try to reinit.
+            }
+            bool fsDir = (pat9125_y - oldPos) > 0;
+            bool stDir = _stepCount > 0;
+            if (fsDir != stDir) {
+                jamErrCnt++;
+            } else if (jamErrCnt) {
+                jamErrCnt--;
+            }
+            oldPos = pat9125_y;
+        }
+        if (jamErrCnt > 10) {
+            jamErrCnt = 0;
+            filJam();
+        }
+    }
+
+    if (!pollingTimer.running() || pollingTimer.expired(pollingPeriod)) {
+        pollingTimer.start();
+        if (!pat9125_update()) {
+            init(); // try to reinit.
+        }
+
+        bool present = (pat9125_s < 17) || (pat9125_s >= 17 && pat9125_b >= 50);
+        if (present != filterFilPresent) {
+            filter++;
+        } else if (filter) {
+            filter--;
+        }
+        if (filter >= filterCnt) {
+            filter = 0;
+            filterFilPresent = present;
+        }
+    }
+    return (filter == 0); // return stability
+}
+#endif // #if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)

+ 52 - 475
Firmware/Filament_sensor.h

@@ -1,22 +1,10 @@
 #pragma once
-
 #include <inttypes.h>
-#include <stdio.h>
-#include <avr/pgmspace.h>
-#include <util/atomic.h>
 
-#include "Marlin.h"
-#include "ultralcd.h"
-#include "menu.h"
-#include "cardreader.h"
-#include "temperature.h"
 #include "cmdqueue.h"
-#include "eeprom.h"
 #include "pins.h"
 #include "fastio.h"
 #include "adc.h"
-#include "Timer.h"
-#include "pat9125.h"
 
 #define FSENSOR_IR 1
 #define FSENSOR_IR_ANALOG 2
@@ -46,44 +34,21 @@ public:
         _Undef = EEPROM_EMPTY_VALUE
     };
     
-    void setEnabled(bool enabled) {
-        eeprom_update_byte((uint8_t *)EEPROM_FSENSOR, enabled);
-        if (enabled) {
-            init();
-        }
-        else {
-            deinit();
-        }
-    }
+    void setEnabled(bool enabled);
     
-    void setAutoLoadEnabled(bool state, bool updateEEPROM = false) {
-        autoLoadEnabled = state;
-        if (updateEEPROM) {
-            eeprom_update_byte((uint8_t *)EEPROM_FSENS_AUTOLOAD_ENABLED, state);
-        }
-    }
+    void setAutoLoadEnabled(bool state, bool updateEEPROM = false);
     
     bool getAutoLoadEnabled() {
         return autoLoadEnabled;
     }
     
-    void setRunoutEnabled(bool state, bool updateEEPROM = false) {
-        runoutEnabled = state;
-        if (updateEEPROM) {
-            eeprom_update_byte((uint8_t *)EEPROM_FSENS_RUNOUT_ENABLED, state);
-        }
-    }
+    void setRunoutEnabled(bool state, bool updateEEPROM = false);
     
     bool getRunoutEnabled() {
         return runoutEnabled;
     }
     
-    void setActionOnError(SensorActionOnError state, bool updateEEPROM = false) {
-        sensorActionOnError = state;
-        if (updateEEPROM) {
-            eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_ACTION_NA, (uint8_t)state);
-        }
-    }
+    void setActionOnError(SensorActionOnError state, bool updateEEPROM = false);
     
     SensorActionOnError getActionOnError() {
         return sensorActionOnError;
@@ -106,85 +71,19 @@ public:
     }
     
 protected:
-    void settings_init() {
-        bool enabled = eeprom_read_byte((uint8_t*)EEPROM_FSENSOR);
-        if ((state != State::disabled) != enabled) {
-            state = enabled ? State::initializing : State::disabled;
-        }
-        
-        autoLoadEnabled = eeprom_read_byte((uint8_t*)EEPROM_FSENS_AUTOLOAD_ENABLED);
-        runoutEnabled = eeprom_read_byte((uint8_t*)EEPROM_FSENS_RUNOUT_ENABLED);
-        sensorActionOnError = (SensorActionOnError)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_ACTION_NA);
-        if (sensorActionOnError == SensorActionOnError::_Undef) {
-            sensorActionOnError = SensorActionOnError::_Continue;
-        }
-    }
+    void settings_init_common();
     
-    bool checkFilamentEvents() {
-        if (state != State::ready)
-            return false;
-        if (eventBlankingTimer.running() && !eventBlankingTimer.expired(100)) {// event blanking for 100ms
-            return false;
-        }
-        
-        bool newFilamentPresent = getFilamentPresent();
-        if (oldFilamentPresent != newFilamentPresent) {
-            oldFilamentPresent = newFilamentPresent;
-            eventBlankingTimer.start();
-            if (newFilamentPresent) { //filament insertion
-                puts_P(PSTR("filament inserted"));
-                triggerFilamentInserted();
-                postponedLoadEvent = true;
-            }
-            else { //filament removal
-                puts_P(PSTR("filament removed"));
-                triggerFilamentRemoved();
-            }
-            return true;
-        }
-        return false;
-    };
+    bool checkFilamentEvents();
     
-    void triggerFilamentInserted() {
-        if (autoLoadEnabled && (eFilamentAction == FilamentAction::None) && !(moves_planned() || IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal) || eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))) {
-            filAutoLoad();
-        }
-    }
+    void triggerFilamentInserted();
     
-    void triggerFilamentRemoved() {
-        if (runoutEnabled && (eFilamentAction == FilamentAction::None) && !saved_printing && (moves_planned() || IS_SD_PRINTING || usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal) || eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE))) {
-            filRunout();
-        }
-    }
+    void triggerFilamentRemoved();
     
-    void filAutoLoad() {
-        eFilamentAction = FilamentAction::AutoLoad;
-        if(target_temperature[0] >= EXTRUDE_MINTEMP){
-            bFilamentPreheatState = true;
-            menu_submenu(mFilamentItemForce);
-        }
-        else {
-            menu_submenu(lcd_generic_preheat_menu);
-            lcd_timeoutToStatus.start();
-        }
-    }
+    void filAutoLoad();
     
-    void filRunout() {
-        runoutEnabled = false;
-        autoLoadEnabled = false;
-        stop_and_save_print_to_ram(0, 0);
-        restore_print_from_ram_and_continue(0);
-        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("M600")));
-    }
+    void filRunout();
     
-    void triggerError() {
-        state = State::error;
-        
-        /// some message, idk
-        ;//
-    }
+    void triggerError();
     
     State state;
     bool autoLoadEnabled;
@@ -198,137 +97,34 @@ protected:
 #if (FILAMENT_SENSOR_TYPE == FSENSOR_IR) || (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
 class IR_sensor: public Filament_sensor {
 public:
-    void init() {
-        if (state == State::error) {
-            deinit(); //deinit first if there was an error.
-        }
-        puts_P(PSTR("fsensor::init()"));
-        SET_INPUT(IR_SENSOR_PIN); //input mode
-        WRITE(IR_SENSOR_PIN, 1); //pullup
-        settings_init(); //also sets the state to State::initializing
-    }
-    
-    void deinit() {
-        puts_P(PSTR("fsensor::deinit()"));
-        SET_INPUT(IR_SENSOR_PIN); //input mode
-        WRITE(IR_SENSOR_PIN, 0); //no pullup
-        state = State::disabled;
-    }
-    
-    bool update() {
-        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;
-        }
-        return false;
-    }
-    
-    bool getFilamentPresent() {
-        return !READ(IR_SENSOR_PIN);
-    }
-    
+    void init() override;
+    void deinit() override;
+    bool update()override ;
+    bool getFilamentPresent()override;
 #ifdef FSENSOR_PROBING
-    bool probeOtherType() {
-        return pat9125_probe();
-    }
+    bool probeOtherType()override;
 #endif
-    
-    void settings_init() {
-        Filament_sensor::settings_init();
-    }
-protected:
+    void settings_init();
 };
 
 #if (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
+constexpr static uint16_t Voltage2Raw(float V) {
+    return (V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F;
+}
+constexpr static float Raw2Voltage(uint16_t raw) {
+    return VOLT_DIV_REF * (raw / (1023.F * OVERSAMPLENR));
+}
+
 class IR_sensor_analog: public IR_sensor {
 public:
-    void init() {
-        IR_sensor::init();
-        settings_init();
-    }
-    
-    void deinit() {
-        IR_sensor::deinit();
-    }
-    
-    bool update() {
-        bool event = IR_sensor::update();
-        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();
-                }
-            }
-        }
-        
-        ;//
-        
-        return event;
-    }
+    void init()override;
+    void deinit()override;
+    bool update()override;
+    void voltUpdate(uint16_t raw);
     
-    void voltUpdate(uint16_t raw) { //to be called from the ADC ISR when a cycle is finished
-        voltRaw = raw;
-        voltReady = true;
-    }
+    uint16_t getVoltRaw();
     
-    uint16_t getVoltRaw() {
-        uint16_t newVoltRaw;
-        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
-            newVoltRaw = voltRaw;
-        }
-        return newVoltRaw;
-    }
-    
-    void settings_init() {
-        IR_sensor::settings_init();
-        sensorRevision = (SensorRevision)eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_PCB);
-    }
+    void settings_init();
     
     enum class SensorRevision : uint8_t {
         _Old = 0,
@@ -340,83 +136,24 @@ public:
         return sensorRevision;
     }
     
-    const char* getIRVersionText() {
-        switch(sensorRevision) {
-            case SensorRevision::_Old:
-                return _T(MSG_IR_03_OR_OLDER);
-            case SensorRevision::_Rev04:
-                return _T(MSG_IR_04_OR_NEWER);
-            default:
-                return _T(MSG_IR_UNKNOWN);
-        }
-    }
+    const char* getIRVersionText();
     
-    void setSensorRevision(SensorRevision rev, bool updateEEPROM = false) {
-        sensorRevision = rev;
-        if (updateEEPROM) {
-            eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_PCB, (uint8_t)rev);
-        }
-    }
+    void setSensorRevision(SensorRevision rev, bool updateEEPROM = false);
     
-    uint16_t Voltage2Raw(float V) {
-        return (V * 1023 * OVERSAMPLENR / VOLT_DIV_REF ) + 0.5F;
-    }
-    float Raw2Voltage(uint16_t raw) {
-        return VOLT_DIV_REF * (raw / (1023.F * OVERSAMPLENR));
-    }
-    
-    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
-            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
-            if(IRsensor_Hopen_TRESHOLD <= raw && raw <= IRsensor_VMax_TRESHOLD) {
-                puts_P(PSTR("fsensor v0.4 in fault range 4.6-5V - unconnected"));
-                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 <= raw && raw <= IRsensor_VMax_TRESHOLD) {
-                puts_P(PSTR("fsensor v0.4 in fault range 0.0-0.3V - wrong IR sensor"));
-                return false;
-            }
-    #endif
-        }
-        /// 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;
-        }
-    #endif
-        // otherwise the IR fsensor is considered working correctly
-        return true;
-    }
+    bool checkVoltage(uint16_t raw);
     
     // Voltage2Raw is not constexpr :/
-    const uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3f); // ~0.3V, raw value=982
-    const uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5f); // ~1.5V (0.3*Vcc), raw value=4910
-    const uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0f); // ~3.0V (0.6*Vcc), raw value=9821
-    const uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6f); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059
-    const uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.f); // ~5V, raw value=16368
+    constexpr static uint16_t IRsensor_Ldiode_TRESHOLD = Voltage2Raw(0.3F); // ~0.3V, raw value=982
+    constexpr static uint16_t IRsensor_Lmax_TRESHOLD = Voltage2Raw(1.5F); // ~1.5V (0.3*Vcc), raw value=4910
+    constexpr static uint16_t IRsensor_Hmin_TRESHOLD = Voltage2Raw(3.0F); // ~3.0V (0.6*Vcc), raw value=9821
+    constexpr static uint16_t IRsensor_Hopen_TRESHOLD = Voltage2Raw(4.6F); // ~4.6V (N.C. @ Ru~20-50k, Rd'=56k, Ru'=10k), raw value=15059
+    constexpr static uint16_t IRsensor_VMax_TRESHOLD = Voltage2Raw(5.F); // ~5V, raw value=16368
     
 private:
     SensorRevision sensorRevision;
     volatile bool voltReady; //this gets set by the adc ISR
     volatile uint16_t voltRaw;
-    uint16_t minVolt = Voltage2Raw(6.f);
+    uint16_t minVolt = Voltage2Raw(6.F);
     uint16_t maxVolt = 0;
     uint16_t nFSCheckCount;
     uint8_t voltageErrorCnt;
@@ -426,33 +163,7 @@ private:
     /// Called from 2 spots which have a very similar behavior
     /// 1: SensorRevision::_Old -> SensorRevision::_Rev04 and print _i("FS v0.4 or newer")
     /// 2: SensorRevision::_Rev04 -> sensorRevision=SensorRevision::_Old and print _i("FS v0.3 or older")
-    void IR_ANALOG_Check(SensorRevision isVersion, SensorRevision switchTo) {
-        bool bTemp = (!CHECK_ALL_HEATERS);
-        bTemp = bTemp && (menu_menu == lcd_status_screen);
-        bTemp = bTemp && ((sensorRevision == isVersion) || (sensorRevision == SensorRevision::_Undef));
-        bTemp = bTemp && (state == State::ready);
-        if (bTemp) {
-            nFSCheckCount++;
-            if (nFSCheckCount > FS_CHECK_COUNT) {
-                nFSCheckCount = 0; // not necessary
-                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;
-                }
-            }
-        }
-        else {
-            nFSCheckCount = 0;
-        }
-    }
+    void IR_ANALOG_Check(SensorRevision isVersion, SensorRevision switchTo);
 };
 #endif //(FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
 #endif //(FILAMENT_SENSOR_TYPE == FSENSOR_IR) || (FILAMENT_SENSOR_TYPE == FSENSOR_IR_ANALOG)
@@ -460,86 +171,18 @@ private:
 #if (FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
 class PAT9125_sensor: public Filament_sensor {
 public:
-    void init() {
-        if (state == State::error) {
-            deinit(); //deinit first if there was an error.
-        }
-        puts_P(PSTR("fsensor::init()"));
-        
-        settings_init(); //also sets the state to State::initializing
-        
-        calcChunkSteps(cs.axis_steps_per_unit[E_AXIS]); //for jam detection
-        
-        if (!pat9125_init()) {
-            deinit();
-            triggerError();
-            ;//
-        }
-#ifdef IR_SENSOR_PIN
-        else if (!READ(IR_SENSOR_PIN)) {
-            ;// MK3 fw on MK3S printer
-        }
-#endif //IR_SENSOR_PIN
-    }
-    
-    void deinit() {
-        puts_P(PSTR("fsensor::deinit()"));
-        ;//
-        state = State::disabled;
-        filter = 0;
-    }
-    
-    bool update() {
-        switch (state) {
-            case State::initializing:
-                if (!updatePAT9125()) {
-                    break; // still not stable. Stay in the initialization state.
-                }
-                oldFilamentPresent = getFilamentPresent(); //initialize the current filament state so that we don't create a switching event right after the sensor is ready.
-                oldPos = pat9125_y;
-                state = State::ready;
-                break;
-            case State::ready: {
-                updatePAT9125();
-                postponedLoadEvent = false;
-                bool event = checkFilamentEvents();
-                
-                ;//
-                
-                return event;
-            } break;
-            case State::disabled:
-            case State::error:
-            default:
-                return false;
-        }
-        return false;
-    }
-    
-    bool getFilamentPresent() {
+    void init()override;
+    void deinit()override;
+    bool update()override;
+    bool getFilamentPresent() override{
         return filterFilPresent;
     }
     
 #ifdef FSENSOR_PROBING
-    bool probeOtherType() {
-        SET_INPUT(IR_SENSOR_PIN); //input mode
-        WRITE(IR_SENSOR_PIN, 1); //pullup
-        _delay_us(100); //wait for the pullup to pull the line high (might be needed, not really sure. The internal pullups are quite weak and there might be a long wire attached).
-        bool fsensorDetected = !READ(IR_SENSOR_PIN);
-        WRITE(IR_SENSOR_PIN, 0); //no pullup
-        return fsensorDetected;
-    }
+    bool probeOtherType() override;
 #endif
     
-    void setJamDetectionEnabled(bool state, bool updateEEPROM = false) {
-        jamDetection = state;
-        oldPos = pat9125_y;
-        resetStepCount();
-        jamErrCnt = 0;
-        if (updateEEPROM) {
-            eeprom_update_byte((uint8_t *)EEPROM_FSENSOR_JAM_DETECTION, state);
-        }
-    }
+    void setJamDetectionEnabled(bool state, bool updateEEPROM = false);
     
     bool getJamDetectionEnabled() {
         return jamDetection;
@@ -549,11 +192,7 @@ public:
         stepCount += rev ? -1 : 1;
     }
     
-    void settings_init() {
-        puts_P(PSTR("settings_init"));
-        Filament_sensor::settings_init();
-        setJamDetectionEnabled(eeprom_read_byte((uint8_t*)EEPROM_FSENSOR_JAM_DETECTION));
-    }
+    void settings_init();
 private:
     static constexpr uint16_t pollingPeriod = 10; //[ms]
     static constexpr uint8_t filterCnt = 5; //how many checks need to be done in order to determine the filament presence precisely.
@@ -567,79 +206,17 @@ private:
     int16_t chunkSteps;
     uint8_t jamErrCnt;
     
-    void calcChunkSteps(float u) {
+    constexpr void calcChunkSteps(float u) {
         chunkSteps = (int16_t)(1.25 * u); //[mm]
     }
     
-    int16_t getStepCount() {
-        int16_t st_cnt;
-        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
-            st_cnt = stepCount;
-        }
-        return st_cnt;
-    }
+    int16_t getStepCount();
     
-    void resetStepCount() {
-        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
-            stepCount = 0;
-        }
-    }
+    void resetStepCount();
     
-    void filJam() {
-        runoutEnabled = false;
-        autoLoadEnabled = false;
-        jamDetection = false;
-        stop_and_save_print_to_ram(0, 0);
-        restore_print_from_ram_and_continue(0);
-        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("M600")));
-    }
+    void filJam();
     
-    bool updatePAT9125() {
-        if (jamDetection) {
-            int16_t _stepCount = getStepCount();
-            if (abs(_stepCount) >= chunkSteps) { //end of chunk. Check distance
-                resetStepCount();
-                if (!pat9125_update()) { //get up to date data. reinit on error.
-                    init(); //try to reinit.
-                }
-                bool fsDir = (pat9125_y - oldPos) > 0;
-                bool stDir = _stepCount > 0;
-                if (fsDir != stDir) {
-                    jamErrCnt++;
-                }
-                else if (jamErrCnt) {
-                    jamErrCnt--;
-                }
-                oldPos = pat9125_y;
-            }
-            if (jamErrCnt > 10) {
-                jamErrCnt = 0;
-                filJam();
-            }
-        }
-        
-        if (!pollingTimer.running() || pollingTimer.expired(pollingPeriod)) {
-            pollingTimer.start();
-            if (!pat9125_update()) {
-                init(); //try to reinit.
-            }
-            
-            bool present = (pat9125_s < 17) || (pat9125_s >= 17 && pat9125_b >= 50);
-            if (present != filterFilPresent) {
-                filter++;
-            }
-            else if (filter) {
-                filter--;
-            }
-            if (filter >= filterCnt) {
-                filter = 0;
-                filterFilPresent = present;
-            }
-        }
-        return (filter == 0); //return stability
-    }
+    bool updatePAT9125();
 };
 #endif //(FILAMENT_SENSOR_TYPE == FSENSOR_PAT9125)
 

+ 11 - 10
Firmware/Tcodes.cpp

@@ -45,7 +45,7 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
 
     if (IsInvalidTCode(strchr_pointer, index)){
         TCodeInvalid();
-    } else if (strchr_pointer[index] == 'x'){
+    } /*else if (strchr_pointer[index] == 'x'){
         // load to bondtech gears; if mmu is not present do nothing
         if (MMU2::mmu2.Enabled()) {
             MMU2::mmu2.tool_change(strchr_pointer[index], choose_menu_P(_T(MSG_CHOOSE_EXTRUDER), _T(MSG_EXTRUDER)));
@@ -55,16 +55,16 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
         if (MMU2::mmu2.Enabled()) {
             MMU2::mmu2.tool_change(strchr_pointer[index], 0);
         }
-    } else {
+    }*/ else {
         SChooseFromMenu selectedSlot;
-        if (strchr_pointer[index] == '?')
-            selectedSlot = TCodeChooseFromMenu();
-        else {
+//        if (strchr_pointer[index] == '?')
+//            selectedSlot = TCodeChooseFromMenu();
+//        else {
             selectedSlot.slot = codeValue;
-            if (MMU2::mmu2.Enabled() && lcd_autoDepleteEnabled()) {
-                selectedSlot.slot = ad_getAlternative(selectedSlot.slot);
-            }
-        }
+//            if (MMU2::mmu2.Enabled() && lcd_autoDepleteEnabled()) {
+//                selectedSlot.slot = ad_getAlternative(selectedSlot.slot);
+//            }
+//        }
         st_synchronize();
 
         if (MMU2::mmu2.Enabled()) {
@@ -78,9 +78,10 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
                     manage_response(true, true, MMU_UNLOAD_MOVE);
                 }
 #endif // defined(MMU_HAS_CUTTER) && defined(MMU_ALWAYS_CUT)
-                MMU2::mmu2.tool_change(selectedSlot.slot);
                 if (selectedSlot.loadToNozzle){ // for single material usage with mmu
                     MMU2::mmu2.load_filament_to_nozzle(selectedSlot.slot);
+                } else {
+                    MMU2::mmu2.tool_change(selectedSlot.slot);
                 }
             }
         } else {

+ 4 - 4
Firmware/mmu2.cpp

@@ -59,8 +59,8 @@ static constexpr E_Step ramming_sequence[] PROGMEM = {
 };
 
 static constexpr E_Step load_to_nozzle_sequence[] PROGMEM = { 
-    { 36.0F,  810.0F / 60.F}, // feed rate = 13.5mm/s - Load fast until filament reach end of nozzle
-    { 30.0F,  198.0F / 60.F}, // feed rate = 3.3mm/s  - Load slower once filament is out of the nozzle
+    { 10.0F,  810.0F / 60.F}, // feed rate = 13.5mm/s - Load fast until filament reach end of nozzle
+    { 25.0F,  198.0F / 60.F}, // feed rate = 3.3mm/s  - Load slower once filament is out of the nozzle
 };
 
 namespace MMU2 {
@@ -663,14 +663,14 @@ void MMU2::OnMMUProgressMsg(ProgressCode pc){
                     // After the MMU knows the FSENSOR is triggered it will:
                     // 1. Push the filament by additional 30mm (see fsensorToNozzle)
                     // 2. Disengage the idler and push another 5mm.
-                    current_position[E_AXIS] += 30.0f + 5.0f;
+                    current_position[E_AXIS] += 30.0f + 2.0f;
                     plan_buffer_line_curposXYZE(MMU2_LOAD_TO_NOZZLE_FEED_RATE);
                     break;
                 case FilamentState::NOT_PRESENT:
                     // fsensor not triggered, continue moving extruder
                     if(!blocks_queued())
                     { // Only plan a move if there is no move ongoing
-                        current_position[E_AXIS] += 5.0f;
+                        current_position[E_AXIS] += 2.0f;
                         plan_buffer_line_curposXYZE(MMU2_LOAD_TO_NOZZLE_FEED_RATE);
                     }
                     break;

+ 2 - 2
Firmware/ultralcd.cpp

@@ -6217,7 +6217,7 @@ static bool lcd_selftest_IRsensor(bool bStandalone)
     uint16_t volt_IR_int = fsensor.getVoltRaw();
     
     newSensorRevision = (volt_IR_int < fsensor.IRsensor_Hopen_TRESHOLD) ? IR_sensor_analog::SensorRevision::_Rev04 : IR_sensor_analog::SensorRevision::_Old;
-    printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"), fsensor.Raw2Voltage(volt_IR_int) );
+    printf_P(PSTR("Measured filament sensor high level: %4.2fV\n"), Raw2Voltage(volt_IR_int) );
     if(volt_IR_int < fsensor.IRsensor_Hmin_TRESHOLD){
         if(!bStandalone)
             lcd_selftest_error(TestError::FsensorLevel,"HIGH","");
@@ -6225,7 +6225,7 @@ static bool lcd_selftest_IRsensor(bool bStandalone)
     }
     lcd_show_fullscreen_message_and_wait_P(_i("Insert the filament (do not load it) into the extruder and then press the knob."));////MSG_INSERT_FIL c=20 r=6
     volt_IR_int = fsensor.getVoltRaw();
-    printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"), fsensor.Raw2Voltage(volt_IR_int));
+    printf_P(PSTR("Measured filament sensor low level: %4.2fV\n"), Raw2Voltage(volt_IR_int));
     if(volt_IR_int > (fsensor.IRsensor_Lmax_TRESHOLD)){
         if(!bStandalone)
             lcd_selftest_error(TestError::FsensorLevel,"LOW","");