Subversion Repositories MK-Marlin

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ron 1
/**
2
 * Marlin 3D Printer Firmware
3
 * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
 *
5
 * Based on Sprinter and grbl.
6
 * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
 
23
#include "MarlinConfig.h"
24
 
25
#if DISABLED(PRINTCOUNTER)
26
 
27
#include "stopwatch.h"
28
Stopwatch print_job_timer;      // Global Print Job Timer instance
29
 
30
#else // PRINTCOUNTER
31
 
32
#include "printcounter.h"
33
#include "duration_t.h"
34
#include "Marlin.h"
35
 
36
PrintCounter print_job_timer;   // Global Print Job Timer instance
37
 
38
#if ENABLED(I2C_EEPROM) || ENABLED(SPI_EEPROM)
39
  // round up address to next page boundary (assuming 32 byte pages)
40
  #define STATS_EEPROM_ADDRESS 0x40
41
#else
42
  #define STATS_EEPROM_ADDRESS 0x32
43
#endif
44
 
45
const PrintCounter::promdress PrintCounter::address = STATS_EEPROM_ADDRESS;
46
 
47
const uint16_t PrintCounter::updateInterval = 10;
48
const uint16_t PrintCounter::saveInterval = 3600;
49
printStatistics PrintCounter::data;
50
millis_t PrintCounter::lastDuration;
51
bool PrintCounter::loaded = false;
52
 
53
millis_t PrintCounter::deltaDuration() {
54
  #if ENABLED(DEBUG_PRINTCOUNTER)
55
    debug(PSTR("deltaDuration"));
56
  #endif
57
 
58
  millis_t tmp = lastDuration;
59
  lastDuration = duration();
60
  return lastDuration - tmp;
61
}
62
 
63
void PrintCounter::incFilamentUsed(float const &amount) {
64
  #if ENABLED(DEBUG_PRINTCOUNTER)
65
    debug(PSTR("incFilamentUsed"));
66
  #endif
67
 
68
  // Refuses to update data if object is not loaded
69
  if (!isLoaded()) return;
70
 
71
  data.filamentUsed += amount; // mm
72
}
73
 
74
void PrintCounter::initStats() {
75
  #if ENABLED(DEBUG_PRINTCOUNTER)
76
    debug(PSTR("initStats"));
77
  #endif
78
 
79
  loaded = true;
80
  data = { 0, 0, 0, 0, 0.0 };
81
 
82
  saveStats();
83
  eeprom_write_byte((uint8_t*)address, 0x16);
84
}
85
 
86
void PrintCounter::loadStats() {
87
  #if ENABLED(DEBUG_PRINTCOUNTER)
88
    debug(PSTR("loadStats"));
89
  #endif
90
 
91
  // Checks if the EEPROM block is initialized
92
  if (eeprom_read_byte((uint8_t*)address) != 0x16) initStats();
93
  else eeprom_read_block(&data,
94
    (void*)(address + sizeof(uint8_t)), sizeof(printStatistics));
95
 
96
  loaded = true;
97
}
98
 
99
void PrintCounter::saveStats() {
100
  #if ENABLED(DEBUG_PRINTCOUNTER)
101
    debug(PSTR("saveStats"));
102
  #endif
103
 
104
  // Refuses to save data if object is not loaded
105
  if (!isLoaded()) return;
106
 
107
  // Saves the struct to EEPROM
108
  eeprom_update_block(&data,
109
    (void*)(address + sizeof(uint8_t)), sizeof(printStatistics));
110
}
111
 
112
void PrintCounter::showStats() {
113
  char buffer[21];
114
 
115
  SERIAL_PROTOCOLPGM(MSG_STATS);
116
 
117
  SERIAL_ECHOPGM("Prints: ");
118
  SERIAL_ECHO(data.totalPrints);
119
 
120
  SERIAL_ECHOPGM(", Finished: ");
121
  SERIAL_ECHO(data.finishedPrints);
122
 
123
  SERIAL_ECHOPGM(", Failed: "); // Note: Removes 1 from failures with an active counter
124
  SERIAL_ECHO(data.totalPrints - data.finishedPrints
125
    - ((isRunning() || isPaused()) ? 1 : 0));
126
 
127
  SERIAL_EOL();
128
  SERIAL_PROTOCOLPGM(MSG_STATS);
129
 
130
  duration_t elapsed = data.printTime;
131
  elapsed.toString(buffer);
132
 
133
  SERIAL_ECHOPGM("Total time: ");
134
  SERIAL_ECHO(buffer);
135
 
136
  #if ENABLED(DEBUG_PRINTCOUNTER)
137
    SERIAL_ECHOPGM(" (");
138
    SERIAL_ECHO(data.printTime);
139
    SERIAL_CHAR(')');
140
  #endif
141
 
142
  elapsed = data.longestPrint;
143
  elapsed.toString(buffer);
144
 
145
  SERIAL_ECHOPGM(", Longest job: ");
146
  SERIAL_ECHO(buffer);
147
 
148
  #if ENABLED(DEBUG_PRINTCOUNTER)
149
    SERIAL_ECHOPGM(" (");
150
    SERIAL_ECHO(data.longestPrint);
151
    SERIAL_CHAR(')');
152
  #endif
153
 
154
  SERIAL_EOL();
155
  SERIAL_PROTOCOLPGM(MSG_STATS);
156
 
157
  SERIAL_ECHOPGM("Filament used: ");
158
  SERIAL_ECHO(data.filamentUsed / 1000);
159
  SERIAL_CHAR('m');
160
 
161
  SERIAL_EOL();
162
}
163
 
164
void PrintCounter::tick() {
165
  if (!isRunning()) return;
166
 
167
  static uint32_t update_last = millis(),
168
                  eeprom_last = millis();
169
 
170
  millis_t now = millis();
171
 
172
  // Trying to get the amount of calculations down to the bare min
173
  const static uint16_t i = updateInterval * 1000;
174
 
175
  if (now - update_last >= i) {
176
    #if ENABLED(DEBUG_PRINTCOUNTER)
177
      debug(PSTR("tick"));
178
    #endif
179
 
180
    data.printTime += deltaDuration();
181
    update_last = now;
182
  }
183
 
184
  // Trying to get the amount of calculations down to the bare min
185
  const static millis_t j = saveInterval * 1000;
186
  if (now - eeprom_last >= j) {
187
    eeprom_last = now;
188
    saveStats();
189
  }
190
}
191
 
192
// @Override
193
bool PrintCounter::start() {
194
  #if ENABLED(DEBUG_PRINTCOUNTER)
195
    debug(PSTR("start"));
196
  #endif
197
 
198
  bool paused = isPaused();
199
 
200
  if (super::start()) {
201
    if (!paused) {
202
      data.totalPrints++;
203
      lastDuration = 0;
204
    }
205
    return true;
206
  }
207
 
208
  return false;
209
}
210
 
211
// @Override
212
bool PrintCounter::stop() {
213
  #if ENABLED(DEBUG_PRINTCOUNTER)
214
    debug(PSTR("stop"));
215
  #endif
216
 
217
  if (super::stop()) {
218
    data.finishedPrints++;
219
    data.printTime += deltaDuration();
220
 
221
    if (duration() > data.longestPrint)
222
      data.longestPrint = duration();
223
 
224
    saveStats();
225
    return true;
226
  }
227
  else return false;
228
}
229
 
230
// @Override
231
void PrintCounter::reset() {
232
  #if ENABLED(DEBUG_PRINTCOUNTER)
233
    debug(PSTR("stop"));
234
  #endif
235
 
236
  super::reset();
237
  lastDuration = 0;
238
}
239
 
240
#if ENABLED(DEBUG_PRINTCOUNTER)
241
 
242
  void PrintCounter::debug(const char func[]) {
243
    if (DEBUGGING(INFO)) {
244
      SERIAL_ECHOPGM("PrintCounter::");
245
      serialprintPGM(func);
246
      SERIAL_ECHOLNPGM("()");
247
    }
248
  }
249
#endif
250
 
251
#endif // PRINTCOUNTER