@ -284,32 +284,51 @@ bool volumetric_enabled = false;
float filament_size [ EXTRUDERS ] = ARRAY_BY_EXTRUDERS1 ( DEFAULT_NOMINAL_FILAMENT_DIA ) ;
float filament_size [ EXTRUDERS ] = ARRAY_BY_EXTRUDERS1 ( DEFAULT_NOMINAL_FILAMENT_DIA ) ;
float volumetric_multiplier [ EXTRUDERS ] = ARRAY_BY_EXTRUDERS1 ( 1.0 ) ;
float volumetric_multiplier [ EXTRUDERS ] = ARRAY_BY_EXTRUDERS1 ( 1.0 ) ;
// The distance that XYZ has been offset by G92. Reset by G28.
float position_shift [ 3 ] = { 0 } ;
float position_shift [ 3 ] = { 0 } ;
// This offset is added to the configured home position.
// Set by M206, M428, or menu item. Saved to EEPROM.
float home_offset [ 3 ] = { 0 } ;
float home_offset [ 3 ] = { 0 } ;
float min_pos [ 3 ] = { X_MIN_POS , Y_MIN_POS , Z_MIN_POS } ;
float max_pos [ 3 ] = { X_MAX_POS , Y_MAX_POS , Z_MAX_POS } ;
// Software Endstops. Default to configured limits.
float sw_endstop_min [ 3 ] = { X_MIN_POS , Y_MIN_POS , Z_MIN_POS } ;
float sw_endstop_max [ 3 ] = { X_MAX_POS , Y_MAX_POS , Z_MAX_POS } ;
# if FAN_COUNT > 0
# if FAN_COUNT > 0
int fanSpeeds [ FAN_COUNT ] = { 0 } ;
int fanSpeeds [ FAN_COUNT ] = { 0 } ;
# endif
# endif
// The active extruder (tool). Set with T<extruder> command.
uint8_t active_extruder = 0 ;
uint8_t active_extruder = 0 ;
// Relative Mode. Enable with G91, disable with G90.
static bool relative_mode = false ;
bool cancel_heatup = false ;
bool cancel_heatup = false ;
const char errormagic [ ] PROGMEM = " Error: " ;
const char errormagic [ ] PROGMEM = " Error: " ;
const char echomagic [ ] PROGMEM = " echo: " ;
const char echomagic [ ] PROGMEM = " echo: " ;
const char axis_codes [ NUM_AXIS ] = { ' X ' , ' Y ' , ' Z ' , ' E ' } ;
const char axis_codes [ NUM_AXIS ] = { ' X ' , ' Y ' , ' Z ' , ' E ' } ;
static bool relative_mode = false ; //Determines Absolute or Relative Coordinates
static int serial_count = 0 ;
static int serial_count = 0 ;
static char * seen_pointer ; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.)
const char * queued_commands_P = NULL ; /* pointer to the current line in the active sequence of commands, or NULL when none */
// GCode parameter pointer used by code_seen(), code_value(), etc.
static char * seen_pointer ;
// Next Immediate GCode Command pointer. NULL if none.
const char * queued_commands_P = NULL ;
const int sensitive_pins [ ] = SENSITIVE_PINS ; ///< Sensitive pin list for M42
const int sensitive_pins [ ] = SENSITIVE_PINS ; ///< Sensitive pin list for M42
// Inactivity shutdown
// Inactivity shutdown
millis_t previous_cmd_ms = 0 ;
millis_t previous_cmd_ms = 0 ;
static millis_t max_inactive_time = 0 ;
static millis_t max_inactive_time = 0 ;
static millis_t stepper_inactive_time = ( DEFAULT_STEPPER_DEACTIVE_TIME ) * 1000UL ;
static millis_t stepper_inactive_time = ( DEFAULT_STEPPER_DEACTIVE_TIME ) * 1000UL ;
// Print Job Timer
Stopwatch print_job_timer = Stopwatch ( ) ;
Stopwatch print_job_timer = Stopwatch ( ) ;
static uint8_t target_extruder ;
static uint8_t target_extruder ;
# if ENABLED(AUTO_BED_LEVELING_FEATURE)
# if ENABLED(AUTO_BED_LEVELING_FEATURE)
@ -344,8 +363,8 @@ static uint8_t target_extruder;
# endif
# endif
# if ENABLED(BARICUDA)
# if ENABLED(BARICUDA)
int ValveP ressure = 0 ;
int baricuda_valve_p ressure = 0 ;
int EtoPP ressure = 0 ;
int baricuda_e_to_p_p ressure = 0 ;
# endif
# endif
# if ENABLED(FWRETRACT)
# if ENABLED(FWRETRACT)
@ -427,7 +446,7 @@ static uint8_t target_extruder;
# endif
# endif
# if ENABLED(FILAMENT_RUNOUT_SENSOR)
# if ENABLED(FILAMENT_RUNOUT_SENSOR)
static bool filrunoutEnqueued = false ;
static bool filament_ran_out = false ;
# endif
# endif
static bool send_ok [ BUFSIZE ] ;
static bool send_ok [ BUFSIZE ] ;
@ -472,13 +491,13 @@ static bool send_ok[BUFSIZE];
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
*/
void stop ( ) ;
void get_available_commands ( ) ;
void get_available_commands ( ) ;
void process_next_command ( ) ;
void process_next_command ( ) ;
void plan_arc ( float target [ NUM_AXIS ] , float * offset , uint8_t clockwise ) ;
void plan_arc ( float target [ NUM_AXIS ] , float * offset , uint8_t clockwise ) ;
bool setTargetedHotend ( int code ) ;
void serial_echopair_P ( const char * s_P , int v ) { serialprintPGM ( s_P ) ; SERIAL_ECHO ( v ) ; }
void serial_echopair_P ( const char * s_P , int v ) { serialprintPGM ( s_P ) ; SERIAL_ECHO ( v ) ; }
void serial_echopair_P ( const char * s_P , long v ) { serialprintPGM ( s_P ) ; SERIAL_ECHO ( v ) ; }
void serial_echopair_P ( const char * s_P , long v ) { serialprintPGM ( s_P ) ; SERIAL_ECHO ( v ) ; }
void serial_echopair_P ( const char * s_P , float v ) { serialprintPGM ( s_P ) ; SERIAL_ECHO ( v ) ; }
void serial_echopair_P ( const char * s_P , float v ) { serialprintPGM ( s_P ) ; SERIAL_ECHO ( v ) ; }
@ -1142,6 +1161,30 @@ bool code_seen(char code) {
return ( seen_pointer ! = NULL ) ; // Return TRUE if the code-letter was found
return ( seen_pointer ! = NULL ) ; // Return TRUE if the code-letter was found
}
}
/**
* Set target_extruder from the T parameter or the active_extruder
*
* Returns TRUE if the target is invalid
*/
bool get_target_extruder_from_command ( int code ) {
if ( code_seen ( ' T ' ) ) {
short t = code_value_short ( ) ;
if ( t > = EXTRUDERS ) {
SERIAL_ECHO_START ;
SERIAL_CHAR ( ' M ' ) ;
SERIAL_ECHO ( code ) ;
SERIAL_ECHOPAIR ( " " MSG_INVALID_EXTRUDER " " , t ) ;
SERIAL_EOL ;
return true ;
}
target_extruder = t ;
}
else
target_extruder = active_extruder ;
return false ;
}
# define DEFINE_PGM_READ_ANY(type, reader) \
# define DEFINE_PGM_READ_ANY(type, reader) \
static inline type pgm_read_any ( const type * p ) \
static inline type pgm_read_any ( const type * p ) \
{ return pgm_read_ # # reader # # _near ( p ) ; }
{ return pgm_read_ # # reader # # _near ( p ) ; }
@ -1212,24 +1255,32 @@ static void update_software_endstops(AxisEnum axis) {
if ( axis = = X_AXIS ) {
if ( axis = = X_AXIS ) {
float dual_max_x = max ( extruder_offset [ X_AXIS ] [ 1 ] , X2_MAX_POS ) ;
float dual_max_x = max ( extruder_offset [ X_AXIS ] [ 1 ] , X2_MAX_POS ) ;
if ( active_extruder ! = 0 ) {
if ( active_extruder ! = 0 ) {
min_pos [ X_AXIS ] = X2_MIN_POS + offs ;
sw_endstop_ min[ X_AXIS ] = X2_MIN_POS + offs ;
max_pos [ X_AXIS ] = dual_max_x + offs ;
sw_endstop_ max[ X_AXIS ] = dual_max_x + offs ;
return ;
return ;
}
}
else if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE ) {
else if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE ) {
min_pos [ X_AXIS ] = base_min_pos ( X_AXIS ) + offs ;
sw_endstop_ min[ X_AXIS ] = base_min_pos ( X_AXIS ) + offs ;
max_pos [ X_AXIS ] = min ( base_max_pos ( X_AXIS ) , dual_max_x - duplicate_extruder_x_offset ) + offs ;
sw_endstop_ max[ X_AXIS ] = min ( base_max_pos ( X_AXIS ) , dual_max_x - duplicate_extruder_x_offset ) + offs ;
return ;
return ;
}
}
}
}
else
else
# endif
# endif
{
{
min_pos [ axis ] = base_min_pos ( axis ) + offs ;
sw_endstop_ min[ axis ] = base_min_pos ( axis ) + offs ;
max_pos [ axis ] = base_max_pos ( axis ) + offs ;
sw_endstop_ max[ axis ] = base_max_pos ( axis ) + offs ;
}
}
}
}
/**
* Change the home offset for an axis , update the current
* position and the software endstops to retain the same
* relative distance to the new home .
*
* Since this changes the current_position , code should
* call sync_plan_position soon after this .
*/
static void set_home_offset ( AxisEnum axis , float v ) {
static void set_home_offset ( AxisEnum axis , float v ) {
current_position [ axis ] + = v - home_offset [ axis ] ;
current_position [ axis ] + = v - home_offset [ axis ] ;
home_offset [ axis ] = v ;
home_offset [ axis ] = v ;
@ -1294,8 +1345,8 @@ static void set_axis_is_at_home(AxisEnum axis) {
* SCARA home positions are based on configuration since the actual
* SCARA home positions are based on configuration since the actual
* limits are determined by the inverse kinematic transform .
* limits are determined by the inverse kinematic transform .
*/
*/
min_pos [ axis ] = base_min_pos ( axis ) ; // + (delta[axis] - base_home_pos(axis));
sw_endstop_ min[ axis ] = base_min_pos ( axis ) ; // + (delta[axis] - base_home_pos(axis));
max_pos [ axis ] = base_max_pos ( axis ) ; // + (delta[axis] - base_home_pos(axis));
sw_endstop_ max[ axis ] = base_max_pos ( axis ) ; // + (delta[axis] - base_home_pos(axis));
}
}
else
else
# endif
# endif
@ -1712,7 +1763,7 @@ static void setup_for_endstop_move() {
SERIAL_ERRORLNPGM ( " Z-Probe failed to engage! " ) ;
SERIAL_ERRORLNPGM ( " Z-Probe failed to engage! " ) ;
LCD_ALERTMESSAGEPGM ( " Err: ZPROBE " ) ;
LCD_ALERTMESSAGEPGM ( " Err: ZPROBE " ) ;
}
}
S top( ) ;
s top( ) ;
}
}
# endif // Z_PROBE_ALLEN_KEY
# endif // Z_PROBE_ALLEN_KEY
@ -1816,7 +1867,7 @@ static void setup_for_endstop_move() {
SERIAL_ERRORLNPGM ( " Z-Probe failed to retract! " ) ;
SERIAL_ERRORLNPGM ( " Z-Probe failed to retract! " ) ;
LCD_ALERTMESSAGEPGM ( " Err: ZPROBE " ) ;
LCD_ALERTMESSAGEPGM ( " Err: ZPROBE " ) ;
}
}
S top( ) ;
s top( ) ;
}
}
# endif // Z_PROBE_ALLEN_KEY
# endif // Z_PROBE_ALLEN_KEY
@ -4206,7 +4257,7 @@ inline void gcode_M77() {
* M104 : Set hot end temperature
* M104 : Set hot end temperature
*/
*/
inline void gcode_M104 ( ) {
inline void gcode_M104 ( ) {
if ( setTargetedHote nd( 104 ) ) return ;
if ( get_target_extruder_from_comma nd( 104 ) ) return ;
if ( DEBUGGING ( DRYRUN ) ) return ;
if ( DEBUGGING ( DRYRUN ) ) return ;
if ( code_seen ( ' S ' ) ) {
if ( code_seen ( ' S ' ) ) {
@ -4314,7 +4365,7 @@ inline void gcode_M104() {
* M105 : Read hot end and bed temperature
* M105 : Read hot end and bed temperature
*/
*/
inline void gcode_M105 ( ) {
inline void gcode_M105 ( ) {
if ( setTargetedHote nd( 105 ) ) return ;
if ( get_target_extruder_from_comma nd( 105 ) ) return ;
# if HAS_TEMP_HOTEND || HAS_TEMP_BED
# if HAS_TEMP_HOTEND || HAS_TEMP_BED
SERIAL_PROTOCOLPGM ( MSG_OK ) ;
SERIAL_PROTOCOLPGM ( MSG_OK ) ;
@ -4358,7 +4409,7 @@ inline void gcode_M105() {
*/
*/
inline void gcode_M109 ( ) {
inline void gcode_M109 ( ) {
if ( setTargetedHote nd( 109 ) ) return ;
if ( get_target_extruder_from_comma nd( 109 ) ) return ;
if ( DEBUGGING ( DRYRUN ) ) return ;
if ( DEBUGGING ( DRYRUN ) ) return ;
bool no_wait_for_cooling = code_seen ( ' S ' ) ;
bool no_wait_for_cooling = code_seen ( ' S ' ) ;
@ -4612,22 +4663,22 @@ inline void gcode_M112() { kill(PSTR(MSG_KILLED)); }
/**
/**
* M126 : Heater 1 valve open
* M126 : Heater 1 valve open
*/
*/
inline void gcode_M126 ( ) { ValveP ressure = code_seen ( ' S ' ) ? constrain ( code_value ( ) , 0 , 255 ) : 255 ; }
inline void gcode_M126 ( ) { baricuda_valve_p ressure = code_seen ( ' S ' ) ? constrain ( code_value ( ) , 0 , 255 ) : 255 ; }
/**
/**
* M127 : Heater 1 valve close
* M127 : Heater 1 valve close
*/
*/
inline void gcode_M127 ( ) { ValveP ressure = 0 ; }
inline void gcode_M127 ( ) { baricuda_valve_p ressure = 0 ; }
# endif
# endif
# if HAS_HEATER_2
# if HAS_HEATER_2
/**
/**
* M128 : Heater 2 valve open
* M128 : Heater 2 valve open
*/
*/
inline void gcode_M128 ( ) { EtoPP ressure = code_seen ( ' S ' ) ? constrain ( code_value ( ) , 0 , 255 ) : 255 ; }
inline void gcode_M128 ( ) { baricuda_e_to_p_p ressure = code_seen ( ' S ' ) ? constrain ( code_value ( ) , 0 , 255 ) : 255 ; }
/**
/**
* M129 : Heater 2 valve close
* M129 : Heater 2 valve close
*/
*/
inline void gcode_M129 ( ) { EtoPP ressure = 0 ; }
inline void gcode_M129 ( ) { baricuda_e_to_p_p ressure = 0 ; }
# endif
# endif
# endif //BARICUDA
# endif //BARICUDA
@ -5025,7 +5076,7 @@ inline void gcode_M121() { enable_endstops_globally(false); }
*/
*/
inline void gcode_M200 ( ) {
inline void gcode_M200 ( ) {
if ( setTargetedHote nd( 200 ) ) return ;
if ( get_target_extruder_from_comma nd( 200 ) ) return ;
if ( code_seen ( ' D ' ) ) {
if ( code_seen ( ' D ' ) ) {
float diameter = code_value ( ) ;
float diameter = code_value ( ) ;
@ -5277,7 +5328,7 @@ inline void gcode_M206() {
* Z < zoffset > - Available with DUAL_X_CARRIAGE
* Z < zoffset > - Available with DUAL_X_CARRIAGE
*/
*/
inline void gcode_M218 ( ) {
inline void gcode_M218 ( ) {
if ( setTargetedHote nd( 218 ) ) return ;
if ( get_target_extruder_from_comma nd( 218 ) ) return ;
if ( code_seen ( ' X ' ) ) extruder_offset [ X_AXIS ] [ target_extruder ] = code_value ( ) ;
if ( code_seen ( ' X ' ) ) extruder_offset [ X_AXIS ] [ target_extruder ] = code_value ( ) ;
if ( code_seen ( ' Y ' ) ) extruder_offset [ Y_AXIS ] [ target_extruder ] = code_value ( ) ;
if ( code_seen ( ' Y ' ) ) extruder_offset [ Y_AXIS ] [ target_extruder ] = code_value ( ) ;
@ -5316,7 +5367,7 @@ inline void gcode_M220() {
inline void gcode_M221 ( ) {
inline void gcode_M221 ( ) {
if ( code_seen ( ' S ' ) ) {
if ( code_seen ( ' S ' ) ) {
int sval = code_value ( ) ;
int sval = code_value ( ) ;
if ( setTargetedHote nd( 221 ) ) return ;
if ( get_target_extruder_from_comma nd( 221 ) ) return ;
extruder_multiplier [ target_extruder ] = sval ;
extruder_multiplier [ target_extruder ] = sval ;
}
}
}
}
@ -5842,7 +5893,7 @@ inline void gcode_M428() {
bool err = false ;
bool err = false ;
for ( int8_t i = X_AXIS ; i < = Z_AXIS ; i + + ) {
for ( int8_t i = X_AXIS ; i < = Z_AXIS ; i + + ) {
if ( axis_homed [ i ] ) {
if ( axis_homed [ i ] ) {
float base = ( current_position [ i ] > ( min_pos [ i ] + max_pos [ i ] ) / 2 ) ? base_home_pos ( i ) : 0 ,
float base = ( current_position [ i ] > ( sw_endstop_ min[ i ] + sw_endstop_ max[ i ] ) / 2 ) ? base_home_pos ( i ) : 0 ,
diff = current_position [ i ] - base ;
diff = current_position [ i ] - base ;
if ( diff > - 20 & & diff < 20 ) {
if ( diff > - 20 & & diff < 20 ) {
set_home_offset ( ( AxisEnum ) i , home_offset [ i ] - diff ) ;
set_home_offset ( ( AxisEnum ) i , home_offset [ i ] - diff ) ;
@ -6078,7 +6129,7 @@ inline void gcode_M503() {
# endif
# endif
# if ENABLED(FILAMENT_RUNOUT_SENSOR)
# if ENABLED(FILAMENT_RUNOUT_SENSOR)
filrunoutEnqueued = false ;
filament_ran_out = false ;
# endif
# endif
}
}
@ -7032,8 +7083,8 @@ void ok_to_send() {
void clamp_to_software_endstops ( float target [ 3 ] ) {
void clamp_to_software_endstops ( float target [ 3 ] ) {
if ( min_software_endstops ) {
if ( min_software_endstops ) {
NOLESS ( target [ X_AXIS ] , min_pos [ X_AXIS ] ) ;
NOLESS ( target [ X_AXIS ] , sw_endstop_ min[ X_AXIS ] ) ;
NOLESS ( target [ Y_AXIS ] , min_pos [ Y_AXIS ] ) ;
NOLESS ( target [ Y_AXIS ] , sw_endstop_ min[ Y_AXIS ] ) ;
float negative_z_offset = 0 ;
float negative_z_offset = 0 ;
# if ENABLED(AUTO_BED_LEVELING_FEATURE)
# if ENABLED(AUTO_BED_LEVELING_FEATURE)
@ -7048,13 +7099,13 @@ void clamp_to_software_endstops(float target[3]) {
negative_z_offset + = home_offset [ Z_AXIS ] ;
negative_z_offset + = home_offset [ Z_AXIS ] ;
}
}
# endif
# endif
NOLESS ( target [ Z_AXIS ] , min_pos [ Z_AXIS ] + negative_z_offset ) ;
NOLESS ( target [ Z_AXIS ] , sw_endstop_ min[ Z_AXIS ] + negative_z_offset ) ;
}
}
if ( max_software_endstops ) {
if ( max_software_endstops ) {
NOMORE ( target [ X_AXIS ] , max_pos [ X_AXIS ] ) ;
NOMORE ( target [ X_AXIS ] , sw_endstop_ max[ X_AXIS ] ) ;
NOMORE ( target [ Y_AXIS ] , max_pos [ Y_AXIS ] ) ;
NOMORE ( target [ Y_AXIS ] , sw_endstop_ max[ Y_AXIS ] ) ;
NOMORE ( target [ Z_AXIS ] , max_pos [ Z_AXIS ] ) ;
NOMORE ( target [ Z_AXIS ] , sw_endstop_ max[ Z_AXIS ] ) ;
}
}
}
}
@ -7714,7 +7765,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
# if HAS_FILRUNOUT
# if HAS_FILRUNOUT
if ( IS_SD_PRINTING & & ! ( READ ( FILRUNOUT_PIN ) ^ FIL_RUNOUT_INVERTING ) )
if ( IS_SD_PRINTING & & ! ( READ ( FILRUNOUT_PIN ) ^ FIL_RUNOUT_INVERTING ) )
filrunout ( ) ;
handle_ filament_ runout( ) ;
# endif
# endif
if ( commands_in_queue < BUFSIZE ) get_available_commands ( ) ;
if ( commands_in_queue < BUFSIZE ) get_available_commands ( ) ;
@ -7897,9 +7948,9 @@ void kill(const char* lcd_msg) {
# if ENABLED(FILAMENT_RUNOUT_SENSOR)
# if ENABLED(FILAMENT_RUNOUT_SENSOR)
void filrunout ( ) {
void handle_ filament_ runout( ) {
if ( ! filrunoutEnqueued ) {
if ( ! filament_ran_out ) {
filrunoutEnqueued = true ;
filament_ran_out = true ;
enqueue_and_echo_commands_P ( PSTR ( FILAMENT_RUNOUT_SCRIPT ) ) ;
enqueue_and_echo_commands_P ( PSTR ( FILAMENT_RUNOUT_SCRIPT ) ) ;
st_synchronize ( ) ;
st_synchronize ( ) ;
}
}
@ -7968,7 +8019,7 @@ void kill(const char* lcd_msg) {
}
}
# endif // FAST_PWM_FAN
# endif // FAST_PWM_FAN
void S top( ) {
void s top( ) {
disable_all_heaters ( ) ;
disable_all_heaters ( ) ;
if ( IsRunning ( ) ) {
if ( IsRunning ( ) ) {
Running = false ;
Running = false ;
@ -7979,27 +8030,6 @@ void Stop() {
}
}
}
}
/**
* Set target_extruder from the T parameter or the active_extruder
*
* Returns TRUE if the target is invalid
*/
bool setTargetedHotend ( int code ) {
target_extruder = active_extruder ;
if ( code_seen ( ' T ' ) ) {
target_extruder = code_value_short ( ) ;
if ( target_extruder > = EXTRUDERS ) {
SERIAL_ECHO_START ;
SERIAL_CHAR ( ' M ' ) ;
SERIAL_ECHO ( code ) ;
SERIAL_ECHOPGM ( " " MSG_INVALID_EXTRUDER " " ) ;
SERIAL_ECHOLN ( ( int ) target_extruder ) ;
return true ;
}
}
return false ;
}
float calculate_volumetric_multiplier ( float diameter ) {
float calculate_volumetric_multiplier ( float diameter ) {
if ( ! volumetric_enabled | | diameter = = 0 ) return 1.0 ;
if ( ! volumetric_enabled | | diameter = = 0 ) return 1.0 ;
float d2 = diameter * 0.5 ;
float d2 = diameter * 0.5 ;