Ver Fonte

Revive MMU stats + LCD screens

D.R.racer há 1 ano atrás
pai
commit
4eaabbf092

+ 12 - 11
Firmware/Marlin_main.cpp

@@ -9747,20 +9747,21 @@ bool setTargetedHotend(int code, uint8_t &extruder)
   return false;
 }
 
-void save_statistics(unsigned long _total_filament_used, unsigned long _total_print_time) //_total_filament_used unit: mm/100; print time in s
-{
-	uint32_t _previous_filament = eeprom_init_default_dword((uint32_t *)EEPROM_FILAMENTUSED, 0); //_previous_filament unit: cm
-	uint32_t _previous_time = eeprom_init_default_dword((uint32_t *)EEPROM_TOTALTIME, 0); //_previous_time unit: min
+void save_statistics(unsigned long _total_filament_used, unsigned long _total_print_time) { //_total_filament_used unit: mm/100; print time in s
+    uint32_t _previous_filament = eeprom_init_default_dword((uint32_t *)EEPROM_FILAMENTUSED, 0); //_previous_filament unit: cm
+    uint32_t _previous_time = eeprom_init_default_dword((uint32_t *)EEPROM_TOTALTIME, 0);        //_previous_time unit: min
 
-	eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, _previous_time + (_total_print_time/60)); //EEPROM_TOTALTIME unit: min
-	eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (_total_filament_used / 1000));
+    eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, _previous_time + (_total_print_time / 60)); // EEPROM_TOTALTIME unit: min
+    eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (_total_filament_used / 1000));
 
-	total_filament_used = 0;
+    total_filament_used = 0;
 
-  if (MMU2::mmu2.Enabled())
-  {
-    MMU2::mmu2.update_tool_change_counter_eeprom();
-  }
+    if (MMU2::mmu2.Enabled()) {
+        eeprom_add_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT, MMU2::mmu2.ToolChangeCounter());
+        // @@TODO why were EEPROM_MMU_FAIL_TOT and EEPROM_MMU_LOAD_FAIL_TOT behaving differently - i.e. updated with every change?
+        MMU2::mmu2.ClearToolChangeCounter();
+        MMU2::mmu2.ClearTMCFailures(); // not stored into EEPROM
+    }
 }
 
 float calculate_extruder_multiplier(float diameter) {

+ 1 - 0
Firmware/messages.cpp

@@ -67,6 +67,7 @@ const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[] PROGMEM_I1 = ISTR("Measuring
 const char MSG_CALIBRATION[] PROGMEM_I1 = ISTR("Calibration"); ////MSG_CALIBRATION c=18
 const char MSG_MMU_FAILS[] PROGMEM_I1 = ISTR("MMU fails"); ////MSG_MMU_FAILS c=15
 const char MSG_MMU_LOAD_FAILS[] PROGMEM_I1 = ISTR("MMU load fails"); ////MSG_MMU_LOAD_FAILS c=15
+const char MSG_MMU_POWER_FAILS[] PROGMEM_I1 = ISTR("MMU power fails"); ////MSG_MMU_POWER_FAILS c=15
 const char MSG_NO[] PROGMEM_I1 = ISTR("No"); ////MSG_NO c=4
 const char MSG_NOZZLE[] PROGMEM_I1 = ISTR("Nozzle"); ////MSG_NOZZLE c=10
 const char MSG_PAPER[] PROGMEM_I1 = ISTR("Place a sheet of paper under the nozzle during the calibration of first 4 points. If the nozzle catches the paper, power off the printer immediately."); ////MSG_PAPER c=20 r=10

+ 1 - 0
Firmware/messages.h

@@ -72,6 +72,7 @@ extern const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1[];
 extern const char MSG_CALIBRATION[];
 extern const char MSG_MMU_FAILS[];
 extern const char MSG_MMU_LOAD_FAILS[];
+extern const char MSG_MMU_POWER_FAILS[];
 extern const char MSG_NO[];
 extern const char MSG_NOZZLE[];
 extern const char MSG_PAPER[];

+ 23 - 25
Firmware/mmu2.cpp

@@ -119,6 +119,7 @@ MMU2::MMU2()
     , inAutoRetry(false)
     , retryAttempts(MAX_RETRIES)
     , toolchange_counter(0)
+    , tmcFailures(0)
 {
 }
 
@@ -305,12 +306,6 @@ void MMU2::DecrementRetryAttempts() {
     }
 }
 
-void MMU2::update_tool_change_counter_eeprom() {
-    uint32_t toolchanges = eeprom_read_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT);
-    eeprom_update_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT, toolchanges + (uint32_t)read_toolchange_counter());
-    reset_toolchange_counter();
-}
-
 void MMU2::ToolChangeCommon(uint8_t slot){
     tool_change_extruder = slot;
     do {
@@ -319,10 +314,13 @@ void MMU2::ToolChangeCommon(uint8_t slot){
             if( manage_response(true, true) )
                 break;
             // otherwise: failed to perform the command - unload first and then let it run again
+            IncrementMMUFails();
             unload();
             // if we run out of retries, we must do something ... may be raise an error screen and allow the user to do something
             // but honestly - if the MMU restarts during every toolchange,
             // something else is seriously broken and stopping a print is probably our best option.
+
+            // IncrementLoadFails(); // this should be contained in the while condition
         }
         // reset current position to whatever the planner thinks it is
         plan_set_e_position(current_position[E_AXIS]);
@@ -336,7 +334,7 @@ void MMU2::ToolChangeCommon(uint8_t slot){
     // @@TODO really report onto the serial? May be for the Octoprint? Not important now
     //        SERIAL_ECHO_START();
     //        SERIAL_ECHOLNPAIR(MSG_ACTIVE_EXTRUDER, int(extruder));
-    increment_tool_change_counter();
+    ++toolchange_counter;
 }
 
 bool MMU2::tool_change(uint8_t slot) {
@@ -378,16 +376,8 @@ bool MMU2::tool_change(char code, uint8_t slot) {
     case 'x': {
         set_extrude_min_temp(0); // Allow cold extrusion since Tx only loads to the gears not nozzle
         st_synchronize();
-        tool_change_extruder = slot;
-        logic.ToolChange(slot);
-        if( ! manage_response(false, false) ){
-            // @@TODO failed to perform the command - retry
-            ;
-        }
-        extruder = slot;
-        SpoolJoin::spooljoin.setSlot(slot);
+        ToolChangeCommon(slot); // the only difference was manage_response(false, false), but probably good enough
         set_extrude_min_temp(EXTRUDE_MINTEMP);
-        increment_tool_change_counter();
     } break;
 
     case 'c': {
@@ -442,9 +432,12 @@ bool MMU2::unload() {
 
         // we assume the printer managed to relieve filament tip from the gears,
         // so repeating that part in case of an MMU restart is not necessary
-        do {
+        for(;;) {
             logic.UnloadFilament();
-        } while( ! manage_response(false, true) );
+            if( manage_response(false, true) )
+                break;
+            IncrementMMUFails();
+        }
 
         Sound_MakeSound(e_SOUND_TYPE_StandardConfirm);
 
@@ -460,12 +453,14 @@ bool MMU2::cut_filament(uint8_t slot){
         return false;
 
     ReportingRAII rep(CommandInProgress::CutFilament);
-    logic.CutFilament(slot);
-    if( ! manage_response(false, true) ){
-        // @@TODO failed to perform the command - retry
-        ;
+
+    for(;;){
+        logic.CutFilament(slot);
+        if( manage_response(false, true) )
+            break;
+        IncrementMMUFails();
     }
-    
+
     return true;
 }
 
@@ -493,9 +488,12 @@ bool MMU2::load_filament(uint8_t slot) {
     FullScreenMsg(_T(MSG_LOADING_FILAMENT), slot);
 
     ReportingRAII rep(CommandInProgress::LoadFilament);
-    do {
+    for(;;) {
         logic.LoadFilament(slot);
-    } while( ! manage_response(false, false) );
+        if( manage_response(false, false) )
+            break;
+        IncrementMMUFails();
+    }
 
     Sound_MakeSound(e_SOUND_TYPE_StandardConfirm);
 

+ 7 - 10
Firmware/mmu2.h

@@ -195,21 +195,17 @@ public:
     // Called by the MMU protocol when a sent button is acknowledged.
     void DecrementRetryAttempts();
 
-    /// Updates toolchange counter in EEPROM
-    /// ATmega2560 EEPROM has only 100'000 write/erase cycles
-    /// so we can't call this function on every tool change.
-    void update_tool_change_counter_eeprom();
-
     /// @return count for toolchange in current print
-    inline uint16_t read_toolchange_counter() const { return toolchange_counter; };
+    inline uint16_t ToolChangeCounter() const { return toolchange_counter; };
 
     /// Set toolchange counter to zero
-    inline void reset_toolchange_counter() { toolchange_counter = 0; };
+    inline void ClearToolChangeCounter() { toolchange_counter = 0; };
 
-private:
-    // Increment the toolchange counter via SRAM to reserve EEPROM write cycles
-    inline void increment_tool_change_counter() { ++toolchange_counter; };
+    inline uint16_t TMCFailures()const { return tmcFailures; }
+    inline void IncrementTMCFailures() { ++tmcFailures; }
+    inline void ClearTMCFailures() { tmcFailures = 0; }
 
+private:
     /// Reset the retryAttempts back to the default value
     void ResetRetryAttempts();
     /// Perform software self-reset of the MMU (sends an X0 command)
@@ -315,6 +311,7 @@ private:
     bool inAutoRetry;
     uint8_t retryAttempts;
     uint16_t toolchange_counter;
+    uint16_t tmcFailures;
 };
 
 /// following Marlin's way of doing stuff - one and only instance of MMU implementation in the code base

+ 23 - 9
Firmware/mmu2_reporting.cpp

@@ -220,8 +220,7 @@ enum class ReportErrorHookStates : uint8_t {
 enum ReportErrorHookStates ReportErrorHookState = ReportErrorHookStates::RENDER_ERROR_SCREEN;
 
 void ReportErrorHook(uint16_t ec) {
-    if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && mmu2.MMULastErrorSource() == MMU2::ErrorSourceMMU)
-    {
+    if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && mmu2.MMULastErrorSource() == MMU2::ErrorSourceMMU) {
         // If the error code suddenly changes to OK, that means
         // a button was pushed on the MMU and the LCD should
         // dismiss the error screen until MMU raises a new error
@@ -230,17 +229,23 @@ void ReportErrorHook(uint16_t ec) {
 
     const uint8_t ei = PrusaErrorCodeIndex(ec);
 
-    switch ((uint8_t)ReportErrorHookState)
-    {
+    switch ((uint8_t)ReportErrorHookState) {
     case (uint8_t)ReportErrorHookStates::RENDER_ERROR_SCREEN:
         ReportErrorHookStaticRender(ei);
         ReportErrorHookState = ReportErrorHookStates::MONITOR_SELECTION;
-        // Fall through
+        IncrementMMUFails();
+
+        // check if it is a "power" failure - we consider TMC-related errors as power failures
+        if( (uint16_t)ec & 0x7e00 ){ // @@TODO can be optimized to uint8_t operation
+            // TMC-related errors are from 0x8200 higher
+            // we can increment a power error at this spot
+            mmu2.IncrementTMCFailures();
+        }
+        [[fallthrough]];
     case (uint8_t)ReportErrorHookStates::MONITOR_SELECTION:
         mmu2.is_mmu_error_monitor_active = true;
         ReportErrorHookDynamicRender(); // Render dynamic characters
-        switch (ReportErrorHookMonitor(ei))
-        {
+        switch (ReportErrorHookMonitor(ei)) {
             case 0:
                 // No choice selected, return to loop()
                 break;
@@ -276,8 +281,7 @@ void ReportErrorHook(uint16_t ec) {
 }
 
 void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
-    if (cip != CommandInProgress::NoCommand)
-    {
+    if (cip != CommandInProgress::NoCommand) {
         custom_message_type = CustomMsg::MMUProgress;
         lcd_setstatuspgm( _T(ProgressCodeToText(ec)) );
     } else {
@@ -288,4 +292,14 @@ void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
     }
 }
 
+void IncrementLoadFails(){
+    eeprom_increment_byte((uint8_t *)EEPROM_MMU_LOAD_FAIL);
+    eeprom_increment_word((uint16_t *)EEPROM_MMU_LOAD_FAIL_TOT);
+}
+
+void IncrementMMUFails(){
+    eeprom_increment_byte((uint8_t *)EEPROM_MMU_FAIL);
+    eeprom_increment_word((uint16_t *)EEPROM_MMU_FAIL_TOT);
+}
+
 } // namespace MMU2

+ 7 - 0
Firmware/mmu2_reporting.h

@@ -46,4 +46,11 @@ bool MMUAvailable();
 /// Global Enable/Disable use MMU (to be stored in EEPROM)
 bool UseMMU();
 
+/// Increments EEPROM cell - number of failed loads into the nozzle
+/// Note: technically, this is not an MMU error but an error of the printer.
+void IncrementLoadFails();
+
+/// Increments EEPROM cell - number of MMU errors
+void IncrementMMUFails();
+
 } // namespace

+ 19 - 27
Firmware/ultralcd.cpp

@@ -1123,11 +1123,14 @@ static void lcd_menu_fails_stats_mmu()
 //! |                    |
 //! ----------------------
 //! @endcode
-static void lcd_menu_fails_stats_mmu_print()
-{
-	lcd_timeoutToStatus.stop(); //infinite timeout
+static void lcd_menu_fails_stats_mmu_print() {
+    lcd_timeoutToStatus.stop(); //infinite timeout
     lcd_home();
-    lcd_printf_P(PSTR("%S\n" " %-16.16S%-3d\n" " %-16.16S%-3d"), 
+    lcd_printf_P(
+        PSTR("%S\n"
+             " %-16.16S%-3d\n"
+             " %-16.16S%-3d"
+        ),
         _T(MSG_LAST_PRINT_FAILURES),
         _T(MSG_MMU_FAILS), clamp999( eeprom_read_byte((uint8_t*)EEPROM_MMU_FAIL) ),
         _T(MSG_MMU_LOAD_FAILS), clamp999( eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL) ));
@@ -1144,31 +1147,20 @@ static void lcd_menu_fails_stats_mmu_print()
 //! | MMU power fails 000|	MSG_MMU_POWER_FAILS c=15
 //! ----------------------
 //! @endcode
-//! @todo Positioning of the messages and values on LCD aren't fixed to their exact place. This causes issues with translations.
-static void lcd_menu_fails_stats_mmu_total()
-{
-    typedef struct
-    {
-        bool initialized;              // 1byte
-    } _menu_data_t;
-    static_assert(sizeof(menu_data)>= sizeof(_menu_data_t),"_menu_data_t doesn't fit into menu_data");
-    _menu_data_t* _md = (_menu_data_t*)&(menu_data[0]);
-    if(_md->initialized) {
-        MMU2::mmu2.get_statistics();
-        lcd_timeoutToStatus.stop(); //infinite timeout
-        _md->initialized = false;
-    }
+static void lcd_menu_fails_stats_mmu_total() {
+    lcd_timeoutToStatus.stop(); //infinite timeout
     lcd_home();
-    lcd_printf_P(PSTR("%S\n" " %-16.16S%-3d\n"/* " %-16.16S%-3d\n" " %-16.16S%-3d"*/), 
+    lcd_printf_P(
+        PSTR("%S\n"
+             " %-16.16S%-3d\n"
+             " %-16.16S%-3d\n"
+             " %-16.16S%-3d"
+        ),
         _T(MSG_TOTAL_FAILURES),
-        _T(MSG_MMU_FAILS), clamp999( MMU2::mmu2.TotalFailStatistics() ));//,
-        //_T(MSG_MMU_LOAD_FAILS), clamp999( eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) ),
-        //_i("MMU power fails"), clamp999( mmu_power_failures )); ////MSG_MMU_POWER_FAILS c=15
-    if (lcd_clicked())
-    {
-        lcd_quick_feedback();
-        menu_back();
-    }
+        _T(MSG_MMU_FAILS), clamp999( eeprom_read_word((uint16_t*)EEPROM_MMU_FAIL_TOT) ),
+        _T(MSG_MMU_LOAD_FAILS), clamp999( eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT) ),
+        _i("MMU power fails"), clamp999( MMU2::mmu2.TMCFailures() ));
+    menu_back_if_clicked_fb();
 }
 
 //! @brief Show Total Failures Statistics MMU