1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
|
/****************************************************************************************************
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 "RepRapFirmware.h"
#include "RepRap.h" // for type ResponseSource
#include "GCodeResult.h"
#include "Movement/RawMove.h"
#include "Libraries/sha1/sha1.h"
#include "Platform.h" // for type EndStopHit
#include "GCodeChannel.h"
#include "GCodeInput.h"
#include "Trigger.h"
#include "Tools/Filament.h"
#include "FilamentMonitors/FilamentMonitor.h"
#include "RestorePoint.h"
#include "Movement/BedProbing/Grid.h"
const char feedrateLetter = 'F'; // GCode feedrate
const char extrudeLetter = 'E'; // GCode extrude
// Bits for T-code P-parameter to specify which macros are supposed to be run
constexpr uint8_t TFreeBit = 1 << 0;
constexpr uint8_t TPreBit = 1 << 1;
constexpr uint8_t TPostBit = 1 << 2;
constexpr uint8_t DefaultToolChangeParam = TFreeBit | TPreBit | TPostBit;
// Machine type enumeration. The numeric values must be in the same order as the corresponding M451..M453 commands.
enum class MachineType : uint8_t
{
fff = 0,
laser = 1,
cnc = 2
};
enum class PauseReason
{
user, // M25 command received
gcode, // M25 or M226 command encountered in the file being printed
filamentChange, // M600 command
trigger, // external switch
heaterFault, // heater fault detected
filament, // filament monitor
#if HAS_SMART_DRIVERS
stall, // motor stall detected
#endif
#if HAS_VOLTAGE_MONITOR
lowVoltage // VIN voltage dropped below configured minimum
#endif
};
// Keep this in sync with PrintStopReason in Linux/MessageFormats.h
enum class StopPrintReason
{
normalCompletion,
userCancelled,
abort
};
//****************************************************************************************************
class LinuxInterface;
// The GCode interpreter
class GCodes INHERIT_OBJECT_MODEL
{
public:
friend class LinuxInterface;
GCodes(Platform& p);
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(RawMove& m); // Called by the Move class to get a movement set by the last G Code
void ClearMove();
#if HAS_MASS_STORAGE
bool QueueFileToPrint(const char* fileName, const StringRef& reply); // Open a file of G Codes to run
#endif
void StartPrinting(bool fromStart); // Start printing the file already selected
void GetCurrentCoordinates(const StringRef& s) const; // Write where we are into a string
bool DoingFileMacro() const; // Or still busy processing a macro file?
FilePosition GetFilePosition() const; // Return the current position of the file being printed in bytes
void Diagnostics(MessageType mtype); // Send helpful information out
bool RunConfigFile(const char* fileName); // Start running the config file
bool IsDaemonBusy() const; // Return true if the daemon is busy running config.g or a trigger file
bool IsAxisHomed(unsigned int axis) const // Has the axis been homed?
{ return IsBitSet(axesHomed, axis); }
void SetAxisIsHomed(unsigned int axis); // Tell us that the axis is now homed
void SetAxisNotHomed(unsigned int axis); // Tell us that the axis is not homed
void SetAllAxesNotHomed(); // Flag all axes as not homed
float GetSpeedFactor() const; // Return the current speed factor
#if SUPPORT_12864_LCD
void SetSpeedFactor(float factor); // Set the speed factor
#endif
float GetExtrusionFactor(size_t extruder); // Return the current extrusion factors
void SetExtrusionFactor(size_t extruder, float factor); // Set an 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
float GetTotalBabyStepOffset(size_t axis) const
pre(axis < maxAxes);
float GetUserCoordinate(size_t axis) const; // Get the current user coordinate in the current workspace coordinate system
#if HAS_NETWORKING
NetworkGCodeInput *GetHTTPInput() const { return httpInput; }
NetworkGCodeInput *GetTelnetInput() const { return telnetInput; }
#endif
bool IsFlashing() const { return isFlashing; } // Is a new firmware binary going to be flashed?
bool IsPaused() const;
bool IsPausing() const;
bool IsResuming() const;
bool IsRunning() const;
bool IsReallyPrinting() const; // Return true if we are printing from SD card and not pausing, paused or resuming
bool IsSimulating() const { return simulationMode != 0; }
bool IsDoingToolChange() const { return doingToolChange; }
bool IsHeatingUp() const; // Return true if the SD card print is waiting for a heater to reach temperature
bool AllAxesAreHomed() const; // Return true if all axes are homed
void StopPrint(StopPrintReason reason); // Stop the current print
void MoveStoppedByZProbe() { zProbeTriggered = true; } // Called from the step ISR when the Z probe is triggered, causing the move to be aborted
size_t GetTotalAxes() const { return numTotalAxes; }
size_t GetVisibleAxes() const { return numVisibleAxes; }
size_t GetNumExtruders() const { return numExtruders; }
const char* GetMachineModeString() const; // Get the name of the current machine mode
void FilamentError(size_t extruder, FilamentSensorStatus fstat);
void HandleHeaterFault(int heater); // Respond to a heater fault
#if HAS_VOLTAGE_MONITOR
bool LowVoltagePause();
bool LowVoltageResume();
#endif
#if HAS_SMART_DRIVERS
bool PauseOnStall(DriversBitmap stalledDrivers);
bool ReHomeOnStall(DriversBitmap stalledDrivers);
#endif
const char *GetAxisLetters() const { return axisLetters; } // Return a null-terminated string of axis letters indexed by drive
MachineType GetMachineType() const { return machineType; }
bool LockMovementAndWaitForStandstill(const GCodeBuffer& gb); // Lock movement and wait for pending moves to finish
#if SUPPORT_12864_LCD
bool ProcessCommandFromLcd(const char *cmd); // Process a GCode command from the 12864 LCD returning true if the command was accepted
float GetItemCurrentTemperature(unsigned int itemNumber) const;
float GetItemActiveTemperature(unsigned int itemNumber) const;
float GetItemStandbyTemperature(unsigned int itemNumber) const;
void SetItemActiveTemperature(unsigned int itemNumber, float temp);
void SetItemStandbyTemperature(unsigned int itemNumber, float temp);
#endif
float GetMappedFanSpeed() const { return lastDefaultFanSpeed; } // Get the mapped fan speed
void SetMappedFanSpeed(float f); // Set the speeds of fans mapped for the current tool
void HandleReply(GCodeBuffer& gb, GCodeResult rslt, const char *reply); // Handle G-Code replies
void EmergencyStop(); // Cancel everything
bool GetLastPrintingHeight(float& height) const; // Get the height in user coordinates of the last printing move
bool AtxPowerControlled() const { return atxPowerControlled; }
void AssignGrid(float xRange[2], float yRange[2], float radius, float spacing[2]); // Assign the heightmap using the given parameters
void ActivateHeightmap(bool activate); // (De-)Activate the height map
#if HAS_MASS_STORAGE
GCodeResult StartSDTiming(GCodeBuffer& gb, const StringRef& reply); // Start timing SD card file writing
#endif
#if SUPPORT_WORKPLACE_COORDINATES
unsigned int GetWorkplaceCoordinateSystemNumber() const { return currentCoordinateSystem + 1; }
#endif
protected:
DECLARE_OBJECT_MODEL
private:
GCodes(const GCodes&) = delete;
enum class HeaterFaultState : uint8_t { noFault, pausePending, timing, stopping, stopped };
// Resources that can be locked.
// To avoid deadlock, if you need multiple resources then you must lock them in increasing numerical order.
typedef uint32_t Resource;
static const Resource MoveResource = 0; // Movement system, including canned cycle variables
static const Resource FileSystemResource = 1; // Non-sharable parts of the file system
static const Resource HeaterResourceBase = 2;
static const size_t NumResources = HeaterResourceBase + 1;
static_assert(NumResources <= sizeof(Resource) * CHAR_BIT, "Too many resources to keep a bitmap of them in class GCodeMachineState");
bool LockResource(const GCodeBuffer& gb, Resource r); // Lock the resource, returning true if success
bool LockFileSystem(const GCodeBuffer& gb); // Lock the unshareable parts of the file system
bool LockMovement(const GCodeBuffer& gb); // Lock movement
void GrabResource(const GCodeBuffer& gb, Resource r); // Grab a resource even if it is already owned
void GrabMovement(const GCodeBuffer& gb); // Grab the movement lock even if it is already owned
void UnlockResource(const GCodeBuffer& gb, Resource r); // Unlock the resource if we own it
void UnlockMovement(const GCodeBuffer& gb); // Unlock the movement resource if we own it
void UnlockAll(const GCodeBuffer& gb); // Release all locks
GCodeBuffer *GetGCodeBuffer(GCodeChannel channel) const { return gcodeSources[(size_t)channel]; }
void StartNextGCode(GCodeBuffer& gb, const StringRef& reply); // Fetch a new or old GCode and process it
void RunStateMachine(GCodeBuffer& gb, const StringRef& reply); // Execute a step of the state machine
void DoFilePrint(GCodeBuffer& gb, const StringRef& reply); // Get G Codes from a file and print them
bool DoFileMacro(GCodeBuffer& gb, const char* fileName, bool reportMissing, int codeRunning = -1);
// Run a GCode macro file, optionally report error if not found
void FileMacroCyclesReturn(GCodeBuffer& gb); // End a macro
bool ActOnCode(GCodeBuffer& gb, const StringRef& reply); // Do a G, M or T Code
bool HandleGcode(GCodeBuffer& gb, const StringRef& reply); // Do a G code
bool HandleMcode(GCodeBuffer& gb, const StringRef& reply); // Do an M code
bool HandleTcode(GCodeBuffer& gb, const StringRef& reply); // Do a T code
bool HandleResult(GCodeBuffer& gb, GCodeResult rslt, const StringRef& reply, OutputBuffer *outBuf)
pre(outBuf == nullptr || rslt == GCodeResult::ok);
void HandleReply(GCodeBuffer& gb, OutputBuffer *reply);
const char* DoStraightMove(GCodeBuffer& gb, bool isCoordinated) __attribute__((hot)); // Execute a straight move returning any error message
const char* DoArcMove(GCodeBuffer& gb, bool clockwise) // Execute an arc move returning any error message
pre(segmentsLeft == 0; resourceOwners[MoveResource] == &gb);
void FinaliseMove(GCodeBuffer& gb); // Adjust the move parameters to account for segmentation and/or part of the move having been done already
bool CheckEnoughAxesHomed(AxesBitmap axesMoved); // Check that enough axes have been homed
void AbortPrint(GCodeBuffer& gb); // Cancel any print in progress
GCodeResult DoDwell(GCodeBuffer& gb); // Wait for a bit
GCodeResult DoHome(GCodeBuffer& gb, const StringRef& reply); // Home some axes
GCodeResult ExecuteG30(GCodeBuffer& gb, const StringRef& reply); // Probes at a given position - see the comment at the head of the function itself
void InitialiseTaps(); // Set up to do the first of a possibly multi-tap probe
void SetBedEquationWithProbe(int sParam, const StringRef& reply); // Probes a series of points and sets the bed equation
GCodeResult SetOrReportOffsets(GCodeBuffer& gb, const StringRef& reply); // Deal with a G10
GCodeResult SetPositions(GCodeBuffer& gb); // Deal with a G92
GCodeResult StraightProbe(GCodeBuffer& gb, const StringRef& reply); // Deal with a G38.x
GCodeResult DoDriveMapping(GCodeBuffer& gb, const StringRef& reply); // Deal with a M584
GCodeResult ProbeTool(GCodeBuffer& gb, const StringRef& reply); // Deal with a M585
GCodeResult FindCenterOfCavity(GCodeBuffer& gb, const StringRef& reply, const bool towardsMin = true); // Deal with a M675
GCodeResult SetDateTime(GCodeBuffer& gb,const StringRef& reply); // Deal with a M905
GCodeResult SavePosition(GCodeBuffer& gb,const StringRef& reply); // Deal with G60
GCodeResult ConfigureDriver(GCodeBuffer& gb,const StringRef& reply); // Deal with M569
bool LoadExtrusionAndFeedrateFromGCode(GCodeBuffer& gb, bool isPrintingMove); // Set up the extrusion of a move
bool Push(GCodeBuffer& gb, bool preserveLineNumber); // Push feedrate etc on the stack
void Pop(GCodeBuffer& gb, bool preserveLineNumber); // Pop feedrate etc
void DisableDrives(); // Turn the motors off
// Start saving GCodes in a file
bool SendConfigToLine(); // Deal with M503
GCodeResult OffsetAxes(GCodeBuffer& gb, const StringRef& reply); // Set/report offsets
#if SUPPORT_WORKPLACE_COORDINATES
GCodeResult GetSetWorkplaceCoordinates(GCodeBuffer& gb, const StringRef& reply, bool compute); // Set workspace coordinates
# if HAS_MASS_STORAGE
bool WriteWorkplaceCoordinates(FileStore *f) const;
# endif
#endif
GCodeResult ManageTool(GCodeBuffer& gb, const StringRef& reply); // Create a new tool definition
void SetToolHeaters(Tool *tool, float temperature, bool both); // Set all a tool's heaters to the temperature, for M104/M109
bool ToolHeatersAtSetTemperatures(const Tool *tool, bool waitWhenCooling, float tolerance) const;
// Wait for the heaters associated with the specified tool to reach their set temperatures
void ReportToolTemperatures(const StringRef& reply, const Tool *tool, bool includeNumber) const;
void GenerateTemperatureReport(const StringRef& reply) const; // Store a standard-format temperature report in reply
OutputBuffer *GenerateJsonStatusResponse(int type, int seq, ResponseSource source) const; // Generate a M408 response
void CheckReportDue(GCodeBuffer& gb, const StringRef& reply) const; // Check whether we need to report temperatures or status
void SavePosition(RestorePoint& rp, const GCodeBuffer& gb) const; // Save position to a restore point
void RestorePosition(const RestorePoint& rp, GCodeBuffer *gb); // Restore user position from a restore point
void SetMachinePosition(const float positionNow[MaxAxesPlusExtruders], bool doBedCompensation = true); // Set the current position to be this
void UpdateCurrentUserPosition(); // Get the current position from the Move class
void ToolOffsetTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes], AxesBitmap explicitAxes = 0) const;
// Convert user coordinates to head reference point coordinates
void ToolOffsetInverseTransform(const float coordsIn[MaxAxes], float coordsOut[MaxAxes]) const; // Convert head reference point coordinates to user coordinates
float GetCurrentToolOffset(size_t axis) const; // Get an axis offset of the current tool
GCodeResult RetractFilament(GCodeBuffer& gb, bool retract); // Retract or un-retract filaments
GCodeResult LoadFilament(GCodeBuffer& gb, const StringRef& reply); // Load the specified filament into a tool
GCodeResult UnloadFilament(GCodeBuffer& gb, const StringRef& reply); // Unload the current filament from a tool
bool ChangeMicrostepping(size_t drive, unsigned int microsteps, bool interp, const StringRef& reply) const; // Change microstepping on the specified drive
void CheckTriggers(); // Check for and execute triggers
void CheckFilament(); // Check for and respond to filament errors
void CheckHeaterFault(); // Check for and respond to a heater fault, returning true if we should exit
void DoEmergencyStop(); // Execute an emergency stop
void DoPause(GCodeBuffer& gb, PauseReason reason, const char *msg) // Pause the print
pre(resourceOwners[movementResource] = &gb);
void CheckForDeferredPause(GCodeBuffer& gb); // Check if a pause is pending, action it if so
#if HAS_VOLTAGE_MONITOR || HAS_SMART_DRIVERS
bool DoEmergencyPause(); // Do an emergency pause following loss of power or a motor stall
#endif
bool IsMappedFan(unsigned int fanNumber); // Return true if this fan number is currently being used as a print cooling fan
void SaveFanSpeeds(); // Save the speeds of all fans
GCodeResult DefineGrid(GCodeBuffer& gb, const StringRef &reply); // Define the probing grid, returning true if error
#if HAS_MASS_STORAGE
GCodeResult LoadHeightMap(GCodeBuffer& gb, const StringRef& reply); // Load the height map from file
bool TrySaveHeightMap(const char *filename, const StringRef& reply) const; // Save the height map to the specified file
GCodeResult SaveHeightMap(GCodeBuffer& gb, const StringRef& reply) const; // Save the height map to the file specified by P parameter
#endif
void ClearBedMapping(); // Stop using bed compensation
GCodeResult ProbeGrid(GCodeBuffer& gb, const StringRef& reply); // Start probing the grid, returning true if we didn't because of an error
GCodeResult ConfigureTrigger(GCodeBuffer& gb, const StringRef& reply, int code); // Handle M581
GCodeResult CheckTrigger(GCodeBuffer& gb, const StringRef& reply, int code); // Handle M582
GCodeResult UpdateFirmware(GCodeBuffer& gb, const StringRef &reply); // Handle M997
GCodeResult SendI2c(GCodeBuffer& gb, const StringRef &reply); // Handle M260
GCodeResult ReceiveI2c(GCodeBuffer& gb, const StringRef &reply); // Handle M261
#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
GCodeResult SimulateFile(GCodeBuffer& gb, const StringRef &reply, const StringRef& file, bool updateFile); // Handle M37 to simulate a whole file
GCodeResult ChangeSimulationMode(GCodeBuffer& gb, const StringRef &reply, uint32_t newSimulationMode); // Handle M37 to change the simulation mode
#endif
GCodeResult WaitForPin(GCodeBuffer& gb, const StringRef &reply); // Handle M577
#if HAS_MASS_STORAGE
GCodeResult WriteConfigOverrideFile(GCodeBuffer& gb, const StringRef& reply) const; // Write the config-override file
bool WriteConfigOverrideHeader(FileStore *f) const; // Write the config-override header
#endif
void CopyConfigFinalValues(GCodeBuffer& gb); // Copy the feed rate etc. from the daemon to the input channels
MessageType GetMessageBoxDevice(GCodeBuffer& gb) const; // Decide which device to display a message box on
void DoManualProbe(GCodeBuffer&, const char *message, const char *title, const AxesBitmap); // Do manual probe in arbitrary direction
void DoManualBedProbe(GCodeBuffer& gb); // Do a manual bed probe
void AppendAxes(const StringRef& reply, AxesBitmap axes) const; // Append a list of axes to a string
void EndSimulation(GCodeBuffer *gb); // Restore positions etc. when exiting simulation mode
bool IsCodeQueueIdle() const; // Return true if the code queue is idle
#if HAS_MASS_STORAGE
void SaveResumeInfo(bool wasPowerFailure);
#endif
void NewMoveAvailable(unsigned int sl); // Flag that a new move is available
void NewMoveAvailable(); // Flag that a new move is available
void SetMoveBufferDefaults(); // Set up default values in the move buffer
void ChangeExtrusionFactor(unsigned int extruder, float factor); // Change a live extrusion factor
#if SUPPORT_12864_LCD
int GetHeaterNumber(unsigned int itemNumber) const;
#endif
Pwm_t ConvertLaserPwm(float reqVal) const;
// This function is called by other functions to account correctly for workplace coordinates, depending on whether the build configuration supports them.
inline float GetWorkplaceOffset(size_t axis) const
{
#if SUPPORT_WORKPLACE_COORDINATES
return workplaceCoordinates[currentCoordinateSystem][axis];
#else
return axisOffsets[axis];
#endif
}
#ifdef SERIAL_AUX_DEVICE
static bool emergencyStopCommanded;
static void CommandEmergencyStop(UARTClass *p);
#endif
Platform& platform; // The RepRap machine
#if HAS_NETWORKING
NetworkGCodeInput* httpInput; // These cache incoming G-codes...
NetworkGCodeInput* telnetInput; // ...
#endif
GCodeBuffer* gcodeSources[NumGCodeChannels]; // The various sources of gcodes
GCodeBuffer*& httpGCode = gcodeSources[0];
GCodeBuffer*& telnetGCode = gcodeSources[1];
GCodeBuffer*& fileGCode = gcodeSources[2];
GCodeBuffer*& usbGCode = gcodeSources[3];
GCodeBuffer*& auxGCode = gcodeSources[4]; // This one is for the PanelDue on the async serial interface
GCodeBuffer*& daemonGCode = gcodeSources[5]; // Used for executing config.g and trigger macro files
GCodeBuffer*& queuedGCode = gcodeSources[6];
GCodeBuffer*& lcdGCode = gcodeSources[7]; // This one for the 12864 LCD
GCodeBuffer*& spiGCode = gcodeSources[8];
GCodeBuffer*& autoPauseGCode = gcodeSources[9]; // ***THIS ONE MUST BE LAST*** GCode state machine used to run macros on power fail, heater faults and filament out
const GCodeBuffer* resourceOwners[NumResources]; // Which gcode buffer owns each resource
MachineType machineType; // whether FFF, laser or CNC
bool active; // Live and running?
bool isPaused; // true if the print has been paused manually or automatically
bool pausePending; // true if we have been asked to pause but we are running a macro
bool filamentChangePausePending; // true if we have been asked to pause for a filament change but we are running a macro
bool runningConfigFile; // We are running config.g during the startup process
bool doingToolChange; // We are running tool change macros
#if HAS_VOLTAGE_MONITOR
bool isPowerFailPaused; // true if the print was paused automatically because of a power failure
char *powerFailScript; // the commands run when there is a power failure
#endif
// The current user position now holds the requested user position after applying workplace coordinate offsets.
// So we must subtract the workplace coordinate offsets when we want to display them.
// We have chosen this approach because it allows us to switch workplace coordinates systems or turn off applying workplace offsets without having to update currentUserPosition.
float currentUserPosition[MaxAxes]; // The current position of the axes as commanded by the input gcode, after accounting for workplace offset, before accounting for tool offset and Z hop
float currentZHop; // The amount of Z hop that is currently applied
float lastPrintingMoveHeight; // the Z coordinate in the last printing move, or a negative value if we don't know it
// The following contain the details of moves that the Move module fetches
// CAUTION: segmentsLeft should ONLY be changed from 0 to not 0 by calling NewMoveAvailable()!
RawMove moveBuffer; // Move details to pass to Move class
unsigned int segmentsLeft; // The number of segments left to do in the current move, or 0 if no move available
unsigned int totalSegments; // The total number of segments left in the complete move
unsigned int segmentsLeftToStartAt;
float moveFractionToSkip;
float firstSegmentFractionToSkip;
float restartMoveFractionDone; // how much of the next move was printed before the pause or power failure (from M26)
float restartInitialUserX; // if the print was paused during an arc move, the user X coordinate at the start of that move (from M26)
float restartInitialUserY; // if the print was paused during an arc move, the user X coordinate at the start of that move (from M26)
float arcCentre[MaxAxes];
float arcRadius;
float arcCurrentAngle;
float arcAngleIncrement;
bool doingArcMove;
enum class SegmentedMoveState : uint8_t
{
inactive = 0,
active,
aborted
};
SegmentedMoveState segMoveState;
AxesBitmap axesHomedBeforeSimulation; // axes that were homed when we started the simulation
RestorePoint simulationRestorePoint; // The position and feed rate when we started a simulation
RestorePoint numberedRestorePoints[NumRestorePoints]; // Restore points accessible using the R parameter in the G0/G1 command
RestorePoint& pauseRestorePoint = numberedRestorePoints[1]; // The position and feed rate when we paused the print
RestorePoint& toolChangeRestorePoint = numberedRestorePoints[2]; // The position and feed rate when we freed a tool
RestorePoint& findCenterOfCavityRestorePoint = numberedRestorePoints[3]; // The position and feed rate when we found the lower boundary of cavity
size_t numTotalAxes; // How many axes we have
size_t numVisibleAxes; // How many axes are visible
size_t numExtruders; // How many extruders we have, or may have
float axisScaleFactors[MaxAxes]; // Scale XYZ coordinates by this factor
float virtualExtruderPosition; // Virtual extruder position of the last move fed into the Move class
float rawExtruderTotalByDrive[MaxExtruders]; // Extrusion amount in the last G1 command with an E parameter when in absolute extrusion mode
float rawExtruderTotal; // Total extrusion amount fed to Move class since starting print, before applying extrusion factor, summed over all drives
#if SUPPORT_WORKPLACE_COORDINATES
static const size_t NumCoordinateSystems = 9;
unsigned int currentCoordinateSystem; // This is zero-based, where as the P parameter in the G10 command is 1-based
float workplaceCoordinates[NumCoordinateSystems][MaxAxes]; // Workplace coordinate offsets
#else
float axisOffsets[MaxAxes]; // M206 axis offsets
#endif
#if HAS_MASS_STORAGE
FileData fileToPrint; // The next file to print
FilePosition fileOffsetToPrint; // The offset to print from
#endif
char axisLetters[MaxAxes + 1]; // The names of the axes, with a null terminator
bool limitAxes; // Don't think outside the box
bool noMovesBeforeHoming; // Don't allow movement prior to homing the associates axes
AxesBitmap toBeHomed; // Bitmap of axes still to be homed
AxesBitmap axesHomed; // Bitmap of which axes have been homed
float pausedFanSpeeds[MaxFans]; // Fan speeds when the print was paused or a tool change started
float lastDefaultFanSpeed; // Last speed given in a M106 command with on fan number
float pausedDefaultFanSpeed; // The speed of the default print cooling fan when the print was paused or a tool change started
float speedFactor; // speed factor as a percentage (normally 100.0)
float extrusionFactors[MaxExtruders]; // extrusion factors (normally 1.0)
float volumetricExtrusionFactors[MaxExtruders]; // Volumetric extrusion factors
float currentBabyStepOffsets[MaxAxes]; // The accumulated axis offsets due to baby stepping requests
// Z probe
GridDefinition defaultGrid; // The grid defined by the M557 command in config.g
int32_t g30ProbePointIndex; // the index of the point we are probing (G30 P parameter), or -1 if none
int g30SValue; // S parameter in the G30 command, or -2 if there wasn't one
float g30HValue; // H parameter in the G30 command, or 0.0 if there wasn't on
float g30zStoppedHeight; // the height to report after running G30 S-1
float g30zHeightError; // the height error last time we probed
float g30PrevHeightError; // the height error the previous time we probed
float g30zHeightErrorSum; // the sum of the height errors for the current probe point
float g30zHeightErrorLowestDiff; // the lowest difference we have seen between consecutive readings
uint32_t lastProbedTime; // time in milliseconds that the probe was last triggered
volatile bool zProbeTriggered; // Set by the step ISR when a move is aborted because the Z probe is triggered
size_t gridXindex, gridYindex; // Which grid probe point is next
bool doingManualBedProbe; // true if we are waiting for the user to jog the nozzle until it touches the bed
bool probeIsDeployed; // true if M401 has been used to deploy the probe and M402 has not yet been used t0 retract it
bool hadProbingError; // true if there was an error probing the last point
bool zDatumSetByProbing; // true if the Z position was last set by probing, not by an endstop switch or by G92
uint8_t tapsDone; // how many times we tapped the current point
float simulationTime; // Accumulated simulation time
uint8_t simulationMode; // 0 = not simulating, 1 = simulating, >1 are simulation modes for debugging
bool exitSimulationWhenFileComplete; // true if simulating a file
bool updateFileWhenSimulationComplete; // true if simulated time should be appended to the file
// Firmware retraction settings
float retractLength, retractExtra; // retraction length and extra length to un-retract
float retractSpeed; // retract speed in mm/min
float unRetractSpeed; // un=retract speed in mm/min
float retractHop; // Z hop when retracting
bool isRetracted; // true if filament has been firmware-retracted
// Triggers
Trigger triggers[MaxTriggers]; // Trigger conditions
TriggerNumbersBitmap triggersPending; // Bitmap of triggers pending but not yet executed
// Firmware update
uint8_t firmwareUpdateModuleMap; // Bitmap of firmware modules to be updated
bool isFlashing; // Is a new firmware binary going to be flashed?
// Code queue
GCodeQueue *codeQueue; // Stores certain codes for deferred execution
#if HAS_MASS_STORAGE
// SHA1 hashing
FileStore *fileBeingHashed;
SHA1Context hash;
bool StartHash(const char* filename);
GCodeResult AdvanceHash(const StringRef &reply);
#endif
// Filament monitoring
FilamentSensorStatus lastFilamentError;
size_t lastFilamentErrorExtruder;
// Laser
float laserMaxPower;
bool laserPowerSticky; // true if G1 S parameters are remembered across G1 commands
// Heater fault handler
HeaterFaultState heaterFaultState; // whether there is a heater fault and what we have done about it so far
uint32_t heaterFaultTime; // when the heater fault occurred
uint32_t heaterFaultTimeout; // how long we wait for the user to fix it before turning everything off
// Misc
uint32_t lastWarningMillis; // When we last sent a warning message for things that can happen very often
AxesBitmap axesToSenseLength; // The axes on which we are performing axis length sensing
bool atxPowerControlled;
#if HAS_MASS_STORAGE
static constexpr uint32_t SdTimingByteIncrement = 8 * 1024; // how many timing bytes we write at a time
static constexpr const char *TimingFileName = "test.tst"; // the name of the file we write
FileStore *sdTimingFile; // file handle being used for SD card write timing
uint32_t timingBytesRequested; // how many bytes we were asked to write
uint32_t timingBytesWritten; // how many timing bytes we have written so far
uint32_t timingStartMillis;
#endif
int8_t lastAuxStatusReportType; // The type of the last status report requested by PanelDue
bool isWaiting; // True if waiting to reach temperature
bool cancelWait; // Set true to cancel waiting
bool displayNoToolWarning; // True if we need to display a 'no tool selected' warning
bool m501SeenInConfigFile; // true if M501 was executed form config.g
char filamentToLoad[FilamentNameLength]; // Name of the filament being loaded
static constexpr const char *AllowedAxisLetters = "XYZUVWABCD";
// Standard macro filenames
static constexpr const char* BED_EQUATION_G = "bed.g";
static constexpr const char* PAUSE_G = "pause.g";
static constexpr const char* RESUME_G = "resume.g";
static constexpr const char* CANCEL_G = "cancel.g";
static constexpr const char* START_G = "start.g";
static constexpr const char* STOP_G = "stop.g";
static constexpr const char* SLEEP_G = "sleep.g";
static constexpr const char* CONFIG_OVERRIDE_G = "config-override.g";
static constexpr const char* DEPLOYPROBE_G = "deployprobe.g";
static constexpr const char* RETRACTPROBE_G = "retractprobe.g";
static constexpr const char* DefaultHeightMapFile = "heightmap.csv";
static constexpr const char* LOAD_FILAMENT_G = "load.g";
static constexpr const char* CONFIG_FILAMENT_G = "config.g";
static constexpr const char* UNLOAD_FILAMENT_G = "unload.g";
static constexpr const char* RESUME_AFTER_POWER_FAIL_G = "resurrect.g";
static constexpr const char* RESUME_PROLOGUE_G = "resurrect-prologue.g";
static constexpr const char* FILAMENT_CHANGE_G = "filament-change.g";
#if HAS_SMART_DRIVERS
static constexpr const char* REHOME_G = "rehome.g";
#endif
static constexpr const float MinServoPulseWidth = 544.0, MaxServoPulseWidth = 2400.0;
};
// Flag that a new move is available for consumption by the Move subsystem
// Code that sets up a new move should ensure that segmentsLeft is zero, then set up all the move parameters,
// then call this function to update SegmentsLeft safely in a multi-threaded environment
inline void GCodes::NewMoveAvailable(unsigned int sl)
{
totalSegments = sl;
__DMB(); // make sure that all the move details have been written first
segmentsLeft = sl; // set the number of segments to indicate that a move is available to be taken
}
// Flag that a new move is available for consumption by the Move subsystem
// This version is for when totalSegments has already be set up.
inline void GCodes::NewMoveAvailable()
{
const unsigned int sl = totalSegments;
__DMB(); // make sure that the move details have been written first
segmentsLeft = sl; // set the number of segments to indicate that a move is available to be taken
}
// Get the total baby stepping offset for an axis
inline float GCodes::GetTotalBabyStepOffset(size_t axis) const
{
return currentBabyStepOffsets[axis];
}
//*****************************************************************************************************
#endif
|