Prusa MINI Firmware overview
PrintCounter Class Reference

#include <printcounter.h>

Inheritance diagram for PrintCounter:
Collaboration diagram for PrintCounter:

Static Public Member Functions

static void init ()
 Initialize the print counter. More...
 
static FORCE_INLINE bool isLoaded ()
 Check if Print Statistics has been loaded. More...
 
static void incFilamentUsed (float const &amount)
 Increment the total filament used. More...
 
static void initStats ()
 Reset the Print Statistics. More...
 
static void loadStats ()
 Load the Print Statistics. More...
 
static void saveStats ()
 Save the Print Statistics. More...
 
static void showStats ()
 Serial output the Print Statistics. More...
 
static printStatistics getStats ()
 Return the currently loaded statistics. More...
 
static void tick ()
 Loop function. More...
 
static bool start ()
 
static bool stop ()
 
static void reset ()
 
- Static Public Member Functions inherited from Stopwatch
static FORCE_INLINE void init ()
 Initialize the stopwatch. More...
 
static bool stop ()
 Stop the stopwatch. More...
 
static bool pause ()
 Pause the stopwatch. More...
 
static bool start ()
 Start the stopwatch. More...
 
static void resume (const millis_t with_time)
 Resume the stopwatch. More...
 
static void reset ()
 Reset the stopwatch. More...
 
static FORCE_INLINE bool isRunning ()
 Check if the timer is running. More...
 
static FORCE_INLINE bool isPaused ()
 Check if the timer is paused. More...
 
static millis_t duration ()
 Get the running time. More...
 

Static Protected Member Functions

static millis_t deltaDuration ()
 dT since the last call More...
 

Member Function Documentation

◆ deltaDuration()

millis_t PrintCounter::deltaDuration ( )
staticprotected

dT since the last call

Return 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.

72  {
73  #if ENABLED(DEBUG_PRINTCOUNTER)
74  debug(PSTR("deltaDuration"));
75  #endif
76 
77  millis_t tmp = lastDuration;
78  lastDuration = duration();
79  return lastDuration - tmp;
80 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init()

static void PrintCounter::init ( )
static

Initialize the print counter.

120  {
121  super::init();
122  loadStats();
123  }
Here is the call graph for this function:

◆ isLoaded()

static FORCE_INLINE bool PrintCounter::isLoaded ( )
static

Check if Print Statistics has been loaded.

Return true if the statistical data has been loaded.

Returns
bool
130 { return loaded; }
Here is the caller graph for this function:

◆ incFilamentUsed()

void PrintCounter::incFilamentUsed ( float const amount)
static

Increment the total filament used.

The total filament used counter will be incremented by "amount".

Parameters
amountThe amount of filament used in mm
82  {
83  #if ENABLED(DEBUG_PRINTCOUNTER)
84  debug(PSTR("incFilamentUsed"));
85  #endif
86 
87  // Refuses to update data if object is not loaded
88  if (!isLoaded()) return;
89 
90  data.filamentUsed += amount; // mm
91 }
Here is the call graph for this function:

◆ initStats()

void PrintCounter::initStats ( )
static

Reset the Print Statistics.

Reset the statistics to zero and saves them to EEPROM creating also the magic header.

93  {
94  #if ENABLED(DEBUG_PRINTCOUNTER)
95  debug(PSTR("initStats"));
96  #endif
97 
98  loaded = true;
99  data = { 0, 0, 0, 0, 0.0
101  #if SERVICE_INTERVAL_1 > 0
102  , SERVICE_INTERVAL_SEC_1
103  #endif
104  #if SERVICE_INTERVAL_2 > 0
105  , SERVICE_INTERVAL_SEC_2
106  #endif
107  #if SERVICE_INTERVAL_3 > 0
108  , SERVICE_INTERVAL_SEC_3
109  #endif
110  #endif
111  };
112 
113  saveStats();
115  persistentStore.write_data(address, (uint8_t)0x16);
117 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadStats()

void PrintCounter::loadStats ( )
static

Load the Print Statistics.

Load the statistics from EEPROM

131  {
132  #if ENABLED(DEBUG_PRINTCOUNTER)
133  debug(PSTR("loadStats"));
134  #endif
135 
136  // Check if the EEPROM block is initialized
137  uint8_t value = 0;
139  persistentStore.read_data(address, &value, sizeof(uint8_t));
140  if (value != 0x16)
141  initStats();
142  else
143  persistentStore.read_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
145  loaded = true;
146 
147  #if HAS_SERVICE_INTERVALS
148  bool doBuzz = false;
149  #if SERVICE_INTERVAL_1 > 0
150  if (data.nextService1 == 0) doBuzz = _service_warn(PSTR(" " SERVICE_NAME_1));
151  #endif
152  #if SERVICE_INTERVAL_2 > 0
153  if (data.nextService2 == 0) doBuzz = _service_warn(PSTR(" " SERVICE_NAME_2));
154  #endif
155  #if SERVICE_INTERVAL_3 > 0
156  if (data.nextService3 == 0) doBuzz = _service_warn(PSTR(" " SERVICE_NAME_3));
157  #endif
158  #if HAS_BUZZER && SERVICE_WARNING_BUZZES > 0
159  if (doBuzz) for (int i = 0; i < SERVICE_WARNING_BUZZES; i++) BUZZ(200, 404);
160  #else
161  UNUSED(doBuzz);
162  #endif
163  #endif // HAS_SERVICE_INTERVALS
164 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveStats()

void PrintCounter::saveStats ( )
static

Save the Print Statistics.

Save the statistics to EEPROM

166  {
167  #if ENABLED(DEBUG_PRINTCOUNTER)
168  debug(PSTR("saveStats"));
169  #endif
170 
171  // Refuses to save data if object is not loaded
172  if (!isLoaded()) return;
173 
174  // Saves the struct to EEPROM
176  persistentStore.write_data(address + sizeof(uint8_t), (uint8_t*)&data, sizeof(printStatistics));
178 
179  #if ENABLED(EXTENSIBLE_UI)
181  #endif
182 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ showStats()

void PrintCounter::showStats ( )
static

Serial output the Print Statistics.

This function may change in the future, for now it directly prints the statistical data to serial.

192  {
193  char buffer[21];
194 
197  "Prints: ", data.totalPrints,
198  ", Finished: ", data.finishedPrints,
199  ", Failed: ", data.totalPrints - data.finishedPrints
200  - ((isRunning() || isPaused()) ? 1 : 0) // Remove 1 from failures with an active counter
201  );
202 
204  duration_t elapsed = data.printTime;
205  elapsed.toString(buffer);
206  SERIAL_ECHOPAIR("Total time: ", buffer);
207  #if ENABLED(DEBUG_PRINTCOUNTER)
208  SERIAL_ECHOPAIR(" (", data.printTime);
209  SERIAL_CHAR(')');
210  #endif
211 
212  elapsed = data.longestPrint;
213  elapsed.toString(buffer);
214  SERIAL_ECHOPAIR(", Longest job: ", buffer);
215  #if ENABLED(DEBUG_PRINTCOUNTER)
216  SERIAL_ECHOPAIR(" (", data.longestPrint);
217  SERIAL_CHAR(')');
218  #endif
219 
220  SERIAL_ECHOPAIR("\n" MSG_STATS "Filament used: ", data.filamentUsed / 1000);
221  SERIAL_CHAR('m');
222  SERIAL_EOL();
223 
224  #if SERVICE_INTERVAL_1 > 0
225  _service_when(buffer, PSTR(SERVICE_NAME_1), data.nextService1);
226  #endif
227  #if SERVICE_INTERVAL_2 > 0
228  _service_when(buffer, PSTR(SERVICE_NAME_2), data.nextService2);
229  #endif
230  #if SERVICE_INTERVAL_3 > 0
231  _service_when(buffer, PSTR(SERVICE_NAME_3), data.nextService3);
232  #endif
233 }
Here is the call graph for this function:

◆ getStats()

static printStatistics PrintCounter::getStats ( )
static

Return the currently loaded statistics.

Return the raw data, in the same structure used internally

170 { return data; }

◆ tick()

void PrintCounter::tick ( )
static

Loop function.

This function should be called at loop, it will take care of periodically save the statistical data to EEPROM and do time keeping.

235  {
236  if (!isRunning()) return;
237 
238  millis_t now = millis();
239 
240  static uint32_t update_next; // = 0
241  if (ELAPSED(now, update_next)) {
242  #if ENABLED(DEBUG_PRINTCOUNTER)
243  debug(PSTR("tick"));
244  #endif
245  millis_t delta = deltaDuration();
246  data.printTime += delta;
247 
248  #if SERVICE_INTERVAL_1 > 0
249  data.nextService1 -= _MIN(delta, data.nextService1);
250  #endif
251  #if SERVICE_INTERVAL_2 > 0
252  data.nextService2 -= _MIN(delta, data.nextService2);
253  #endif
254  #if SERVICE_INTERVAL_3 > 0
255  data.nextService3 -= _MIN(delta, data.nextService3);
256  #endif
257 
258  update_next = now + updateInterval * 1000;
259  }
260 
261  static uint32_t eeprom_next; // = 0
262  if (ELAPSED(now, eeprom_next)) {
263  eeprom_next = now + saveInterval * 1000;
264  saveStats();
265  }
266 }
Here is the call graph for this function:

◆ start()

bool PrintCounter::start ( )
static

The following functions are being overridden

269  {
270  #if ENABLED(DEBUG_PRINTCOUNTER)
271  debug(PSTR("start"));
272  #endif
273 
274  bool paused = isPaused();
275 
276  if (super::start()) {
277  if (!paused) {
278  data.totalPrints++;
279  lastDuration = 0;
280  }
281  return true;
282  }
283 
284  return false;
285 }
Here is the call graph for this function:

◆ stop()

bool PrintCounter::stop ( )
static
288  {
289  #if ENABLED(DEBUG_PRINTCOUNTER)
290  debug(PSTR("stop"));
291  #endif
292 
293  if (super::stop()) {
294  data.finishedPrints++;
295  data.printTime += deltaDuration();
296 
297  if (duration() > data.longestPrint)
298  data.longestPrint = duration();
299 
300  saveStats();
301  return true;
302  }
303  else return false;
304 }
Here is the call graph for this function:

◆ reset()

void PrintCounter::reset ( )
static
307  {
308  #if ENABLED(DEBUG_PRINTCOUNTER)
309  debug(PSTR("stop"));
310  #endif
311 
312  super::reset();
313  lastDuration = 0;
314 }
Here is the call graph for this function:
duration_t::toString
char * toString(char *const buffer) const
Formats the duration as a string.
Definition: duration_t.h:123
SERIAL_CHAR
#define SERIAL_CHAR(x)
Definition: serial.h:69
Stopwatch::isRunning
static FORCE_INLINE bool isRunning()
Check if the timer is running.
Definition: stopwatch.h:93
printStatistics::filamentUsed
float filamentUsed
Definition: printcounter.h:44
PrintCounter::saveStats
static void saveStats()
Save the Print Statistics.
Definition: printcounter.cpp:166
PersistentStore::write_data
static bool write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc)
MSG_STATS
#define MSG_STATS
Definition: language.h:159
SERIAL_ECHOPAIR
#define SERIAL_ECHOPAIR(V...)
Definition: serial.h:114
PersistentStore::access_finish
static bool access_finish()
data
uint8_t data[8]
Definition: masstorage.h:49
PersistentStore::access_start
static bool access_start()
i
uint8_t i
Definition: screen_test_graph.c:72
_MIN
#define _MIN(V...)
Definition: macros.h:333
millis
uint32_t millis(void)
Definition: wiring_time.c:29
Stopwatch::stop
static bool stop()
Stop the stopwatch.
Definition: stopwatch.cpp:36
PrintCounter::isLoaded
static FORCE_INLINE bool isLoaded()
Check if Print Statistics has been loaded.
Definition: printcounter.h:130
printStatistics::longestPrint
uint32_t longestPrint
Definition: printcounter.h:43
printStatistics::finishedPrints
uint16_t finishedPrints
Definition: printcounter.h:41
PrintCounter::deltaDuration
static millis_t deltaDuration()
dT since the last call
Definition: printcounter.cpp:72
PSTR
#define PSTR(str)
Definition: pgmspace.h:31
printStatistics::printTime
uint32_t printTime
Definition: printcounter.h:42
ExtUI::onConfigurationStoreWritten
void onConfigurationStoreWritten(bool success)
Definition: marlin_server.cpp:937
Stopwatch::duration
static millis_t duration()
Get the running time.
Definition: stopwatch.cpp:108
SERIAL_ECHOPGM
#define SERIAL_ECHOPGM(S)
Definition: serial.h:173
printStatistics
Definition: printcounter.h:38
Stopwatch::start
static bool start()
Start the stopwatch.
Definition: stopwatch.cpp:68
SERIAL_ECHOLNPAIR
#define SERIAL_ECHOLNPAIR(V...)
Definition: serial.h:144
Stopwatch::reset
static void reset()
Reset the stopwatch.
Definition: stopwatch.cpp:97
PrintCounter::loadStats
static void loadStats()
Load the Print Statistics.
Definition: printcounter.cpp:131
ELAPSED
#define ELAPSED(NOW, SOON)
Definition: millis_t.h:29
uint8_t
const uint8_t[]
Definition: 404_html.c:3
Stopwatch::isPaused
static FORCE_INLINE bool isPaused()
Check if the timer is paused.
Definition: stopwatch.h:100
PersistentStore::read_data
static bool read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing=true)
printStatistics::totalPrints
uint16_t totalPrints
Definition: printcounter.h:40
SERIAL_EOL
#define SERIAL_EOL()
Definition: serial.h:181
HAS_SERVICE_INTERVALS
#define HAS_SERVICE_INTERVALS
Definition: Conditionals_LCD.h:534
Stopwatch::init
static FORCE_INLINE void init()
Initialize the stopwatch.
Definition: stopwatch.h:50
persistentStore
PersistentStore persistentStore
Definition: persistent_store_api.cpp:28
duration_t
Definition: duration_t.h:26
PrintCounter::initStats
static void initStats()
Reset the Print Statistics.
Definition: printcounter.cpp:93
UNUSED
#define UNUSED(X)
Definition: stm32f4xx_hal_def.h:74
millis_t
uint32_t millis_t
Definition: millis_t.h:26
BUZZ
#define BUZZ(d, f)
Definition: buzzer.h:126