diff --git a/.travis.yml b/.travis.yml
index a2e58f228..fecb82a8d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -139,7 +139,7 @@ script:
### I2C PANELS ###
#
# LCD_I2C_SAINSMART_YWROBOT
- # Failing at the moment needs different library
+ # Failing at the moment needs different library
#- restore_configs
#- opt_enable LCD_I2C_SAINSMART_YWROBOT
#- build_marlin
@@ -199,6 +199,12 @@ script:
- opt_set_adv Z2_MAX_PIN 2
- build_marlin
#
+ # Test PRINTCOUNTER
+ #
+ - restore_configs
+ - opt_enable PRINTCOUNTER
+ - build_marlin
+ #
#
######## Example Configurations ##############
#
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 37e5ea20b..e0b9a2ff4 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -757,6 +757,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 110
#define ABS_PREHEAT_FAN_SPEED 0 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index cc08d724b..9cd13c90e 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -65,7 +65,11 @@ typedef unsigned long millis_t;
#include "WString.h"
-#include "stopwatch.h"
+#if ENABLED(PRINTCOUNTER)
+ #include "printcounter.h"
+#else
+ #include "stopwatch.h"
+#endif
#ifdef USBCON
#if ENABLED(BLUETOOTH)
@@ -364,7 +368,11 @@ extern bool axis_homed[3]; // axis[n].is_homed
#endif
// Print job timer
-extern Stopwatch print_job_timer;
+#if ENABLED(PRINTCOUNTER)
+ extern PrintCounter print_job_timer;
+#else
+ extern Stopwatch print_job_timer;
+#endif
// Handling multiple extruders pins
extern uint8_t active_extruder;
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index eac4acf10..18d69cada 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -137,6 +137,10 @@
* M33 - Get the longname version of a path
* M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
* M48 - Measure Z_Probe repeatability. M48 [P # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel]
+ * M75 - Start the print job timer
+ * M76 - Pause the print job timer
+ * M77 - Stop the print job timer
+ * M78 - Show statistical information about the print jobs
* M80 - Turn on Power Supply
* M81 - Turn off Power Supply
* M82 - Set E codes absolute (default)
@@ -327,7 +331,11 @@ static millis_t max_inactive_time = 0;
static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL;
// Print Job Timer
-Stopwatch print_job_timer = Stopwatch();
+#if ENABLED(PRINTCOUNTER)
+ PrintCounter print_job_timer = PrintCounter();
+#else
+ Stopwatch print_job_timer = Stopwatch();
+#endif
static uint8_t target_extruder;
@@ -4252,6 +4260,15 @@ inline void gcode_M77() {
print_job_timer.stop();
}
+#if ENABLED(PRINTCOUNTER)
+ /*+
+ * M78: Show print statistics
+ */
+ inline void gcode_M78() {
+ print_job_timer.showStats();
+ }
+#endif
+
/**
* M104: Set hot end temperature
*/
@@ -6641,6 +6658,12 @@ void process_next_command() {
gcode_M77();
break;
+ #if ENABLED(PRINTCOUNTER)
+ case 78: // Show print statistics
+ gcode_M78();
+ break;
+ #endif
+
#if ENABLED(M100_FREE_MEMORY_WATCHER)
case 100:
gcode_M100();
@@ -7755,6 +7778,9 @@ void idle(
);
host_keepalive();
lcd_update();
+ #if ENABLED(PRINTCOUNTER)
+ print_job_timer.tick();
+ #endif
}
/**
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index 017888c70..1209c667b 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -739,6 +739,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index d971dbb51..b9201e5b3 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -748,6 +748,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration.h b/Marlin/example_configurations/Hephestos_2/Configuration.h
index 2f51a9b46..6217383a8 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration.h
@@ -750,6 +750,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 110
#define ABS_PREHEAT_FAN_SPEED 0 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index 23a376742..ddd3edd2a 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -773,6 +773,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 60 // K8200: set back to 110 if you have an upgraded heatbed power supply
#define ABS_PREHEAT_FAN_SPEED 0 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
index 5ce12bbd6..8010cd7e6 100644
--- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
+++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
@@ -756,6 +756,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 110
#define ABS_PREHEAT_FAN_SPEED 0 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h
index 4c0d912a9..c9dada365 100644
--- a/Marlin/example_configurations/RigidBot/Configuration.h
+++ b/Marlin/example_configurations/RigidBot/Configuration.h
@@ -1,4 +1,4 @@
-/**
+f/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
@@ -751,6 +751,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 110
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index e5e13c19d..2acd5f337 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -764,6 +764,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/TAZ4/Configuration.h b/Marlin/example_configurations/TAZ4/Configuration.h
index 68f1cd99e..0a6e093b6 100644
--- a/Marlin/example_configurations/TAZ4/Configuration.h
+++ b/Marlin/example_configurations/TAZ4/Configuration.h
@@ -777,6 +777,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 110
#define ABS_PREHEAT_FAN_SPEED 0 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 390ede3ec..81db59816 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -748,6 +748,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
index 4f23b136c..c7d69f79f 100644
--- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h
+++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
@@ -756,6 +756,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 110
#define ABS_PREHEAT_FAN_SPEED 0 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/delta/biv2.5/Configuration.h b/Marlin/example_configurations/delta/biv2.5/Configuration.h
index 50ebe27ce..0c77a1177 100644
--- a/Marlin/example_configurations/delta/biv2.5/Configuration.h
+++ b/Marlin/example_configurations/delta/biv2.5/Configuration.h
@@ -885,6 +885,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index c84aeb3b0..6e7691636 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -885,6 +885,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index 63e2014ef..c04781810 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -889,6 +889,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
index 038305958..c8093b161 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
@@ -882,6 +882,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
index 579999ba1..73e49c7e5 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
@@ -890,6 +890,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index 77adce269..416765b25 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -759,6 +759,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 425914893..65fd6aacc 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -750,6 +750,19 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
+
+//
+// Print Counter
+//
+// When enabled Marlin will keep track of some print statistical data such as:
+// - Total print jobs
+// - Total successful print jobs
+// - Total failed print jobs
+// - Total time printing
+//
+// This information can be viewed by the M78 command.
+//#define PRINTCOUNTER
+
//=============================================================================
//============================= LCD and SD support ============================
//=============================================================================
diff --git a/Marlin/printcounter.cpp b/Marlin/printcounter.cpp
new file mode 100644
index 000000000..59b8bc3e3
--- /dev/null
+++ b/Marlin/printcounter.cpp
@@ -0,0 +1,179 @@
+/*
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "Marlin.h"
+#include "printcounter.h"
+#include
+
+PrintCounter::PrintCounter(): super() {
+ this->loadStats();
+}
+
+uint16_t PrintCounter::deltaDuration() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("deltaDuration"));
+ #endif
+
+ uint16_t tmp = this->lastDuration;
+ this->lastDuration = this->duration();
+ return this->lastDuration - tmp;
+}
+
+bool PrintCounter::isLoaded() {
+ return this->loaded;
+}
+
+void PrintCounter::initStats() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("initStats"));
+ #endif
+
+ this->loaded = true;
+ this->data = { 0, 0, 0, 0 };
+
+ this->saveStats();
+ eeprom_write_byte((uint8_t *) this->address, 0x16);
+}
+
+void PrintCounter::loadStats() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("loadStats"));
+ #endif
+
+ // Checks if the EEPROM block is initialized
+ if (eeprom_read_byte((uint8_t *) this->address) != 0x16) this->initStats();
+ else eeprom_read_block(&this->data, (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
+
+ this->loaded = true;
+}
+
+void PrintCounter::saveStats() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("saveStats"));
+ #endif
+
+ // Refuses to save data is object is not loaded
+ if (!this->isLoaded()) return;
+
+ eeprom_update_block(&this->data, (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
+}
+
+void PrintCounter::showStats() {
+ SERIAL_ECHOPGM("Print statistics: Total: ");
+ SERIAL_ECHO(this->data.totalPrints);
+
+ SERIAL_ECHOPGM(", Finished: ");
+ SERIAL_ECHO(this->data.finishedPrints);
+
+ SERIAL_ECHOPGM(", Failed: ");
+ SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints
+ - (this->isRunning() || this->isPaused()) ? 1 : 0); // Removes 1 from failures with an active counter
+
+ uint32_t t = this->data.printTime /60;
+ SERIAL_ECHOPGM(", Total print time: ");
+ SERIAL_ECHO(t / 60);
+
+ SERIAL_ECHOPGM("h ");
+ SERIAL_ECHO(t % 60);
+
+ SERIAL_ECHOPGM("min");
+
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ SERIAL_ECHOPGM(" (");
+ SERIAL_ECHO(this->data.printTime);
+ SERIAL_ECHOPGM(")");
+ #endif
+
+ // @todo longestPrint missing implementation
+ SERIAL_EOL;
+}
+
+void PrintCounter::tick() {
+ if (!this->isRunning()) return;
+
+ static uint32_t update_before = millis(),
+ eeprom_before = millis();
+
+ uint32_t now = millis();
+
+ // Trying to get the amount of calculations down to the bare min
+ const static uint16_t i = this->updateInterval * 1000;
+
+ if (now - update_before >= i) {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("tick"));
+ #endif
+
+ uint16_t t = this->duration();;
+ this->data.printTime += this->deltaDuration();
+ update_before = now;
+ }
+
+ // Trying to get the amount of calculations down to the bare min
+ const static uint16_t j = this->saveInterval * 1000;
+
+ if (now - eeprom_before >= j) {
+ eeprom_before = now;
+ this->saveStats();
+ }
+}
+
+void PrintCounter::start() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("start"));
+ #endif
+
+ if (!this->isPaused()) this->data.totalPrints++;
+ super::start();
+}
+
+void PrintCounter::stop() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("stop"));
+ #endif
+
+ super::stop();
+ this->data.finishedPrints++;
+ this->data.printTime += this->deltaDuration();
+ this->saveStats();
+}
+
+void PrintCounter::reset() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("stop"));
+ #endif
+
+ this->lastDuration = 0;
+ super::reset();
+}
+
+#if ENABLED(DEBUG_PRINTCOUNTER)
+
+ void PrintCounter::debug(const char func[]) {
+ if (DEBUGGING(INFO)) {
+ SERIAL_ECHOPGM("PrintCounter::");
+ serialprintPGM(func);
+ SERIAL_ECHOLNPGM("()");
+ }
+ }
+
+#endif
diff --git a/Marlin/printcounter.h b/Marlin/printcounter.h
new file mode 100644
index 000000000..b44caeefd
--- /dev/null
+++ b/Marlin/printcounter.h
@@ -0,0 +1,154 @@
+/*
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#ifndef PRINTCOUNTER_H
+#define PRINTCOUNTER_H
+
+#include "macros.h"
+#include "stopwatch.h"
+
+// Print debug messages with M111 S2
+//#define DEBUG_PRINTCOUNTER
+
+struct printStatistics { // 13 bytes
+ //const uint8_t magic; // Magic header, it will always be 0x16
+ uint16_t totalPrints; // Number of prints
+ uint16_t finishedPrints; // Number of complete prints
+ uint32_t printTime; // Total printing time
+ uint32_t longestPrint; // Longest print job - not in use
+};
+
+class PrintCounter: public Stopwatch {
+ private:
+ typedef Stopwatch super;
+
+ printStatistics data;
+
+ /**
+ * @brief EEPROM address
+ * @details Defines the start offset address where the data is stored.
+ */
+ const uint16_t address = 0x32;
+
+ /**
+ * @brief Interval in seconds between counter updates
+ * @details This const value defines what will be the time between each
+ * accumulator update. This is different from the EEPROM save interval.
+ */
+ const uint16_t updateInterval = 10;
+
+ /**
+ * @brief Interval in seconds between EEPROM saves
+ * @details This const value defines what will be the time between each
+ * EEPROM save cycle, the development team recommends to set this value
+ * no lower than 3600 secs (1 hour).
+ */
+ const uint16_t saveInterval = 3600;
+
+ /**
+ * @brief Timestamp of the last call to deltaDuration()
+ * @details Stores the timestamp of the last deltaDuration(), this is
+ * required due to the updateInterval cycle.
+ */
+ uint16_t lastDuration;
+
+ /**
+ * @brief Stats were loaded from EERPROM
+ * @details If set to true it indicates if the statistical data was already
+ * loaded from the EEPROM.
+ */
+ bool loaded = false;
+
+ protected:
+ /**
+ * @brief dT since the last call
+ * @details Returns the elapsed time in seconds since the last call, this is
+ * used internally for print statistics accounting is not intended to be a
+ * user callable function.
+ */
+ uint16_t deltaDuration();
+
+ public:
+ /**
+ * @brief Class constructor
+ */
+ PrintCounter();
+
+ /**
+ * @brief Checks if Print Statistics has been loaded
+ * @details Returns true if the statistical data has been loaded.
+ * @return bool
+ */
+ bool isLoaded();
+
+ /**
+ * @brief Resets the Print Statistics
+ * @details Resets the statistics to zero and saves them to EEPROM creating
+ * also the magic header.
+ */
+ void initStats();
+
+ /**
+ * @brief Loads the Print Statistics
+ * @details Loads the statistics from EEPROM
+ */
+ void loadStats();
+
+ /**
+ * @brief Saves the Print Statistics
+ * @details Saves the statistics to EEPROM
+ */
+ void saveStats();
+
+ /**
+ * @brief Serial output the Print Statistics
+ * @details This function may change in the future, for now it directly
+ * prints the statistical data to serial.
+ */
+ void showStats();
+
+ /**
+ * @brief Loop function
+ * @details This function should be called at loop, it will take care of
+ * periodically save the statistical data to EEPROM and do time keeping.
+ */
+ void tick();
+
+ /**
+ * The following functions are being overridden
+ */
+ void start();
+ void stop();
+ void reset();
+
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+
+ /**
+ * @brief Prints a debug message
+ * @details Prints a simple debug message "PrintCounter::function"
+ */
+ static void debug(const char func[]);
+
+ #endif
+};
+
+#endif // PRINTCOUNTER_H
diff --git a/Marlin/stopwatch.cpp b/Marlin/stopwatch.cpp
index f871af1c7..4a1344db1 100644
--- a/Marlin/stopwatch.cpp
+++ b/Marlin/stopwatch.cpp
@@ -29,7 +29,7 @@ Stopwatch::Stopwatch() {
void Stopwatch::stop() {
#if ENABLED(DEBUG_STOPWATCH)
- debug(PSTR("stop"));
+ Stopwatch::debug(PSTR("stop"));
#endif
if (!this->isRunning()) return;
@@ -40,7 +40,7 @@ void Stopwatch::stop() {
void Stopwatch::pause() {
#if ENABLED(DEBUG_STOPWATCH)
- debug(PSTR("pause"));
+ Stopwatch::debug(PSTR("pause"));
#endif
if (!this->isRunning()) return;
@@ -51,7 +51,7 @@ void Stopwatch::pause() {
void Stopwatch::start() {
#if ENABLED(DEBUG_STOPWATCH)
- debug(PSTR("start"));
+ Stopwatch::debug(PSTR("start"));
#endif
if (this->isRunning()) return;
@@ -65,7 +65,7 @@ void Stopwatch::start() {
void Stopwatch::reset() {
#if ENABLED(DEBUG_STOPWATCH)
- debug(PSTR("reset"));
+ Stopwatch::debug(PSTR("reset"));
#endif
this->state = STPWTCH_STOPPED;