Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PFW-1206: Implement Marlin's print job timer and add M75-M78 #4493

Merged
merged 6 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ set(FW_SOURCES
spi.c
SpoolJoin.cpp
stepper.cpp
stopwatch.cpp
strtod.c
swi2c.c
Tcodes.cpp
Expand Down
7 changes: 1 addition & 6 deletions Firmware/Marlin.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,18 +262,13 @@ extern float retract_length_swap;
extern float retract_recover_length_swap;
#endif

extern uint32_t starttime; // milliseconds
extern uint32_t pause_time; // milliseconds
extern uint32_t start_pause_print; // milliseconds
extern ShortTimer usb_timer;
extern bool processing_tcode;
extern bool homing_flag;
extern uint32_t total_filament_used; // mm/100 or 10um

/// @brief Save print statistics to EEPROM
/// @param _total_filament_used has unit mm/100 or 10um
/// @param _total_print_time has unit minutes, for example 123 minutes
void save_statistics(uint32_t _total_filament_used, uint32_t _total_print_time);
void save_statistics();

extern int fan_edge_counter[2];
extern int fan_speed[2];
Expand Down
92 changes: 66 additions & 26 deletions Firmware/Marlin_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#include "Tcodes.h"
#include "Dcodes.h"
#include "SpoolJoin.h"
#include "stopwatch.h"

#ifndef LA_NOCOMPAT
#include "la10compat.h"
Expand Down Expand Up @@ -174,7 +175,7 @@ static LongTimer crashDetTimer;

bool mesh_bed_leveling_flag = false;

uint32_t total_filament_used;
uint32_t total_filament_used; // unit mm/100 or 10um
HeatingStatus heating_status;
int fan_edge_counter[2];
int fan_speed[2];
Expand Down Expand Up @@ -289,9 +290,6 @@ static uint32_t max_inactive_time = 0;
static uint32_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l;
static uint32_t safetytimer_inactive_time = DEFAULT_SAFETYTIMER_TIME_MINS*60*1000ul;

uint32_t starttime;
uint32_t pause_time;
uint32_t start_pause_print;
ShortTimer usb_timer;

bool Stopped=false;
Expand Down Expand Up @@ -509,12 +507,12 @@ void servo_init()
}

bool __attribute__((noinline)) printJobOngoing() {
return (IS_SD_PRINTING || usb_timer.running());
return (IS_SD_PRINTING || usb_timer.running() || print_job_timer.isRunning());
}

bool __attribute__((noinline)) printer_active() {
return printJobOngoing()
|| isPrintPaused
|| print_job_timer.isPaused()
|| saved_printing
|| (lcd_commands_type != LcdCommands::Idle)
|| MMU2::mmu2.MMU_PRINT_SAVED()
Expand All @@ -535,7 +533,7 @@ bool check_fsensor() {
bool __attribute__((noinline)) babystep_allowed() {
return ( !homing_flag
&& !mesh_bed_leveling_flag
&& !isPrintPaused
&& !print_job_timer.isPaused()
&& ((lcd_commands_type == LcdCommands::Layer1Cal && CHECK_ALL_HEATERS)
|| printJobOngoing()
|| lcd_commands_type == LcdCommands::Idle
Expand Down Expand Up @@ -633,7 +631,7 @@ void crashdet_detected(uint8_t mask)

void crashdet_recover()
{
if (!isPrintPaused) crashdet_restore_print_and_continue();
if (!print_job_timer.isPaused()) crashdet_restore_print_and_continue();
if (lcd_crash_detect_enabled()) tmc2130_sg_stop_on_crash = true;
}

Expand Down Expand Up @@ -1731,7 +1729,7 @@ void loop()
KEEPALIVE_STATE(NOT_BUSY);
}

if (isPrintPaused && saved_printing_type == PowerPanic::PRINT_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing.
if (print_job_timer.isPaused() && saved_printing_type == PowerPanic::PRINT_TYPE_USB) { //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing.
usb_timer.start();
}
else if (usb_timer.expired(10000)) { //just need to check if it expired. Nothing else is needed to be done.
Expand Down Expand Up @@ -1828,7 +1826,7 @@ void loop()
}
//check heater every n milliseconds
manage_heater();
manage_inactivity(isPrintPaused);
manage_inactivity(print_job_timer.isPaused());
checkHitEndstops();
lcd_update(0);
#ifdef TMC2130
Expand Down Expand Up @@ -3425,7 +3423,7 @@ static void gcode_M600(const bool automatic, const float x_position, const float
fanSpeed = 0;

// Retract E
if (!isPrintPaused)
if (!print_job_timer.isPaused())
{
current_position[E_AXIS] += e_shift;
plan_buffer_line_curposXYZE(FILAMENTCHANGE_RFEED);
Expand Down Expand Up @@ -3488,7 +3486,7 @@ static void gcode_M600(const bool automatic, const float x_position, const float

// Feed a little of filament to stabilize pressure
if (!automatic) {
if (isPrintPaused)
if (print_job_timer.isPaused())
{
// Return to retracted state during a pause
// @todo is retraction really needed? E-position is reverted a few lines below
Expand Down Expand Up @@ -3524,7 +3522,7 @@ static void gcode_M600(const bool automatic, const float x_position, const float
feedmultiply = feedmultiplyBckp;
enquecommandf_P(MSG_M220, feedmultiplyBckp);
}
if (isPrintPaused) lcd_setstatuspgm(_T(MSG_PRINT_PAUSED));
if (print_job_timer.isPaused()) lcd_setstatuspgm(_T(MSG_PRINT_PAUSED));
else lcd_setstatuspgm(MSG_WELCOME);
custom_message_type = CustomMsg::Status;
}
Expand Down Expand Up @@ -5256,7 +5254,7 @@ void process_commands()
### M24 - Start SD print <a href="https://reprap.org/wiki/G-code#M24:_Start.2Fresume_SD_print">M24: Start/resume SD print</a>
*/
case 24:
if (isPrintPaused)
if (print_job_timer.isPaused())
lcd_resume_print();
else
{
Expand All @@ -5271,7 +5269,7 @@ void process_commands()
}

card.startFileprint();
starttime=_millis();
print_job_timer.start();
if (MMU2::mmu2.Enabled())
{
if (MMU2::mmu2.FindaDetectsFilament() && !fsensor.getFilamentPresent())
Expand Down Expand Up @@ -5389,7 +5387,7 @@ void process_commands()
la10c_reset();
#endif
}
starttime=_millis(); // procedure calls count as normal print time.
print_job_timer.start(); // procedure calls count as normal print time.
}
}
} break;
Expand All @@ -5413,7 +5411,7 @@ void process_commands()
case 31: //M31 take time since the start of the SD print or an M109 command
{
char time[30];
uint32_t t = (_millis() - starttime) / 1000;
uint32_t t = print_job_timer.duration();
int16_t sec, min;
min = t / 60;
sec = t % 60;
Expand Down Expand Up @@ -5875,6 +5873,48 @@ SERIAL_PROTOCOLPGM("\n\n");
break;
}

/*!
### M75 - Start the print job timer <a href="https://reprap.org/wiki/G-code#M75:_Start_the_print_job_timer">M75: Start the print job timer</a>
*/
case 75:
{
print_job_timer.start();
break;
}

/*!
### M76 - Pause the print job timer <a href="https://reprap.org/wiki/G-code#M76:_Pause_the_print_job_timer">M76: Pause the print job timer</a>
*/
case 76:
{
print_job_timer.pause();
break;
}

/*!
### M77 - Stop the print job timer <a href="https://reprap.org/wiki/G-code#M77:_Stop_the_print_job_timer">M77: Stop the print job timer</a>
*/
case 77:
{
print_job_timer.stop();
save_statistics();
break;
}

/*!
### M78 - Show statistical information about the print jobs <a href="https://reprap.org/wiki/G-code#M78:_Show_statistical_information_about_the_print_jobs">M78: Show statistical information about the print jobs</a>
*/
case 78:
{
// @todo useful for maintenance notifications
SERIAL_ECHOPGM("STATS ");
SERIAL_ECHO(eeprom_read_dword((uint32_t *)EEPROM_TOTALTIME));
SERIAL_ECHOPGM(" min ");
SERIAL_ECHO(eeprom_read_dword((uint32_t *)EEPROM_FILAMENTUSED));
SERIAL_ECHOLNPGM(" cm.");
break;
}

/*!
### M79 - Start host timer <a href="https://reprap.org/wiki/G-code#M79:_Start_host_timer">M79: Start host timer</a>
Start the printer-host enable keep-alive timer. While the timer has not expired, the printer will enable host specific features.
Expand Down Expand Up @@ -6050,8 +6090,7 @@ SERIAL_PROTOCOLPGM("\n\n");
LCD_MESSAGERPGM(_T(MSG_HEATING_COMPLETE));
heating_status = HeatingStatus::EXTRUDER_HEATING_COMPLETE;
prusa_statistics(2);

//starttime=_millis();

previous_millis_cmd.start();
}
break;
Expand Down Expand Up @@ -7743,7 +7782,7 @@ SERIAL_PROTOCOLPGM("\n\n");
SERIAL_ECHOPGM("Z:");
SERIAL_ECHOLN(pause_position[Z_AXIS]);
*/
if (!isPrintPaused) {
if (!print_job_timer.isPaused()) {
st_synchronize();
ClearToSend(); //send OK even before the command finishes executing because we want to make sure it is not skipped because of cmdqueue_pop_front();
cmdqueue_pop_front(); //trick because we want skip this command (M601) after restore
Expand All @@ -7757,7 +7796,7 @@ SERIAL_PROTOCOLPGM("\n\n");
*/
case 602:
{
if (isPrintPaused) lcd_resume_print();
if (print_job_timer.isPaused()) lcd_resume_print();
}
break;

Expand Down Expand Up @@ -9631,7 +9670,7 @@ void ThermalStop(bool allow_recovery)

// Either pause or stop the print
if(allow_recovery && printJobOngoing()) {
if (!isPrintPaused) {
if (!print_job_timer.isPaused()) {
lcd_setalertstatuspgm(_T(MSG_PAUSED_THERMAL_ERROR), LCD_STATUS_CRITICAL);

// we cannot make a distinction for the host here, the pause must be instantaneous
Expand Down Expand Up @@ -9765,13 +9804,15 @@ void setPwmFrequency(uint8_t pin, int val)
}
#endif //FAST_PWM_FAN

void save_statistics(uint32_t _total_filament_used, uint32_t _total_print_time) {
void save_statistics() {
uint32_t _previous_filament = eeprom_init_default_dword((uint32_t *)EEPROM_FILAMENTUSED, 0); //_previous_filament unit: meter
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); // EEPROM_TOTALTIME unit: min
eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (_total_filament_used / 1000));
uint32_t time_minutes = print_job_timer.duration() / 60;
eeprom_update_dword((uint32_t *)EEPROM_TOTALTIME, _previous_time + time_minutes); // EEPROM_TOTALTIME unit: min
eeprom_update_dword((uint32_t *)EEPROM_FILAMENTUSED, _previous_filament + (total_filament_used / 1000));

print_job_timer.reset();
total_filament_used = 0;

if (MMU2::mmu2.Enabled()) {
Expand Down Expand Up @@ -10460,7 +10501,6 @@ float temp_compensation_pinda_thermistor_offset(float temperature_pinda)
void long_pause() //long pause print
{
st_synchronize();
start_pause_print = _millis();

// Stop heaters
heating_status = HeatingStatus::NO_HEATING;
Expand Down
7 changes: 4 additions & 3 deletions Firmware/Prusa_farm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "ultralcd.h"
#include "Filament_sensor.h"
#include "language.h"
#include "stopwatch.h"

#ifdef PRUSA_FARM
uint8_t farm_mode = 0;
Expand Down Expand Up @@ -92,8 +93,8 @@ static void prusa_stat_printinfo() {
SERIAL_ECHOPGM("][FNM:");
SERIAL_ECHO(card.longFilename[0] ? card.longFilename : card.filename);
SERIAL_ECHOPGM("][TIM:");
if (starttime != 0) {
SERIAL_ECHO((_millis() - starttime) / 1000);
if (print_job_timer.isRunning()) {
SERIAL_ECHO(print_job_timer.duration());
}
else {
SERIAL_ECHO(0);
Expand Down Expand Up @@ -237,7 +238,7 @@ void prusa_statistics(uint8_t _message) {
if (busy_state == PAUSED_FOR_USER) {
prusa_statistics_case0(15);
}
else if (isPrintPaused) {
else if (print_job_timer.isPaused()) {
prusa_statistics_case0(14);
}
else if (IS_SD_PRINTING || (eFilamentAction != FilamentAction::None)) {
Expand Down
5 changes: 3 additions & 2 deletions Firmware/cardreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "language.h"
#include "Prusa_farm.h"
#include "power_panic.h"
#include "stopwatch.h"

#ifdef SDSUPPORT

Expand Down Expand Up @@ -556,7 +557,7 @@ uint32_t CardReader::getFileSize()

void CardReader::getStatus(bool arg_P)
{
if (isPrintPaused)
if (print_job_timer.isPaused())
{
if (saved_printing && (saved_printing_type == PowerPanic::PRINT_TYPE_SD))
SERIAL_PROTOCOLLNPGM("SD print paused");
Expand All @@ -577,7 +578,7 @@ void CardReader::getStatus(bool arg_P)
SERIAL_PROTOCOL(sdpos);
SERIAL_PROTOCOL('/');
SERIAL_PROTOCOLLN(filesize);
uint16_t time = ( _millis() - starttime ) / 60000U;
uint16_t time = print_job_timer.duration() / 60;
SERIAL_PROTOCOL((int)(time / 60));
SERIAL_PROTOCOL(':');
SERIAL_PROTOCOLLN((int)(time % 60));
Expand Down
8 changes: 4 additions & 4 deletions Firmware/cmdqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "meatpack.h"
#include "messages.h"
#include "language.h"
#include "stopwatch.h"

// Reserve BUFSIZE lines of length MAX_CMD_SIZE plus CMDBUFFER_RESERVE_FRONT.
char cmdbuffer[BUFSIZE * (MAX_CMD_SIZE + 1) + CMDBUFFER_RESERVE_FRONT];
Expand Down Expand Up @@ -366,7 +367,7 @@ void get_command()
}

// start of serial line processing loop
while (((MYSERIAL.available() > 0 && !saved_printing) || (MYSERIAL.available() > 0 && isPrintPaused)) && !cmdqueue_serial_disabled) { //is print is saved (crash detection or filament detection), dont process data from serial line
while (((MYSERIAL.available() > 0 && !saved_printing) || (MYSERIAL.available() > 0 && print_job_timer.isPaused())) && !cmdqueue_serial_disabled) { //is print is saved (crash detection or filament detection), dont process data from serial line

#ifdef ENABLE_MEATPACK
// MeatPack Changes
Expand Down Expand Up @@ -658,12 +659,11 @@ void get_command()

SERIAL_PROTOCOLLNRPGM(_n("Done printing file"));////MSG_FILE_PRINTED
char time[30];
uint32_t t = (_millis() - starttime - pause_time) / 60000;
pause_time = 0;
uint32_t t = print_job_timer.duration() / 60;
int hours, minutes;
minutes = t % 60;
hours = t / 60;
save_statistics(total_filament_used, t);
save_statistics();
sprintf_P(time, PSTR("%i hours %i minutes"),hours, minutes);
SERIAL_ECHO_START;
SERIAL_ECHOLN(time);
Expand Down
3 changes: 2 additions & 1 deletion Firmware/fancheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "messages.h"
#include "temperature.h"
#include "stepper.h"
#include "stopwatch.h"

#define FAN_CHECK_PERIOD 5000 //5s
#define FAN_CHECK_DURATION 100 //100ms
Expand Down Expand Up @@ -93,7 +94,7 @@ void fanSpeedError(unsigned char _fan) {

if (printJobOngoing()) {
// A print is ongoing, pause the print normally
if(!isPrintPaused) {
if(!print_job_timer.isPaused()) {
if (usb_timer.running())
lcd_pause_usb_print();
else
Expand Down
Loading
Loading