@ -3,17 +3,17 @@
/*
Reprap firmware based on Sprinter and grbl .
Copyright ( C ) 2011 Camiel Gubbels / Erik van der Zalm
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
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
@ -22,8 +22,8 @@
This firmware is a mashup between Sprinter and grbl .
( https : //github.com/kliment/Sprinter)
( 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
*/
@ -40,6 +40,10 @@
# include "language.h"
# include "pins_arduino.h"
# if (defined NUM_SERVOS) && (NUM_SERVOS > 0)
# include "Servo.h"
# endif
# if DIGIPOTSS_PIN > -1
# include <SPI.h>
# endif
@ -93,11 +97,11 @@
// 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,
// 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
// M114 - Output current position to serial port
// M114 - Output current position to serial port
// M115 - Capabilities string
// M117 - display message
// M119 - Output Endstop status to serial port
@ -121,6 +125,7 @@
// M220 S<factor in percent>- set speed factor override percentage
// M221 S<factor in percent>- set extrude factor override percentage
// M240 - Trigger a camera to take a photograph
// M280 - set servo position absolute. P: servo index, S: angle or microseconds
// M300 - Play beepsound S<frequency Hz> P<duration ms>
// M301 - Set PID parameters P I and D
// M302 - Allow cold extrudes
@ -128,7 +133,7 @@
// M304 - Set bed PID parameters P I and D
// M400 - Finish all moves
// M500 - stores paramters in EEPROM
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).
// M502 - reverts 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)
// M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
@ -164,11 +169,11 @@ 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 } ;
// Extruder offset, only in XY plane
# if EXTRUDERS > 1
float extruder_offset [ 2 ] [ EXTRUDERS ] = {
float extruder_offset [ 2 ] [ EXTRUDERS ] = {
# if defined(EXTRUDER_OFFSET_X) && defined(EXTRUDER_OFFSET_Y)
EXTRUDER_OFFSET_X , EXTRUDER_OFFSET_Y
EXTRUDER_OFFSET_X , EXTRUDER_OFFSET_Y
# endif
} ;
} ;
# endif
uint8_t active_extruder = 0 ;
int fanSpeed = 0 ;
@ -225,6 +230,10 @@ static uint8_t tmp_extruder;
bool Stopped = false ;
# if (defined NUM_SERVOS) && (NUM_SERVOS > 0)
Servo servos [ NUM_SERVOS ] ;
# endif
//===========================================================================
//=============================ROUTINES=============================
//===========================================================================
@ -296,7 +305,7 @@ void setup_killpin()
WRITE ( KILL_PIN , HIGH ) ;
# endif
}
void setup_photpin ( )
{
# ifdef PHOTOGRAPH_PIN
@ -304,7 +313,7 @@ void setup_photpin()
SET_OUTPUT ( PHOTOGRAPH_PIN ) ;
WRITE ( PHOTOGRAPH_PIN , LOW ) ;
# endif
# endif
# endif
}
void setup_powerhold ( )
@ -324,16 +333,35 @@ void setup_powerhold()
void suicide ( )
{
# ifdef SUICIDE_PIN
# if (SUICIDE_PIN> -1)
# if (SUICIDE_PIN> -1)
SET_OUTPUT ( SUICIDE_PIN ) ;
WRITE ( SUICIDE_PIN , LOW ) ;
# endif
# endif
}
void servo_init ( )
{
# if (NUM_SERVOS >= 1) && defined (SERVO0_PIN) && (SERVO0_PIN > -1)
servos [ 0 ] . attach ( SERVO0_PIN ) ;
# endif
# if (NUM_SERVOS >= 2) && defined (SERVO1_PIN) && (SERVO1_PIN > -1)
servos [ 1 ] . attach ( SERVO1_PIN ) ;
# endif
# if (NUM_SERVOS >= 3) && defined (SERVO2_PIN) && (SERVO2_PIN > -1)
servos [ 2 ] . attach ( SERVO2_PIN ) ;
# endif
# if (NUM_SERVOS >= 4) && defined (SERVO3_PIN) && (SERVO3_PIN > -1)
servos [ 3 ] . attach ( SERVO3_PIN ) ;
# endif
# if (NUM_SERVOS >= 5)
# error "TODO: enter initalisation code for more servos"
# endif
}
void setup ( )
{
setup_killpin ( ) ;
setup_killpin ( ) ;
setup_powerhold ( ) ;
MYSERIAL . begin ( BAUDRATE ) ;
SERIAL_PROTOCOLLNPGM ( " start " ) ;
@ -370,22 +398,23 @@ void setup()
{
fromsd [ i ] = false ;
}
// loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
Config_RetrieveSettings ( ) ;
Config_RetrieveSettings ( ) ;
tp_init ( ) ; // Initialize temperature loop
tp_init ( ) ; // Initialize temperature loop
plan_init ( ) ; // Initialize planner;
watchdog_init ( ) ;
st_init ( ) ; // Initialize stepper, this enables interrupts!
setup_photpin ( ) ;
servo_init ( ) ;
lcd_init ( ) ;
# ifdef CONTROLLERFAN_PIN
SET_OUTPUT ( CONTROLLERFAN_PIN ) ; //Set pin used for driver cooling fan
# endif
# ifdef EXTRUDERFAN_PIN
SET_OUTPUT ( EXTRUDERFAN_PIN ) ; //Set pin used for extruder cooling fan
# endif
@ -439,14 +468,14 @@ void loop()
lcd_update ( ) ;
}
void get_command ( )
{
void get_command ( )
{
while ( MYSERIAL . available ( ) > 0 & & buflen < BUFSIZE ) {
serial_char = MYSERIAL . read ( ) ;
if ( serial_char = = ' \n ' | |
serial_char = = ' \r ' | |
( serial_char = = ' : ' & & comment_mode = = false ) | |
serial_count > = ( MAX_CMD_SIZE - 1 ) )
if ( serial_char = = ' \n ' | |
serial_char = = ' \r ' | |
( serial_char = = ' : ' & & comment_mode = = false ) | |
serial_count > = ( MAX_CMD_SIZE - 1 ) )
{
if ( ! serial_count ) { //if empty line
comment_mode = false ; //for new command
@ -487,7 +516,7 @@ void get_command()
}
//if no errors, continue parsing
}
else
else
{
SERIAL_ERROR_START ;
SERIAL_ERRORPGM ( MSG_ERR_NO_CHECKSUM ) ;
@ -523,7 +552,7 @@ void get_command()
if ( card . saving )
break ;
# endif //SDSUPPORT
SERIAL_PROTOCOLLNPGM ( MSG_OK ) ;
SERIAL_PROTOCOLLNPGM ( MSG_OK ) ;
}
else {
SERIAL_ERRORLNPGM ( MSG_ERR_STOPPED ) ;
@ -553,10 +582,10 @@ void get_command()
while ( ! card . eof ( ) & & buflen < BUFSIZE ) {
int16_t n = card . get ( ) ;
serial_char = ( char ) n ;
if ( serial_char = = ' \n ' | |
serial_char = = ' \r ' | |
( serial_char = = ' : ' & & comment_mode = = false ) | |
serial_count > = ( MAX_CMD_SIZE - 1 ) | | n = = - 1 )
if ( serial_char = = ' \n ' | |
serial_char = = ' \r ' | |
( serial_char = = ' : ' & & comment_mode = = false ) | |
serial_count > = ( MAX_CMD_SIZE - 1 ) | | n = = - 1 )
{
if ( card . eof ( ) ) {
SERIAL_PROTOCOLLNPGM ( MSG_FILE_PRINTED ) ;
@ -572,7 +601,7 @@ void get_command()
lcd_setstatus ( time ) ;
card . printingHasFinished ( ) ;
card . checkautostart ( true ) ;
}
if ( ! serial_count )
{
@ -584,7 +613,7 @@ void get_command()
fromsd [ bufindw ] = true ;
buflen + = 1 ;
bufindw = ( bufindw + 1 ) % BUFSIZE ;
// }
// }
comment_mode = false ; //for new command
serial_count = 0 ; //clear buffer
}
@ -594,20 +623,20 @@ void get_command()
if ( ! comment_mode ) cmdbuffer [ bufindw ] [ serial_count + + ] = serial_char ;
}
}
# endif //SDSUPPORT
}
float code_value ( )
{
return ( strtod ( & cmdbuffer [ bufindr ] [ strchr_pointer - cmdbuffer [ bufindr ] + 1 ] , NULL ) ) ;
float code_value ( )
{
return ( strtod ( & cmdbuffer [ bufindr ] [ strchr_pointer - cmdbuffer [ bufindr ] + 1 ] , NULL ) ) ;
}
long code_value_long ( )
{
return ( strtol ( & cmdbuffer [ bufindr ] [ strchr_pointer - cmdbuffer [ bufindr ] + 1 ] , NULL , 10 ) ) ;
long code_value_long ( )
{
return ( strtol ( & cmdbuffer [ bufindr ] [ strchr_pointer - cmdbuffer [ bufindr ] + 1 ] , NULL , 10 ) ) ;
}
bool code_seen ( char code )
@ -656,19 +685,19 @@ static void homeaxis(int axis) {
feedrate = homing_feedrate [ axis ] ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
st_synchronize ( ) ;
current_position [ axis ] = 0 ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
destination [ axis ] = - home_retract_mm ( axis ) * home_dir ( axis ) ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
st_synchronize ( ) ;
destination [ axis ] = 2 * home_retract_mm ( axis ) * home_dir ( axis ) ;
feedrate = homing_feedrate [ axis ] / 2 ;
feedrate = homing_feedrate [ axis ] / 2 ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
st_synchronize ( ) ;
axis_is_at_home ( axis ) ;
axis_is_at_home ( axis ) ;
destination [ axis ] = current_position [ axis ] ;
feedrate = 0.0 ;
endstops_hit_on_purpose ( ) ;
@ -711,7 +740,7 @@ void process_commands()
codenum = 0 ;
if ( code_seen ( ' P ' ) ) codenum = code_value ( ) ; // milliseconds to wait
if ( code_seen ( ' S ' ) ) codenum = code_value ( ) * 1000 ; // seconds to wait
st_synchronize ( ) ;
codenum + = millis ( ) ; // keep track of when we started waiting
previous_millis_cmd = millis ( ) ;
@ -721,30 +750,30 @@ void process_commands()
lcd_update ( ) ;
}
break ;
# ifdef FWRETRACT
# ifdef FWRETRACT
case 10 : // G10 retract
if ( ! retracted )
if ( ! retracted )
{
destination [ X_AXIS ] = current_position [ X_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 ;
destination [ E_AXIS ] = current_position [ E_AXIS ] - retract_length ;
destination [ E_AXIS ] = current_position [ E_AXIS ] - retract_length ;
feedrate = retract_feedrate ;
retracted = true ;
prepare_move ( ) ;
}
break ;
case 11 : // G10 retract_recover
if ( ! retracted )
if ( ! retracted )
{
destination [ X_AXIS ] = current_position [ X_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 [ E_AXIS ] + = - retract_recover_length ;
current_position [ E_AXIS ] + = - retract_recover_length ;
feedrate = retract_recover_feedrate ;
retracted = false ;
prepare_move ( ) ;
@ -756,34 +785,34 @@ void process_commands()
saved_feedmultiply = feedmultiply ;
feedmultiply = 100 ;
previous_millis_cmd = millis ( ) ;
enable_endstops ( true ) ;
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + ) {
destination [ i ] = current_position [ i ] ;
}
feedrate = 0.0 ;
home_all_axis = ! ( ( code_seen ( axis_codes [ 0 ] ) ) | | ( code_seen ( axis_codes [ 1 ] ) ) | | ( code_seen ( axis_codes [ 2 ] ) ) ) ;
# if Z_HOME_DIR > 0 // If homing away from BED do Z first
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Z_AXIS ] ) ) ) {
HOMEAXIS ( Z ) ;
}
# endif
# ifdef QUICK_HOME
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ X_AXIS ] ) & & code_seen ( axis_codes [ Y_AXIS ] ) ) ) //first diagonal move
{
current_position [ X_AXIS ] = 0 ; current_position [ Y_AXIS ] = 0 ;
current_position [ X_AXIS ] = 0 ; current_position [ Y_AXIS ] = 0 ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
destination [ X_AXIS ] = 1.5 * X_MAX_LENGTH * X_HOME_DIR ; destination [ Y_AXIS ] = 1.5 * Y_MAX_LENGTH * Y_HOME_DIR ;
feedrate = homing_feedrate [ X_AXIS ] ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
destination [ X_AXIS ] = 1.5 * X_MAX_LENGTH * X_HOME_DIR ; destination [ Y_AXIS ] = 1.5 * Y_MAX_LENGTH * Y_HOME_DIR ;
feedrate = homing_feedrate [ X_AXIS ] ;
if ( homing_feedrate [ Y_AXIS ] < feedrate )
feedrate = homing_feedrate [ Y_AXIS ] ;
feedrate = homing_feedrate [ Y_AXIS ] ;
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
st_synchronize ( ) ;
axis_is_at_home ( X_AXIS ) ;
axis_is_at_home ( Y_AXIS ) ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
@ -795,8 +824,8 @@ void process_commands()
endstops_hit_on_purpose ( ) ;
}
# endif
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ X_AXIS ] ) ) )
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ X_AXIS ] ) ) )
{
HOMEAXIS ( X ) ;
}
@ -804,14 +833,14 @@ void process_commands()
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Y_AXIS ] ) ) ) {
HOMEAXIS ( Y ) ;
}
# if Z_HOME_DIR < 0 // If homing towards BED do Z last
if ( ( home_all_axis ) | | ( code_seen ( axis_codes [ Z_AXIS ] ) ) ) {
HOMEAXIS ( Z ) ;
}
# endif
if ( code_seen ( axis_codes [ X_AXIS ] ) )
if ( code_seen ( axis_codes [ X_AXIS ] ) )
{
if ( code_value_long ( ) ! = 0 ) {
current_position [ X_AXIS ] = code_value ( ) + add_homeing [ 0 ] ;
@ -830,11 +859,11 @@ void process_commands()
}
}
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
# ifdef ENDSTOPS_ONLY_FOR_HOMING
enable_endstops ( false ) ;
# endif
feedrate = saved_feedrate ;
feedmultiply = saved_feedmultiply ;
previous_millis_cmd = millis ( ) ;
@ -850,13 +879,13 @@ void process_commands()
if ( ! code_seen ( axis_codes [ E_AXIS ] ) )
st_synchronize ( ) ;
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + ) {
if ( code_seen ( axis_codes [ i ] ) ) {
if ( code_seen ( axis_codes [ i ] ) ) {
if ( i = = E_AXIS ) {
current_position [ i ] = code_value ( ) ;
current_position [ i ] = code_value ( ) ;
plan_set_e_position ( current_position [ E_AXIS ] ) ;
}
else {
current_position [ i ] = code_value ( ) + add_homeing [ i ] ;
current_position [ i ] = code_value ( ) + add_homeing [ i ] ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
}
}
@ -867,7 +896,7 @@ void process_commands()
else if ( code_seen ( ' M ' ) )
{
switch ( ( int ) code_value ( ) )
switch ( ( int ) code_value ( ) )
{
# ifdef ULTIPANEL
case 0 : // M0 - Unconditional stop - Wait for user button press on LCD
@ -877,7 +906,7 @@ void process_commands()
codenum = 0 ;
if ( code_seen ( ' P ' ) ) codenum = code_value ( ) ; // milliseconds to wait
if ( code_seen ( ' S ' ) ) codenum = code_value ( ) * 1000 ; // seconds to wait
st_synchronize ( ) ;
previous_millis_cmd = millis ( ) ;
if ( codenum > 0 ) {
@ -900,12 +929,12 @@ void process_commands()
# endif
case 17 :
LCD_MESSAGEPGM ( MSG_NO_MOVE ) ;
enable_x ( ) ;
enable_y ( ) ;
enable_z ( ) ;
enable_e0 ( ) ;
enable_e1 ( ) ;
enable_e2 ( ) ;
enable_x ( ) ;
enable_y ( ) ;
enable_z ( ) ;
enable_e0 ( ) ;
enable_e1 ( ) ;
enable_e2 ( ) ;
break ;
# ifdef SDSUPPORT
@ -915,9 +944,9 @@ void process_commands()
SERIAL_PROTOCOLLNPGM ( MSG_END_FILE_LIST ) ;
break ;
case 21 : // M21 - init SD card
card . initsd ( ) ;
break ;
case 22 : //M22 - release SD card
card . release ( ) ;
@ -957,7 +986,7 @@ void process_commands()
//processed in write to file routine above
//card,saving = false;
break ;
case 30 : //M30 <filename> Delete File
case 30 : //M30 <filename> Delete File
if ( card . cardOK ) {
card . closefile ( ) ;
starpos = ( strchr ( strchr_pointer + 4 , ' * ' ) ) ;
@ -978,7 +1007,7 @@ void process_commands()
}
card . openLogFile ( strchr_pointer + 5 ) ;
break ;
# endif //SDSUPPORT
case 31 : //M31 take time since the start of the SD print or an M109 command
@ -1035,11 +1064,11 @@ void process_commands()
}
# if (TEMP_0_PIN > -1)
SERIAL_PROTOCOLPGM ( " ok T: " ) ;
SERIAL_PROTOCOL_F ( degHotend ( tmp_extruder ) , 1 ) ;
SERIAL_PROTOCOL_F ( degHotend ( tmp_extruder ) , 1 ) ;
SERIAL_PROTOCOLPGM ( " / " ) ;
SERIAL_PROTOCOL_F ( degTargetHotend ( tmp_extruder ) , 1 ) ;
SERIAL_PROTOCOL_F ( degTargetHotend ( tmp_extruder ) , 1 ) ;
# if TEMP_BED_PIN > -1
SERIAL_PROTOCOLPGM ( " B: " ) ;
SERIAL_PROTOCOLPGM ( " B: " ) ;
SERIAL_PROTOCOL_F ( degBed ( ) , 1 ) ;
SERIAL_PROTOCOLPGM ( " / " ) ;
SERIAL_PROTOCOL_F ( degTargetBed ( ) , 1 ) ;
@ -1050,20 +1079,20 @@ void process_commands()
# endif
SERIAL_PROTOCOLPGM ( " @: " ) ;
SERIAL_PROTOCOL ( getHeaterPower ( tmp_extruder ) ) ;
SERIAL_PROTOCOL ( getHeaterPower ( tmp_extruder ) ) ;
SERIAL_PROTOCOLPGM ( " B@: " ) ;
SERIAL_PROTOCOL ( getHeaterPower ( - 1 ) ) ;
SERIAL_PROTOCOL ( getHeaterPower ( - 1 ) ) ;
SERIAL_PROTOCOLLN ( " " ) ;
return ;
break ;
case 109 :
case 109 :
{ // M109 - Wait for extruder heater to reach target.
if ( setTargetedHotend ( 109 ) ) {
break ;
}
LCD_MESSAGEPGM ( MSG_HEATING ) ;
LCD_MESSAGEPGM ( MSG_HEATING ) ;
# ifdef AUTOTEMP
autotemp_enabled = false ;
# endif
@ -1071,15 +1100,15 @@ void process_commands()
# ifdef AUTOTEMP
if ( code_seen ( ' S ' ) ) autotemp_min = code_value ( ) ;
if ( code_seen ( ' B ' ) ) autotemp_max = code_value ( ) ;
if ( code_seen ( ' F ' ) )
if ( code_seen ( ' F ' ) )
{
autotemp_factor = code_value ( ) ;
autotemp_enabled = true ;
}
# endif
setWatch ( ) ;
codenum = millis ( ) ;
codenum = millis ( ) ;
/* See if we are heating up or cooling down */
bool target_direction = isHeatingHotend ( tmp_extruder ) ; // true if heating, false if cooling
@ -1087,7 +1116,7 @@ void process_commands()
# ifdef TEMP_RESIDENCY_TIME
long residencyStart ;
residencyStart = - 1 ;
/* continue to loop until we have reached the target temp
/* continue to loop until we have reached the target temp
_and_ until TEMP_RESIDENCY_TIME hasn ' t passed since we reached it */
while ( ( residencyStart = = - 1 ) | |
( residencyStart > = 0 & & ( ( ( unsigned int ) ( millis ( ) - residencyStart ) ) < ( TEMP_RESIDENCY_TIME * 1000UL ) ) ) ) {
@ -1097,9 +1126,9 @@ void process_commands()
if ( ( millis ( ) - codenum ) > 1000UL )
{ //Print Temp Reading and remaining time every 1 second while heating up/cooling down
SERIAL_PROTOCOLPGM ( " T: " ) ;
SERIAL_PROTOCOL_F ( degHotend ( tmp_extruder ) , 1 ) ;
SERIAL_PROTOCOL_F ( degHotend ( tmp_extruder ) , 1 ) ;
SERIAL_PROTOCOLPGM ( " E: " ) ;
SERIAL_PROTOCOL ( ( int ) tmp_extruder ) ;
SERIAL_PROTOCOL ( ( int ) tmp_extruder ) ;
# ifdef TEMP_RESIDENCY_TIME
SERIAL_PROTOCOLPGM ( " W: " ) ;
if ( residencyStart > - 1 )
@ -1107,7 +1136,7 @@ void process_commands()
codenum = ( ( TEMP_RESIDENCY_TIME * 1000UL ) - ( millis ( ) - residencyStart ) ) / 1000UL ;
SERIAL_PROTOCOLLN ( codenum ) ;
}
else
else
{
SERIAL_PROTOCOLLN ( " ? " ) ;
}
@ -1124,7 +1153,7 @@ void process_commands()
or when current temp falls outside the hysteresis after target temp was reached */
if ( ( residencyStart = = - 1 & & target_direction & & ( degHotend ( tmp_extruder ) > = ( degTargetHotend ( tmp_extruder ) - TEMP_WINDOW ) ) ) | |
( residencyStart = = - 1 & & ! target_direction & & ( degHotend ( tmp_extruder ) < = ( degTargetHotend ( tmp_extruder ) + TEMP_WINDOW ) ) ) | |
( residencyStart > - 1 & & labs ( degHotend ( tmp_extruder ) - degTargetHotend ( tmp_extruder ) ) > TEMP_HYSTERESIS ) )
( residencyStart > - 1 & & labs ( degHotend ( tmp_extruder ) - degTargetHotend ( tmp_extruder ) ) > TEMP_HYSTERESIS ) )
{
residencyStart = millis ( ) ;
}
@ -1139,8 +1168,8 @@ void process_commands()
# if TEMP_BED_PIN > -1
LCD_MESSAGEPGM ( MSG_BED_HEATING ) ;
if ( code_seen ( ' S ' ) ) setTargetBed ( code_value ( ) ) ;
codenum = millis ( ) ;
while ( isHeatingBed ( ) )
codenum = millis ( ) ;
while ( isHeatingBed ( ) )
{
if ( ( millis ( ) - codenum ) > 1000 ) //Print Temp Reading every 1 second while heating up.
{
@ -1148,11 +1177,11 @@ void process_commands()
SERIAL_PROTOCOLPGM ( " T: " ) ;
SERIAL_PROTOCOL ( tt ) ;
SERIAL_PROTOCOLPGM ( " E: " ) ;
SERIAL_PROTOCOL ( ( int ) active_extruder ) ;
SERIAL_PROTOCOL ( ( int ) active_extruder ) ;
SERIAL_PROTOCOLPGM ( " B: " ) ;
SERIAL_PROTOCOL_F ( degBed ( ) , 1 ) ;
SERIAL_PROTOCOLLN ( " " ) ;
codenum = millis ( ) ;
SERIAL_PROTOCOL_F ( degBed ( ) , 1 ) ;
SERIAL_PROTOCOLLN ( " " ) ;
codenum = millis ( ) ;
}
manage_heater ( ) ;
manage_inactivity ( ) ;
@ -1169,7 +1198,7 @@ void process_commands()
fanSpeed = constrain ( code_value ( ) , 0 , 255 ) ;
}
else {
fanSpeed = 255 ;
fanSpeed = 255 ;
}
break ;
case 107 : //M107 Fan Off
@ -1184,7 +1213,7 @@ void process_commands()
ValvePressure = constrain ( code_value ( ) , 0 , 255 ) ;
}
else {
ValvePressure = 255 ;
ValvePressure = 255 ;
}
break ;
case 127 : //M127 valve closed
@ -1199,7 +1228,7 @@ void process_commands()
EtoPPressure = constrain ( code_value ( ) , 0 , 255 ) ;
}
else {
EtoPPressure = 255 ;
EtoPPressure = 255 ;
}
break ;
case 129 : //M129 valve closed
@ -1214,18 +1243,18 @@ void process_commands()
WRITE ( PS_ON_PIN , PS_ON_AWAKE ) ;
break ;
# endif
case 81 : // M81 - ATX Power Off
# if defined SUICIDE_PIN && SUICIDE_PIN > -1
st_synchronize ( ) ;
suicide ( ) ;
# elif (PS_ON_PIN > -1)
SET_OUTPUT ( PS_ON_PIN ) ;
SET_OUTPUT ( PS_ON_PIN ) ;
WRITE ( PS_ON_PIN , PS_ON_ASLEEP ) ;
# endif
break ;
case 82 :
axis_relative_modes [ 3 ] = false ;
break ;
@ -1234,11 +1263,11 @@ void process_commands()
break ;
case 18 : //compatibility
case 84 : // M84
if ( code_seen ( ' S ' ) ) {
stepper_inactive_time = code_value ( ) * 1000 ;
if ( code_seen ( ' S ' ) ) {
stepper_inactive_time = code_value ( ) * 1000 ;
}
else
{
{
bool all_axis = ! ( ( code_seen ( axis_codes [ 0 ] ) ) | | ( code_seen ( axis_codes [ 1 ] ) ) | | ( code_seen ( axis_codes [ 2 ] ) ) | | ( code_seen ( axis_codes [ 3 ] ) ) ) ;
if ( all_axis )
{
@ -1260,18 +1289,18 @@ void process_commands()
disable_e1 ( ) ;
disable_e2 ( ) ;
}
# endif
# endif
}
}
break ;
case 85 : // M85
code_seen ( ' S ' ) ;
max_inactive_time = code_value ( ) * 1000 ;
max_inactive_time = code_value ( ) * 1000 ;
break ;
case 92 : // M92
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + )
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + )
{
if ( code_seen ( axis_codes [ i ] ) )
if ( code_seen ( axis_codes [ i ] ) )
{
if ( i = = 3 ) { // E
float value = code_value ( ) ;
@ -1305,16 +1334,16 @@ void process_commands()
SERIAL_PROTOCOL ( current_position [ Y_AXIS ] ) ;
SERIAL_PROTOCOLPGM ( " Z: " ) ;
SERIAL_PROTOCOL ( current_position [ Z_AXIS ] ) ;
SERIAL_PROTOCOLPGM ( " E: " ) ;
SERIAL_PROTOCOLPGM ( " E: " ) ;
SERIAL_PROTOCOL ( current_position [ E_AXIS ] ) ;
SERIAL_PROTOCOLPGM ( MSG_COUNT_X ) ;
SERIAL_PROTOCOL ( float ( st_get_position ( X_AXIS ) ) / axis_steps_per_unit [ X_AXIS ] ) ;
SERIAL_PROTOCOLPGM ( " Y: " ) ;
SERIAL_PROTOCOL ( float ( st_get_position ( Y_AXIS ) ) / axis_steps_per_unit [ Y_AXIS ] ) ;
SERIAL_PROTOCOLPGM ( " Z: " ) ;
SERIAL_PROTOCOL ( float ( st_get_position ( Z_AXIS ) ) / axis_steps_per_unit [ Z_AXIS ] ) ;
SERIAL_PROTOCOLLN ( " " ) ;
break ;
case 120 : // M120
@ -1352,7 +1381,7 @@ void process_commands()
break ;
//TODO: update for all axis, use for loop
case 201 : // M201
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + )
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + )
{
if ( code_seen ( axis_codes [ i ] ) )
{
@ -1391,7 +1420,7 @@ void process_commands()
}
break ;
case 206 : // M206 additional homeing offset
for ( int8_t i = 0 ; i < 3 ; i + + )
for ( int8_t i = 0 ; i < 3 ; i + + )
{
if ( code_seen ( axis_codes [ i ] ) ) add_homeing [ i ] = code_value ( ) ;
}
@ -1399,47 +1428,47 @@ void process_commands()
# ifdef FWRETRACT
case 207 : //M207 - set retract length S[positive mm] F[feedrate mm/sec] Z[additional zlift/hop]
{
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
{
retract_length = code_value ( ) ;
}
if ( code_seen ( ' F ' ) )
if ( code_seen ( ' F ' ) )
{
retract_feedrate = code_value ( ) ;
}
if ( code_seen ( ' Z ' ) )
if ( code_seen ( ' Z ' ) )
{
retract_zlift = code_value ( ) ;
}
} break ;
case 208 : // M208 - set retract recover length S[positive mm surplus to the M207 S*] F[feedrate mm/sec]
{
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
{
retract_recover_length = code_value ( ) ;
}
if ( code_seen ( ' F ' ) )
if ( code_seen ( ' F ' ) )
{
retract_recover_feedrate = code_value ( ) ;
}
} break ;
case 209 : // 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.
{
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
{
int t = code_value ( ) ;
switch ( t )
{
case 0 : autoretract_enabled = false ; retracted = false ; break ;
case 1 : autoretract_enabled = true ; retracted = false ; break ;
default :
default :
SERIAL_ECHO_START ;
SERIAL_ECHOPGM ( MSG_UNKNOWN_COMMAND ) ;
SERIAL_ECHO ( cmdbuffer [ bufindr ] ) ;
SERIAL_ECHOLNPGM ( " \" " ) ;
}
}
} break ;
# endif // FWRETRACT
# if EXTRUDERS > 1
@ -1448,7 +1477,7 @@ void process_commands()
if ( setTargetedHotend ( 218 ) ) {
break ;
}
if ( code_seen ( ' X ' ) )
if ( code_seen ( ' X ' ) )
{
extruder_offset [ X_AXIS ] [ tmp_extruder ] = code_value ( ) ;
}
@ -1458,7 +1487,7 @@ void process_commands()
}
SERIAL_ECHO_START ;
SERIAL_ECHOPGM ( MSG_HOTEND_OFFSET ) ;
for ( tmp_extruder = 0 ; tmp_extruder < EXTRUDERS ; tmp_extruder + + )
for ( tmp_extruder = 0 ; tmp_extruder < EXTRUDERS ; tmp_extruder + + )
{
SERIAL_ECHO ( " " ) ;
SERIAL_ECHO ( extruder_offset [ X_AXIS ] [ tmp_extruder ] ) ;
@ -1470,7 +1499,7 @@ void process_commands()
# endif
case 220 : // M220 S<factor in percent>- set speed factor override percentage
{
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
{
feedmultiply = code_value ( ) ;
}
@ -1478,13 +1507,44 @@ void process_commands()
break ;
case 221 : // M221 S<factor in percent>- set extrude factor override percentage
{
if ( code_seen ( ' S ' ) )
if ( code_seen ( ' S ' ) )
{
extrudemultiply = code_value ( ) ;
}
}
break ;
# if (defined NUM_SERVOS) && (NUM_SERVOS > 0)
case 280 : // M280 - set servo position absolute. P: servo index, S: angle or microseconds
{
int servo_index = - 1 ;
int servo_position = 0 ;
if ( code_seen ( ' P ' ) )
servo_index = code_value ( ) ;
if ( code_seen ( ' S ' ) ) {
servo_position = code_value ( ) ;
if ( ( servo_index > = 0 ) & & ( servo_index < NUM_SERVOS ) ) {
servos [ servo_index ] . write ( servo_position ) ;
}
else {
SERIAL_ECHO_START ;
SERIAL_ECHO ( " Servo " ) ;
SERIAL_ECHO ( servo_index ) ;
SERIAL_ECHOLN ( " out of range " ) ;
}
}
else if ( servo_index > = 0 ) {
SERIAL_PROTOCOL ( MSG_OK ) ;
SERIAL_PROTOCOL ( " Servo " ) ;
SERIAL_PROTOCOL ( servo_index ) ;
SERIAL_PROTOCOL ( " : " ) ;
SERIAL_PROTOCOL ( servos [ servo_index ] . read ( ) ) ;
SERIAL_PROTOCOLLN ( " " ) ;
}
}
break ;
# endif // NUM_SERVOS > 0
# if defined(LARGE_FLASH) && LARGE_FLASH == true && defined(BEEPER) && BEEPER > -1
case 300 : // M300
{
@ -1509,7 +1569,7 @@ void process_commands()
# ifdef PID_ADD_EXTRUSION_RATE
if ( code_seen ( ' C ' ) ) Kc = code_value ( ) ;
# endif
updatePID ( ) ;
SERIAL_PROTOCOL ( MSG_OK ) ;
SERIAL_PROTOCOL ( " p: " ) ;
@ -1569,7 +1629,7 @@ void process_commands()
# endif
}
break ;
case 302 : // allow cold extrudes
{
allow_cold_extrudes ( true ) ;
@ -1634,7 +1694,7 @@ void process_commands()
lastpos [ Z_AXIS ] = current_position [ Z_AXIS ] ;
lastpos [ E_AXIS ] = current_position [ E_AXIS ] ;
//retract by E
if ( code_seen ( ' E ' ) )
if ( code_seen ( ' E ' ) )
{
target [ E_AXIS ] + = code_value ( ) ;
}
@ -1645,9 +1705,9 @@ void process_commands()
# endif
}
plan_buffer_line ( target [ X_AXIS ] , target [ Y_AXIS ] , target [ Z_AXIS ] , target [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
//lift Z
if ( code_seen ( ' Z ' ) )
if ( code_seen ( ' Z ' ) )
{
target [ Z_AXIS ] + = code_value ( ) ;
}
@ -1658,9 +1718,9 @@ void process_commands()
# endif
}
plan_buffer_line ( target [ X_AXIS ] , target [ Y_AXIS ] , target [ Z_AXIS ] , target [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
//move xy
if ( code_seen ( ' X ' ) )
if ( code_seen ( ' X ' ) )
{
target [ X_AXIS ] + = code_value ( ) ;
}
@ -1670,7 +1730,7 @@ void process_commands()
target [ X_AXIS ] = FILAMENTCHANGE_XPOS ;
# endif
}
if ( code_seen ( ' Y ' ) )
if ( code_seen ( ' Y ' ) )
{
target [ Y_AXIS ] = code_value ( ) ;
}
@ -1680,9 +1740,9 @@ void process_commands()
target [ Y_AXIS ] = FILAMENTCHANGE_YPOS ;
# endif
}
plan_buffer_line ( target [ X_AXIS ] , target [ Y_AXIS ] , target [ Z_AXIS ] , target [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
if ( code_seen ( ' L ' ) )
{
target [ E_AXIS ] + = code_value ( ) ;
@ -1693,9 +1753,9 @@ void process_commands()
target [ E_AXIS ] + = FILAMENTCHANGE_FINALRETRACT ;
# endif
}
plan_buffer_line ( target [ X_AXIS ] , target [ Y_AXIS ] , target [ Z_AXIS ] , target [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
//finish moves
st_synchronize ( ) ;
//disable extruder steppers so filament can be removed
@ -1710,12 +1770,12 @@ void process_commands()
manage_heater ( ) ;
manage_inactivity ( ) ;
lcd_update ( ) ;
# if BEEPER > -1
if ( cnt = = 0 )
{
SET_OUTPUT ( BEEPER ) ;
WRITE ( BEEPER , HIGH ) ;
delay ( 3 ) ;
WRITE ( BEEPER , LOW ) ;
@ -1723,9 +1783,9 @@ void process_commands()
}
# endif
}
//return to normal
if ( code_seen ( ' L ' ) )
if ( code_seen ( ' L ' ) )
{
target [ E_AXIS ] + = - code_value ( ) ;
}
@ -1743,7 +1803,7 @@ void process_commands()
plan_buffer_line ( lastpos [ X_AXIS ] , lastpos [ Y_AXIS ] , lastpos [ Z_AXIS ] , lastpos [ E_AXIS ] , feedrate / 60 , active_extruder ) ; //final untretract
}
break ;
# endif //FILAMENTCHANGEENABLE
# endif //FILAMENTCHANGEENABLE
case 907 : // M907 Set digital trimpot motor current using axis codes.
{
# if DIGIPOTSS_PIN > -1
@ -1766,7 +1826,7 @@ void process_commands()
case 350 : // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
{
# if X_MS1_PIN > -1
if ( code_seen ( ' S ' ) ) for ( int i = 0 ; i < = 4 ; i + + ) microstep_mode ( i , code_value ( ) ) ;
if ( code_seen ( ' S ' ) ) for ( int i = 0 ; i < = 4 ; i + + ) microstep_mode ( i , code_value ( ) ) ;
for ( int i = 0 ; i < NUM_AXIS ; i + + ) if ( code_seen ( axis_codes [ i ] ) ) microstep_mode ( i , ( uint8_t ) code_value ( ) ) ;
if ( code_seen ( ' B ' ) ) microstep_mode ( 4 , code_value ( ) ) ;
microstep_readings ( ) ;
@ -1800,7 +1860,7 @@ void process_commands()
}
}
else if ( code_seen ( ' T ' ) )
else if ( code_seen ( ' T ' ) )
{
tmp_extruder = code_value ( ) ;
if ( tmp_extruder > = EXTRUDERS ) {
@ -1825,7 +1885,7 @@ void process_commands()
// Offset extruder (only by XY)
int i ;
for ( i = 0 ; i < 2 ; i + + ) {
current_position [ i ] = current_position [ i ] -
current_position [ i ] = current_position [ i ] -
extruder_offset [ i ] [ active_extruder ] +
extruder_offset [ i ] [ tmp_extruder ] ;
}
@ -1871,14 +1931,14 @@ void ClearToSend()
if ( fromsd [ bufindr ] )
return ;
# endif //SDSUPPORT
SERIAL_PROTOCOLLNPGM ( MSG_OK ) ;
SERIAL_PROTOCOLLNPGM ( MSG_OK ) ;
}
void get_coordinates ( )
{
bool seen [ 4 ] = { false , false , false , false } ;
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + ) {
if ( code_seen ( axis_codes [ i ] ) )
if ( code_seen ( axis_codes [ i ] ) )
{
destination [ i ] = ( float ) code_value ( ) + ( axis_relative_modes [ i ] | | relative_mode ) * current_position [ i ] ;
seen [ i ] = true ;
@ -1896,23 +1956,23 @@ void get_coordinates()
float echange = destination [ E_AXIS ] - current_position [ E_AXIS ] ;
if ( echange < - MIN_RETRACT ) //retract
{
if ( ! retracted )
if ( ! retracted )
{
destination [ Z_AXIS ] + = retract_zlift ; //not sure why chaninging current_position negatively does not work.
//if slicer retracted by echange=-1mm and you want to retract 3mm, corrrectede=-2mm additionally
float correctede = - echange - retract_length ;
//to generate the additional steps, not the destination is changed, but inversely the current position
current_position [ E_AXIS ] + = - correctede ;
current_position [ E_AXIS ] + = - correctede ;
feedrate = retract_feedrate ;
retracted = true ;
}
}
else
else
if ( echange > MIN_RETRACT ) //retract_recover
{
if ( retracted )
if ( retracted )
{
//current_position[Z_AXIS]+=-retract_zlift;
//if slicer retracted_recovered by echange=+1mm and you want to retract_recover 3mm, corrrectede=2mm additionally
@ -1922,7 +1982,7 @@ void get_coordinates()
retracted = false ;
}
}
}
# endif //FWRETRACT
}
@ -1940,7 +2000,7 @@ void get_arc_coordinates()
if ( code_seen ( ' I ' ) ) {
offset [ 0 ] = code_value ( ) ;
}
}
else {
offset [ 0 ] = 0.0 ;
}
@ -1971,7 +2031,7 @@ void prepare_move()
{
clamp_to_software_endstops ( destination ) ;
previous_millis_cmd = millis ( ) ;
previous_millis_cmd = millis ( ) ;
// Do not use feedmultiply for E or Z only moves
if ( ( current_position [ X_AXIS ] = = destination [ X_AXIS ] ) & & ( current_position [ Y_AXIS ] = = destination [ Y_AXIS ] ) ) {
plan_buffer_line ( destination [ X_AXIS ] , destination [ Y_AXIS ] , destination [ Z_AXIS ] , destination [ E_AXIS ] , feedrate / 60 , active_extruder ) ;
@ -1989,7 +2049,7 @@ void prepare_arc_move(char isclockwise) {
// Trace the arc
mc_arc ( current_position , destination , offset , X_AXIS , Y_AXIS , Z_AXIS , feedrate * feedmultiply / 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
// in any intermediate location.
@ -2008,7 +2068,7 @@ void controllerFan()
if ( ( millis ( ) - lastMotorCheck ) > = 2500 ) //Not a time critical function, so we only check every 2500ms
{
lastMotorCheck = millis ( ) ;
if ( ! READ ( X_ENABLE_PIN ) | | ! READ ( Y_ENABLE_PIN ) | | ! READ ( Z_ENABLE_PIN )
# if EXTRUDERS > 2
| | ! READ ( E2_ENABLE_PIN )
@ -2016,12 +2076,12 @@ void controllerFan()
# if EXTRUDER > 1
| | ! READ ( E1_ENABLE_PIN )
# endif
| | ! READ ( E0_ENABLE_PIN ) ) //If any of the drivers are enabled...
| | ! READ ( E0_ENABLE_PIN ) ) //If any of the drivers are enabled...
{
lastMotor = millis ( ) ; //... set time to NOW so the fan will turn on
}
if ( ( millis ( ) - lastMotor ) > = ( CONTROLLERFAN_SEC * 1000UL ) | | lastMotor = = 0 ) //If the last time any driver was enabled, is longer since than CONTROLLERSEC...
if ( ( millis ( ) - lastMotor ) > = ( CONTROLLERFAN_SEC * 1000UL ) | | lastMotor = = 0 ) //If the last time any driver was enabled, is longer since than CONTROLLERSEC...
{
WRITE ( CONTROLLERFAN_PIN , LOW ) ; //... turn the fan off
}
@ -2041,7 +2101,7 @@ void extruderFan()
if ( ( millis ( ) - lastExtruderCheck ) > = 2500 ) //Not a time critical function, so we only check every 2500ms
{
lastExtruderCheck = millis ( ) ;
if ( degHotend ( active_extruder ) < EXTRUDERFAN_DEC )
{
WRITE ( EXTRUDERFAN_PIN , LOW ) ; //... turn the fan off
@ -2054,13 +2114,13 @@ void extruderFan()
}
# endif
void manage_inactivity ( )
{
if ( ( millis ( ) - previous_millis_cmd ) > max_inactive_time )
if ( max_inactive_time )
kill ( ) ;
void manage_inactivity ( )
{
if ( ( millis ( ) - previous_millis_cmd ) > max_inactive_time )
if ( max_inactive_time )
kill ( ) ;
if ( stepper_inactive_time ) {
if ( ( millis ( ) - previous_millis_cmd ) > stepper_inactive_time )
if ( ( millis ( ) - previous_millis_cmd ) > stepper_inactive_time )
{
if ( blocks_queued ( ) = = false ) {
disable_x ( ) ;
@ -2080,15 +2140,15 @@ void manage_inactivity()
controllerFan ( ) ; //Check if fan should be turned on to cool stepper drivers down
# endif
# ifdef EXTRUDER_RUNOUT_PREVENT
if ( ( millis ( ) - previous_millis_cmd ) > EXTRUDER_RUNOUT_SECONDS * 1000 )
if ( ( millis ( ) - previous_millis_cmd ) > EXTRUDER_RUNOUT_SECONDS * 1000 )
if ( degHotend ( active_extruder ) > EXTRUDER_RUNOUT_MINTEMP )
{
bool oldstatus = READ ( E0_ENABLE_PIN ) ;
enable_e0 ( ) ;
float oldepos = current_position [ E_AXIS ] ;
float oldedes = destination [ E_AXIS ] ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
current_position [ E_AXIS ] + EXTRUDER_RUNOUT_EXTRUDE * EXTRUDER_RUNOUT_ESTEPS / axis_steps_per_unit [ E_AXIS ] ,
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] ,
current_position [ E_AXIS ] + EXTRUDER_RUNOUT_EXTRUDE * EXTRUDER_RUNOUT_ESTEPS / axis_steps_per_unit [ E_AXIS ] ,
EXTRUDER_RUNOUT_SPEED / 60. * EXTRUDER_RUNOUT_ESTEPS / axis_steps_per_unit [ E_AXIS ] , active_extruder ) ;
current_position [ E_AXIS ] = oldepos ;
destination [ E_AXIS ] = oldedes ;
@ -2112,7 +2172,7 @@ void kill()
disable_e0 ( ) ;
disable_e1 ( ) ;
disable_e2 ( ) ;
if ( PS_ON_PIN > - 1 ) pinMode ( PS_ON_PIN , INPUT ) ;
SERIAL_ERROR_START ;
SERIAL_ERRORLNPGM ( MSG_ERR_KILLED ) ;
@ -2141,7 +2201,7 @@ void setPwmFrequency(uint8_t pin, int val)
val & = 0x07 ;
switch ( digitalPinToTimer ( pin ) )
{
# if defined(TCCR0A)
case TIMER0A :
case TIMER0B :
@ -2183,7 +2243,7 @@ void setPwmFrequency(uint8_t pin, int val)
break ;
# endif
# if defined(TCCR4A)
# if defined(TCCR4A)
case TIMER4A :
case TIMER4B :
case TIMER4C :
@ -2192,7 +2252,7 @@ void setPwmFrequency(uint8_t pin, int val)
break ;
# endif
# if defined(TCCR5A)
# if defined(TCCR5A)
case TIMER5A :
case TIMER5B :
case TIMER5C :