Commit cd948299 authored by MagoKimbra's avatar MagoKimbra

Merge remote-tracking branch 'refs/remotes/origin/dev'

parents dd4af352 62b0e7f2
......@@ -884,24 +884,7 @@ void Config_ResetDefault() {
ECHO_LVM(INFO, power_consumption_hour," Wh");
#endif
if (!forReplay) {
ECHO_LM(INFO, "Power on time:");
}
char time[30];
unsigned int day = printer_usage_seconds / 60 / 60 / 24, hours = (printer_usage_seconds / 60 / 60) % 24, minutes = (printer_usage_seconds / 60) % 60;
sprintf_P(time, PSTR(" %i " MSG_END_DAY " %i " MSG_END_HOUR " %i " MSG_END_MINUTE), day, hours, minutes);
ECHO_LT(INFO, time);
if (!forReplay) {
ECHO_LM(INFO, "Filament printed:");
}
char lung[30];
unsigned int kmeter = (long)printer_usage_filament / 1000 / 1000,
meter = ((long)printer_usage_filament / 1000) % 1000,
centimeter = ((long)printer_usage_filament / 10) % 100,
millimeter = ((long)printer_usage_filament) % 10;
sprintf_P(lung, PSTR(" %i Km %i m %i cm %i mm"), kmeter, meter, centimeter, millimeter);
ECHO_LT(INFO, lung);
print_job_counter.showStats();
}
#endif // !DISABLE_M503
......@@ -916,26 +899,31 @@ void ConfigSD_ResetDefault() {
#if HAS(POWER_CONSUMPTION_SENSOR)
power_consumption_hour = 0;
#endif
printer_usage_seconds = 0;
printer_usage_filament = 0;
print_job_counter.initStats();
ECHO_LM(OK, "Hardcoded SD Default Settings Loaded");
}
#if ENABLED(SDSUPPORT) && ENABLED(SD_SETTINGS)
static const char *cfgSD_KEY[] = { // Keep this in lexicographical order for better search performance(O(Nlog2(N)) insted of O(N*N)) (if you don't keep this sorted, the algorithm for find the key index won't work, keep attention.)
#if HAS(POWER_CONSUMPTION_SENSOR)
"PWR",
#endif
"FIL",
"TME"
"CPR", // Number of complete prints
"FIL", // Filament Usage
"NPR", // Number of prints
#if HAS(POWER_CONSUMPTION_SENSOR)
"PWR", // Power Consumption
#endif
"TME", // Longest print job
"TPR" // Total printing time
};
enum cfgSD_ENUM { // This need to be in the same order as cfgSD_KEY
#if HAS(POWER_CONSUMPTION_SENSOR)
SD_CFG_PWR,
#endif
SD_CFG_CPR,
SD_CFG_FIL,
SD_CFG_NPR,
#if HAS(POWER_CONSUMPTION_SENSOR)
SD_CFG_PWR,
#endif
SD_CFG_TME,
SD_CFG_TPR,
SD_CFG_END // Leave this always as the last
};
......@@ -949,9 +937,15 @@ void ConfigSD_ResetDefault() {
ltoa(power_consumption_hour, buff, 10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_PWR], buff);
#endif
ltoa(printer_usage_seconds, buff, 10);
ltoa(print_job_counter.data.numberPrints, buff, 10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_NPR], buff);
ltoa(print_job_counter.data.completePrints, buff, 10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_CPR], buff);
ltoa(print_job_counter.data.printTime, buff, 10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_TPR], buff);
ltoa(print_job_counter.data.printer_usage_seconds, buff, 10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_TME], buff);
ltoa(printer_usage_filament, buff, 10);
ltoa(print_job_counter.data.printer_usage_filament, buff, 10);
card.unparseKeyLine(cfgSD_KEY[SD_CFG_FIL], buff);
card.closeFile();
......@@ -983,14 +977,29 @@ void ConfigSD_ResetDefault() {
}
break;
#endif
case SD_CFG_NPR: {
if(addValue) print_job_counter.data.numberPrints += (unsigned long)atol(value);
else print_job_counter.data.numberPrints = (unsigned long)atol(value);
}
break;
case SD_CFG_CPR: {
if(addValue) print_job_counter.data.completePrints += (unsigned long)atol(value);
else print_job_counter.data.completePrints = (unsigned long)atol(value);
}
break;
case SD_CFG_TPR: {
if(addValue) print_job_counter.data.printTime += (unsigned long)atol(value);
else print_job_counter.data.printTime = (unsigned long)atol(value);
}
break;
case SD_CFG_TME: {
if(addValue) printer_usage_seconds += (unsigned long)atol(value);
else printer_usage_seconds = (unsigned long)atol(value);
if(addValue) print_job_counter.data.printer_usage_seconds += (unsigned long)atol(value);
else print_job_counter.data.printer_usage_seconds = (unsigned long)atol(value);
}
break;
case SD_CFG_FIL: {
if(addValue) printer_usage_filament += (unsigned long)atol(value);
else printer_usage_filament = (unsigned long)atol(value);
if(addValue) print_job_counter.data.printer_usage_filament += (unsigned long)atol(value);
else print_job_counter.data.printer_usage_filament = (unsigned long)atol(value);
}
break;
}
......
......@@ -46,7 +46,7 @@
#include "Configuration_Store.h"
#include "module/language/language.h"
#include "module/stopwatch/stopwatch.h"
#include "module/printcounter/printcounter.h"
#include "module/MK_Main.h"
#include "module/motion/planner.h"
#include "module/motion/stepper_indirection.h"
......
......@@ -116,15 +116,12 @@ 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();
PrintCounter print_job_counter = PrintCounter();
static uint8_t target_extruder;
bool software_endstops = true;
unsigned long printer_usage_seconds;
double printer_usage_filament;
#if !MECH(DELTA)
int xy_travel_speed = XY_TRAVEL_SPEED;
float zprobe_zoffset = 0;
......@@ -979,9 +976,9 @@ inline void get_serial_commands() {
) {
if (card_eof) {
ECHO_EM(SERIAL_FILE_PRINTED);
print_job_timer.stop();
print_job_counter.stop();
char time[30];
millis_t t = print_job_timer.duration();
millis_t t = print_job_counter.duration();
int hours = t / 60 / 60, minutes = (t / 60) % 60;
sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes);
ECHO_LT(DB, time);
......@@ -3125,7 +3122,7 @@ void gcode_get_destination() {
destination[E_AXIS] = (code_value() * density_multiplier[previous_extruder] / 100) + current_position[E_AXIS];
}
printer_usage_filament += (destination[E_AXIS] - current_position[E_AXIS]);
print_job_counter.data.printer_usage_filament += (destination[E_AXIS] - current_position[E_AXIS]);
#if ENABLED(RFID_MODULE)
RFID522.RfidData[active_extruder].data.lenght -= (destination[E_AXIS] - current_position[E_AXIS]);
......@@ -4663,7 +4660,7 @@ inline void gcode_M17() {
*/
inline void gcode_M24() {
card.startPrint();
print_job_timer.start();
print_job_counter.start();
#if HAS(POWER_CONSUMPTION_SENSOR)
startpower = power_consumption_hour;
#endif
......@@ -4720,7 +4717,7 @@ inline void gcode_M17() {
* M31: Get the time since the start of SD Print (or last M109)
*/
inline void gcode_M31() {
millis_t t = print_job_timer.duration();
millis_t t = print_job_counter.duration();
int min = t / 60, sec = t % 60;
char time[30];
sprintf_P(time, PSTR("%i min, %i sec"), min, sec);
......@@ -5038,21 +5035,31 @@ inline void gcode_M42() {
* M75: Start print timer
*/
inline void gcode_M75() {
print_job_timer.start();
print_job_counter.start();
}
/**
* M76: Pause print timer
*/
inline void gcode_M76() {
print_job_timer.pause();
print_job_counter.pause();
}
/**
* M77: Stop print timer
*/
inline void gcode_M77() {
print_job_timer.stop();
print_job_counter.stop();
}
/**
* M78: Show print statistics
*/
inline void gcode_M78() {
// "M78 S78" will reset the statistics
if (code_seen('S') && code_value_short() == 78)
print_job_counter.initStats();
else print_job_counter.showStats();
}
#if HAS(POWER_SWITCH)
......@@ -5417,7 +5424,7 @@ inline void gcode_M104() {
* the running print timer.
*/
if (temp <= (EXTRUDE_MINTEMP)/2) {
print_job_timer.stop();
print_job_counter.stop();
LCD_MESSAGEPGM(WELCOME_MSG);
}
/**
......@@ -5425,7 +5432,7 @@ inline void gcode_M104() {
* be done for us inside the Stopwatch::start() method thus a running timer
* will not restart.
*/
else print_job_timer.start();
else print_job_counter.start();
if (temp > degHotend(target_extruder)) LCD_MESSAGEPGM(MSG_HEATING);
}
......@@ -5487,7 +5494,7 @@ inline void gcode_M109() {
* the running print timer.
*/
if (temp <= (EXTRUDE_MINTEMP) / 2) {
print_job_timer.stop();
print_job_counter.stop();
LCD_MESSAGEPGM(WELCOME_MSG);
}
/**
......@@ -5495,7 +5502,7 @@ inline void gcode_M109() {
* be done for us inside the Stopwatch::start() method thus a running timer
* will not restart.
*/
else print_job_timer.start();
else print_job_counter.start();
if (temp > degHotend(target_extruder)) LCD_MESSAGEPGM(MSG_HEATING);
}
......@@ -7875,6 +7882,9 @@ void process_next_command() {
case 77: // Stop print timer
gcode_M77(); break;
case 78: // Show print statistics
gcode_M78(); break;
#if HAS(POWER_SWITCH)
case 80: // M80 - Turn on Power Supply
gcode_M80(); break;
......@@ -8774,6 +8784,7 @@ void idle(
);
host_keepalive();
lcd_update();
print_job_counter.tick();
}
/**
......
......@@ -165,11 +165,6 @@ int16_t code_value_short();
extern float axis_scaling[3]; // Build size scaling
#endif
// Lifetime stats
extern unsigned long printer_usage_seconds; // this can old about 136 year before go overflow. If you belive that you can live more than this please contact me.
// Filament stats
extern double printer_usage_filament;
#if ENABLED(PREVENT_DANGEROUS_EXTRUDE)
extern float extrude_min_temp;
#endif
......@@ -251,7 +246,7 @@ extern int fanSpeed;
#endif
// Print job timer
extern Stopwatch print_job_timer;
extern PrintCounter print_job_counter;
// Handling multiple extruders pins
extern uint8_t active_extruder;
......
......@@ -399,7 +399,7 @@ static void lcd_implementation_status_screen() {
}
u8g.setPrintPos(53, 47);
uint16_t time = print_job_timer.duration() / 60;
uint16_t time = print_job_counter.duration() / 60;
if (time != 0) {
#if HAS(LCD_POWER_SENSOR)
if (millis() < print_millis + 1000) {
......
......@@ -790,7 +790,7 @@ static void lcd_implementation_status_screen() {
#endif // LCD_WIDTH > 19 && SDSUPPORT
lcd.setCursor(LCD_WIDTH - 6, 2);
uint16_t time = print_job_timer.duration() / 60;
uint16_t time = print_job_counter.duration() / 60;
if(time != 0) {
#if HAS(LCD_POWER_SENSOR)
if (millis() < print_millis + 1000) {
......
......@@ -250,7 +250,7 @@
#if ENABLED(DUAL_X_CARRIAGE) && HAS(X_ENABLE) && HAS(X2_ENABLE)
#define enable_x() do { X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); } while (0)
#define disable_x() do { X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); CBI(axis_known_position, X_AXIS); } while (0)
#define disable_x() do { X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0)
#elif HAS(X_ENABLE)
#define enable_x() X_ENABLE_WRITE( X_ENABLE_ON)
#define disable_x() { X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
......@@ -262,7 +262,7 @@
#if HAS(Y_ENABLE)
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
#define enable_y() { Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); CBI(axis_known_position, Y_AXIS); }
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
#else
#define enable_y() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
......
......@@ -755,7 +755,7 @@
NPlay.setPic(17);
// Estimate End Time
uint16_t time = print_job_timer.duration() / 60;
uint16_t time = print_job_counter.duration() / 60;
uint16_t end_time = (time * (100 - card.percentDone())) / card.percentDone();
if (end_time > (60 * 23)) {
lcd_setstatus("End --:--");
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "../../base.h"
#include "printcounter.h"
PrintCounter::PrintCounter(): super() {
this->initStats();
}
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;
}
void PrintCounter::initStats() {
#if ENABLED(DEBUG_PRINTCOUNTER)
PrintCounter::debug(PSTR("initStats"));
#endif
this->data = { 0, 0, 0, 0, 0.0 };
}
void PrintCounter::showStats() {
char temp[30];
uint32_t day, hours, minutes;
ECHO_MV("Print statistics: Total: ", this->data.numberPrints);
ECHO_MV(", Finished: ", this->data.completePrints);
ECHO_M(", Failed: ");
ECHO_EV (this->data.numberPrints - this->data.completePrints -
((this->isRunning() || this->isPaused()) ? 1 : 0)); // Removes 1 from failures with an active counter
day = (this->data.printTime / 60 / 60 / 24);
hours = (this->data.printTime / 60 / 60) % 24;
minutes = (this->data.printTime / 60) % 60;
sprintf_P(temp, PSTR(" %i " MSG_END_DAY " %i " MSG_END_HOUR " %i " MSG_END_MINUTE), day, hours, minutes);
ECHO_EMT("Total print time: ", temp);
day = this->data.printer_usage_seconds / 60 / 60 / 24;
hours = (this->data.printer_usage_seconds / 60 / 60) % 24;
minutes = (this->data.printer_usage_seconds / 60) % 60;
sprintf_P(temp, PSTR(" %i " MSG_END_DAY " %i " MSG_END_HOUR " %i " MSG_END_MINUTE), day, hours, minutes);
ECHO_EMT("Power on time: ", temp);
uint32_t kmeter = (long)this->data.printer_usage_filament / 1000 / 1000,
meter = ((long)this->data.printer_usage_filament / 1000) % 1000,
centimeter = ((long)this->data.printer_usage_filament / 10) % 100,
millimeter = ((long)this->data.printer_usage_filament) % 10;
sprintf_P(temp, PSTR(" %i Km %i m %i cm %i mm"), kmeter, meter, centimeter, millimeter);
ECHO_EMT("Filament printed: ", temp);
}
void PrintCounter::tick() {
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->data.printer_usage_seconds += this->updateInterval;
if (this->isRunning())
this->data.printTime += this->deltaDuration();
update_before = now;
#if ENABLED(DEBUG_PRINTCOUNTER)
PrintCounter::debug(PSTR("tick"));
#endif
}
}
void PrintCounter::start() {
#if ENABLED(DEBUG_PRINTCOUNTER)
PrintCounter::debug(PSTR("start"));
#endif
if (!this->isPaused()) this->data.numberPrints++;
super::start();
}
void PrintCounter::stop() {
#if ENABLED(DEBUG_PRINTCOUNTER)
PrintCounter::debug(PSTR("stop"));
#endif
if (!this->isRunning()) return;
super::stop();
this->data.completePrints++;
this->data.printTime += this->deltaDuration();
}
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
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef PRINTCOUNTER_H
#define PRINTCOUNTER_H
#include "stopwatch.h"
// Print debug messages with M111 S2
//#define DEBUG_PRINTCOUNTER
struct printStatistics {
uint16_t numberPrints; // Number of prints
uint16_t completePrints; // Number of complete prints
uint32_t printTime; // Total printing time
uint32_t printer_usage_seconds; // Longest print job
double printer_usage_filament; // Filament usage
};
class PrintCounter: public Stopwatch {
private:
typedef Stopwatch super;
/**
* @brief Interval in seconds between counter updates
* @details This const value defines what will be the time between each
* accumulator update.
*/
const uint16_t updateInterval = 10;
/**
* @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;
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:
printStatistics data;
/**
* @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
* also the magic header.
*/
void initStats();
/**
* @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
......@@ -917,9 +917,7 @@ static float analog2tempBed(int raw) {
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
static void updateTemperaturesFromRawValues() {
static millis_t last_update = millis();
millis_t temp_last_update = millis();
millis_t from_last_update = temp_last_update - last_update;
#if ENABLED(HEATER_0_USES_MAX6675)
current_temperature_raw[0] = read_max6675();
#endif
......@@ -934,6 +932,9 @@ static void updateTemperaturesFromRawValues() {
filament_width_meas = analog2widthFil();
#endif
#if HAS(POWER_CONSUMPTION_SENSOR)
static millis_t last_update = millis();
millis_t temp_last_update = millis();
millis_t from_last_update = temp_last_update - last_update;
static float watt_overflow = 0.0;
power_consumption_meas = analog2power();
/*ECHO_MV("raw:", raw_analog2voltage(), 5);
......@@ -945,16 +946,9 @@ static void updateTemperaturesFromRawValues() {
power_consumption_hour++;
watt_overflow--;
}
last_update = temp_last_update;
#endif
// Update printer usage
static unsigned int second_overflow = 0;
second_overflow += from_last_update;
if (second_overflow >= 1000) {
printer_usage_seconds++;
second_overflow -= 1000;
}
last_update = temp_last_update;
#if ENABLED(USE_WATCHDOG)
// Reset the watchdog after we know we have a temperature measurement.
watchdog_reset();
......@@ -1316,7 +1310,7 @@ void disable_all_heaters() {
setTargetBed(0);
// If all heaters go down then for sure our print job has stopped
print_job_timer.stop();
print_job_counter.stop();
#define DISABLE_HEATER(NR) { \
target_temperature[NR] = 0; \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment