@ -50,7 +50,7 @@
# ifdef BLINKM
# ifdef BLINKM
# include "BlinkM.h"
# include "BlinkM.h"
# include "Wire.h"
# include "Wire.h"
# endif
# endif
# if NUM_SERVOS > 0
# if NUM_SERVOS > 0
@ -99,7 +99,7 @@
// M29 - Stop SD write
// M29 - Stop SD write
// M30 - Delete file from SD (M30 filename.g)
// M30 - Delete file from SD (M30 filename.g)
// M31 - Output time since last M109 or SD card start to serial
// 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):
// 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#"
// syntax "M32 /path/filename#", or "M32 S<startpos bytes> !filename#"
// Call gcode file : "M32 P !filename#" and return to caller file after finishing (simiarl to #include).
// Call gcode file : "M32 P !filename#" and return to caller file after finishing (simiarl to #include).
// The '#' is necessary when calling from within sd files, as it stops buffer prereading
// The '#' is necessary when calling from within sd files, as it stops buffer prereading
@ -229,7 +229,11 @@ int EtoPPressure=0;
# endif
# endif
# ifdef ULTIPANEL
# ifdef ULTIPANEL
bool powersupply = true ;
# ifdef PS_DEFAULT_OFF
bool powersupply = false ;
# else
bool powersupply = true ;
# endif
# endif
# endif
# ifdef DELTA
# ifdef DELTA
@ -418,7 +422,7 @@ void servo_init()
# if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
# if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
delay ( PROBE_SERVO_DEACTIVATION_DELAY ) ;
delay ( PROBE_SERVO_DEACTIVATION_DELAY ) ;
servos [ servo_endstops [ Z_AXIS ] ] . detach ( ) ;
servos [ servo_endstops [ Z_AXIS ] ] . detach ( ) ;
# endif
# endif
}
}
@ -639,17 +643,17 @@ void get_command()
if ( ! card . sdprinting | | serial_count ! = 0 ) {
if ( ! card . sdprinting | | serial_count ! = 0 ) {
return ;
return ;
}
}
//'#' stops reading from sd to the buffer prematurely, so procedural macro calls are possible
//'#' stops reading from sd to the buffer prematurely, so procedural macro calls are possible
// if it occures, stop_buffering is triggered and the buffer is ran dry.
// if it occures, stop_buffering is triggered and the buffer is ran dry.
// this character _can_ occure in serial com, due to checksums. however, no checksums are used in sd printing
// this character _can_ occure in serial com, due to checksums. however, no checksums are used in sd printing
static bool stop_buffering = false ;
static bool stop_buffering = false ;
if ( buflen = = 0 ) stop_buffering = false ;
if ( buflen = = 0 ) stop_buffering = false ;
while ( ! card . eof ( ) & & buflen < BUFSIZE & & ! stop_buffering ) {
while ( ! card . eof ( ) & & buflen < BUFSIZE & & ! stop_buffering ) {
int16_t n = card . get ( ) ;
int16_t n = card . get ( ) ;
serial_char = ( char ) n ;
serial_char = ( char ) n ;
if ( serial_char = = ' \n ' | |
if ( serial_char = = ' \n ' | |
serial_char = = ' \r ' | |
serial_char = = ' \r ' | |
( serial_char = = ' # ' & & comment_mode = = false ) | |
( serial_char = = ' # ' & & comment_mode = = false ) | |
@ -674,7 +678,7 @@ void get_command()
}
}
if ( serial_char = = ' # ' )
if ( serial_char = = ' # ' )
stop_buffering = true ;
stop_buffering = true ;
if ( ! serial_count )
if ( ! serial_count )
{
{
comment_mode = false ; //for new command
comment_mode = false ; //for new command
@ -746,13 +750,13 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
# endif
# endif
# if X_HOME_DIR != -1 || X2_HOME_DIR != 1
# if X_HOME_DIR != -1 || X2_HOME_DIR != 1
# error "Please use canonical x-carriage assignment" // the x-carriages are defined by their homing directions
# error "Please use canonical x-carriage assignment" // the x-carriages are defined by their homing directions
# endif
# endif
# define DXC_FULL_CONTROL_MODE 0
# define DXC_FULL_CONTROL_MODE 0
# define DXC_AUTO_PARK_MODE 1
# define DXC_AUTO_PARK_MODE 1
# define DXC_DUPLICATION_MODE 2
# define DXC_DUPLICATION_MODE 2
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE ;
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE ;
static float x_home_pos ( int extruder ) {
static float x_home_pos ( int extruder ) {
if ( extruder = = 0 )
if ( extruder = = 0 )
return base_home_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ;
return base_home_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ;
@ -770,12 +774,12 @@ static int x_home_dir(int extruder) {
static float inactive_extruder_x_pos = X2_MAX_POS ; // used in mode 0 & 1
static float inactive_extruder_x_pos = X2_MAX_POS ; // used in mode 0 & 1
static bool active_extruder_parked = false ; // used in mode 1 & 2
static bool active_extruder_parked = false ; // used in mode 1 & 2
static float raised_parked_position [ NUM_AXIS ] ; // used in mode 1
static float raised_parked_position [ NUM_AXIS ] ; // used in mode 1
static unsigned long delayed_move_time = 0 ; // used in mode 1
static unsigned long delayed_move_time = 0 ; // used in mode 1
static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET ; // used in mode 2
static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET ; // used in mode 2
static float duplicate_extruder_temp_offset = 0 ; // used in mode 2
static float duplicate_extruder_temp_offset = 0 ; // used in mode 2
bool extruder_duplication_enabled = false ; // used in mode 2
bool extruder_duplication_enabled = false ; // used in mode 2
# endif //DUAL_X_CARRIAGE
# endif //DUAL_X_CARRIAGE
static void axis_is_at_home ( int axis ) {
static void axis_is_at_home ( int axis ) {
# ifdef DUAL_X_CARRIAGE
# ifdef DUAL_X_CARRIAGE
@ -788,8 +792,8 @@ static void axis_is_at_home(int axis) {
}
}
else if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & active_extruder = = 0 ) {
else if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & active_extruder = = 0 ) {
current_position [ X_AXIS ] = base_home_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ;
current_position [ X_AXIS ] = base_home_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ;
min_pos [ X_AXIS ] = base_min_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ;
min_pos [ X_AXIS ] = base_min_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ;
max_pos [ X_AXIS ] = min ( base_max_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ,
max_pos [ X_AXIS ] = min ( base_max_pos ( X_AXIS ) + add_homeing [ X_AXIS ] ,
max ( extruder_offset [ X_AXIS ] [ 1 ] , X2_MAX_POS ) - duplicate_extruder_x_offset ) ;
max ( extruder_offset [ X_AXIS ] [ 1 ] , X2_MAX_POS ) - duplicate_extruder_x_offset ) ;
return ;
return ;
}
}
@ -881,7 +885,7 @@ static void run_z_probe() {
st_synchronize ( ) ;
st_synchronize ( ) ;
// move back down slowly to find bed
// move back down slowly to find bed
feedrate = homing_feedrate [ Z_AXIS ] / 4 ;
feedrate = homing_feedrate [ Z_AXIS ] / 4 ;
zPosition - = home_retract_mm ( Z_AXIS ) * 2 ;
zPosition - = home_retract_mm ( Z_AXIS ) * 2 ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , zPosition , current_position [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , zPosition , current_position [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
st_synchronize ( ) ;
st_synchronize ( ) ;
@ -978,7 +982,7 @@ static void homeaxis(int axis) {
current_position [ axis ] = 0 ;
current_position [ axis ] = 0 ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
// Engage Servo endstop if enabled
// Engage Servo endstop if enabled
# ifdef SERVO_ENDSTOPS
# ifdef SERVO_ENDSTOPS
@ -1036,7 +1040,7 @@ static void homeaxis(int axis) {
# if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
# if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
if ( axis = = Z_AXIS ) retract_z_probe ( ) ;
if ( axis = = Z_AXIS ) retract_z_probe ( ) ;
# endif
# endif
}
}
}
}
# define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS)
# define HOMEAXIS(LETTER) homeaxis(LETTER##_AXIS)
@ -1110,7 +1114,7 @@ void process_commands()
destination [ Y_AXIS ] = current_position [ Y_AXIS ] ;
destination [ Y_AXIS ] = current_position [ Y_AXIS ] ;
destination [ Z_AXIS ] = current_position [ Z_AXIS ] ;
destination [ Z_AXIS ] = current_position [ Z_AXIS ] ;
current_position [ Z_AXIS ] + = retract_zlift ;
current_position [ Z_AXIS ] + = retract_zlift ;
destination [ E_AXIS ] = current_position [ E_AXIS ] + retract_length + retract_recover_length ;
destination [ E_AXIS ] = current_position [ E_AXIS ] + retract_length + retract_recover_length ;
feedrate = retract_recover_feedrate ;
feedrate = retract_recover_feedrate ;
retracted = false ;
retracted = false ;
prepare_move ( ) ;
prepare_move ( ) ;
@ -1224,10 +1228,10 @@ void process_commands()
// reset state used by the different modes
// reset state used by the different modes
memcpy ( raised_parked_position , current_position , sizeof ( raised_parked_position ) ) ;
memcpy ( raised_parked_position , current_position , sizeof ( raised_parked_position ) ) ;
delayed_move_time = 0 ;
delayed_move_time = 0 ;
active_extruder_parked = true ;
active_extruder_parked = true ;
# else
# else
HOMEAXIS ( X ) ;
HOMEAXIS ( X ) ;
# endif
# endif
}
}
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Y_AXIS ] ) ) ) {
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Y_AXIS ] ) ) ) {
@ -1246,7 +1250,7 @@ void process_commands()
current_position [ Y_AXIS ] = code_value ( ) + add_homeing [ 1 ] ;
current_position [ Y_AXIS ] = code_value ( ) + add_homeing [ 1 ] ;
}
}
}
}
# if Z_HOME_DIR < 0 // If homing towards BED do Z last
# if Z_HOME_DIR < 0 // If homing towards BED do Z last
# ifndef Z_SAFE_HOMING
# ifndef Z_SAFE_HOMING
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Z_AXIS ] ) ) ) {
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Z_AXIS ] ) ) ) {
@ -1258,14 +1262,14 @@ void process_commands()
# endif
# endif
HOMEAXIS ( Z ) ;
HOMEAXIS ( Z ) ;
}
}
# else // Z Safe mode activated.
# else // Z Safe mode activated.
if ( home_all_axis ) {
if ( home_all_axis ) {
destination [ X_AXIS ] = round ( Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER ) ;
destination [ X_AXIS ] = round ( Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER ) ;
destination [ Y_AXIS ] = round ( Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER ) ;
destination [ Y_AXIS ] = round ( Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER ) ;
destination [ Z_AXIS ] = Z_RAISE_BEFORE_HOMING * home_dir ( Z_AXIS ) * ( - 1 ) ; // Set destination away from bed
destination [ Z_AXIS ] = Z_RAISE_BEFORE_HOMING * home_dir ( Z_AXIS ) * ( - 1 ) ; // Set destination away from bed
feedrate = XY_TRAVEL_SPEED ;
feedrate = XY_TRAVEL_SPEED ;
current_position [ Z_AXIS ] = 0 ;
current_position [ Z_AXIS ] = 0 ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate , active_extruder ) ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate , active_extruder ) ;
st_synchronize ( ) ;
st_synchronize ( ) ;
@ -1283,7 +1287,7 @@ void process_commands()
& & ( current_position [ Y_AXIS ] + Y_PROBE_OFFSET_FROM_EXTRUDER < = Y_MAX_POS ) ) {
& & ( current_position [ Y_AXIS ] + Y_PROBE_OFFSET_FROM_EXTRUDER < = Y_MAX_POS ) ) {
current_position [ Z_AXIS ] = 0 ;
current_position [ Z_AXIS ] = 0 ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
destination [ Z_AXIS ] = Z_RAISE_BEFORE_HOMING * home_dir ( Z_AXIS ) * ( - 1 ) ; // Set destination away from bed
destination [ Z_AXIS ] = Z_RAISE_BEFORE_HOMING * home_dir ( Z_AXIS ) * ( - 1 ) ; // Set destination away from bed
feedrate = max_feedrate [ Z_AXIS ] ;
feedrate = max_feedrate [ Z_AXIS ] ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate , active_extruder ) ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate , active_extruder ) ;
@ -1303,8 +1307,8 @@ void process_commands()
# endif
# endif
# endif
# endif
if ( code_seen ( axis_codes [ Z_AXIS ] ) ) {
if ( code_seen ( axis_codes [ Z_AXIS ] ) ) {
if ( code_value_long ( ) ! = 0 ) {
if ( code_value_long ( ) ! = 0 ) {
current_position [ Z_AXIS ] = code_value ( ) + add_homeing [ 2 ] ;
current_position [ Z_AXIS ] = code_value ( ) + add_homeing [ 2 ] ;
@ -1467,7 +1471,7 @@ void process_commands()
run_z_probe ( ) ;
run_z_probe ( ) ;
float z_at_xLeft_yFront = current_position [ Z_AXIS ] ;
float z_at_xLeft_yFront = current_position [ Z_AXIS ] ;
retract_z_probe ( ) ;
retract_z_probe ( ) ;
SERIAL_PROTOCOLPGM ( " Bed x: " ) ;
SERIAL_PROTOCOLPGM ( " Bed x: " ) ;
SERIAL_PROTOCOL ( LEFT_PROBE_BED_POSITION ) ;
SERIAL_PROTOCOL ( LEFT_PROBE_BED_POSITION ) ;
SERIAL_PROTOCOLPGM ( " y: " ) ;
SERIAL_PROTOCOLPGM ( " y: " ) ;
@ -1485,7 +1489,7 @@ void process_commands()
run_z_probe ( ) ;
run_z_probe ( ) ;
float z_at_xRight_yFront = current_position [ Z_AXIS ] ;
float z_at_xRight_yFront = current_position [ Z_AXIS ] ;
retract_z_probe ( ) ; // Retract Z Servo endstop if available
retract_z_probe ( ) ; // Retract Z Servo endstop if available
SERIAL_PROTOCOLPGM ( " Bed x: " ) ;
SERIAL_PROTOCOLPGM ( " Bed x: " ) ;
SERIAL_PROTOCOL ( RIGHT_PROBE_BED_POSITION ) ;
SERIAL_PROTOCOL ( RIGHT_PROBE_BED_POSITION ) ;
SERIAL_PROTOCOLPGM ( " y: " ) ;
SERIAL_PROTOCOLPGM ( " y: " ) ;
@ -1500,10 +1504,10 @@ void process_commands()
# endif // ACCURATE_BED_LEVELING
# endif // ACCURATE_BED_LEVELING
st_synchronize ( ) ;
st_synchronize ( ) ;
// The following code correct the Z height difference from z-probe position and hotend tip position.
// The following code correct the Z height difference from z-probe position and hotend tip position.
// The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
// The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
// When the bed is uneven, this height must be corrected.
// When the bed is uneven, this height must be corrected.
real_z = float ( st_get_position ( Z_AXIS ) ) / axis_steps_per_unit [ Z_AXIS ] ; //get the real Z (since the auto bed leveling is already correcting the plane)
real_z = float ( st_get_position ( Z_AXIS ) ) / axis_steps_per_unit [ Z_AXIS ] ; //get the real Z (since the auto bed leveling is already correcting the plane)
x_tmp = current_position [ X_AXIS ] + X_PROBE_OFFSET_FROM_EXTRUDER ;
x_tmp = current_position [ X_AXIS ] + X_PROBE_OFFSET_FROM_EXTRUDER ;
@ -1515,11 +1519,11 @@ void process_commands()
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
}
}
break ;
break ;
case 30 : // G30 Single Z Probe
case 30 : // G30 Single Z Probe
{
{
engage_z_probe ( ) ; // Engage Z Servo endstop if available
engage_z_probe ( ) ; // Engage Z Servo endstop if available
st_synchronize ( ) ;
st_synchronize ( ) ;
// TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
// TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
setup_for_endstop_move ( ) ;
setup_for_endstop_move ( ) ;
@ -1670,14 +1674,14 @@ void process_commands()
card . removeFile ( strchr_pointer + 4 ) ;
card . removeFile ( strchr_pointer + 4 ) ;
}
}
break ;
break ;
case 32 : //M32 - Select file and start SD print
case 32 : //M32 - Select file and start SD print
{
{
if ( card . sdprinting ) {
if ( card . sdprinting ) {
st_synchronize ( ) ;
st_synchronize ( ) ;
}
}
starpos = ( strchr ( strchr_pointer + 4 , ' * ' ) ) ;
starpos = ( strchr ( strchr_pointer + 4 , ' * ' ) ) ;
char * namestartpos = ( strchr ( strchr_pointer + 4 , ' ! ' ) ) ; //find ! to indicate filename string start.
char * namestartpos = ( strchr ( strchr_pointer + 4 , ' ! ' ) ) ; //find ! to indicate filename string start.
if ( namestartpos = = NULL )
if ( namestartpos = = NULL )
{
{
@ -1685,16 +1689,16 @@ void process_commands()
}
}
else
else
namestartpos + + ; //to skip the '!'
namestartpos + + ; //to skip the '!'
if ( starpos ! = NULL )
if ( starpos ! = NULL )
* ( starpos - 1 ) = ' \0 ' ;
* ( starpos - 1 ) = ' \0 ' ;
bool call_procedure = ( code_seen ( ' P ' ) ) ;
bool call_procedure = ( code_seen ( ' P ' ) ) ;
if ( strchr_pointer > namestartpos )
if ( strchr_pointer > namestartpos )
call_procedure = false ; //false alert, 'P' found within filename
call_procedure = false ; //false alert, 'P' found within filename
if ( card . cardOK )
if ( card . cardOK )
{
{
card . openFile ( namestartpos , true , ! call_procedure ) ;
card . openFile ( namestartpos , true , ! call_procedure ) ;
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
@ -1767,7 +1771,7 @@ void process_commands()
# ifdef DUAL_X_CARRIAGE
# ifdef DUAL_X_CARRIAGE
if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & tmp_extruder = = 0 )
if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & tmp_extruder = = 0 )
setTargetHotend1 ( code_value ( ) = = 0.0 ? 0.0 : code_value ( ) + duplicate_extruder_temp_offset ) ;
setTargetHotend1 ( code_value ( ) = = 0.0 ? 0.0 : code_value ( ) + duplicate_extruder_temp_offset ) ;
# endif
# endif
setWatch ( ) ;
setWatch ( ) ;
break ;
break ;
case 140 : // M140 set bed temp
case 140 : // M140 set bed temp
@ -1823,7 +1827,7 @@ void process_commands()
SERIAL_PROTOCOL_F ( rawHotendTemp ( cur_extruder ) / OVERSAMPLENR , 0 ) ;
SERIAL_PROTOCOL_F ( rawHotendTemp ( cur_extruder ) / OVERSAMPLENR , 0 ) ;
}
}
# endif
# endif
SERIAL_PROTOCOLLN ( " " ) ;
SERIAL_PROTOCOLLN ( " " ) ;
return ;
return ;
break ;
break ;
@ -1841,14 +1845,14 @@ void process_commands()
# ifdef DUAL_X_CARRIAGE
# ifdef DUAL_X_CARRIAGE
if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & tmp_extruder = = 0 )
if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & tmp_extruder = = 0 )
setTargetHotend1 ( code_value ( ) = = 0.0 ? 0.0 : code_value ( ) + duplicate_extruder_temp_offset ) ;
setTargetHotend1 ( code_value ( ) = = 0.0 ? 0.0 : code_value ( ) + duplicate_extruder_temp_offset ) ;
# endif
# endif
CooldownNoWait = true ;
CooldownNoWait = true ;
} else if ( code_seen ( ' R ' ) ) {
} else if ( code_seen ( ' R ' ) ) {
setTargetHotend ( code_value ( ) , tmp_extruder ) ;
setTargetHotend ( code_value ( ) , tmp_extruder ) ;
# ifdef DUAL_X_CARRIAGE
# ifdef DUAL_X_CARRIAGE
if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & tmp_extruder = = 0 )
if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE & & tmp_extruder = = 0 )
setTargetHotend1 ( code_value ( ) = = 0.0 ? 0.0 : code_value ( ) + duplicate_extruder_temp_offset ) ;
setTargetHotend1 ( code_value ( ) = = 0.0 ? 0.0 : code_value ( ) + duplicate_extruder_temp_offset ) ;
# endif
# endif
CooldownNoWait = false ;
CooldownNoWait = false ;
}
}
# ifdef AUTOTEMP
# ifdef AUTOTEMP
@ -2012,7 +2016,7 @@ void process_commands()
SET_OUTPUT ( SUICIDE_PIN ) ;
SET_OUTPUT ( SUICIDE_PIN ) ;
WRITE ( SUICIDE_PIN , HIGH ) ;
WRITE ( SUICIDE_PIN , HIGH ) ;
# endif
# endif
# ifdef ULTIPANEL
# ifdef ULTIPANEL
powersupply = true ;
powersupply = true ;
LCD_MESSAGEPGM ( WELCOME_MSG ) ;
LCD_MESSAGEPGM ( WELCOME_MSG ) ;
@ -2169,18 +2173,18 @@ void process_commands()
# endif
# endif
break ;
break ;
//TODO: update for all axis, use for loop
//TODO: update for all axis, use for loop
# ifdef BLINKM
# ifdef BLINKM
case 150 : // M150
case 150 : // M150
{
{
byte red ;
byte red ;
byte grn ;
byte grn ;
byte blu ;
byte blu ;
if ( code_seen ( ' R ' ) ) red = code_value ( ) ;
if ( code_seen ( ' R ' ) ) red = code_value ( ) ;
if ( code_seen ( ' U ' ) ) grn = code_value ( ) ;
if ( code_seen ( ' U ' ) ) grn = code_value ( ) ;
if ( code_seen ( ' B ' ) ) blu = code_value ( ) ;
if ( code_seen ( ' B ' ) ) blu = code_value ( ) ;
SendColors ( red , grn , blu ) ;
SendColors ( red , grn , blu ) ;
}
}
break ;
break ;
# endif //BLINKM
# endif //BLINKM
@ -2302,7 +2306,7 @@ void process_commands()
{
{
extruder_offset [ Z_AXIS ] [ tmp_extruder ] = code_value ( ) ;
extruder_offset [ Z_AXIS ] [ tmp_extruder ] = code_value ( ) ;
}
}
# endif
# endif
SERIAL_ECHO_START ;
SERIAL_ECHO_START ;
SERIAL_ECHOPGM ( MSG_HOTEND_OFFSET ) ;
SERIAL_ECHOPGM ( MSG_HOTEND_OFFSET ) ;
for ( tmp_extruder = 0 ; tmp_extruder < EXTRUDERS ; tmp_extruder + + )
for ( tmp_extruder = 0 ; tmp_extruder < EXTRUDERS ; tmp_extruder + + )
@ -2335,17 +2339,17 @@ void process_commands()
}
}
}
}
break ;
break ;
case 226 : // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required
case 226 : // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required
{
{
if ( code_seen ( ' P ' ) ) {
if ( code_seen ( ' P ' ) ) {
int pin_number = code_value ( ) ; // pin number
int pin_number = code_value ( ) ; // pin number
int pin_state = - 1 ; // required pin state - default is inverted
int pin_state = - 1 ; // required pin state - default is inverted
if ( code_seen ( ' S ' ) ) pin_state = code_value ( ) ; // required pin state
if ( code_seen ( ' S ' ) ) pin_state = code_value ( ) ; // required pin state
if ( pin_state > = - 1 & & pin_state < = 1 ) {
if ( pin_state > = - 1 & & pin_state < = 1 ) {
for ( int8_t i = 0 ; i < ( int8_t ) sizeof ( sensitive_pins ) ; i + + )
for ( int8_t i = 0 ; i < ( int8_t ) sizeof ( sensitive_pins ) ; i + + )
{
{
if ( sensitive_pins [ i ] = = pin_number )
if ( sensitive_pins [ i ] = = pin_number )
@ -2354,28 +2358,28 @@ void process_commands()
break ;
break ;
}
}
}
}
if ( pin_number > - 1 )
if ( pin_number > - 1 )
{
{
st_synchronize ( ) ;
st_synchronize ( ) ;
pinMode ( pin_number , INPUT ) ;
pinMode ( pin_number , INPUT ) ;
int target ;
int target ;
switch ( pin_state ) {
switch ( pin_state ) {
case 1 :
case 1 :
target = HIGH ;
target = HIGH ;
break ;
break ;
case 0 :
case 0 :
target = LOW ;
target = LOW ;
break ;
break ;
case - 1 :
case - 1 :
target = ! digitalRead ( pin_number ) ;
target = ! digitalRead ( pin_number ) ;
break ;
break ;
}
}
while ( digitalRead ( pin_number ) ! = target ) {
while ( digitalRead ( pin_number ) ! = target ) {
manage_heater ( ) ;
manage_heater ( ) ;
manage_inactivity ( ) ;
manage_inactivity ( ) ;
@ -2385,7 +2389,7 @@ void process_commands()
}
}
}
}
}
}
break ;
break ;
# if NUM_SERVOS > 0
# if NUM_SERVOS > 0
case 280 : // M280 - set servo position absolute. P: servo index, S: angle or microseconds
case 280 : // M280 - set servo position absolute. P: servo index, S: angle or microseconds
@ -2561,13 +2565,13 @@ void process_commands()
engage_z_probe ( ) ; // Engage Z Servo endstop if available
engage_z_probe ( ) ; // Engage Z Servo endstop if available
}
}
break ;
break ;
case 402 :
case 402 :
{
{
retract_z_probe ( ) ; // Retract Z Servo endstop if enabled
retract_z_probe ( ) ; // Retract Z Servo endstop if enabled
}
}
break ;
break ;
# endif
# endif
case 500 : // M500 Store settings in EEPROM
case 500 : // M500 Store settings in EEPROM
{
{
Config_StoreSettings ( ) ;
Config_StoreSettings ( ) ;
@ -2725,14 +2729,14 @@ void process_commands()
// M605 S0: Full control mode. The slicer has full control over x-carriage movement
// M605 S0: Full control mode. The slicer has full control over x-carriage movement
// M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement
// M605 S1: Auto-park mode. The inactive head will auto park/unpark without slicer involvement
// M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn
// M605 S2 [Xnnn] [Rmmm]: Duplication mode. The second extruder will duplicate the first with nnn
// millimeters x-offset and an optional differential hotend temperature of
// millimeters x-offset and an optional differential hotend temperature of
// mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate
// mmm degrees. E.g., with "M605 S2 X100 R2" the second extruder will duplicate
// the first with a spacing of 100mm in the x direction and 2 degrees hotter.
// the first with a spacing of 100mm in the x direction and 2 degrees hotter.
//
//
// Note: the X axis should be homed after changing dual x-carriage mode.
// Note: the X axis should be homed after changing dual x-carriage mode.
{
{
st_synchronize ( ) ;
st_synchronize ( ) ;
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
dual_x_carriage_mode = code_value ( ) ;
dual_x_carriage_mode = code_value ( ) ;
@ -2743,7 +2747,7 @@ void process_commands()
if ( code_seen ( ' R ' ) )
if ( code_seen ( ' R ' ) )
duplicate_extruder_temp_offset = code_value ( ) ;
duplicate_extruder_temp_offset = code_value ( ) ;
SERIAL_ECHO_START ;
SERIAL_ECHO_START ;
SERIAL_ECHOPGM ( MSG_HOTEND_OFFSET ) ;
SERIAL_ECHOPGM ( MSG_HOTEND_OFFSET ) ;
SERIAL_ECHO ( " " ) ;
SERIAL_ECHO ( " " ) ;
@ -2759,13 +2763,13 @@ void process_commands()
{
{
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE ;
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE ;
}
}
active_extruder_parked = false ;
active_extruder_parked = false ;
extruder_duplication_enabled = false ;
extruder_duplication_enabled = false ;
delayed_move_time = 0 ;
delayed_move_time = 0 ;
}
}
break ;
break ;
# endif //DUAL_X_CARRIAGE
# endif //DUAL_X_CARRIAGE
case 907 : // M907 Set digital trimpot motor current using axis codes.
case 907 : // M907 Set digital trimpot motor current using axis codes.
{
{
@ -2846,19 +2850,19 @@ void process_commands()
// Save current position to return to after applying extruder offset
// Save current position to return to after applying extruder offset
memcpy ( destination , current_position , sizeof ( destination ) ) ;
memcpy ( destination , current_position , sizeof ( destination ) ) ;
# ifdef DUAL_X_CARRIAGE
# ifdef DUAL_X_CARRIAGE
if ( dual_x_carriage_mode = = DXC_AUTO_PARK_MODE & & Stopped = = false & &
if ( dual_x_carriage_mode = = DXC_AUTO_PARK_MODE & & Stopped = = false & &
( delayed_move_time ! = 0 | | current_position [ X_AXIS ] ! = x_home_pos ( active_extruder ) ) )
( delayed_move_time ! = 0 | | current_position [ X_AXIS ] ! = x_home_pos ( active_extruder ) ) )
{
{
// Park old head: 1) raise 2) move to park position 3) lower
// Park old head: 1) raise 2) move to park position 3) lower
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] + TOOLCHANGE_PARK_ZLIFT ,
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] + TOOLCHANGE_PARK_ZLIFT ,
current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
plan_buffer_line ( x_home_pos ( active_extruder ) , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] + TOOLCHANGE_PARK_ZLIFT ,
plan_buffer_line ( x_home_pos ( active_extruder ) , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] + TOOLCHANGE_PARK_ZLIFT ,
current_position [ E_AXIS ] , max_feedrate [ X_AXIS ] , active_extruder ) ;
current_position [ E_AXIS ] , max_feedrate [ X_AXIS ] , active_extruder ) ;
plan_buffer_line ( x_home_pos ( active_extruder ) , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
plan_buffer_line ( x_home_pos ( active_extruder ) , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
st_synchronize ( ) ;
st_synchronize ( ) ;
}
}
// apply Y & Z extruder offset (x offset is already used in determining home pos)
// apply Y & Z extruder offset (x offset is already used in determining home pos)
current_position [ Y_AXIS ] = current_position [ Y_AXIS ] -
current_position [ Y_AXIS ] = current_position [ Y_AXIS ] -
extruder_offset [ Y_AXIS ] [ active_extruder ] +
extruder_offset [ Y_AXIS ] [ active_extruder ] +
@ -2866,7 +2870,7 @@ void process_commands()
current_position [ Z_AXIS ] = current_position [ Z_AXIS ] -
current_position [ Z_AXIS ] = current_position [ Z_AXIS ] -
extruder_offset [ Z_AXIS ] [ active_extruder ] +
extruder_offset [ Z_AXIS ] [ active_extruder ] +
extruder_offset [ Z_AXIS ] [ tmp_extruder ] ;
extruder_offset [ Z_AXIS ] [ tmp_extruder ] ;
active_extruder = tmp_extruder ;
active_extruder = tmp_extruder ;
// This function resets the max/min values - the current position may be overwritten below.
// This function resets the max/min values - the current position may be overwritten below.
@ -2874,18 +2878,18 @@ void process_commands()
if ( dual_x_carriage_mode = = DXC_FULL_CONTROL_MODE )
if ( dual_x_carriage_mode = = DXC_FULL_CONTROL_MODE )
{
{
current_position [ X_AXIS ] = inactive_extruder_x_pos ;
current_position [ X_AXIS ] = inactive_extruder_x_pos ;
inactive_extruder_x_pos = destination [ X_AXIS ] ;
inactive_extruder_x_pos = destination [ X_AXIS ] ;
}
}
else if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE )
else if ( dual_x_carriage_mode = = DXC_DUPLICATION_MODE )
{
{
active_extruder_parked = ( active_extruder = = 0 ) ; // this triggers the second extruder to move into the duplication position
active_extruder_parked = ( active_extruder = = 0 ) ; // this triggers the second extruder to move into the duplication position
if ( active_extruder = = 0 | | active_extruder_parked )
if ( active_extruder = = 0 | | active_extruder_parked )
current_position [ X_AXIS ] = inactive_extruder_x_pos ;
current_position [ X_AXIS ] = inactive_extruder_x_pos ;
else
else
current_position [ X_AXIS ] = destination [ X_AXIS ] + duplicate_extruder_x_offset ;
current_position [ X_AXIS ] = destination [ X_AXIS ] + duplicate_extruder_x_offset ;
inactive_extruder_x_pos = destination [ X_AXIS ] ;
inactive_extruder_x_pos = destination [ X_AXIS ] ;
extruder_duplication_enabled = false ;
extruder_duplication_enabled = false ;
}
}
else
else
{
{
@ -2895,7 +2899,7 @@ void process_commands()
active_extruder_parked = true ;
active_extruder_parked = true ;
delayed_move_time = 0 ;
delayed_move_time = 0 ;
}
}
# else
# else
// Offset extruder (only by XY)
// Offset extruder (only by XY)
int i ;
int i ;
for ( i = 0 ; i < 2 ; i + + ) {
for ( i = 0 ; i < 2 ; i + + ) {
@ -3108,13 +3112,13 @@ void prepare_move()
{
{
// move duplicate extruder into correct duplication position.
// move duplicate extruder into correct duplication position.
plan_set_position ( inactive_extruder_x_pos , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( inactive_extruder_x_pos , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_buffer_line ( current_position [ X_AXIS ] + duplicate_extruder_x_offset , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
plan_buffer_line ( current_position [ X_AXIS ] + duplicate_extruder_x_offset , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
current_position [ E_AXIS ] , max_feedrate [ X_AXIS ] , 1 ) ;
current_position [ E_AXIS ] , max_feedrate [ X_AXIS ] , 1 ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
st_synchronize ( ) ;
st_synchronize ( ) ;
extruder_duplication_enabled = true ;
extruder_duplication_enabled = true ;
active_extruder_parked = false ;
active_extruder_parked = false ;
}
}
else if ( dual_x_carriage_mode = = DXC_AUTO_PARK_MODE ) // handle unparking of head
else if ( dual_x_carriage_mode = = DXC_AUTO_PARK_MODE ) // handle unparking of head
{
{
if ( current_position [ E_AXIS ] = = destination [ E_AXIS ] )
if ( current_position [ E_AXIS ] = = destination [ E_AXIS ] )
@ -3123,7 +3127,7 @@ void prepare_move()
// be used as start of first non-travel move)
// be used as start of first non-travel move)
if ( delayed_move_time ! = 0xFFFFFFFFUL )
if ( delayed_move_time ! = 0xFFFFFFFFUL )
{
{
memcpy ( current_position , destination , sizeof ( current_position ) ) ;
memcpy ( current_position , destination , sizeof ( current_position ) ) ;
if ( destination [ Z_AXIS ] > raised_parked_position [ Z_AXIS ] )
if ( destination [ Z_AXIS ] > raised_parked_position [ Z_AXIS ] )
raised_parked_position [ Z_AXIS ] = destination [ Z_AXIS ] ;
raised_parked_position [ Z_AXIS ] = destination [ Z_AXIS ] ;
delayed_move_time = millis ( ) ;
delayed_move_time = millis ( ) ;
@ -3133,9 +3137,9 @@ void prepare_move()
delayed_move_time = 0 ;
delayed_move_time = 0 ;
// unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
// unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
plan_buffer_line ( raised_parked_position [ X_AXIS ] , raised_parked_position [ Y_AXIS ] , raised_parked_position [ Z_AXIS ] , current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
plan_buffer_line ( raised_parked_position [ X_AXIS ] , raised_parked_position [ Y_AXIS ] , raised_parked_position [ Z_AXIS ] , current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , raised_parked_position [ Z_AXIS ] ,
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , raised_parked_position [ Z_AXIS ] ,
current_position [ E_AXIS ] , min ( max_feedrate [ X_AXIS ] , max_feedrate [ Y_AXIS ] ) , active_extruder ) ;
current_position [ E_AXIS ] , min ( max_feedrate [ X_AXIS ] , max_feedrate [ Y_AXIS ] ) , active_extruder ) ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
current_position [ E_AXIS ] , max_feedrate [ Z_AXIS ] , active_extruder ) ;
active_extruder_parked = false ;
active_extruder_parked = false ;
}
}
@ -3301,7 +3305,7 @@ void manage_inactivity()
// travel moves have been received so enact them
// travel moves have been received so enact them
delayed_move_time = 0xFFFFFFFFUL ; // force moves to be done
delayed_move_time = 0xFFFFFFFFUL ; // force moves to be done
memcpy ( destination , current_position , sizeof ( destination ) ) ;
memcpy ( destination , current_position , sizeof ( destination ) ) ;
prepare_move ( ) ;
prepare_move ( ) ;
}
}
# endif
# endif
# ifdef TEMP_STAT_LEDS
# ifdef TEMP_STAT_LEDS