
Implemented F, H and R parameters to M106 command. The second fan output on a Duet 0.8.5 now defaults to being a thermostatic fan at power up. Improved speed of file upload to SD card G32 is now allowed if the printer has not been homed, if there is a bed.g file G30 commands are no longer allowed on a delta that has not been homed M572 parameter P (drive number) replaced by parameter D (extruder number) File info requests are now processed in stages to reduce impact on printing (thanks chrishamm) Use latest network stack and webserver modules from chrishamm (thanks chrishamm) Added Roland mill support (thanks RRP/chrishamm) Added S parameter (idle timeout) to M18 ans M84 commands (thanks chrishamm) Moved I/O pin assignments to separate Pins.h file to more easily support alternative hardware (thanks dnewman) Bug fix: filament usage and % print complete figures were incorrect when absolute extruder coordinates were used Bug fix: file-based print estimate was occasionally returned as 'inf' which caused the web interface to disconnect Bug fix: M666 now flags all towers as not homed Bug fixes to extruder pressure compensation (M572 command).
268 lines
14 KiB
C++
268 lines
14 KiB
C++
/****************************************************************************************************
|
|
|
|
RepRapFirmware - G Codes
|
|
|
|
This class interprets G Codes from one or more sources, and calls the functions in Move, Heat etc
|
|
that drive the machine to do what the G Codes command.
|
|
|
|
-----------------------------------------------------------------------------------------------------
|
|
|
|
Version 0.1
|
|
|
|
13 February 2013
|
|
|
|
Adrian Bowyer
|
|
RepRap Professional Ltd
|
|
http://reprappro.com
|
|
|
|
Licence: GPL
|
|
|
|
****************************************************************************************************/
|
|
|
|
#ifndef GCODES_H
|
|
#define GCODES_H
|
|
|
|
#include "GCodeBuffer.h"
|
|
|
|
const unsigned int StackSize = 5;
|
|
|
|
const char feedrateLetter = 'F'; // GCode feedrate
|
|
const char extrudeLetter = 'E'; // GCode extrude
|
|
|
|
// Type for specifying which endstops we want to check
|
|
typedef uint16_t EndstopChecks; // must be large enough to hold a bitmap of drive numbers or ZProbeActive
|
|
const EndstopChecks ZProbeActive = 1 << 15; // must be distinct from 1 << (any drive number)
|
|
|
|
const float minutesToSeconds = 60.0;
|
|
const float secondsToMinutes = 1.0/minutesToSeconds;
|
|
|
|
// Enumeration to list all the possible states that the Gcode processing machine may be in
|
|
enum class GCodeState
|
|
{
|
|
normal, // not doing anything and ready to process a new GCode
|
|
waitingForMoveToComplete, // doing a homing move, so we must wait for it to finish before processing another GCode
|
|
homing,
|
|
setBed1,
|
|
setBed2,
|
|
setBed3,
|
|
toolChange1,
|
|
toolChange2,
|
|
toolChange3,
|
|
pausing1,
|
|
pausing2,
|
|
resuming1,
|
|
resuming2,
|
|
resuming3
|
|
};
|
|
|
|
// Small class to stack the state when we execute a macro file
|
|
class GCodeMachineState
|
|
{
|
|
public:
|
|
GCodeState state;
|
|
GCodeBuffer *gb; // this may be null when executing config.g
|
|
float feedrate;
|
|
FileData fileState;
|
|
bool drivesRelative;
|
|
bool axesRelative;
|
|
bool doingFileMacro;
|
|
};
|
|
|
|
//****************************************************************************************************
|
|
|
|
// The GCode interpreter
|
|
|
|
class GCodes
|
|
{
|
|
public:
|
|
|
|
GCodes(Platform* p, Webserver* w);
|
|
void Spin(); // Called in a tight loop to make this class work
|
|
void Init(); // Set it up
|
|
void Exit(); // Shut it down
|
|
void Reset(); // Reset some parameter to defaults
|
|
bool ReadMove(float* m, EndstopChecks& ce, uint8_t& rMoveType, FilePosition& fPos); // Called by the Move class to get a movement set by the last G Code
|
|
void ClearMove();
|
|
void QueueFileToPrint(const char* fileName); // Open a file of G Codes to run
|
|
void DeleteFile(const char* fileName); // Does what it says
|
|
bool GetProbeCoordinates(int count, float& x, float& y, float& z) const; // Get pre-recorded probe coordinates
|
|
void GetCurrentCoordinates(StringRef& s) const; // Write where we are into a string
|
|
bool DoingFileMacro() const; // Or still busy processing a macro file?
|
|
float FractionOfFilePrinted() const; // Get fraction of file printed
|
|
void Diagnostics(); // Send helpful information out
|
|
bool HaveIncomingData() const; // Is there something that we have to do?
|
|
size_t GetStackPointer() const; // Returns the current stack pointer
|
|
bool GetAxisIsHomed(uint8_t axis) const { return axisIsHomed[axis]; } // Is the axis at 0?
|
|
void SetAxisIsHomed(uint8_t axis) { axisIsHomed[axis] = true; } // Tell us that the axis is now homed
|
|
|
|
void PauseSDPrint(); // Pause the current print from SD card
|
|
float GetSpeedFactor() const { return speedFactor * minutesToSeconds; } // Return the current speed factor
|
|
float GetExtrusionFactor(size_t extruder) { return extrusionFactors[extruder]; } // Return the current extrusion factors
|
|
float GetRawExtruderPosition(size_t drive) const; // Get the actual extruder position, after adjusting the extrusion factor
|
|
float GetRawExtruderTotalByDrive(size_t extruder) const; // Get the total extrusion since start of print, for one drive
|
|
float GetTotalRawExtrusion() const { return rawExtruderTotal; } // Get the total extrusion since start of print, all drives
|
|
|
|
bool HaveAux() const { return auxDetected; } // Any device on the AUX line?
|
|
OutputBuffer *GetAuxGCodeReply(); // Returns cached G-Code reply for AUX devices and clears its reference
|
|
uint32_t GetAuxSeq() { return auxSeq; }
|
|
|
|
bool IsPaused() const;
|
|
bool IsPausing() const;
|
|
bool IsResuming() const;
|
|
|
|
bool AllAxesAreHomed() const; // Return true if all axes are homed
|
|
bool DoFileMacro(const char* fileName, bool reportMissing = true); // Run a GCode macro in a file, optionally report error if not found
|
|
|
|
private:
|
|
|
|
void StartNextGCode(StringRef& reply); // Fetch a new GCode and process it
|
|
void DoFilePrint(GCodeBuffer* gb, StringRef& reply); // Get G Codes from a file and print them
|
|
bool AllMovesAreFinishedAndMoveBufferIsLoaded(); // Wait for move queue to exhaust and the current position is loaded
|
|
bool DoCannedCycleMove(EndstopChecks ce); // Do a move from an internally programmed canned cycle
|
|
void FileMacroCyclesReturn(); // End a macro
|
|
bool ActOnCode(GCodeBuffer* gb, StringRef& reply); // Do a G, M or T Code
|
|
bool HandleGcode(GCodeBuffer* gb, StringRef& reply); // Do a G code
|
|
bool HandleMcode(GCodeBuffer* gb, StringRef& reply); // Do an M code
|
|
bool HandleTcode(GCodeBuffer* gb, StringRef& reply); // Do a T code
|
|
void CancelPrint(); // Cancel the current print
|
|
int SetUpMove(GCodeBuffer* gb, StringRef& reply); // Pass a move on to the Move module
|
|
bool DoDwell(GCodeBuffer *gb); // Wait for a bit
|
|
bool DoDwellTime(float dwell); // Really wait for a bit
|
|
bool DoHome(GCodeBuffer *gb, StringRef& reply, bool& error); // Home some axes
|
|
bool DoSingleZProbeAtPoint(int probePointIndex, float heightAdjust); // Probe at a given point
|
|
bool DoSingleZProbe(bool reportOnly, float heightAdjust); // Probe where we are
|
|
int DoZProbe(float distance); // Do a Z probe cycle up to the maximum specified distance
|
|
bool SetSingleZProbeAtAPosition(GCodeBuffer *gb, StringRef& reply); // Probes at a given position - see the comment at the head of the function itself
|
|
void SetBedEquationWithProbe(int sParam, StringRef& reply); // Probes a series of points and sets the bed equation
|
|
bool SetPrintZProbe(GCodeBuffer *gb, StringRef& reply); // Either return the probe value, or set its threshold
|
|
void SetOrReportOffsets(StringRef& reply, GCodeBuffer *gb); // Deal with a G10
|
|
bool SetPositions(GCodeBuffer *gb); // Deal with a G92
|
|
bool LoadMoveBufferFromGCode(GCodeBuffer *gb, // Set up a move for the Move class
|
|
bool doingG92, bool applyLimits);
|
|
bool NoHome() const; // Are we homing and not finished?
|
|
void Push(); // Push feedrate etc on the stack
|
|
void Pop(); // Pop feedrate etc
|
|
void DisableDrives(); // Turn the motors off
|
|
void SetEthernetAddress(GCodeBuffer *gb, int mCode); // Does what it says
|
|
void SetMACAddress(GCodeBuffer *gb); // Deals with an M540
|
|
void HandleReply(GCodeBuffer *gb, bool error, const char *reply); // Handle G-Code replies
|
|
void HandleReply(GCodeBuffer *gb, bool error, OutputBuffer *reply);
|
|
bool OpenFileToWrite(const char* directory, // Start saving GCodes in a file
|
|
const char* fileName, GCodeBuffer *gb);
|
|
void WriteGCodeToFile(GCodeBuffer *gb); // Write this GCode into a file
|
|
bool SendConfigToLine(); // Deal with M503
|
|
void WriteHTMLToFile(char b, GCodeBuffer *gb); // Save an HTML file (usually to upload a new web interface)
|
|
bool OffsetAxes(GCodeBuffer *gb); // Set offsets - deprecated, use G10
|
|
void SetPidParameters(GCodeBuffer *gb, int heater, StringRef& reply); // Set the P/I/D parameters for a heater
|
|
void SetHeaterParameters(GCodeBuffer *gb, StringRef& reply); // Set the thermistor and ADC parameters for a heater
|
|
void ManageTool(GCodeBuffer *gb, StringRef& reply); // Create a new tool definition
|
|
void SetToolHeaters(Tool *tool, float temperature); // Set all a tool's heaters to the temperature. For M104...
|
|
bool ToolHeatersAtSetTemperatures(const Tool *tool) const; // Wait for the heaters associated with the specified tool to reach their set temperatures
|
|
void SetAllAxesNotHomed(); // Flag all axes as not homed
|
|
void SetPositions(float positionNow[DRIVES]); // Set the current position to be this
|
|
const char *TranslateEndStopResult(EndStopHit es); // Translate end stop result to text
|
|
|
|
Platform* platform; // The RepRap machine
|
|
bool active; // Live and running?
|
|
bool isPaused; // true if the print has been paused
|
|
Webserver* webserver; // The webserver class
|
|
float dwellTime; // How long a pause for a dwell (seconds)?
|
|
bool dwellWaiting; // We are in a dwell
|
|
GCodeBuffer* httpGCode; // The sources...
|
|
GCodeBuffer* telnetGCode; // ...
|
|
GCodeBuffer* fileGCode; // ...
|
|
GCodeBuffer* serialGCode; // ...
|
|
GCodeBuffer* auxGCode; // this one is for the LCD display on the async serial interface
|
|
GCodeBuffer* fileMacroGCode; // ...
|
|
GCodeBuffer *gbCurrent;
|
|
bool moveAvailable; // Have we seen a move G Code and set it up?
|
|
float moveBuffer[DRIVES+1]; // Move coordinates; last is feed rate
|
|
float savedMoveBuffer[DRIVES+1]; // The position and feedrate when we started the current simulation
|
|
float pausedMoveBuffer[DRIVES+1]; // Move coordinates; last is feed rate
|
|
EndstopChecks endStopsToCheck; // Which end stops we check them on the next move
|
|
uint8_t moveType; // 0 = normal move, 1 = homing move, 2 = direct motor move
|
|
GCodeState state; // The main state variable of the GCode state machine
|
|
bool drivesRelative;
|
|
bool axesRelative;
|
|
GCodeMachineState stack[StackSize]; // State that we save when calling macro files
|
|
unsigned int stackPointer; // Push and Pop stack pointer
|
|
static const char axisLetters[AXES]; // 'X', 'Y', 'Z'
|
|
float axisScaleFactors[AXES]; // Scale XYZ coordinates by this factor (for Delta configurations)
|
|
float lastRawExtruderPosition[DRIVES - AXES]; // Extruder position of the last move fed into the Move class
|
|
float rawExtruderTotalByDrive[DRIVES - AXES]; // Total extrusion amount fed to Move class since starting print, before applying extrusion factor, per drive
|
|
float rawExtruderTotal; // Total extrusion amount fed to Move class since starting print, before applying extrusion factor, summed over all drives
|
|
float record[DRIVES+1]; // Temporary store for move positions
|
|
float moveToDo[DRIVES+1]; // Where to go set by G1 etc
|
|
bool activeDrive[DRIVES+1]; // Is this drive involved in a move?
|
|
bool offSetSet; // Are any axis offsets non-zero?
|
|
float distanceScale; // MM or inches
|
|
FileData fileBeingPrinted;
|
|
FileData fileToPrint;
|
|
FileStore* fileBeingWritten; // A file to write G Codes (or sometimes HTML) in
|
|
uint16_t toBeHomed; // Bitmap of axes still to be homed
|
|
bool doingFileMacro; // Are we executing a macro file?
|
|
int oldToolNumber, newToolNumber; // Tools being changed
|
|
const char* eofString; // What's at the end of an HTML file?
|
|
uint8_t eofStringCounter; // Check the...
|
|
uint8_t eofStringLength; // ... EoF string as we read.
|
|
int probeCount; // Counts multiple probe points
|
|
int8_t cannedCycleMoveCount; // Counts through internal (i.e. not macro) canned cycle moves
|
|
bool cannedCycleMoveQueued; // True if a canned cycle move has been set
|
|
bool zProbesSet; // True if all Z probing is done and we can set the bed equation
|
|
float longWait; // Timer for things that happen occasionally (seconds)
|
|
bool limitAxes; // Don't think outside the box.
|
|
bool axisIsHomed[AXES]; // These record which of the axes have been homed
|
|
float pausedFanValues[NUM_FANS]; // Fan speeds when the print was paused
|
|
float speedFactor; // speed factor, including the conversion from mm/min to mm/sec, normally 1/60
|
|
float speedFactorChange; // factor by which we changed the speed factor since the last move
|
|
float extrusionFactors[DRIVES - AXES]; // extrusion factors (normally 1.0)
|
|
float lastProbedZ; // the last height at which the Z probe stopped
|
|
|
|
bool auxDetected; // Have we processed at least one G-Code from an AUX device?
|
|
OutputBuffer *auxGCodeReply; // G-Code reply for AUX devices (special one because it is actually encapsulated before sending)
|
|
uint32_t auxSeq; // Sequence number for AUX devices
|
|
bool simulating;
|
|
float simulationTime;
|
|
FilePosition filePos; // The position we got up to in the file being printed
|
|
FilePosition moveFilePos; // Saved version of filePos for the next real move to be processed
|
|
};
|
|
|
|
//*****************************************************************************************************
|
|
|
|
inline bool GCodes::DoingFileMacro() const
|
|
{
|
|
return doingFileMacro;
|
|
}
|
|
|
|
inline bool GCodes::HaveIncomingData() const
|
|
{
|
|
return fileBeingPrinted.IsLive() ||
|
|
webserver->GCodeAvailable(WebSource::HTTP) ||
|
|
webserver->GCodeAvailable(WebSource::Telnet) ||
|
|
platform->GCodeAvailable(SerialSource::USB) ||
|
|
platform->GCodeAvailable(SerialSource::AUX);
|
|
}
|
|
|
|
inline bool GCodes::AllAxesAreHomed() const
|
|
{
|
|
return axisIsHomed[X_AXIS] && axisIsHomed[Y_AXIS] && axisIsHomed[Z_AXIS];
|
|
}
|
|
|
|
inline void GCodes::SetAllAxesNotHomed()
|
|
{
|
|
axisIsHomed[X_AXIS] = axisIsHomed[Y_AXIS] = axisIsHomed[Z_AXIS] = false;
|
|
}
|
|
|
|
inline size_t GCodes::GetStackPointer() const
|
|
{
|
|
return stackPointer;
|
|
}
|
|
|
|
inline OutputBuffer *GCodes::GetAuxGCodeReply()
|
|
{
|
|
OutputBuffer *temp = auxGCodeReply;
|
|
auxGCodeReply = nullptr;
|
|
return temp;
|
|
}
|
|
|
|
#endif
|