
Implemented rr_config web request for zpl's latest web interface Implemented 7-factor auto calibration for delta printers Fix bug with fileinfo calls corrupting memory M563 can now be used to delete tools
260 lines
13 KiB
C++
260 lines
13 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 PrintingAFile() const; // Are we in the middle of printing a file?
|
|
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?
|
|
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
|
|
bool CoolingInverted() const; // Is the current fan value inverted?
|
|
|
|
void PauseSDPrint(); // Pause the current print from SD card
|
|
float GetSpeedFactor() const { return speedFactor * minutesToSeconds; } // Return the current speed factor
|
|
const float *GetExtrusionFactors() const { return extrusionFactors; } // Return the current extrusion factors
|
|
float GetRawExtruderPosition(size_t drive) const; // Get the actual extruder position, after adjusting the extrusion factor
|
|
|
|
bool HaveAux() const { return auxDetected; } // Any device on the AUX line?
|
|
|
|
bool IsPaused() const;
|
|
bool IsPausing() const;
|
|
bool IsResuming() const;
|
|
|
|
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 DoFileMacro(const char* fileName); // Run a GCode macro in a file, error if not found
|
|
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
|
|
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 DoSingleZProbeAtPoint(int probePointIndex); // Probe at a given point
|
|
bool DoSingleZProbe(); // Probe where we are
|
|
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(bool error, const GCodeBuffer *gb, // If the GCode is from the serial interface, reply to it
|
|
const char* reply, char gMOrT, int code, bool resend);
|
|
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
|
|
int8_t Heater(int8_t head) const; // Legacy G codes start heaters at 0, but we use 0 for the bed. This sorts that out.
|
|
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
|
|
bool AllAxesAreHomed() const; // Return true if all axes are homed
|
|
void SetAllAxesNotHomed(); // Flag all axes as not homed
|
|
void SetPositions(float positionNow[DRIVES]); // Set the current position to be this
|
|
|
|
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* webGCode; // The sources...
|
|
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 lastRawExtruderPosition[DRIVES - AXES]; // Extruder position of the last move fed into the Move class
|
|
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
|
|
FileStore* configFile; // A file containing a macro
|
|
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
|
|
bool coolingInverted;
|
|
float pausedFanValue;
|
|
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?
|
|
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::PrintingAFile() const
|
|
{
|
|
return FractionOfFilePrinted() >= 0.0;
|
|
}
|
|
|
|
inline bool GCodes::DoingFileMacro() const
|
|
{
|
|
return doingFileMacro;
|
|
}
|
|
|
|
inline bool GCodes::HaveIncomingData() const
|
|
{
|
|
return fileBeingPrinted.IsLive() ||
|
|
webserver->GCodeAvailable() ||
|
|
(platform->GetLine()->Status() & byteAvailable) ||
|
|
(platform->GetAux()->Status() & byteAvailable);
|
|
}
|
|
|
|
// This function takes care of the fact that the heater and head indices don't match because the bed is heater 0.
|
|
inline int8_t GCodes::Heater(int8_t head) const
|
|
{
|
|
return head+1;
|
|
}
|
|
|
|
inline bool GCodes::CoolingInverted() const
|
|
{
|
|
return coolingInverted;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#endif
|