This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/src/PrintMonitor.h
David Crocker d47cc13765 Version 1.18RC2
Fixed bug with M408 S1/S2 reples when there are no extruders configured
Changed Duet085 network startup to not startb protocols when network is
not active
2017-04-02 10:22:34 +01:00

159 lines
5.8 KiB
C++

/****************************************************************************************************
RepRapFirmware - PrintMonitor
This class provides methods to obtain print end-time estimations and file information from generated
G-Code files, which may be reported to auxiliary devices and to the web interface using status responses.
-----------------------------------------------------------------------------------------------------
Version 0.1
Created on: Feb 24, 2015
Christian Hammacher
Licence: GPL
****************************************************************************************************/
#ifndef PRINTMONITOR_H
#define PRINTMONITOR_H
#include "RepRapFirmware.h"
const FilePosition GCODE_HEADER_SIZE = 8192uL; // How many bytes to read from the header
const FilePosition GCODE_FOOTER_SIZE = 400000uL; // How many bytes to read from the footer
#ifdef DUET_NG
const size_t GCODE_READ_SIZE = 4096; // How many bytes to read in one go in GetFileInfo() (should be a multiple of 512 for read efficiency)
#else
const size_t GCODE_READ_SIZE = 1024; // How many bytes to read in one go in GetFileInfo() (should be a multiple of 512 for read efficiency)
#endif
const size_t GCODE_OVERLAP_SIZE = 100; // Size of the overlapping buffer for searching (should be a multiple of 4)
const float LAYER_HEIGHT_TOLERANCE = 0.015; // Tolerance for comparing two Z heights (in mm)
const size_t MAX_LAYER_SAMPLES = 5; // Number of layer samples for end-time estimation (except for first layer)
const float ESTIMATION_MIN_FILAMENT_USAGE = 0.01; // Minimum per cent of filament to be printed before the filament-based estimation returns values
const float ESTIMATION_MIN_FILE_USAGE = 0.001; // Minium per cent of the file to be processed before any file-based estimations are made
const float FIRST_LAYER_SPEED_FACTOR = 0.25; // First layer speed factor compared to other layers (only for layer-based estimation)
const uint32_t PRINTMONITOR_UPDATE_INTERVAL = 200; // Update interval in milliseconds
const uint32_t MAX_FILEINFO_PROCESS_TIME = 200; // Maximum time to spend polling for file info in each call
enum PrintEstimationMethod
{
filamentBased,
fileBased,
layerBased
};
// Struct to hold Gcode file information
struct GCodeFileInfo
{
bool isValid;
FilePosition fileSize;
time_t lastModifiedTime;
float firstLayerHeight;
float objectHeight;
float filamentNeeded[DRIVES - MIN_AXES];
unsigned int numFilaments;
float layerHeight;
char generatedBy[50];
};
enum FileParseState
{
notParsing,
parsingHeader,
parsingFooter
};
class PrintMonitor
{
public:
PrintMonitor(Platform *p, GCodes *gc);
void Spin();
void Init();
bool IsPrinting() const; // Is a file being printed?
void StartingPrint(const char *filename); // Called to indicate a file will be printed (see M23)
void StartedPrint(); // Called whenever a new live print starts (see M24)
void StoppedPrint(); // Called whenever a file print has stopped
// The following two methods need to be called until they return true - this may take a few runs
bool GetFileInfo(const char *directory, const char *fileName, GCodeFileInfo& info);
bool GetFileInfoResponse(const char *filename, OutputBuffer *&response);
void StopParsing(const char *filename);
// Return an estimate in seconds based on a specific estimation method
float EstimateTimeLeft(PrintEstimationMethod method) const;
// Provide some information about the file being printed
unsigned int GetCurrentLayer() const;
float GetCurrentLayerTime() const;
float GetPrintDuration() const;
float GetWarmUpDuration() const;
float GetFirstLayerDuration() const;
float GetFirstLayerHeight() const;
private:
Platform * const platform;
GCodes * const gCodes;
float longWait;
uint32_t lastUpdateTime;
// Information/Events concerning the file being printed
void WarmUpComplete();
void FirstLayerComplete();
void LayerComplete();
bool isPrinting;
float printStartTime;
float pauseStartTime, totalPauseTime;
bool heatingUp;
unsigned int currentLayer;
float warmUpDuration, firstLayerDuration;
float firstLayerFilament, firstLayerProgress;
float lastLayerChangeTime, lastLayerFilament, lastLayerZ;
unsigned int numLayerSamples;
float layerDurations[MAX_LAYER_SAMPLES];
float filamentUsagePerLayer[MAX_LAYER_SAMPLES];
float fileProgressPerLayer[MAX_LAYER_SAMPLES];
float layerEstimatedTimeLeft;
// We parse G-Code files in multiple stages. These variables hold the required information
volatile FileParseState parseState;
char filenameBeingParsed[FILENAME_LENGTH];
FileStore *fileBeingParsed;
GCodeFileInfo parsedFileInfo;
char fileOverlap[GCODE_OVERLAP_SIZE];
size_t fileOverlapLength;
bool printingFileParsed;
GCodeFileInfo printingFileInfo;
char filenameBeingPrinted[FILENAME_LENGTH];
// G-Code parser methods
bool FindHeight(const char* buf, size_t len, float& height) const;
bool FindFirstLayerHeight(const char* buf, size_t len, float& layerHeight) const;
bool FindLayerHeight(const char* buf, size_t len, float& layerHeight) const;
unsigned int FindFilamentUsed(const char* buf, size_t len, float *filamentUsed, unsigned int maxFilaments) const;
uint32_t accumulatedParseTime, accumulatedReadTime, accumulatedSeekTime;
};
inline bool PrintMonitor::IsPrinting() const { return isPrinting; }
inline unsigned int PrintMonitor::GetCurrentLayer() const { return currentLayer; }
inline float PrintMonitor::GetCurrentLayerTime() const { return (lastLayerChangeTime > 0.0) ? (GetPrintDuration() - lastLayerChangeTime) : 0.0; }
inline float PrintMonitor::GetFirstLayerDuration() const { return (firstLayerDuration > 0.0) ? firstLayerDuration : ((currentLayer > 0) ? GetPrintDuration() - warmUpDuration : 0.0); }
inline float PrintMonitor::GetFirstLayerHeight() const { return printingFileParsed ? printingFileInfo.firstLayerHeight : 0.0; }
#endif /* PRINTMONITOR_H */
// vim: ts=4:sw=4