Browse Source

Added a new object: PrintCounter

João Brázio 8 years ago
parent
commit
4f541c5bb5
No account linked to committer's email address
2 changed files with 197 additions and 48 deletions
  1. 132
    37
      Marlin/printcounter.cpp
  2. 65
    11
      Marlin/printcounter.h

+ 132
- 37
Marlin/printcounter.cpp View File

@@ -24,7 +24,112 @@
24 24
 #include "printcounter.h"
25 25
 #include <avr/eeprom.h>
26 26
 
27
-PrintCounter::PrintCounter(): super() {}
27
+PrintCounter::PrintCounter(): super() {
28
+  this->loadStats();
29
+}
30
+
31
+bool PrintCounter::isLoaded() {
32
+  return this->loaded;
33
+}
34
+
35
+void PrintCounter::initStats() {
36
+  #if ENABLED(DEBUG_PRINTCOUNTER)
37
+    PrintCounter::debug(PSTR("initStats"));
38
+  #endif
39
+
40
+  this->loaded = true;
41
+  this->data = {
42
+    0, 0, 0, 0
43
+  };
44
+
45
+  this->saveStats();
46
+  eeprom_write_byte((uint8_t*) this->addr, 0x16);
47
+}
48
+
49
+void PrintCounter::loadStats() {
50
+  #if ENABLED(DEBUG_PRINTCOUNTER)
51
+    PrintCounter::debug(PSTR("loadStats"));
52
+  #endif
53
+
54
+  uint16_t addr = this->addr;
55
+
56
+  // Checks if the EEPROM block is initialized
57
+  if (eeprom_read_byte((uint8_t*) addr) != 0x16) this->initStats();
58
+
59
+  else {
60
+    // Skip the magic header byte
61
+    addr += sizeof(uint8_t);
62
+
63
+    // @todo This section will need rewrite once the ConfigurationStore
64
+    // and/or PersistentStorage object comes along.
65
+    this->data.totalPrints = eeprom_read_word((uint16_t*) addr);
66
+    addr += sizeof(uint16_t);
67
+
68
+    this->data.finishedPrints = eeprom_read_word((uint16_t*) addr);
69
+    addr += sizeof(uint16_t);
70
+
71
+    this->data.printTime = eeprom_read_dword((uint32_t*) addr);
72
+    addr += sizeof(uint32_t);
73
+
74
+    this->data.longestPrint = eeprom_read_dword((uint32_t*) addr);
75
+  }
76
+
77
+  this->loaded = true;
78
+}
79
+
80
+void PrintCounter::saveStats() {
81
+  #if ENABLED(DEBUG_PRINTCOUNTER)
82
+    PrintCounter::debug(PSTR("saveStats"));
83
+  #endif
84
+
85
+  // Refuses to save data is object is not loaded
86
+  if (!this->isLoaded()) return;
87
+
88
+  // Skip the magic header byte
89
+  uint16_t addr = this->addr + sizeof(uint8_t);
90
+
91
+  // @todo This section will need rewrite once the ConfigurationStore
92
+  // and/or PersistentStorage object comes along.
93
+  eeprom_write_word ((uint16_t*) addr, this->data.totalPrints);
94
+  addr += sizeof(uint16_t);
95
+
96
+  eeprom_write_word ((uint16_t*) addr, this->data.finishedPrints);
97
+  addr += sizeof(uint16_t);
98
+
99
+  eeprom_write_dword((uint32_t*) addr, this->data.printTime);
100
+  addr += sizeof(uint32_t);
101
+
102
+  eeprom_write_dword((uint32_t*) addr, this->data.longestPrint);
103
+}
104
+
105
+void PrintCounter::showStats() {
106
+  SERIAL_ECHOPGM("Print statistics: Total: ");
107
+  SERIAL_ECHO(this->data.totalPrints);
108
+
109
+  SERIAL_ECHOPGM(", Finished: ");
110
+  SERIAL_ECHO(this->data.finishedPrints);
111
+
112
+  SERIAL_ECHOPGM(", Failed: ");
113
+  SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints);
114
+
115
+  uint32_t t = this->data.printTime /60;
116
+  SERIAL_ECHOPGM(", Total print time: ");
117
+  SERIAL_ECHO(t / 60);
118
+
119
+  SERIAL_ECHOPGM("h ");
120
+  SERIAL_ECHO(t % 60);
121
+
122
+  SERIAL_ECHOPGM("min");
123
+
124
+  #if ENABLED(DEBUG_PRINTCOUNTER)
125
+    SERIAL_ECHOPGM(" (");
126
+    SERIAL_ECHO(this->data.printTime);
127
+    SERIAL_ECHOPGM(")");
128
+  #endif
129
+
130
+  // @todo longestPrint missing implementation
131
+  SERIAL_EOL;
132
+}
28 133
 
29 134
 void PrintCounter::tick() {
30 135
   if (!this->isRunning()) return;
@@ -38,9 +143,14 @@ void PrintCounter::tick() {
38 143
   const static uint16_t i = this->updateInterval * 1000;
39 144
 
40 145
   if (now - update_before >= i) {
41
-    //this->addToTimeCounter((uint16_t) (now - update_before) / 1000);
146
+    #if ENABLED(DEBUG_PRINTCOUNTER)
147
+      PrintCounter::debug(PSTR("tick"));
148
+    #endif
149
+
150
+    uint16_t t = this->duration();;
151
+    this->data.printTime += t - this->lastUpdate;
152
+    this->lastUpdate = t;
42 153
     update_before = now;
43
-    PrintCounter::debug(PSTR("tick1"));
44 154
   }
45 155
 
46 156
   // Trying to get the amount of calculations down to the bare min
@@ -48,52 +158,37 @@ void PrintCounter::tick() {
48 158
 
49 159
   if (now - eeprom_before >= j) {
50 160
     eeprom_before = now;
51
-    this->save();
161
+    this->saveStats();
52 162
   }
53 163
 }
54 164
 
55
-void PrintCounter::load() {
56
-  uint16_t pos = this->addr;
57
-
58
-  this->data.successPrints= eeprom_read_word ((uint16_t*) pos);
59
-  this->data.failedPrints = eeprom_read_word ((uint16_t*) pos);
60
-  this->data.printTime    = eeprom_read_dword((uint32_t*) pos);
61
-  this->data.longestPrint = eeprom_read_dword((uint32_t*) pos);
62
-
63
-  SERIAL_ECHOPGM("successPrints: ");
64
-  SERIAL_ECHOLN(this->data.successPrints);
65
-
66
-  SERIAL_ECHOPGM("failedPrints: ");
67
-  SERIAL_ECHOLN(this->data.failedPrints);
68
-
69
-  SERIAL_ECHOPGM("printTime: ");
70
-  SERIAL_ECHOLN(this->data.printTime);
165
+void PrintCounter::start() {
166
+  #if ENABLED(DEBUG_PRINTCOUNTER)
167
+    PrintCounter::debug(PSTR("start"));
168
+  #endif
71 169
 
72
-  SERIAL_ECHOPGM("longestPrint: ");
73
-  SERIAL_ECHOLN(this->data.longestPrint);
170
+  if (!this->isPaused()) this->data.totalPrints++;
171
+  super::start();
74 172
 }
75 173
 
76
-void PrintCounter::save() {
174
+void PrintCounter::stop() {
77 175
   #if ENABLED(DEBUG_PRINTCOUNTER)
78
-    PrintCounter::debug(PSTR("save"));
176
+    PrintCounter::debug(PSTR("stop"));
79 177
   #endif
80 178
 
81
-  uint16_t pos = this->addr;
82
-
83
-  eeprom_write_word ((uint16_t*) pos, this->data.successPrints);
84
-  eeprom_write_word ((uint16_t*) pos, this->data.failedPrints);
85
-  eeprom_write_dword((uint32_t*) pos, this->data.printTime);
86
-  eeprom_write_dword((uint32_t*) pos, this->data.longestPrint);
179
+  super::stop();
180
+  this->data.finishedPrints++;
181
+  this->data.printTime += this->duration() - this->lastUpdate;
182
+  this->saveStats();
87 183
 }
88 184
 
89
-void PrintCounter::start() {
90
-  super::start();
91
-  this->load();
92
-}
185
+void PrintCounter::reset() {
186
+  #if ENABLED(DEBUG_PRINTCOUNTER)
187
+    PrintCounter::debug(PSTR("stop"));
188
+  #endif
93 189
 
94
-void PrintCounter::stop() {
95
-  super::stop();
96
-  this->save();
190
+  this->lastUpdate = 0;
191
+  super::reset();
97 192
 }
98 193
 
99 194
 #if ENABLED(DEBUG_PRINTCOUNTER)

+ 65
- 11
Marlin/printcounter.h View File

@@ -29,11 +29,12 @@
29 29
 // Print debug messages with M111 S2
30 30
 #define DEBUG_PRINTCOUNTER
31 31
 
32
-struct printStatistics {  // 12 bytes
33
-  uint16_t successPrints; // Total number of prints
34
-  uint16_t failedPrints;  // Total number of aborted prints - not in use
35
-  uint32_t printTime;     // Total time printing
36
-  uint32_t longestPrint;  // Longest print job - not in use
32
+struct printStatistics {    // 13 bytes
33
+  //uint8_t  magic;         // Magic header, it will always be 0x16
34
+  uint16_t totalPrints;     // Number of prints
35
+  uint16_t finishedPrints;  // Number of complete prints
36
+  uint32_t printTime;       // Total printing time
37
+  uint32_t longestPrint;    // Longest print job - not in use
37 38
 };
38 39
 
39 40
 class PrintCounter: public Stopwatch {
@@ -43,10 +44,18 @@ class PrintCounter: public Stopwatch {
43 44
     printStatistics data;
44 45
 
45 46
     /**
47
+     * @brief Timestamp of the last update
48
+     * @details Stores the timestamp of the last data.pritnTime update, when the
49
+     * print job finishes, this will be used to calculate the exact time elapsed,
50
+     * this is required due to the updateInterval cycle.
51
+     */
52
+    uint16_t lastUpdate;
53
+
54
+    /**
46 55
      * @brief EEPROM address
47 56
      * @details Defines the start offset address where the data is stored.
48 57
      */
49
-    const uint16_t addr = 60;
58
+    const uint16_t addr = 50;
50 59
 
51 60
     /**
52 61
      * @brief Interval in seconds between counter updates
@@ -54,7 +63,7 @@ class PrintCounter: public Stopwatch {
54 63
      * accumulator update. This is different from the EEPROM save interval
55 64
      * which is user defined at the Configuration.h file.
56 65
      */
57
-    const uint16_t updateInterval = 2;
66
+    const uint16_t updateInterval = 10;
58 67
 
59 68
     /**
60 69
      * @brief Interval in seconds between EEPROM saves
@@ -64,20 +73,65 @@ class PrintCounter: public Stopwatch {
64 73
      */
65 74
     const uint16_t saveInterval = PRINTCOUNTER_SAVE_INTERVAL;
66 75
 
76
+    /**
77
+     * @brief Stats were loaded from EERPROM
78
+     * @details If set to true it indicates if the statistical data was already
79
+     * loaded from the EEPROM.
80
+     */
81
+    bool loaded = false;
82
+
67 83
   public:
68 84
     /**
69 85
      * @brief Class constructor
70 86
      */
71 87
     PrintCounter();
72 88
 
89
+    /**
90
+     * @brief Checks if Print Statistics has been loaded
91
+     * @details Returns true if the statistical data has been loaded.
92
+     * @return bool
93
+     */
94
+    bool isLoaded();
95
+
96
+    /**
97
+     * @brief Resets the Print Statistics
98
+     * @details Resets the statistics to zero and saves them to EEPROM creating
99
+     * also the magic header.
100
+     */
101
+    void initStats();
102
+
103
+    /**
104
+     * @brief Loads the Print Statistics
105
+     * @details Loads the statistics from EEPROM
106
+     */
107
+    void loadStats();
108
+
109
+    /**
110
+     * @brief Saves the Print Statistics
111
+     * @details Saves the statistics to EEPROM
112
+     */
113
+    void saveStats();
114
+
115
+    /**
116
+     * @brief Serial output the Print Statistics
117
+     * @details This function may change in the future, for now it directly
118
+     * prints the statistical data to serial.
119
+     */
120
+    void showStats();
121
+
122
+    /**
123
+     * @brief Loop function
124
+     * @details This function should be called at loop, it will take care of
125
+     * periodically save the statistical data to EEPROM and do time keeping.
126
+     */
73 127
     void tick();
74
-    void save();
75
-    void load();
76
-    void addToTimeCounter(uint16_t const &minutes);
77
-    void addToPrintCounter(uint8_t const &prints);
78 128
 
129
+    /**
130
+     * The following functions are being overridden
131
+     */
79 132
     void start();
80 133
     void stop();
134
+    void reset();
81 135
 
82 136
     #if ENABLED(DEBUG_PRINTCOUNTER)
83 137
 

Loading…
Cancel
Save