@ -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
//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
/**
* 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
* - - - - - - - - - - - - - - - - - - -
*
* " 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 = 150 C )
* 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 ( 3 mm , 1.75 mm ) 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_feed multiply ;
int feed rate_multiplier = 100 ; //100->1 200->2
int saved_feed rate_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 filrunoutEnque d = false ;
static bool filrunoutEnque ue d = 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_Enque ing) ;
SERIAL_ECHO ( c mdbuffer[ bufindw ] ) ;
SERIAL_ECHOPGM ( MSG_Enque ue ing) ;
SERIAL_ECHO ( c ommand ) ;
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 ] ) ;
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 ( ) ;
process_commands ( ) ; // The card is saving because it's logging
else
SERIAL_PROTOCOLLNPGM ( MSG_OK ) ;
}
else {
card . closefile ( ) ;
SERIAL_PROTOCOLLNPGM ( MSG_FILE_SAVED ) ;
}
}
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 [ bufind w] = false ;
fromsd [ cmd_queue_index_ w] = false ;
# endif
if ( strchr ( c mdbuffer[ bufindw ] , ' N ' ) ! = NULL ) {
strchr_pointer = strchr ( c mdbuffer[ bufindw ] , ' N ' ) ;
if ( strchr ( c ommand , ' N ' ) ! = NULL ) {
strchr_pointer = strchr ( c ommand , ' N ' ) ;
gcode_N = ( strtol ( strchr_pointer + 1 , NULL , 10 ) ) ;
if ( gcode_N ! = gcode_LastN + 1 & & strstr_P ( c mdbuffer[ bufindw ] , PSTR ( " M110 " ) ) = = NULL ) {
if ( gcode_N ! = gcode_LastN + 1 & & strstr_P ( c ommand , 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 ( c mdbuffer[ bufindw ] , ' * ' ) ! = NULL ) {
if ( strchr ( c ommand , ' * ' ) ! = NULL ) {
byte checksum = 0 ;
byte count = 0 ;
while ( c mdbuffer[ bufindw ] [ count ] ! = ' * ' ) checksum ^ = c mdbuffer[ bufindw ] [ count + + ] ;
strchr_pointer = strchr ( c mdbuffer[ bufindw ] , ' * ' ) ;
while ( c ommand [ count ] ! = ' * ' ) checksum ^ = c ommand [ count + + ] ;
strchr_pointer = strchr ( c ommand , ' * ' ) ;
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 ( c mdbuffer[ bufindw ] , ' * ' ) ! = NULL ) ) {
if ( ( strchr ( c ommand , ' * ' ) ! = 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 ( c mdbuffer[ bufindw ] , ' G ' ) ! = NULL ) {
strchr_pointer = strchr ( c mdbuffer[ bufindw ] , ' G ' ) ;
if ( strchr ( c ommand , ' G ' ) ! = NULL ) {
strchr_pointer = strchr ( c ommand , ' 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 ( c mdbuffer[ bufindw ] , " M112 " ) = = 0 ) kill ( ) ;
if ( strcmp ( c ommand , " M112 " ) = = 0 ) kill ( ) ;
bufindw = ( bufind w + 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 ( ) ;
c mdbuffer[ bufind w] [ serial_count + + ] = serial_char ;
c ommand_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 ) c mdbuffer[ bufind w] [ serial_count + + ] = serial_char ;
if ( ! comment_mode ) c ommand_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
}
c mdbuffer[ bufind w] [ serial_count ] = 0 ; //terminate string
c ommand_queue[ cmd_queue_index_ w] [ serial_count ] = 0 ; //terminate string
// if (!comment_mode) {
fromsd [ bufind w] = 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 ) c mdbuffer[ bufind w] [ serial_count + + ] = serial_char ;
if ( ! comment_mode ) c ommand_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 ( c mdbuffer[ bufind r] , code ) ;
strchr_pointer = strchr ( c ommand_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 ) * ( feed multiply / 100.0 ) , active_extruder ) ;
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , destination [ E_AXIS ] , ( feedrate / 60 ) * ( feed rate_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_feed multiply = feedmultiply ;
feed multiply = 100 ;
saved_feed rate_multiplier = feedrate_multiplier ;
feed rate_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 ;
feed multiply = saved_feedmultiply ;
feed rate_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_feed multiply = feedmultiply ;
feed multiply = 100 ;
saved_feed rate_multiplier = feedrate_multiplier ;
feed rate_multiplier = 100 ;
refresh_cmd_timeout ( ) ;
enable_endstops ( true ) ;
@ -2013,7 +2073,7 @@ inline void gcode_G28() {
# endif
feedrate = saved_feedrate ;
feed multiply = saved_feedmultiply ;
feed rate_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 ( c mdbuffer[ bufind r] , ' N ' ) ;
char * npos = strchr ( c ommand_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 ( c mdbuffer[ bufind r] , ' N ' ) ;
char * npos = strchr ( c ommand_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 ( c mdbuffer[ bufind r] , ' N ' ) ;
char * npos = strchr ( c ommand_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 ( c mdbuffer[ bufind r] ) ;
SERIAL_ECHO ( c ommand_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 ' ) ) feed multiply = code_value ( ) ;
if ( code_seen ( ' S ' ) ) feed rate_multiplier = code_value ( ) ;
}
/**
@ -4485,7 +4545,7 @@ inline void gcode_M503() {
# endif
# ifdef FILAMENT_RUNOUT_SENSOR
filrunoutEnque d = false ;
filrunoutEnque ue d = 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 ( c mdbuffer[ bufind r] ) ;
SERIAL_ECHO ( c ommand_queue[ cmd_queue_index_ r] ) ;
SERIAL_ECHOLNPGM ( " \" " ) ;
}
@ -5216,7 +5279,7 @@ void process_commands() {
}
void FlushSerialRequestResend ( ) {
//char c mdbuffer[bufind r][100]="Resend:";
//char c ommand_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 [ bufind r] ) 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 / feed multiply ;
float seconds = 6000 * cartesian_mm / feedrate / feed rate_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 * feed multiply / 100.0 , active_extruder ) ;
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 * feed rate_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 / feed multiply ;
float seconds = 6000 * cartesian_mm / feedrate / feed rate_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 * feed multiply / 100.0 , active_extruder ) ;
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 * feed rate_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 feed multiply for E or Z only moves
// Do not use feed rate_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 ) * ( feed multiply / 100.0 ) , active_extruder ) ;
mesh_plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , ( feedrate / 60 ) * ( feed rate_multiplier / 100.0 ) , active_extruder ) ;
return ;
# else
line_to_destination ( feedrate * feed multiply / 100.0 ) ;
line_to_destination ( feedrate * feed rate_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 * feed multiply / 60 / 100.0 , r , isclockwise , active_extruder ) ;
mc_arc ( current_position , destination , offset , X_AXIS , Y_AXIS , Z_AXIS , feedrate * feed rate_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 ) {
filrunoutEnq ued = true ;
void filrunout ( ) {
if ( ! filrunoutEnqueued ) {
filrunoutEnq ue ued = 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