diff --git a/Marlin/printcounter.cpp b/Marlin/printcounter.cpp
new file mode 100644
index 0000000000..a8da87d330
--- /dev/null
+++ b/Marlin/printcounter.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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() {}
+
+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) {
+ //this->addToTimeCounter((uint16_t) (now - update_before) / 1000);
+ update_before = now;
+ PrintCounter::debug(PSTR("tick1"));
+ }
+
+ // 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->save();
+ }
+}
+
+void PrintCounter::load() {
+ uint16_t pos = this->addr;
+
+ this->data.successPrints= eeprom_read_word ((uint16_t*) pos);
+ this->data.failedPrints = eeprom_read_word ((uint16_t*) pos);
+ this->data.printTime = eeprom_read_dword((uint32_t*) pos);
+ this->data.longestPrint = eeprom_read_dword((uint32_t*) pos);
+
+ SERIAL_ECHOPGM("successPrints: ");
+ SERIAL_ECHOLN(this->data.successPrints);
+
+ SERIAL_ECHOPGM("failedPrints: ");
+ SERIAL_ECHOLN(this->data.failedPrints);
+
+ SERIAL_ECHOPGM("printTime: ");
+ SERIAL_ECHOLN(this->data.printTime);
+
+ SERIAL_ECHOPGM("longestPrint: ");
+ SERIAL_ECHOLN(this->data.longestPrint);
+}
+
+void PrintCounter::save() {
+ #if ENABLED(DEBUG_PRINTCOUNTER)
+ PrintCounter::debug(PSTR("save"));
+ #endif
+
+ uint16_t pos = this->addr;
+
+ eeprom_write_word ((uint16_t*) pos, this->data.successPrints);
+ eeprom_write_word ((uint16_t*) pos, this->data.failedPrints);
+ eeprom_write_dword((uint32_t*) pos, this->data.printTime);
+ eeprom_write_dword((uint32_t*) pos, this->data.longestPrint);
+}
+
+void PrintCounter::start() {
+ super::start();
+ this->load();
+}
+
+void PrintCounter::stop() {
+ super::stop();
+ this->save();
+}
+
+#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 0000000000..99d5b207b6
--- /dev/null
+++ b/Marlin/printcounter.h
@@ -0,0 +1,93 @@
+/*
+ * 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 { // 12 bytes
+ uint16_t successPrints; // Total number of prints
+ uint16_t failedPrints; // Total number of aborted prints - not in use
+ uint32_t printTime; // Total time printing
+ 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 addr = 60;
+
+ /**
+ * @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
+ * which is user defined at the Configuration.h file.
+ */
+ const uint16_t updateInterval = 2;
+
+ /**
+ * @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 = PRINTCOUNTER_SAVE_INTERVAL;
+
+ public:
+ /**
+ * @brief Class constructor
+ */
+ PrintCounter();
+
+ void tick();
+ void save();
+ void load();
+ void addToTimeCounter(uint16_t const &minutes);
+ void addToPrintCounter(uint8_t const &prints);
+
+ void start();
+ void stop();
+
+ #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 f871af1c7c..4a1344db14 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;