Revive MMU stats + LCD screens

This commit is contained in:
D.R.racer 2022-11-19 15:09:06 +01:00 committed by DRracer
parent fe11b7a247
commit 4eaabbf092
8 changed files with 93 additions and 82 deletions

View File

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

View File

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

View File

@ -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[];

View File

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

View File

@ -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; };
inline uint16_t TMCFailures()const { return tmcFailures; }
inline void IncrementTMCFailures() { ++tmcFailures; }
inline void ClearTMCFailures() { tmcFailures = 0; }
private:
// Increment the toolchange counter via SRAM to reserve EEPROM write cycles
inline void increment_tool_change_counter() { ++toolchange_counter; };
/// 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

View File

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

View File

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

View File

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