|
|
|
@ -67,136 +67,149 @@
|
|
|
|
|
#include <SPI.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// look here for descriptions of G-codes: http://linuxcnc.org/handbook/gcode/g-code.html
|
|
|
|
|
// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
|
|
|
|
|
/**
|
|
|
|
|
* Look here for descriptions of G-codes:
|
|
|
|
|
* - http://linuxcnc.org/handbook/gcode/g-code.html
|
|
|
|
|
* - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
|
|
|
|
|
*
|
|
|
|
|
* Help us document these G-codes online:
|
|
|
|
|
* - http://reprap.org/wiki/G-code
|
|
|
|
|
* - https://github.com/MarlinFirmware/Marlin/wiki/Marlin-G-Code
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
//Implemented Codes
|
|
|
|
|
//-------------------
|
|
|
|
|
// G0 -> G1
|
|
|
|
|
// G1 - Coordinated Movement X Y Z E
|
|
|
|
|
// G2 - CW ARC
|
|
|
|
|
// G3 - CCW ARC
|
|
|
|
|
// G4 - Dwell S<seconds> or P<milliseconds>
|
|
|
|
|
// G10 - retract filament according to settings of M207
|
|
|
|
|
// G11 - retract recover filament according to settings of M208
|
|
|
|
|
// G28 - Home one or more axes
|
|
|
|
|
// G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet.
|
|
|
|
|
// G30 - Single Z Probe, probes bed at current XY location.
|
|
|
|
|
// G31 - Dock sled (Z_PROBE_SLED only)
|
|
|
|
|
// G32 - Undock sled (Z_PROBE_SLED only)
|
|
|
|
|
// G90 - Use Absolute Coordinates
|
|
|
|
|
// G91 - Use Relative Coordinates
|
|
|
|
|
// G92 - Set current position to coordinates given
|
|
|
|
|
|
|
|
|
|
// M Codes
|
|
|
|
|
// M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled)
|
|
|
|
|
// M1 - Same as M0
|
|
|
|
|
// M17 - Enable/Power all stepper motors
|
|
|
|
|
// M18 - Disable all stepper motors; same as M84
|
|
|
|
|
// M20 - List SD card
|
|
|
|
|
// M21 - Init SD card
|
|
|
|
|
// M22 - Release SD card
|
|
|
|
|
// M23 - Select SD file (M23 filename.g)
|
|
|
|
|
// M24 - Start/resume SD print
|
|
|
|
|
// M25 - Pause SD print
|
|
|
|
|
// M26 - Set SD position in bytes (M26 S12345)
|
|
|
|
|
// M27 - Report SD print status
|
|
|
|
|
// M28 - Start SD write (M28 filename.g)
|
|
|
|
|
// M29 - Stop SD write
|
|
|
|
|
// M30 - Delete file from SD (M30 filename.g)
|
|
|
|
|
// M31 - Output time since last M109 or SD card start to serial
|
|
|
|
|
// M32 - Select file and start SD print (Can be used _while_ printing from SD card files):
|
|
|
|
|
// syntax "M32 /path/filename#", or "M32 S<startpos bytes> !filename#"
|
|
|
|
|
// Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include).
|
|
|
|
|
// The '#' is necessary when calling from within sd files, as it stops buffer prereading
|
|
|
|
|
// M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
|
|
|
|
|
// M48 - Measure Z_Probe repeatability. M48 [n # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel]
|
|
|
|
|
// M80 - Turn on Power Supply
|
|
|
|
|
// M81 - Turn off Power Supply
|
|
|
|
|
// M82 - Set E codes absolute (default)
|
|
|
|
|
// M83 - Set E codes relative while in Absolute Coordinates (G90) mode
|
|
|
|
|
// M84 - Disable steppers until next move,
|
|
|
|
|
// or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout.
|
|
|
|
|
// M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
|
|
|
|
|
// M92 - Set axis_steps_per_unit - same syntax as G92
|
|
|
|
|
// M104 - Set extruder target temp
|
|
|
|
|
// M105 - Read current temp
|
|
|
|
|
// M106 - Fan on
|
|
|
|
|
// M107 - Fan off
|
|
|
|
|
// M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
|
|
|
|
|
// Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
|
|
|
|
|
// IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
|
|
|
|
|
// M112 - Emergency stop
|
|
|
|
|
// M114 - Output current position to serial port
|
|
|
|
|
// M115 - Capabilities string
|
|
|
|
|
// M117 - display message
|
|
|
|
|
// M119 - Output Endstop status to serial port
|
|
|
|
|
// M120 - Enable endstop detection
|
|
|
|
|
// M121 - Disable endstop detection
|
|
|
|
|
// M126 - Solenoid Air Valve Open (BariCUDA support by jmil)
|
|
|
|
|
// M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil)
|
|
|
|
|
// M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil)
|
|
|
|
|
// M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil)
|
|
|
|
|
// M140 - Set bed target temp
|
|
|
|
|
// M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work.
|
|
|
|
|
// M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating
|
|
|
|
|
// Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
|
|
|
|
|
// M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>-
|
|
|
|
|
// M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
|
|
|
|
|
// M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
|
|
|
|
|
// M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
|
|
|
|
|
// M204 - Set default acceleration: P for Printing moves, R for Retract only (no X, Y, Z) moves and T for Travel (non printing) moves (ex. M204 P800 T3000 R9000) in mm/sec^2
|
|
|
|
|
// M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk
|
|
|
|
|
// M206 - Set additional homing offset
|
|
|
|
|
// M207 - Set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting
|
|
|
|
|
// M208 - Set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec]
|
|
|
|
|
// M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
|
|
|
|
|
// M218 - Set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y>
|
|
|
|
|
// M220 - Set speed factor override percentage: S<factor in percent>
|
|
|
|
|
// M221 - Set extrude factor override percentage: S<factor in percent>
|
|
|
|
|
// M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state>
|
|
|
|
|
// M240 - Trigger a camera to take a photograph
|
|
|
|
|
// M250 - Set LCD contrast C<contrast value> (value 0..63)
|
|
|
|
|
// M280 - Set servo position absolute. P: servo index, S: angle or microseconds
|
|
|
|
|
// M300 - Play beep sound S<frequency Hz> P<duration ms>
|
|
|
|
|
// M301 - Set PID parameters P I and D
|
|
|
|
|
// M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
|
|
|
|
|
// M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
|
|
|
|
|
// M304 - Set bed PID parameters P I and D
|
|
|
|
|
// M380 - Activate solenoid on active extruder
|
|
|
|
|
// M381 - Disable all solenoids
|
|
|
|
|
// M400 - Finish all moves
|
|
|
|
|
// M401 - Lower z-probe if present
|
|
|
|
|
// M402 - Raise z-probe if present
|
|
|
|
|
// M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
|
|
|
|
|
// M405 - Turn on Filament Sensor extrusion control. Optional D<delay in cm> to set delay in centimeters between sensor and extruder
|
|
|
|
|
// M406 - Turn off Filament Sensor extrusion control
|
|
|
|
|
// M407 - Display measured filament diameter
|
|
|
|
|
// M500 - Store parameters in EEPROM
|
|
|
|
|
// M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily).
|
|
|
|
|
// M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
|
|
|
|
|
// M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings.
|
|
|
|
|
// M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
|
|
|
|
|
// M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
|
|
|
|
|
// M665 - Set delta configurations: L<diagonal rod> R<delta radius> S<segments/s>
|
|
|
|
|
// M666 - Set delta endstop adjustment
|
|
|
|
|
// M605 - Set dual x-carriage movement mode: S<mode> [ X<duplication x-offset> R<duplication temp offset> ]
|
|
|
|
|
// M907 - Set digital trimpot motor current using axis codes.
|
|
|
|
|
// M908 - Control digital trimpot directly.
|
|
|
|
|
// M350 - Set microstepping mode.
|
|
|
|
|
// M351 - Toggle MS1 MS2 pins directly.
|
|
|
|
|
|
|
|
|
|
// ************ SCARA Specific - This can change to suit future G-code regulations
|
|
|
|
|
// M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
|
|
|
|
|
// M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
|
|
|
|
|
// M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
|
|
|
|
|
// M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
|
|
|
|
|
// M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
|
|
|
|
|
// M365 - SCARA calibration: Scaling factor, X, Y, Z axis
|
|
|
|
|
//************* SCARA End ***************
|
|
|
|
|
|
|
|
|
|
// M928 - Start SD logging (M928 filename.g) - ended by M29
|
|
|
|
|
// M999 - Restart after being stopped by error
|
|
|
|
|
/**
|
|
|
|
|
* Implemented Codes
|
|
|
|
|
* -------------------
|
|
|
|
|
*
|
|
|
|
|
* "G" Codes
|
|
|
|
|
*
|
|
|
|
|
* G0 -> G1
|
|
|
|
|
* G1 - Coordinated Movement X Y Z E
|
|
|
|
|
* G2 - CW ARC
|
|
|
|
|
* G3 - CCW ARC
|
|
|
|
|
* G4 - Dwell S<seconds> or P<milliseconds>
|
|
|
|
|
* G10 - retract filament according to settings of M207
|
|
|
|
|
* G11 - retract recover filament according to settings of M208
|
|
|
|
|
* G28 - Home one or more axes
|
|
|
|
|
* G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet.
|
|
|
|
|
* G30 - Single Z Probe, probes bed at current XY location.
|
|
|
|
|
* G31 - Dock sled (Z_PROBE_SLED only)
|
|
|
|
|
* G32 - Undock sled (Z_PROBE_SLED only)
|
|
|
|
|
* G90 - Use Absolute Coordinates
|
|
|
|
|
* G91 - Use Relative Coordinates
|
|
|
|
|
* G92 - Set current position to coordinates given
|
|
|
|
|
*
|
|
|
|
|
* "M" Codes
|
|
|
|
|
*
|
|
|
|
|
* M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled)
|
|
|
|
|
* M1 - Same as M0
|
|
|
|
|
* M17 - Enable/Power all stepper motors
|
|
|
|
|
* M18 - Disable all stepper motors; same as M84
|
|
|
|
|
* M20 - List SD card
|
|
|
|
|
* M21 - Init SD card
|
|
|
|
|
* M22 - Release SD card
|
|
|
|
|
* M23 - Select SD file (M23 filename.g)
|
|
|
|
|
* M24 - Start/resume SD print
|
|
|
|
|
* M25 - Pause SD print
|
|
|
|
|
* M26 - Set SD position in bytes (M26 S12345)
|
|
|
|
|
* M27 - Report SD print status
|
|
|
|
|
* M28 - Start SD write (M28 filename.g)
|
|
|
|
|
* M29 - Stop SD write
|
|
|
|
|
* M30 - Delete file from SD (M30 filename.g)
|
|
|
|
|
* M31 - Output time since last M109 or SD card start to serial
|
|
|
|
|
* M32 - Select file and start SD print (Can be used _while_ printing from SD card files):
|
|
|
|
|
* syntax "M32 /path/filename#", or "M32 S<startpos bytes> !filename#"
|
|
|
|
|
* Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include).
|
|
|
|
|
* The '#' is necessary when calling from within sd files, as it stops buffer prereading
|
|
|
|
|
* M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
|
|
|
|
|
* M48 - Measure Z_Probe repeatability. M48 [n # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel]
|
|
|
|
|
* M80 - Turn on Power Supply
|
|
|
|
|
* M81 - Turn off Power Supply
|
|
|
|
|
* M82 - Set E codes absolute (default)
|
|
|
|
|
* M83 - Set E codes relative while in Absolute Coordinates (G90) mode
|
|
|
|
|
* M84 - Disable steppers until next move,
|
|
|
|
|
* or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout.
|
|
|
|
|
* M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
|
|
|
|
|
* M92 - Set axis_steps_per_unit - same syntax as G92
|
|
|
|
|
* M104 - Set extruder target temp
|
|
|
|
|
* M105 - Read current temp
|
|
|
|
|
* M106 - Fan on
|
|
|
|
|
* M107 - Fan off
|
|
|
|
|
* M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
|
|
|
|
|
* Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
|
|
|
|
|
* IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
|
|
|
|
|
* M112 - Emergency stop
|
|
|
|
|
* M114 - Output current position to serial port
|
|
|
|
|
* M115 - Capabilities string
|
|
|
|
|
* M117 - display message
|
|
|
|
|
* M119 - Output Endstop status to serial port
|
|
|
|
|
* M120 - Enable endstop detection
|
|
|
|
|
* M121 - Disable endstop detection
|
|
|
|
|
* M126 - Solenoid Air Valve Open (BariCUDA support by jmil)
|
|
|
|
|
* M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil)
|
|
|
|
|
* M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil)
|
|
|
|
|
* M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil)
|
|
|
|
|
* M140 - Set bed target temp
|
|
|
|
|
* M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work.
|
|
|
|
|
* M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating
|
|
|
|
|
* Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
|
|
|
|
|
* M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>-
|
|
|
|
|
* M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
|
|
|
|
|
* M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
|
|
|
|
|
* M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
|
|
|
|
|
* M204 - Set default acceleration: P for Printing moves, R for Retract only (no X, Y, Z) moves and T for Travel (non printing) moves (ex. M204 P800 T3000 R9000) in mm/sec^2
|
|
|
|
|
* M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk, E=maximum E jerk
|
|
|
|
|
* M206 - Set additional homing offset
|
|
|
|
|
* M207 - Set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting
|
|
|
|
|
* M208 - Set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec]
|
|
|
|
|
* M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
|
|
|
|
|
* M218 - Set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y>
|
|
|
|
|
* M220 - Set speed factor override percentage: S<factor in percent>
|
|
|
|
|
* M221 - Set extrude factor override percentage: S<factor in percent>
|
|
|
|
|
* M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state>
|
|
|
|
|
* M240 - Trigger a camera to take a photograph
|
|
|
|
|
* M250 - Set LCD contrast C<contrast value> (value 0..63)
|
|
|
|
|
* M280 - Set servo position absolute. P: servo index, S: angle or microseconds
|
|
|
|
|
* M300 - Play beep sound S<frequency Hz> P<duration ms>
|
|
|
|
|
* M301 - Set PID parameters P I and D
|
|
|
|
|
* M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
|
|
|
|
|
* M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
|
|
|
|
|
* M304 - Set bed PID parameters P I and D
|
|
|
|
|
* M380 - Activate solenoid on active extruder
|
|
|
|
|
* M381 - Disable all solenoids
|
|
|
|
|
* M400 - Finish all moves
|
|
|
|
|
* M401 - Lower z-probe if present
|
|
|
|
|
* M402 - Raise z-probe if present
|
|
|
|
|
* M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
|
|
|
|
|
* M405 - Turn on Filament Sensor extrusion control. Optional D<delay in cm> to set delay in centimeters between sensor and extruder
|
|
|
|
|
* M406 - Turn off Filament Sensor extrusion control
|
|
|
|
|
* M407 - Display measured filament diameter
|
|
|
|
|
* M500 - Store parameters in EEPROM
|
|
|
|
|
* M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily).
|
|
|
|
|
* M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
|
|
|
|
|
* M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings.
|
|
|
|
|
* M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
|
|
|
|
|
* M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
|
|
|
|
|
* M665 - Set delta configurations: L<diagonal rod> R<delta radius> S<segments/s>
|
|
|
|
|
* M666 - Set delta endstop adjustment
|
|
|
|
|
* M605 - Set dual x-carriage movement mode: S<mode> [ X<duplication x-offset> R<duplication temp offset> ]
|
|
|
|
|
* M907 - Set digital trimpot motor current using axis codes.
|
|
|
|
|
* M908 - Control digital trimpot directly.
|
|
|
|
|
* M350 - Set microstepping mode.
|
|
|
|
|
* M351 - Toggle MS1 MS2 pins directly.
|
|
|
|
|
*
|
|
|
|
|
* ************ SCARA Specific - This can change to suit future G-code regulations
|
|
|
|
|
* M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
|
|
|
|
|
* M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
|
|
|
|
|
* M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
|
|
|
|
|
* M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
|
|
|
|
|
* M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
|
|
|
|
|
* M365 - SCARA calibration: Scaling factor, X, Y, Z axis
|
|
|
|
|
* ************* SCARA End ***************
|
|
|
|
|
*
|
|
|
|
|
* M928 - Start SD logging (M928 filename.g) - ended by M29
|
|
|
|
|
* M999 - Restart after being stopped by error
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
|
CardReader card;
|
|
|
|
@ -210,12 +223,16 @@ static float destination[NUM_AXIS] = { 0.0 };
|
|
|
|
|
bool axis_known_position[3] = { false };
|
|
|
|
|
|
|
|
|
|
static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
|
|
|
|
|
static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
|
|
|
|
|
|
|
|
|
|
static int cmd_queue_index_r = 0;
|
|
|
|
|
static int cmd_queue_index_w = 0;
|
|
|
|
|
static int commands_in_queue = 0;
|
|
|
|
|
static char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
|
|
|
|
|
|
|
|
|
float homing_feedrate[] = HOMING_FEEDRATE;
|
|
|
|
|
bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
|
|
|
|
|
int feedmultiply = 100; //100->1 200->2
|
|
|
|
|
int saved_feedmultiply;
|
|
|
|
|
int feedrate_multiplier = 100; //100->1 200->2
|
|
|
|
|
int saved_feedrate_multiplier;
|
|
|
|
|
int extruder_multiply[EXTRUDERS] = ARRAY_BY_EXTRUDERS(100, 100, 100, 100);
|
|
|
|
|
bool volumetric_enabled = false;
|
|
|
|
|
float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA);
|
|
|
|
@ -234,9 +251,6 @@ const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
|
|
|
|
|
|
|
|
|
|
static float offset[3] = { 0 };
|
|
|
|
|
static bool relative_mode = false; //Determines Absolute or Relative Coordinates
|
|
|
|
|
static int bufindr = 0;
|
|
|
|
|
static int bufindw = 0;
|
|
|
|
|
static int buflen = 0;
|
|
|
|
|
static char serial_char;
|
|
|
|
|
static int serial_count = 0;
|
|
|
|
|
static boolean comment_mode = false;
|
|
|
|
@ -247,10 +261,10 @@ const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
|
|
|
|
|
millis_t previous_cmd_ms = 0;
|
|
|
|
|
static millis_t max_inactive_time = 0;
|
|
|
|
|
static millis_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME * 1000L;
|
|
|
|
|
millis_t starttime = 0; ///< Print job start time
|
|
|
|
|
millis_t stoptime = 0; ///< Print job stop time
|
|
|
|
|
millis_t print_job_start_ms = 0; ///< Print job start time
|
|
|
|
|
millis_t print_job_stop_ms = 0; ///< Print job stop time
|
|
|
|
|
static uint8_t target_extruder;
|
|
|
|
|
bool CooldownNoWait = true;
|
|
|
|
|
bool no_wait_for_cooling = true;
|
|
|
|
|
bool target_direction;
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
|
|
|
@ -357,7 +371,7 @@ bool target_direction;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef FILAMENT_RUNOUT_SENSOR
|
|
|
|
|
static bool filrunoutEnqued = false;
|
|
|
|
|
static bool filrunoutEnqueued = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
@ -410,8 +424,10 @@ void serial_echopair_P(const char *s_P, unsigned long v) { serialprintPGM(s_P);
|
|
|
|
|
}
|
|
|
|
|
#endif //!SDSUPPORT
|
|
|
|
|
|
|
|
|
|
//Injects the next command from the pending sequence of commands, when possible
|
|
|
|
|
//Return false if and only if no command was pending
|
|
|
|
|
/**
|
|
|
|
|
* Inject the next command from the command queue, when possible
|
|
|
|
|
* Return false only if no command was pending
|
|
|
|
|
*/
|
|
|
|
|
static bool drain_queued_commands_P() {
|
|
|
|
|
if (!queued_commands_P) return false;
|
|
|
|
|
|
|
|
|
@ -434,45 +450,46 @@ static bool drain_queued_commands_P() {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Record one or many commands to run from program memory.
|
|
|
|
|
//Aborts the current queue, if any.
|
|
|
|
|
//Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards
|
|
|
|
|
/**
|
|
|
|
|
* Record one or many commands to run from program memory.
|
|
|
|
|
* Aborts the current queue, if any.
|
|
|
|
|
* Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards
|
|
|
|
|
*/
|
|
|
|
|
void enqueuecommands_P(const char* pgcode) {
|
|
|
|
|
queued_commands_P = pgcode;
|
|
|
|
|
drain_queued_commands_P(); // first command executed asap (when possible)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//adds a single command to the main command buffer, from RAM
|
|
|
|
|
//that is really done in a non-safe way.
|
|
|
|
|
//needs overworking someday
|
|
|
|
|
//Returns false if it failed to do so
|
|
|
|
|
bool enqueuecommand(const char *cmd)
|
|
|
|
|
{
|
|
|
|
|
if(*cmd==';')
|
|
|
|
|
return false;
|
|
|
|
|
if(buflen >= BUFSIZE)
|
|
|
|
|
return false;
|
|
|
|
|
//this is dangerous if a mixing of serial and this happens
|
|
|
|
|
strcpy(&(cmdbuffer[bufindw][0]),cmd);
|
|
|
|
|
/**
|
|
|
|
|
* Copy a command directly into the main command buffer, from RAM.
|
|
|
|
|
*
|
|
|
|
|
* This is done in a non-safe way and needs a rework someday.
|
|
|
|
|
* Returns false if it doesn't add any command
|
|
|
|
|
*/
|
|
|
|
|
bool enqueuecommand(const char *cmd) {
|
|
|
|
|
|
|
|
|
|
if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
|
|
|
|
|
|
|
|
|
|
// This is dangerous if a mixing of serial and this happens
|
|
|
|
|
char *command = command_queue[cmd_queue_index_w];
|
|
|
|
|
strcpy(command, cmd);
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
SERIAL_ECHOPGM(MSG_Enqueing);
|
|
|
|
|
SERIAL_ECHO(cmdbuffer[bufindw]);
|
|
|
|
|
SERIAL_ECHOPGM(MSG_Enqueueing);
|
|
|
|
|
SERIAL_ECHO(command);
|
|
|
|
|
SERIAL_ECHOLNPGM("\"");
|
|
|
|
|
bufindw= (bufindw + 1)%BUFSIZE;
|
|
|
|
|
buflen += 1;
|
|
|
|
|
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
|
|
|
|
|
commands_in_queue++;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setup_killpin()
|
|
|
|
|
{
|
|
|
|
|
void setup_killpin() {
|
|
|
|
|
#if HAS_KILL
|
|
|
|
|
SET_INPUT(KILL_PIN);
|
|
|
|
|
WRITE(KILL_PIN, HIGH);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setup_filrunoutpin()
|
|
|
|
|
{
|
|
|
|
|
void setup_filrunoutpin() {
|
|
|
|
|
#if HAS_FILRUNOUT
|
|
|
|
|
pinMode(FILRUNOUT_PIN, INPUT);
|
|
|
|
|
#ifdef ENDSTOPPULLUP_FIL_RUNOUT
|
|
|
|
@ -482,8 +499,7 @@ void setup_filrunoutpin()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set home pin
|
|
|
|
|
void setup_homepin(void)
|
|
|
|
|
{
|
|
|
|
|
void setup_homepin(void) {
|
|
|
|
|
#if HAS_HOME
|
|
|
|
|
SET_INPUT(HOME_PIN);
|
|
|
|
|
WRITE(HOME_PIN, HIGH);
|
|
|
|
@ -491,15 +507,13 @@ void setup_homepin(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setup_photpin()
|
|
|
|
|
{
|
|
|
|
|
void setup_photpin() {
|
|
|
|
|
#if HAS_PHOTOGRAPH
|
|
|
|
|
OUT_WRITE(PHOTOGRAPH_PIN, LOW);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setup_powerhold()
|
|
|
|
|
{
|
|
|
|
|
void setup_powerhold() {
|
|
|
|
|
#if HAS_SUICIDE
|
|
|
|
|
OUT_WRITE(SUICIDE_PIN, HIGH);
|
|
|
|
|
#endif
|
|
|
|
@ -512,15 +526,13 @@ void setup_powerhold()
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void suicide()
|
|
|
|
|
{
|
|
|
|
|
void suicide() {
|
|
|
|
|
#if HAS_SUICIDE
|
|
|
|
|
OUT_WRITE(SUICIDE_PIN, LOW);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void servo_init()
|
|
|
|
|
{
|
|
|
|
|
void servo_init() {
|
|
|
|
|
#if NUM_SERVOS >= 1 && HAS_SERVO_0
|
|
|
|
|
servos[0].attach(SERVO0_PIN);
|
|
|
|
|
#endif
|
|
|
|
@ -547,6 +559,24 @@ void servo_init()
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Marlin entry-point: Set up before the program loop
|
|
|
|
|
* - Set up the kill pin, filament runout, power hold
|
|
|
|
|
* - Start the serial port
|
|
|
|
|
* - Print startup messages and diagnostics
|
|
|
|
|
* - Get EEPROM or default settings
|
|
|
|
|
* - Initialize managers for:
|
|
|
|
|
* • temperature
|
|
|
|
|
* • planner
|
|
|
|
|
* • watchdog
|
|
|
|
|
* • stepper
|
|
|
|
|
* • photo pin
|
|
|
|
|
* • servos
|
|
|
|
|
* • LCD controller
|
|
|
|
|
* • Digipot I2C
|
|
|
|
|
* • Z probe sled
|
|
|
|
|
* • status LEDs
|
|
|
|
|
*/
|
|
|
|
|
void setup() {
|
|
|
|
|
setup_killpin();
|
|
|
|
|
setup_filrunoutpin();
|
|
|
|
@ -587,7 +617,7 @@ void setup() {
|
|
|
|
|
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
|
for (int8_t i = 0; i < BUFSIZE; i++) fromsd[i] = false;
|
|
|
|
|
#endif // !SDSUPPORT
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
|
|
|
|
|
Config_RetrieveSettings();
|
|
|
|
@ -628,36 +658,54 @@ void setup() {
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The main Marlin program loop
|
|
|
|
|
*
|
|
|
|
|
* - Save or log commands to SD
|
|
|
|
|
* - Process available commands (if not saving)
|
|
|
|
|
* - Call heater manager
|
|
|
|
|
* - Call inactivity manager
|
|
|
|
|
* - Call endstop manager
|
|
|
|
|
* - Call LCD update
|
|
|
|
|
*/
|
|
|
|
|
void loop() {
|
|
|
|
|
if (buflen < BUFSIZE - 1) get_command();
|
|
|
|
|
if (commands_in_queue < BUFSIZE - 1) get_command();
|
|
|
|
|
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
|
card.checkautostart(false);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (buflen) {
|
|
|
|
|
if (commands_in_queue) {
|
|
|
|
|
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
|
|
|
|
|
|
if (card.saving) {
|
|
|
|
|
if (strstr_P(cmdbuffer[bufindr], PSTR("M29")) == NULL) {
|
|
|
|
|
card.write_command(cmdbuffer[bufindr]);
|
|
|
|
|
if (card.logging)
|
|
|
|
|
process_commands();
|
|
|
|
|
else
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_OK);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char *command = command_queue[cmd_queue_index_r];
|
|
|
|
|
if (strstr_P(command, PSTR("M29"))) {
|
|
|
|
|
// M29 closes the file
|
|
|
|
|
card.closefile();
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// Write the string from the read buffer to SD
|
|
|
|
|
card.write_command(command);
|
|
|
|
|
if (card.logging)
|
|
|
|
|
process_commands(); // The card is saving because it's logging
|
|
|
|
|
else
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_OK);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
process_commands();
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
process_commands();
|
|
|
|
|
|
|
|
|
|
#endif // SDSUPPORT
|
|
|
|
|
buflen--;
|
|
|
|
|
bufindr = (bufindr + 1) % BUFSIZE;
|
|
|
|
|
|
|
|
|
|
commands_in_queue--;
|
|
|
|
|
cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE;
|
|
|
|
|
}
|
|
|
|
|
// Check heater every n milliseconds
|
|
|
|
|
manage_heater();
|
|
|
|
@ -666,12 +714,20 @@ void loop() {
|
|
|
|
|
lcd_update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add to the circular command queue the next command from:
|
|
|
|
|
* - The command-injection queue (queued_commands_P)
|
|
|
|
|
* - The active serial input (usually USB)
|
|
|
|
|
* - The SD card file being actively printed
|
|
|
|
|
*/
|
|
|
|
|
void get_command() {
|
|
|
|
|
|
|
|
|
|
if (drain_queued_commands_P()) return; // priority is given to non-serial commands
|
|
|
|
|
|
|
|
|
|
while (MYSERIAL.available() > 0 && buflen < BUFSIZE) {
|
|
|
|
|
while (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
|
|
|
|
|
|
|
|
|
|
serial_char = MYSERIAL.read();
|
|
|
|
|
|
|
|
|
|
if (serial_char == '\n' || serial_char == '\r' ||
|
|
|
|
|
serial_count >= (MAX_CMD_SIZE - 1)
|
|
|
|
|
) {
|
|
|
|
@ -680,16 +736,17 @@ void get_command() {
|
|
|
|
|
|
|
|
|
|
if (!serial_count) return; // shortcut for empty lines
|
|
|
|
|
|
|
|
|
|
cmdbuffer[bufindw][serial_count] = 0; // terminate string
|
|
|
|
|
char *command = command_queue[cmd_queue_index_w];
|
|
|
|
|
command[serial_count] = 0; // terminate string
|
|
|
|
|
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
|
fromsd[bufindw] = false;
|
|
|
|
|
fromsd[cmd_queue_index_w] = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (strchr(cmdbuffer[bufindw], 'N') != NULL) {
|
|
|
|
|
strchr_pointer = strchr(cmdbuffer[bufindw], 'N');
|
|
|
|
|
if (strchr(command, 'N') != NULL) {
|
|
|
|
|
strchr_pointer = strchr(command, 'N');
|
|
|
|
|
gcode_N = (strtol(strchr_pointer + 1, NULL, 10));
|
|
|
|
|
if (gcode_N != gcode_LastN + 1 && strstr_P(cmdbuffer[bufindw], PSTR("M110")) == NULL) {
|
|
|
|
|
if (gcode_N != gcode_LastN + 1 && strstr_P(command, PSTR("M110")) == NULL) {
|
|
|
|
|
SERIAL_ERROR_START;
|
|
|
|
|
SERIAL_ERRORPGM(MSG_ERR_LINE_NO);
|
|
|
|
|
SERIAL_ERRORLN(gcode_LastN);
|
|
|
|
@ -699,11 +756,11 @@ void get_command() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strchr(cmdbuffer[bufindw], '*') != NULL) {
|
|
|
|
|
if (strchr(command, '*') != NULL) {
|
|
|
|
|
byte checksum = 0;
|
|
|
|
|
byte count = 0;
|
|
|
|
|
while (cmdbuffer[bufindw][count] != '*') checksum ^= cmdbuffer[bufindw][count++];
|
|
|
|
|
strchr_pointer = strchr(cmdbuffer[bufindw], '*');
|
|
|
|
|
while (command[count] != '*') checksum ^= command[count++];
|
|
|
|
|
strchr_pointer = strchr(command, '*');
|
|
|
|
|
|
|
|
|
|
if (strtol(strchr_pointer + 1, NULL, 10) != checksum) {
|
|
|
|
|
SERIAL_ERROR_START;
|
|
|
|
@ -728,7 +785,7 @@ void get_command() {
|
|
|
|
|
//if no errors, continue parsing
|
|
|
|
|
}
|
|
|
|
|
else { // if we don't receive 'N' but still see '*'
|
|
|
|
|
if ((strchr(cmdbuffer[bufindw], '*') != NULL)) {
|
|
|
|
|
if ((strchr(command, '*') != NULL)) {
|
|
|
|
|
SERIAL_ERROR_START;
|
|
|
|
|
SERIAL_ERRORPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
|
|
|
|
|
SERIAL_ERRORLN(gcode_LastN);
|
|
|
|
@ -737,8 +794,8 @@ void get_command() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strchr(cmdbuffer[bufindw], 'G') != NULL) {
|
|
|
|
|
strchr_pointer = strchr(cmdbuffer[bufindw], 'G');
|
|
|
|
|
if (strchr(command, 'G') != NULL) {
|
|
|
|
|
strchr_pointer = strchr(command, 'G');
|
|
|
|
|
switch (strtol(strchr_pointer + 1, NULL, 10)) {
|
|
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
@ -755,24 +812,24 @@ void get_command() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If command was e-stop process now
|
|
|
|
|
if (strcmp(cmdbuffer[bufindw], "M112") == 0) kill();
|
|
|
|
|
if (strcmp(command, "M112") == 0) kill();
|
|
|
|
|
|
|
|
|
|
bufindw = (bufindw + 1) % BUFSIZE;
|
|
|
|
|
buflen += 1;
|
|
|
|
|
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
|
|
|
|
|
commands_in_queue += 1;
|
|
|
|
|
|
|
|
|
|
serial_count = 0; //clear buffer
|
|
|
|
|
}
|
|
|
|
|
else if (serial_char == '\\') { // Handle escapes
|
|
|
|
|
if (MYSERIAL.available() > 0 && buflen < BUFSIZE) {
|
|
|
|
|
if (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
|
|
|
|
|
// if we have one more character, copy it over
|
|
|
|
|
serial_char = MYSERIAL.read();
|
|
|
|
|
cmdbuffer[bufindw][serial_count++] = serial_char;
|
|
|
|
|
command_queue[cmd_queue_index_w][serial_count++] = serial_char;
|
|
|
|
|
}
|
|
|
|
|
// otherwise do nothing
|
|
|
|
|
}
|
|
|
|
|
else { // its not a newline, carriage return or escape char
|
|
|
|
|
if (serial_char == ';') comment_mode = true;
|
|
|
|
|
if (!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char;
|
|
|
|
|
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -785,9 +842,9 @@ void get_command() {
|
|
|
|
|
// this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
|
|
|
|
|
|
|
|
|
|
static bool stop_buffering = false;
|
|
|
|
|
if (buflen == 0) stop_buffering = false;
|
|
|
|
|
if (commands_in_queue == 0) stop_buffering = false;
|
|
|
|
|
|
|
|
|
|
while (!card.eof() && buflen < BUFSIZE && !stop_buffering) {
|
|
|
|
|
while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) {
|
|
|
|
|
int16_t n = card.get();
|
|
|
|
|
serial_char = (char)n;
|
|
|
|
|
if (serial_char == '\n' || serial_char == '\r' ||
|
|
|
|
@ -796,9 +853,9 @@ void get_command() {
|
|
|
|
|
) {
|
|
|
|
|
if (card.eof()) {
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
|
|
|
|
|
stoptime = millis();
|
|
|
|
|
print_job_stop_ms = millis();
|
|
|
|
|
char time[30];
|
|
|
|
|
millis_t t = (stoptime - starttime) / 1000;
|
|
|
|
|
millis_t t = (print_job_stop_ms - print_job_start_ms) / 1000;
|
|
|
|
|
int hours = t / 60 / 60, minutes = (t / 60) % 60;
|
|
|
|
|
sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes);
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
@ -813,18 +870,18 @@ void get_command() {
|
|
|
|
|
comment_mode = false; //for new command
|
|
|
|
|
return; //if empty line
|
|
|
|
|
}
|
|
|
|
|
cmdbuffer[bufindw][serial_count] = 0; //terminate string
|
|
|
|
|
command_queue[cmd_queue_index_w][serial_count] = 0; //terminate string
|
|
|
|
|
// if (!comment_mode) {
|
|
|
|
|
fromsd[bufindw] = true;
|
|
|
|
|
buflen += 1;
|
|
|
|
|
bufindw = (bufindw + 1)%BUFSIZE;
|
|
|
|
|
fromsd[cmd_queue_index_w] = true;
|
|
|
|
|
commands_in_queue += 1;
|
|
|
|
|
cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
|
|
|
|
|
// }
|
|
|
|
|
comment_mode = false; //for new command
|
|
|
|
|
serial_count = 0; //clear buffer
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (serial_char == ';') comment_mode = true;
|
|
|
|
|
if (!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char;
|
|
|
|
|
if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -854,7 +911,7 @@ long code_value_long() { return strtol(strchr_pointer + 1, NULL, 10); }
|
|
|
|
|
int16_t code_value_short() { return (int16_t)strtol(strchr_pointer + 1, NULL, 10); }
|
|
|
|
|
|
|
|
|
|
bool code_seen(char code) {
|
|
|
|
|
strchr_pointer = strchr(cmdbuffer[bufindr], code);
|
|
|
|
|
strchr_pointer = strchr(command_queue[cmd_queue_index_r], code);
|
|
|
|
|
return (strchr_pointer != NULL); //Return True if a character was found
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1023,7 +1080,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
|
|
|
|
|
void prepare_move_raw() {
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
calculate_delta(destination);
|
|
|
|
|
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
|
|
|
|
|
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedrate_multiplier/100.0), active_extruder);
|
|
|
|
|
set_current_to_destination();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
@ -1176,8 +1233,8 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
|
|
|
|
|
|
|
|
|
|
static void setup_for_endstop_move() {
|
|
|
|
|
saved_feedrate = feedrate;
|
|
|
|
|
saved_feedmultiply = feedmultiply;
|
|
|
|
|
feedmultiply = 100;
|
|
|
|
|
saved_feedrate_multiplier = feedrate_multiplier;
|
|
|
|
|
feedrate_multiplier = 100;
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
enable_endstops(true);
|
|
|
|
|
}
|
|
|
|
@ -1187,7 +1244,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
|
|
|
|
|
enable_endstops(false);
|
|
|
|
|
#endif
|
|
|
|
|
feedrate = saved_feedrate;
|
|
|
|
|
feedmultiply = saved_feedmultiply;
|
|
|
|
|
feedrate_multiplier = saved_feedrate_multiplier;
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1610,12 +1667,12 @@ static void homeaxis(AxisEnum axis) {
|
|
|
|
|
#define SLED_DOCKING_OFFSET 0
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Method to dock/undock a sled designed by Charles Bell.
|
|
|
|
|
//
|
|
|
|
|
// dock[in] If true, move to MAX_X and engage the electromagnet
|
|
|
|
|
// offset[in] The additional distance to move to adjust docking location
|
|
|
|
|
//
|
|
|
|
|
/**
|
|
|
|
|
* Method to dock/undock a sled designed by Charles Bell.
|
|
|
|
|
*
|
|
|
|
|
* dock[in] If true, move to MAX_X and engage the electromagnet
|
|
|
|
|
* offset[in] The additional distance to move to adjust docking location
|
|
|
|
|
*/
|
|
|
|
|
static void dock_sled(bool dock, int offset=0) {
|
|
|
|
|
if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
|
|
|
|
|
LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
|
|
|
|
@ -1649,9 +1706,10 @@ static void homeaxis(AxisEnum axis) {
|
|
|
|
|
inline void gcode_G0_G1() {
|
|
|
|
|
if (IsRunning()) {
|
|
|
|
|
get_coordinates(); // For X Y Z E F
|
|
|
|
|
|
|
|
|
|
#ifdef FWRETRACT
|
|
|
|
|
if (autoretract_enabled)
|
|
|
|
|
if (!(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
|
|
|
|
|
|
|
|
|
|
if (autoretract_enabled && !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
|
|
|
|
|
float echange = destination[E_AXIS] - current_position[E_AXIS];
|
|
|
|
|
// Is this move an attempt to retract or recover?
|
|
|
|
|
if ((echange < -MIN_RETRACT && !retracted[active_extruder]) || (echange > MIN_RETRACT && retracted[active_extruder])) {
|
|
|
|
@ -1661,7 +1719,9 @@ inline void gcode_G0_G1() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif //FWRETRACT
|
|
|
|
|
|
|
|
|
|
prepare_move();
|
|
|
|
|
//ClearToSend();
|
|
|
|
|
}
|
|
|
|
@ -1758,8 +1818,8 @@ inline void gcode_G28() {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
saved_feedrate = feedrate;
|
|
|
|
|
saved_feedmultiply = feedmultiply;
|
|
|
|
|
feedmultiply = 100;
|
|
|
|
|
saved_feedrate_multiplier = feedrate_multiplier;
|
|
|
|
|
feedrate_multiplier = 100;
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
|
|
|
|
|
enable_endstops(true);
|
|
|
|
@ -2013,7 +2073,7 @@ inline void gcode_G28() {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
feedrate = saved_feedrate;
|
|
|
|
|
feedmultiply = saved_feedmultiply;
|
|
|
|
|
feedrate_multiplier = saved_feedrate_multiplier;
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
endstops_hit_on_purpose(); // clear endstop hit flags
|
|
|
|
|
}
|
|
|
|
@ -2659,7 +2719,7 @@ inline void gcode_M17() {
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_M24() {
|
|
|
|
|
card.startFileprint();
|
|
|
|
|
starttime = millis();
|
|
|
|
|
print_job_start_ms = millis();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -2691,7 +2751,7 @@ inline void gcode_M17() {
|
|
|
|
|
char* codepos = strchr_pointer + 4;
|
|
|
|
|
char* starpos = strchr(codepos, '*');
|
|
|
|
|
if (starpos) {
|
|
|
|
|
char* npos = strchr(cmdbuffer[bufindr], 'N');
|
|
|
|
|
char* npos = strchr(command_queue[cmd_queue_index_r], 'N');
|
|
|
|
|
strchr_pointer = strchr(npos, ' ') + 1;
|
|
|
|
|
*(starpos) = '\0';
|
|
|
|
|
}
|
|
|
|
@ -2714,7 +2774,7 @@ inline void gcode_M17() {
|
|
|
|
|
card.closefile();
|
|
|
|
|
char* starpos = strchr(strchr_pointer + 4, '*');
|
|
|
|
|
if (starpos) {
|
|
|
|
|
char* npos = strchr(cmdbuffer[bufindr], 'N');
|
|
|
|
|
char* npos = strchr(command_queue[cmd_queue_index_r], 'N');
|
|
|
|
|
strchr_pointer = strchr(npos, ' ') + 1;
|
|
|
|
|
*(starpos) = '\0';
|
|
|
|
|
}
|
|
|
|
@ -2728,8 +2788,8 @@ inline void gcode_M17() {
|
|
|
|
|
* M31: Get the time since the start of SD Print (or last M109)
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_M31() {
|
|
|
|
|
stoptime = millis();
|
|
|
|
|
millis_t t = (stoptime - starttime) / 1000;
|
|
|
|
|
print_job_stop_ms = millis();
|
|
|
|
|
millis_t t = (print_job_stop_ms - print_job_start_ms) / 1000;
|
|
|
|
|
int min = t / 60, sec = t % 60;
|
|
|
|
|
char time[30];
|
|
|
|
|
sprintf_P(time, PSTR("%i min, %i sec"), min, sec);
|
|
|
|
@ -2769,7 +2829,7 @@ inline void gcode_M31() {
|
|
|
|
|
|
|
|
|
|
card.startFileprint();
|
|
|
|
|
if (!call_procedure)
|
|
|
|
|
starttime = millis(); //procedure calls count as normal print time.
|
|
|
|
|
print_job_start_ms = millis(); //procedure calls count as normal print time.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2779,7 +2839,7 @@ inline void gcode_M31() {
|
|
|
|
|
inline void gcode_M928() {
|
|
|
|
|
char* starpos = strchr(strchr_pointer + 5, '*');
|
|
|
|
|
if (starpos) {
|
|
|
|
|
char* npos = strchr(cmdbuffer[bufindr], 'N');
|
|
|
|
|
char* npos = strchr(command_queue[cmd_queue_index_r], 'N');
|
|
|
|
|
strchr_pointer = strchr(npos, ' ') + 1;
|
|
|
|
|
*(starpos) = '\0';
|
|
|
|
|
}
|
|
|
|
@ -3185,8 +3245,8 @@ inline void gcode_M109() {
|
|
|
|
|
|
|
|
|
|
LCD_MESSAGEPGM(MSG_HEATING);
|
|
|
|
|
|
|
|
|
|
CooldownNoWait = code_seen('S');
|
|
|
|
|
if (CooldownNoWait || code_seen('R')) {
|
|
|
|
|
no_wait_for_cooling = code_seen('S');
|
|
|
|
|
if (no_wait_for_cooling || code_seen('R')) {
|
|
|
|
|
float temp = code_value();
|
|
|
|
|
setTargetHotend(temp, target_extruder);
|
|
|
|
|
#ifdef DUAL_X_CARRIAGE
|
|
|
|
@ -3218,7 +3278,7 @@ inline void gcode_M109() {
|
|
|
|
|
while((!cancel_heatup)&&((residency_start_ms == -1) ||
|
|
|
|
|
(residency_start_ms >= 0 && (((unsigned int) (millis() - residency_start_ms)) < (TEMP_RESIDENCY_TIME * 1000UL)))) )
|
|
|
|
|
#else
|
|
|
|
|
while ( target_direction ? (isHeatingHotend(target_extruder)) : (isCoolingHotend(target_extruder)&&(CooldownNoWait==false)) )
|
|
|
|
|
while ( target_direction ? (isHeatingHotend(target_extruder)) : (isCoolingHotend(target_extruder)&&(no_wait_for_cooling==false)) )
|
|
|
|
|
#endif //TEMP_RESIDENCY_TIME
|
|
|
|
|
|
|
|
|
|
{ // while loop
|
|
|
|
@ -3258,7 +3318,7 @@ inline void gcode_M109() {
|
|
|
|
|
|
|
|
|
|
LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
starttime = previous_cmd_ms;
|
|
|
|
|
print_job_start_ms = previous_cmd_ms;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if HAS_TEMP_BED
|
|
|
|
@ -3269,8 +3329,8 @@ inline void gcode_M109() {
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_M190() {
|
|
|
|
|
LCD_MESSAGEPGM(MSG_BED_HEATING);
|
|
|
|
|
CooldownNoWait = code_seen('S');
|
|
|
|
|
if (CooldownNoWait || code_seen('R'))
|
|
|
|
|
no_wait_for_cooling = code_seen('S');
|
|
|
|
|
if (no_wait_for_cooling || code_seen('R'))
|
|
|
|
|
setTargetBed(code_value());
|
|
|
|
|
|
|
|
|
|
millis_t temp_ms = millis();
|
|
|
|
@ -3278,7 +3338,7 @@ inline void gcode_M109() {
|
|
|
|
|
cancel_heatup = false;
|
|
|
|
|
target_direction = isHeatingBed(); // true if heating, false if cooling
|
|
|
|
|
|
|
|
|
|
while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) {
|
|
|
|
|
while ((target_direction && !cancel_heatup) ? isHeatingBed() : isCoolingBed() && !no_wait_for_cooling) {
|
|
|
|
|
millis_t ms = millis();
|
|
|
|
|
if (ms > temp_ms + 1000UL) { //Print Temp Reading every 1 second while heating up.
|
|
|
|
|
temp_ms = ms;
|
|
|
|
@ -3371,7 +3431,7 @@ inline void gcode_M140() {
|
|
|
|
|
* This code should ALWAYS be available for EMERGENCY SHUTDOWN!
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_M81() {
|
|
|
|
|
disable_heater();
|
|
|
|
|
disable_all_heaters();
|
|
|
|
|
st_synchronize();
|
|
|
|
|
disable_e0();
|
|
|
|
|
disable_e1();
|
|
|
|
@ -3803,7 +3863,7 @@ inline void gcode_M206() {
|
|
|
|
|
default:
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND);
|
|
|
|
|
SERIAL_ECHO(cmdbuffer[bufindr]);
|
|
|
|
|
SERIAL_ECHO(command_queue[cmd_queue_index_r]);
|
|
|
|
|
SERIAL_ECHOLNPGM("\"");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -3849,7 +3909,7 @@ inline void gcode_M206() {
|
|
|
|
|
* M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_M220() {
|
|
|
|
|
if (code_seen('S')) feedmultiply = code_value();
|
|
|
|
|
if (code_seen('S')) feedrate_multiplier = code_value();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -4485,7 +4545,7 @@ inline void gcode_M503() {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef FILAMENT_RUNOUT_SENSOR
|
|
|
|
|
filrunoutEnqued = false;
|
|
|
|
|
filrunoutEnqueued = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
@ -4619,6 +4679,9 @@ inline void gcode_M999() {
|
|
|
|
|
FlushSerialRequestResend();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* T0-T3: Switch tool, usually switching extruders
|
|
|
|
|
*/
|
|
|
|
|
inline void gcode_T() {
|
|
|
|
|
int tmp_extruder = code_value();
|
|
|
|
|
if (tmp_extruder >= EXTRUDERS) {
|
|
|
|
@ -5208,7 +5271,7 @@ void process_commands() {
|
|
|
|
|
else {
|
|
|
|
|
SERIAL_ECHO_START;
|
|
|
|
|
SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND);
|
|
|
|
|
SERIAL_ECHO(cmdbuffer[bufindr]);
|
|
|
|
|
SERIAL_ECHO(command_queue[cmd_queue_index_r]);
|
|
|
|
|
SERIAL_ECHOLNPGM("\"");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -5216,7 +5279,7 @@ void process_commands() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FlushSerialRequestResend() {
|
|
|
|
|
//char cmdbuffer[bufindr][100]="Resend:";
|
|
|
|
|
//char command_queue[cmd_queue_index_r][100]="Resend:";
|
|
|
|
|
MYSERIAL.flush();
|
|
|
|
|
SERIAL_PROTOCOLPGM(MSG_RESEND);
|
|
|
|
|
SERIAL_PROTOCOLLN(gcode_LastN + 1);
|
|
|
|
@ -5226,7 +5289,7 @@ void FlushSerialRequestResend() {
|
|
|
|
|
void ClearToSend() {
|
|
|
|
|
refresh_cmd_timeout();
|
|
|
|
|
#ifdef SDSUPPORT
|
|
|
|
|
if (fromsd[bufindr]) return;
|
|
|
|
|
if (fromsd[cmd_queue_index_r]) return;
|
|
|
|
|
#endif
|
|
|
|
|
SERIAL_PROTOCOLLNPGM(MSG_OK);
|
|
|
|
|
}
|
|
|
|
@ -5470,7 +5533,7 @@ void prepare_move() {
|
|
|
|
|
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
|
|
|
|
|
if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
|
|
|
|
|
if (cartesian_mm < 0.000001) { return; }
|
|
|
|
|
float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
|
|
|
|
|
float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier;
|
|
|
|
|
int steps = max(1, int(scara_segments_per_second * seconds));
|
|
|
|
|
|
|
|
|
|
//SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
|
|
|
|
@ -5489,7 +5552,7 @@ void prepare_move() {
|
|
|
|
|
//SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
|
|
|
|
|
//SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
|
|
|
|
|
|
|
|
|
|
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedmultiply/100.0, active_extruder);
|
|
|
|
|
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // SCARA
|
|
|
|
@ -5502,7 +5565,7 @@ void prepare_move() {
|
|
|
|
|
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
|
|
|
|
|
if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
|
|
|
|
|
if (cartesian_mm < 0.000001) return;
|
|
|
|
|
float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
|
|
|
|
|
float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier;
|
|
|
|
|
int steps = max(1, int(delta_segments_per_second * seconds));
|
|
|
|
|
|
|
|
|
|
// SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
|
|
|
|
@ -5516,7 +5579,7 @@ void prepare_move() {
|
|
|
|
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
|
|
|
|
adjust_delta(destination);
|
|
|
|
|
#endif
|
|
|
|
|
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedmultiply/100.0, active_extruder);
|
|
|
|
|
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // DELTA
|
|
|
|
@ -5556,16 +5619,16 @@ void prepare_move() {
|
|
|
|
|
#endif // DUAL_X_CARRIAGE
|
|
|
|
|
|
|
|
|
|
#if !defined(DELTA) && !defined(SCARA)
|
|
|
|
|
// Do not use feedmultiply for E or Z only moves
|
|
|
|
|
// Do not use feedrate_multiplier for E or Z only moves
|
|
|
|
|
if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) {
|
|
|
|
|
line_to_destination();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
#ifdef MESH_BED_LEVELING
|
|
|
|
|
mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
|
|
|
|
|
mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedrate_multiplier/100.0), active_extruder);
|
|
|
|
|
return;
|
|
|
|
|
#else
|
|
|
|
|
line_to_destination(feedrate * feedmultiply / 100.0);
|
|
|
|
|
line_to_destination(feedrate * feedrate_multiplier / 100.0);
|
|
|
|
|
#endif // MESH_BED_LEVELING
|
|
|
|
|
}
|
|
|
|
|
#endif // !(DELTA || SCARA)
|
|
|
|
@ -5577,7 +5640,7 @@ void prepare_arc_move(char isclockwise) {
|
|
|
|
|
float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
|
|
|
|
|
|
|
|
|
|
// Trace the arc
|
|
|
|
|
mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedmultiply/60/100.0, r, isclockwise, active_extruder);
|
|
|
|
|
mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedrate_multiplier/60/100.0, r, isclockwise, active_extruder);
|
|
|
|
|
|
|
|
|
|
// As far as the parser is concerned, the position is now == target. In reality the
|
|
|
|
|
// motion control system might still be processing the action and the real tool position
|
|
|
|
@ -5762,7 +5825,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
|
|
|
|
|
filrunout();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (buflen < BUFSIZE - 1) get_command();
|
|
|
|
|
if (commands_in_queue < BUFSIZE - 1) get_command();
|
|
|
|
|
|
|
|
|
|
millis_t ms = millis();
|
|
|
|
|
|
|
|
|
@ -5898,7 +5961,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
|
|
|
|
|
void kill()
|
|
|
|
|
{
|
|
|
|
|
cli(); // Stop interrupts
|
|
|
|
|
disable_heater();
|
|
|
|
|
disable_all_heaters();
|
|
|
|
|
|
|
|
|
|
disable_all_steppers();
|
|
|
|
|
|
|
|
|
@ -5919,18 +5982,18 @@ void kill()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef FILAMENT_RUNOUT_SENSOR
|
|
|
|
|
void filrunout()
|
|
|
|
|
{
|
|
|
|
|
if (filrunoutEnqued == false) {
|
|
|
|
|
filrunoutEnqued = true;
|
|
|
|
|
|
|
|
|
|
void filrunout() {
|
|
|
|
|
if (!filrunoutEnqueued) {
|
|
|
|
|
filrunoutEnqueued = true;
|
|
|
|
|
enqueuecommand("M600");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void Stop()
|
|
|
|
|
{
|
|
|
|
|
disable_heater();
|
|
|
|
|
void Stop() {
|
|
|
|
|
disable_all_heaters();
|
|
|
|
|
if (IsRunning()) {
|
|
|
|
|
Running = false;
|
|
|
|
|
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
|
|
|
|