@ -1,30 +1,30 @@
/* -*- c++ -*- */
/* *
* Marlin Firmware
/*
*
Reprap firmware b ased on Sprinter and grbl .
* B ased on Sprinter and grbl .
Copyright ( C ) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright ( C ) 2011 Camiel Gubbels / Erik van der Zalm
*
This program is free software : you can redistribute it and / or modify
* This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
* the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
* ( at your option ) any later version .
*
This program is distributed in the hope that it will be useful ,
* This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
* GNU General Public License for more details .
*
You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
*
* About Marlin
/*
*
This firmware is a mashup between Sprinter and grbl .
* This firmware is a mashup between Sprinter and grbl .
( https : //github.com/kliment/Sprinter )
* - https : //github.com/kliment/Sprinter
( https : //github.com/simen/grbl/tree )
* - https : //github.com/simen/grbl/tree
*
It has preliminary support for Matthew Roberts advance algorithm
* It has preliminary support for Matthew Roberts advance algorithm
http : //reprap.org/pipermail/reprap-dev/2011-May/003323.html
* - http : //reprap.org/pipermail/reprap-dev/2011-May/003323.html
*/
*/
# include "Marlin.h"
# include "Marlin.h"
@ -73,13 +73,12 @@
* - http : //objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
* - http : //objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
*
*
* Help us document these G - codes online :
* Help us document these G - codes online :
* - http : //www.marlinfirmware.org/index.php/G-Code
* - http : //reprap.org/wiki/G-code
* - http : //reprap.org/wiki/G-code
* - https : //github.com/MarlinFirmware/Marlin/wiki/Marlin-G-Code
*
*/
* - - - - - - - - - - - - - - - - -
/**
* Implemented Codes
* Implemented Codes
* - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - -
*
*
* " G " Codes
* " G " Codes
*
*
@ -163,7 +162,7 @@
* 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
* 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
* 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
* 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 ]
* M208 - Set recover = unretract length S [ positive mm surplus to the M207 S * ] F [ feedrate mm / min ]
* 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 .
* 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 >
* 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 >
* M220 - Set speed factor override percentage : S < factor in percent >
@ -215,6 +214,11 @@
*
*
* M928 - Start SD logging ( M928 filename . g ) - ended by M29
* M928 - Start SD logging ( M928 filename . g ) - ended by M29
* M999 - Restart after being stopped by error
* M999 - Restart after being stopped by error
*
* " T " Codes
*
* T0 - T3 - Select a tool by index ( usually an extruder ) [ F < mm / min > ]
*
*/
*/
# ifdef SDSUPPORT
# ifdef SDSUPPORT
@ -993,7 +997,7 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
# endif //DUAL_X_CARRIAGE
# endif //DUAL_X_CARRIAGE
static void axis_is_at_home ( int axis ) {
static void axis_is_at_home ( AxisEnum axis ) {
# ifdef DUAL_X_CARRIAGE
# ifdef DUAL_X_CARRIAGE
if ( axis = = X_AXIS ) {
if ( axis = = X_AXIS ) {
@ -1198,12 +1202,12 @@ static void setup_for_endstop_move() {
plan_bed_level_matrix . set_to_identity ( ) ;
plan_bed_level_matrix . set_to_identity ( ) ;
feedrate = homing_feedrate [ Z_AXIS ] ;
feedrate = homing_feedrate [ Z_AXIS ] ;
// move down until you find the b ed
// Move down until the probe (or endstop?) is trigger ed
float zPosition = - 10 ;
float zPosition = - 10 ;
line_to_z ( zPosition ) ;
line_to_z ( zPosition ) ;
st_synchronize ( ) ;
st_synchronize ( ) ;
// we have to let the planner know where we are right now as it is not where we said to go.
// Tell the planner where we ended up - Get this from the stepper handler
zPosition = st_get_position_mm ( Z_AXIS ) ;
zPosition = st_get_position_mm ( Z_AXIS ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , zPosition , current_position [ E_AXIS ] ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , zPosition , current_position [ E_AXIS ] ) ;
@ -1406,7 +1410,7 @@ static void setup_for_endstop_move() {
Stop ( ) ;
Stop ( ) ;
}
}
# endif
# endif // Z_PROBE_ALLEN_KEY
}
}
@ -1418,32 +1422,31 @@ static void setup_for_endstop_move() {
} ;
} ;
// Probe bed height at position (x,y), returns the measured z value
// Probe bed height at position (x,y), returns the measured z value
static float probe_pt ( float x , float y , float z_before , ProbeAction retract _action= ProbeDeployAndStow , int verbose_level = 1 ) {
static float probe_pt ( float x , float y , float z_before , ProbeAction p rob e_action= ProbeDeployAndStow , int verbose_level = 1 ) {
// move to right place
// move to right place
do_blocking_move_to ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , z_before ) ; // this also updates current_position
do_blocking_move_to ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , z_before ) ; // this also updates current_position
do_blocking_move_to ( x - X_PROBE_OFFSET_FROM_EXTRUDER , y - Y_PROBE_OFFSET_FROM_EXTRUDER , current_position [ Z_AXIS ] ) ; // this also updates current_position
do_blocking_move_to ( x - X_PROBE_OFFSET_FROM_EXTRUDER , y - Y_PROBE_OFFSET_FROM_EXTRUDER , current_position [ Z_AXIS ] ) ; // this also updates current_position
# if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
# if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
if ( retract _action & ProbeDeploy ) deploy_z_probe ( ) ;
if ( p rob e_action & ProbeDeploy ) deploy_z_probe ( ) ;
# endif
# endif
run_z_probe ( ) ;
run_z_probe ( ) ;
float measured_z = current_position [ Z_AXIS ] ;
float measured_z = current_position [ Z_AXIS ] ;
# if Z_RAISE_BETWEEN_PROBINGS > 0
# if Z_RAISE_BETWEEN_PROBINGS > 0
if ( retract _action = = ProbeStay ) {
if ( p rob e_action = = ProbeStay ) {
do_blocking_move_to ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] + Z_RAISE_BETWEEN_PROBINGS ) ; // this also updates current_position
do_blocking_move_to ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] + Z_RAISE_BETWEEN_PROBINGS ) ; // this also updates current_position
st_synchronize ( ) ;
st_synchronize ( ) ;
}
}
# endif
# endif
# if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
# if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
if ( retract _action & ProbeStow ) stow_z_probe ( ) ;
if ( p rob e_action & ProbeStow ) stow_z_probe ( ) ;
# endif
# endif
if ( verbose_level > 2 ) {
if ( verbose_level > 2 ) {
SERIAL_PROTOCOLPGM ( " Bed " ) ;
SERIAL_PROTOCOLPGM ( " Bed X: " ) ;
SERIAL_PROTOCOLPGM ( " X: " ) ;
SERIAL_PROTOCOL_F ( x , 3 ) ;
SERIAL_PROTOCOL_F ( x , 3 ) ;
SERIAL_PROTOCOLPGM ( " Y: " ) ;
SERIAL_PROTOCOLPGM ( " Y: " ) ;
SERIAL_PROTOCOL_F ( y , 3 ) ;
SERIAL_PROTOCOL_F ( y , 3 ) ;
@ -1593,12 +1596,11 @@ static void homeaxis(AxisEnum axis) {
if ( axis = = Z_AXIS ) {
if ( axis = = Z_AXIS ) {
if ( axis_home_dir < 0 ) deploy_z_probe ( ) ;
if ( axis_home_dir < 0 ) deploy_z_probe ( ) ;
}
}
else
# endif
# endif
# ifdef SERVO_ENDSTOPS
# ifdef SERVO_ENDSTOPS
{
if ( axis ! = Z_AXIS ) {
// Engage Servo endstop if enabled
// Engage Servo endstop if enabled
if ( servo_endstops [ axis ] > - 1 )
if ( servo_endstops [ axis ] > - 1 )
servo [ servo_endstops [ axis ] ] . write ( servo_endstop_angles [ axis * 2 ] ) ;
servo [ servo_endstops [ axis ] ] . write ( servo_endstop_angles [ axis * 2 ] ) ;
@ -2763,8 +2765,8 @@ inline void gcode_G28() {
z_tmp = current_position [ Z_AXIS ] ,
z_tmp = current_position [ Z_AXIS ] ,
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)
apply_rotation_xyz ( plan_bed_level_matrix , x_tmp , y_tmp , z_tmp ) ; // Apply the correction sending the probe offset
apply_rotation_xyz ( plan_bed_level_matrix , x_tmp , y_tmp , z_tmp ) ; // Apply the correction sending the probe offset
current_position [ Z_AXIS ] = z_tmp - real_z + current_position [ Z_AXIS ] ; // The difference is added to current position and sent to planner.
current_position [ Z_AXIS ] + = z_tmp - real_z ; // The difference is added to current position and sent to planner.
sync_plan_position ( ) ;
sync_plan_position ( ) ;
}
}
# endif // !DELTA
# endif // !DELTA
@ -2792,8 +2794,7 @@ inline void gcode_G28() {
feedrate = homing_feedrate [ Z_AXIS ] ;
feedrate = homing_feedrate [ Z_AXIS ] ;
run_z_probe ( ) ;
run_z_probe ( ) ;
SERIAL_PROTOCOLPGM ( " Bed " ) ;
SERIAL_PROTOCOLPGM ( " Bed X: " ) ;
SERIAL_PROTOCOLPGM ( " X: " ) ;
SERIAL_PROTOCOL ( current_position [ X_AXIS ] + 0.0001 ) ;
SERIAL_PROTOCOL ( current_position [ X_AXIS ] + 0.0001 ) ;
SERIAL_PROTOCOLPGM ( " Y: " ) ;
SERIAL_PROTOCOLPGM ( " Y: " ) ;
SERIAL_PROTOCOL ( current_position [ Y_AXIS ] + 0.0001 ) ;
SERIAL_PROTOCOL ( current_position [ Y_AXIS ] + 0.0001 ) ;
@ -4624,7 +4625,7 @@ inline void gcode_M400() { st_synchronize(); }
stow_z_probe ( false ) ;
stow_z_probe ( false ) ;
}
}
# endif
# endif // ENABLE_AUTO_BED_LEVELING && (SERVO_ENDSTOPS || Z_PROBE_ALLEN_KEY) && !Z_PROBE_SLED
# ifdef FILAMENT_SENSOR
# ifdef FILAMENT_SENSOR
@ -4819,7 +4820,7 @@ inline void gcode_M503() {
if ( code_seen ( ' Z ' ) ) {
if ( code_seen ( ' Z ' ) ) {
value = code_value ( ) ;
value = code_value ( ) ;
if ( Z_PROBE_OFFSET_RANGE_MIN < = value & & value < = Z_PROBE_OFFSET_RANGE_MAX ) {
if ( Z_PROBE_OFFSET_RANGE_MIN < = value & & value < = Z_PROBE_OFFSET_RANGE_MAX ) {
zprobe_zoffset = - value ; // compare w/ line 278 of configuration_store.cpp
zprobe_zoffset = - value ;
SERIAL_ECHO_START ;
SERIAL_ECHO_START ;
SERIAL_ECHOLNPGM ( MSG_ZPROBE_ZOFFSET " " MSG_OK ) ;
SERIAL_ECHOLNPGM ( MSG_ZPROBE_ZOFFSET " " MSG_OK ) ;
SERIAL_EOL ;
SERIAL_EOL ;
@ -5074,9 +5075,11 @@ inline void gcode_M999() {
/**
/**
* T0 - T3 : Switch tool , usually switching extruders
* T0 - T3 : Switch tool , usually switching extruders
*
* F [ mm / min ] Set the movement feedrate
*/
*/
inline void gcode_T ( ) {
inline void gcode_T ( ) {
int tmp_extruder = code_value ( ) ;
u int16_ t tmp_extruder = code_value _short ( ) ;
if ( tmp_extruder > = EXTRUDERS ) {
if ( tmp_extruder > = EXTRUDERS ) {
SERIAL_ECHO_START ;
SERIAL_ECHO_START ;
SERIAL_CHAR ( ' T ' ) ;
SERIAL_CHAR ( ' T ' ) ;
@ -5589,14 +5592,14 @@ void process_next_command() {
gcode_M400 ( ) ;
gcode_M400 ( ) ;
break ;
break ;
# if defined(ENABLE_AUTO_BED_LEVELING) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY)) && not defined(Z_PROBE_SLED)
# if defined(ENABLE_AUTO_BED_LEVELING) && (defined(SERVO_ENDSTOPS) || defined(Z_PROBE_ALLEN_KEY)) && ! defined(Z_PROBE_SLED)
case 401 :
case 401 :
gcode_M401 ( ) ;
gcode_M401 ( ) ;
break ;
break ;
case 402 :
case 402 :
gcode_M402 ( ) ;
gcode_M402 ( ) ;
break ;
break ;
# endif
# endif // ENABLE_AUTO_BED_LEVELING && (SERVO_ENDSTOPS || Z_PROBE_ALLEN_KEY) && !Z_PROBE_SLED
# ifdef FILAMENT_SENSOR
# ifdef FILAMENT_SENSOR
case 404 : //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width
case 404 : //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or display nominal filament width
@ -6089,8 +6092,8 @@ void prepare_move() {
# endif // HAS_CONTROLLERFAN
# endif // HAS_CONTROLLERFAN
# ifdef SCARA
# ifdef SCARA
void calculate_SCARA_forward_Transform ( float f_scara [ 3 ] )
{
void calculate_SCARA_forward_Transform ( float f_scara [ 3 ] ) {
// Perform forward kinematics, and place results in delta[3]
// Perform forward kinematics, and place results in delta[3]
// The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
// The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
@ -6104,19 +6107,19 @@ void calculate_SCARA_forward_Transform(float f_scara[3])
y_sin = sin ( f_scara [ Y_AXIS ] / SCARA_RAD2DEG ) * Linkage_2 ;
y_sin = sin ( f_scara [ Y_AXIS ] / SCARA_RAD2DEG ) * Linkage_2 ;
y_cos = cos ( f_scara [ Y_AXIS ] / SCARA_RAD2DEG ) * Linkage_2 ;
y_cos = cos ( f_scara [ Y_AXIS ] / SCARA_RAD2DEG ) * Linkage_2 ;
// SERIAL_ECHOPGM(" x_sin="); SERIAL_ECHO(x_sin);
// SERIAL_ECHOPGM(" x_sin="); SERIAL_ECHO(x_sin);
// SERIAL_ECHOPGM(" x_cos="); SERIAL_ECHO(x_cos);
// SERIAL_ECHOPGM(" x_cos="); SERIAL_ECHO(x_cos);
// SERIAL_ECHOPGM(" y_sin="); SERIAL_ECHO(y_sin);
// SERIAL_ECHOPGM(" y_sin="); SERIAL_ECHO(y_sin);
// SERIAL_ECHOPGM(" y_cos="); SERIAL_ECHOLN(y_cos);
// SERIAL_ECHOPGM(" y_cos="); SERIAL_ECHOLN(y_cos);
delta [ X_AXIS ] = x_cos + y_cos + SCARA_offset_x ; //theta
delta [ X_AXIS ] = x_cos + y_cos + SCARA_offset_x ; //theta
delta [ Y_AXIS ] = x_sin + y_sin + SCARA_offset_y ; //theta+phi
delta [ Y_AXIS ] = x_sin + y_sin + SCARA_offset_y ; //theta+phi
//SERIAL_ECHOPGM(" delta[X_AXIS]="); SERIAL_ECHO(delta[X_AXIS]);
//SERIAL_ECHOPGM(" delta[X_AXIS]="); SERIAL_ECHO(delta[X_AXIS]);
//SERIAL_ECHOPGM(" delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
//SERIAL_ECHOPGM(" delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
}
}
void calculate_delta ( float cartesian [ 3 ] ) {
void calculate_delta ( float cartesian [ 3 ] ) {
//reverse kinematics.
//reverse kinematics.
// Perform reversed kinematics, and place results in delta[3]
// Perform reversed kinematics, and place results in delta[3]
// The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
// The maths and first version has been done by QHARLEY . Integrated into masterbranch 06/2014 and slightly restructured by Joachim Cerny in June 2014
@ -6161,10 +6164,11 @@ void calculate_delta(float cartesian[3]){
SERIAL_ECHOPGM ( " S2= " ) ; SERIAL_ECHO ( SCARA_S2 ) ;
SERIAL_ECHOPGM ( " S2= " ) ; SERIAL_ECHO ( SCARA_S2 ) ;
SERIAL_ECHOPGM ( " Theta= " ) ; SERIAL_ECHO ( SCARA_theta ) ;
SERIAL_ECHOPGM ( " Theta= " ) ; SERIAL_ECHO ( SCARA_theta ) ;
SERIAL_ECHOPGM ( " Psi= " ) ; SERIAL_ECHOLN ( SCARA_psi ) ;
SERIAL_ECHOPGM ( " Psi= " ) ; SERIAL_ECHOLN ( SCARA_psi ) ;
SERIAL_ECHOLN ( " " ) ; */
SERIAL_EOL ;
}
*/
}
# endif
# endif // SCARA
# ifdef TEMP_STAT_LEDS
# ifdef TEMP_STAT_LEDS
@ -6395,39 +6399,28 @@ void kill()
st_synchronize ( ) ;
st_synchronize ( ) ;
}
}
}
}
# endif
void Stop ( ) {
# endif // FILAMENT_RUNOUT_SENSOR
disable_all_heaters ( ) ;
if ( IsRunning ( ) ) {
Running = false ;
Stopped_gcode_LastN = gcode_LastN ; // Save last g_code for restart
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( MSG_ERR_STOPPED ) ;
LCD_MESSAGEPGM ( MSG_STOPPED ) ;
}
}
# ifdef FAST_PWM_FAN
# ifdef FAST_PWM_FAN
void setPwmFrequency ( uint8_t pin , int val )
{
void setPwmFrequency ( uint8_t pin , int val ) {
val & = 0x07 ;
val & = 0x07 ;
switch ( digitalPinToTimer ( pin ) )
switch ( digitalPinToTimer ( pin ) ) {
{
# if defined(TCCR0A)
# if defined(TCCR0A)
case TIMER0A :
case TIMER0A :
case TIMER0B :
case TIMER0B :
// TCCR0B &= ~(_BV(CS00) | _BV(CS01) | _BV(CS02));
// TCCR0B &= ~(_BV(CS00) | _BV(CS01) | _BV(CS02));
// TCCR0B |= val;
// TCCR0B |= val;
break ;
break ;
# endif
# endif
# if defined(TCCR1A)
# if defined(TCCR1A)
case TIMER1A :
case TIMER1A :
case TIMER1B :
case TIMER1B :
// TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
// TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
// TCCR1B |= val;
// TCCR1B |= val;
break ;
break ;
# endif
# endif
@ -6475,8 +6468,20 @@ void setPwmFrequency(uint8_t pin, int val)
# endif
# endif
}
}
}
# endif // FAST_PWM_FAN
void Stop ( ) {
disable_all_heaters ( ) ;
if ( IsRunning ( ) ) {
Running = false ;
Stopped_gcode_LastN = gcode_LastN ; // Save last g_code for restart
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( MSG_ERR_STOPPED ) ;
LCD_MESSAGEPGM ( MSG_STOPPED ) ;
}
}
}
# endif //FAST_PWM_FAN
bool setTargetedHotend ( int code ) {
bool setTargetedHotend ( int code ) {
target_extruder = active_extruder ;
target_extruder = active_extruder ;