Browse Source

PFW-1362 Initial commit

Guðni Már Gilbert 2 years ago
parent
commit
afc67332c7
7 changed files with 123 additions and 105 deletions
  1. 40 53
      Firmware/AutoDeplete.cpp
  2. 52 13
      Firmware/AutoDeplete.h
  3. 8 6
      Firmware/Marlin_main.cpp
  4. 6 7
      Firmware/Tcodes.cpp
  5. 15 0
      Firmware/mmu2.cpp
  6. 2 25
      Firmware/ultralcd.cpp
  7. 0 1
      Firmware/ultralcd.h

+ 40 - 53
Firmware/AutoDeplete.cpp

@@ -1,79 +1,66 @@
-//! @file
-//! @author: Marek Bel
-//! @date Jan 3, 2019
-
 #include "AutoDeplete.h"
-#include "assert.h"
+#include "eeprom.h"
+#include "Filament_sensor.h"
+
+namespace SpoolJoin {
 
-//! @brief bit field marking depleted filaments
-//!
-//! binary 1 marks filament as depleted
-//! Zero initialized value means, that no filament is depleted.
-static uint8_t depleted;
-static const uint8_t filamentCount = 5;
+SpoolJoin spooljoin;
 
-//! @return binary 1 for all filaments
-//! @par fCount number of filaments
-static constexpr uint8_t allDepleted(uint8_t fCount)
+SpoolJoin::SpoolJoin()
+    : status(EEPROM::Unknown)
+    , currentMMUSlot(0)
 {
-    return fCount == 1 ? 1 : ((1 << (fCount - 1)) | allDepleted(fCount - 1));
 }
 
-//! @brief Is filament available for printing?
-//! @par filament Filament number to be checked
-//! @retval true Filament is available for printing.
-//! @retval false Filament is not available for printing.
-static bool loaded(uint8_t filament)
+void SpoolJoin::updateSpoolJoinStatus(EEPROM newStatus)
 {
-    if (depleted & (1 << filament)) return false;
-    return true;
+    status = newStatus;
+    eeprom_write_byte((uint8_t*)EEPROM_AUTO_DEPLETE, (uint8_t)status);
 }
 
-//! @brief Mark filament as not available for printing.
-//! @par filament filament to be marked
-void ad_markDepleted(uint8_t filament)
+void SpoolJoin::initSpoolJoinStatus()
 {
-    assert(filament < filamentCount);
-    if (filament < filamentCount)
+    EEPROM currentStatus = (EEPROM)eeprom_read_byte((uint8_t*)EEPROM_AUTO_DEPLETE);
+    if( currentStatus == EEPROM::Empty)
     {
-        depleted |= 1 << filament;
+        // By default SpoolJoin is disabled
+        updateSpoolJoinStatus(EEPROM::Disabled);
+    } else {
+        updateSpoolJoinStatus(currentStatus);
     }
 }
 
-//! @brief Mark filament as available for printing.
-//! @par filament filament to be marked
-void ad_markLoaded(uint8_t filament)
+void SpoolJoin::toggleSpoolJoin()
 {
-    assert(filament < filamentCount);
-    if (filament < filamentCount)
+    if (eeprom_read_byte((uint8_t*)EEPROM_AUTO_DEPLETE) == (uint8_t)EEPROM::Disabled)
     {
-        depleted &= ~(1 << filament);
+        eeprom_write_byte((uint8_t*)EEPROM_AUTO_DEPLETE, (uint8_t)EEPROM::Enabled);
+    } else {
+        eeprom_write_byte((uint8_t*)EEPROM_AUTO_DEPLETE, (uint8_t)EEPROM::Disabled);
     }
 }
 
-//! @brief Get alternative filament, which is not depleted
-//! @par filament filament
-//! @return Filament, if it is depleted, returns next available,
-//! if all filaments are depleted, returns filament function parameter.
-uint8_t ad_getAlternative(uint8_t filament)
+uint8_t SpoolJoin::isSpoolJoinEnabled()
 {
-    assert(filament < filamentCount);
-    for (uint8_t i = 0; i<filamentCount; ++i)
+    if(eeprom_read_byte((uint8_t*)EEPROM_AUTO_DEPLETE) == (uint8_t)EEPROM::Enabled
+#ifdef FILAMENT_SENSOR
+    && fsensor.isReady()
+#endif
+    )
     {
-        uint8_t nextFilament = (filament + i) % filamentCount;
-        if (loaded(nextFilament)) return nextFilament;
+        return 1;
+    } else {
+        return 0;
     }
-    return filament;
 }
 
-//! @brief Are all filaments depleted?
-//! @retval true All filaments are depleted.
-//! @retval false All filaments are not depleted.
-bool ad_allDepleted()
+
+uint8_t SpoolJoin::nextSlot()
 {
-    if (allDepleted(filamentCount) == depleted)
-    {
-        return true;
-    }
-    return false;
+    if (currentMMUSlot == 4) currentMMUSlot = 0;
+    else currentMMUSlot++;
+
+    return currentMMUSlot;
+}
+
 }

+ 52 - 13
Firmware/AutoDeplete.h

@@ -1,17 +1,56 @@
-//! @file
-//! @author: Marek Bel
-//! @brief Filament auto deplete engine for multi-material prints with MMUv2 (Now marketed as SpoolJoin)
-//!
-//! Interface for marking MMUv2 filaments as depleted and getting alternative filament for printing.
+/// @file
+#pragma once
+#include <stdint.h>
+#include "eeprom.h"
 
-#ifndef AUTODEPLETE_H
-#define AUTODEPLETE_H
+// See documentation here: https://help.prusa3d.com/article/spooljoin-mmu2s_134252
 
-#include <stdint.h>
+namespace SpoolJoin {
+
+class SpoolJoin {
+public:
+    SpoolJoin();
+
+    enum class EEPROM : uint8_t {
+        Unknown, ///< SpoolJoin is unknown while printer is booting up
+        Enabled, ///< SpoolJoin is enabled in EEPROM
+        Disabled, ///< SpoolJoin is disabled in EEPROM
+        NA, ///< SpoolJoin is 'Not Applicable' when Fsensor is faulty
+        Empty = 0xFF ///< EEPROM has not been set before and all bits are 1 (0xFF) - either a new printer or user erased the memory
+    };
+
+    /// @brief Called when EEPROM is ready to be read
+    void initSpoolJoinStatus();
+
+    /// @brief Enable SpoolJoin
+    inline void enableSpoolJoin() { updateSpoolJoinStatus(EEPROM::Enabled); };
+
+    /// @brief Disable SpoolJoin
+    inline void disableSpoolJoin() { updateSpoolJoinStatus(EEPROM::Disabled); };
+
+    /// @brief Toggle SpoolJoin
+    static void toggleSpoolJoin();
+
+    /// @brief Check if SpoolJoin is enabled
+    uint8_t isSpoolJoinEnabled();
+
+    /// @brief Fetch the next slot number should count from 0 to 4.
+    /// When filament slot 4 is depleted, the next slot should be 0.
+    /// @returns the next slot, ranges from 0 to 4
+    uint8_t nextSlot();
+
+private:
+    /// @brief Update EEPROM
+    /// @param newStatus Status to write into EEPROM
+    void updateSpoolJoinStatus(EEPROM newStatus);
+
+    /// @brief SpoolJoin status
+    enum EEPROM status;
+
+    /// @brief Currently used slot, ranges from 0 to 4
+    uint8_t currentMMUSlot;
+};
 
-void ad_markDepleted(uint8_t filament);
-void ad_markLoaded(uint8_t filament);
-uint8_t ad_getAlternative(uint8_t filament);
-bool ad_allDepleted();
+extern SpoolJoin spooljoin;
 
-#endif /* AUTODEPLETE_H */
+} // namespace SpoolJoin

+ 8 - 6
Firmware/Marlin_main.cpp

@@ -1115,6 +1115,7 @@ void setup()
 	if (eeprom_read_byte((uint8_t *)EEPROM_MMU_ENABLED)) {
 		MMU2::mmu2.Start();
 	}
+	SpoolJoin::spooljoin.initSpoolJoinStatus();
 
 	//SERIAL_ECHOPAIR("Active sheet before:", static_cast<unsigned long int>(eeprom_read_byte(&(EEPROM_Sheets_base->active_sheet))));
 
@@ -3510,12 +3511,13 @@ static void mmu_M600_unload_filament() {
 /// @brief load filament for mmu v2
 /// @par nozzle_temp nozzle temperature to load filament
 static void mmu_M600_load_filament(bool automatic, float nozzle_temp) {
-    // TODO: Only ask for the slot if automatic/ SpoolJoin is off
-    uint8_t slot = choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER));
-    // TODO SpoolJoin
-    /*if (automatic) {
-        tmp_extruder = ad_getAlternative(tmp_extruder);
-    }*/
+    uint8_t slot;
+    if (automatic) {
+        slot = SpoolJoin::spooljoin.nextSlot();
+    } else {
+        // Only ask for the slot if automatic/SpoolJoin is off
+        slot = choose_menu_P(_T(MSG_SELECT_EXTRUDER), _T(MSG_EXTRUDER));
+    }
 
     setTargetHotend(nozzle_temp, active_extruder);
 

+ 6 - 7
Firmware/Tcodes.cpp

@@ -57,14 +57,13 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) {
         }
     } else {
         SChooseFromMenu selectedSlot;
-//        if (strchr_pointer[index] == '?')
-//            selectedSlot = TCodeChooseFromMenu();
-//        else {
+        if (strchr_pointer[index] == '?') {
+            selectedSlot = TCodeChooseFromMenu();
+        } else if (MMU2::mmu2.Enabled() && SpoolJoin::spooljoin.isSpoolJoinEnabled()) {
+            selectedSlot.slot = SpoolJoin::spooljoin.nextSlot();
+        } else {
             selectedSlot.slot = codeValue;
-//            if (MMU2::mmu2.Enabled() && lcd_autoDepleteEnabled()) {
-//                selectedSlot.slot = ad_getAlternative(selectedSlot.slot);
-//            }
-//        }
+        }
         st_synchronize();
 
         if (MMU2::mmu2.Enabled()) {

+ 15 - 0
Firmware/mmu2.cpp

@@ -15,6 +15,7 @@
 #include "temperature.h"
 #include "ultralcd.h"
 #include "cardreader.h" // for IS_SD_PRINTING
+#include "AutoDeplete.h"
 
 // As of FW 3.12 we only support building the FW with only one extruder, all the multi-extruder infrastructure will be removed.
 // Saves at least 800B of code size
@@ -211,6 +212,20 @@ void MMU2::mmu_loop() {
         ReportErrorHook((uint16_t)lastErrorCode, mmu2.MMUCurrentErrorCode() == ErrorCode::OK ? ErrorSourcePrinter : ErrorSourceMMU);
     }
 
+    // Check for FINDA filament runout
+    if (!FindaDetectsFilament() && CHECK_FSENSOR) {
+        stop_and_save_print_to_ram(0, 0);
+        restore_print_from_ram_and_continue(0);
+        if (SpoolJoin::spooljoin.isSpoolJoinEnabled() && get_current_tool() != (uint8_t)FILAMENT_UNKNOWN) // Can't auto if F=?
+        {
+            enquecommand_front_P(PSTR("M600 AUTO")); //save print and run M600 command
+        }
+        else
+        {
+            enquecommand_front_P(PSTR("M600")); //save print and run M600 command
+        }
+    }
+
     avoidRecursion = false;
 }
 

+ 2 - 25
Firmware/ultralcd.cpp

@@ -37,6 +37,7 @@
 #include "sound.h"
 
 #include "mmu2.h"
+#include "AutoDeplete.h"
 
 #include "static_assert.h"
 #include "first_lay_cal.h"
@@ -76,9 +77,6 @@ bool isPrintPaused = false;
 static ShortTimer display_time; //just timer for showing pid finished message on lcd;
 static uint16_t pid_temp = DEFAULT_PID_TEMP;
 
-static bool lcd_autoDeplete;
-
-
 static float manual_feedrate[] = MANUAL_FEEDRATE;
 
 /* LCD message status */
@@ -3958,15 +3956,6 @@ static void lcd_wizard_load() {
     //enquecommand_P(PSTR("M701"));
 }
 
-bool lcd_autoDepleteEnabled()
-{
-    return (lcd_autoDeplete
-#ifdef FILAMENT_SENSOR // @todo leptun: should be removed during mmu2 refactoring - needs checking
-    && fsensor.isReady()
-#endif
-    );
-}
-
 static void wizard_lay1cal_message(bool cold)
 {
     lcd_show_fullscreen_message_and_wait_P(
@@ -4302,12 +4291,6 @@ static void lcd_fsensor_settings_menu() {
 
 #endif //FILAMENT_SENSOR
 
-static void auto_deplete_switch()
-{
-    lcd_autoDeplete = !lcd_autoDeplete;
-    eeprom_update_byte((unsigned char *)EEPROM_AUTO_DEPLETE, lcd_autoDeplete);
-}
-
 static void settingsAutoDeplete()
 {
     if (MMU2::mmu2.Enabled())
@@ -4319,7 +4302,7 @@ static void settingsAutoDeplete()
         else
 #endif //FILAMENT_SENSOR
         {
-            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), lcd_autoDeplete ? _T(MSG_ON) : _T(MSG_OFF), auto_deplete_switch);
+            MENU_ITEM_TOGGLE_P(_T(MSG_AUTO_DEPLETE), SpoolJoin::spooljoin.isSpoolJoinEnabled() ? _T(MSG_ON) : _T(MSG_OFF), SpoolJoin::spooljoin.toggleSpoolJoin);
         }
     }
 }
@@ -7538,12 +7521,6 @@ void menu_action_sddirectory(const char* filename)
 
 void ultralcd_init()
 {
-    {
-        uint8_t autoDepleteRaw = eeprom_read_byte(reinterpret_cast<uint8_t*>(EEPROM_AUTO_DEPLETE));
-        if (0xff == autoDepleteRaw) lcd_autoDeplete = false;
-        else lcd_autoDeplete = autoDepleteRaw;
-
-    }
     backlight_init();
 	lcd_init();
 	lcd_refresh();

+ 0 - 1
Firmware/ultralcd.h

@@ -215,7 +215,6 @@ void lcd_language();
 #endif
 
 void lcd_wizard();
-bool lcd_autoDepleteEnabled();
 
 //! @brief Wizard state
 enum class WizState : uint8_t