Naming and code comments

master
Scott Lahteine 10 years ago
parent c05b347617
commit 09d60e0128

@ -247,7 +247,7 @@ inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
extern float homing_feedrate[]; extern float homing_feedrate[];
extern bool axis_relative_modes[]; extern bool axis_relative_modes[];
extern int feedmultiply; extern int feedrate_multiplier;
extern bool volumetric_enabled; extern bool volumetric_enabled;
extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder. extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
@ -309,8 +309,8 @@ extern int fanSpeed;
extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate; extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate;
#endif #endif
extern millis_t starttime; extern millis_t print_job_start_ms;
extern millis_t stoptime; extern millis_t print_job_stop_ms;
// Handling multiple extruders pins // Handling multiple extruders pins
extern uint8_t active_extruder; extern uint8_t active_extruder;

@ -67,136 +67,149 @@
#include <SPI.h> #include <SPI.h>
#endif #endif
// look here for descriptions of G-codes: http://linuxcnc.org/handbook/gcode/g-code.html /**
// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes * Look here for descriptions of G-codes:
* - http://linuxcnc.org/handbook/gcode/g-code.html
//Implemented Codes * - http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
//------------------- *
// G0 -> G1 * Help us document these G-codes online:
// G1 - Coordinated Movement X Y Z E * - http://reprap.org/wiki/G-code
// G2 - CW ARC * - https://github.com/MarlinFirmware/Marlin/wiki/Marlin-G-Code
// G3 - CCW ARC */
// G4 - Dwell S<seconds> or P<milliseconds>
// G10 - retract filament according to settings of M207 /**
// G11 - retract recover filament according to settings of M208 * Implemented Codes
// G28 - Home one or more axes * -------------------
// G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet. *
// G30 - Single Z Probe, probes bed at current XY location. * "G" Codes
// G31 - Dock sled (Z_PROBE_SLED only) *
// G32 - Undock sled (Z_PROBE_SLED only) * G0 -> G1
// G90 - Use Absolute Coordinates * G1 - Coordinated Movement X Y Z E
// G91 - Use Relative Coordinates * G2 - CW ARC
// G92 - Set current position to coordinates given * G3 - CCW ARC
* G4 - Dwell S<seconds> or P<milliseconds>
// M Codes * G10 - retract filament according to settings of M207
// M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled) * G11 - retract recover filament according to settings of M208
// M1 - Same as M0 * G28 - Home one or more axes
// M17 - Enable/Power all stepper motors * G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet.
// M18 - Disable all stepper motors; same as M84 * G30 - Single Z Probe, probes bed at current XY location.
// M20 - List SD card * G31 - Dock sled (Z_PROBE_SLED only)
// M21 - Init SD card * G32 - Undock sled (Z_PROBE_SLED only)
// M22 - Release SD card * G90 - Use Absolute Coordinates
// M23 - Select SD file (M23 filename.g) * G91 - Use Relative Coordinates
// M24 - Start/resume SD print * G92 - Set current position to coordinates given
// M25 - Pause SD print *
// M26 - Set SD position in bytes (M26 S12345) * "M" Codes
// M27 - Report SD print status *
// M28 - Start SD write (M28 filename.g) * M0 - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled)
// M29 - Stop SD write * M1 - Same as M0
// M30 - Delete file from SD (M30 filename.g) * M17 - Enable/Power all stepper motors
// M31 - Output time since last M109 or SD card start to serial * M18 - Disable all stepper motors; same as M84
// M32 - Select file and start SD print (Can be used _while_ printing from SD card files): * M20 - List SD card
// syntax "M32 /path/filename#", or "M32 S<startpos bytes> !filename#" * M21 - Init SD card
// Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include). * M22 - Release SD card
// The '#' is necessary when calling from within sd files, as it stops buffer prereading * M23 - Select SD file (M23 filename.g)
// M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used. * M24 - Start/resume SD print
// M48 - Measure Z_Probe repeatability. M48 [n # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel] * M25 - Pause SD print
// M80 - Turn on Power Supply * M26 - Set SD position in bytes (M26 S12345)
// M81 - Turn off Power Supply * M27 - Report SD print status
// M82 - Set E codes absolute (default) * M28 - Start SD write (M28 filename.g)
// M83 - Set E codes relative while in Absolute Coordinates (G90) mode * M29 - Stop SD write
// M84 - Disable steppers until next move, * M30 - Delete file from SD (M30 filename.g)
// or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. * M31 - Output time since last M109 or SD card start to serial
// M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default) * M32 - Select file and start SD print (Can be used _while_ printing from SD card files):
// M92 - Set axis_steps_per_unit - same syntax as G92 * syntax "M32 /path/filename#", or "M32 S<startpos bytes> !filename#"
// M104 - Set extruder target temp * Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include).
// M105 - Read current temp * The '#' is necessary when calling from within sd files, as it stops buffer prereading
// M106 - Fan on * M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
// M107 - Fan off * M48 - Measure Z_Probe repeatability. M48 [n # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel]
// M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating * M80 - Turn on Power Supply
// Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling * M81 - Turn off Power Supply
// IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F * M82 - Set E codes absolute (default)
// M112 - Emergency stop * M83 - Set E codes relative while in Absolute Coordinates (G90) mode
// M114 - Output current position to serial port * M84 - Disable steppers until next move,
// M115 - Capabilities string * or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout.
// M117 - display message * M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
// M119 - Output Endstop status to serial port * M92 - Set axis_steps_per_unit - same syntax as G92
// M120 - Enable endstop detection * M104 - Set extruder target temp
// M121 - Disable endstop detection * M105 - Read current temp
// M126 - Solenoid Air Valve Open (BariCUDA support by jmil) * M106 - Fan on
// M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil) * M107 - Fan off
// M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil) * M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
// M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil) * Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
// M140 - Set bed target temp * IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
// M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work. * M112 - Emergency stop
// M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating * M114 - Output current position to serial port
// Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling * M115 - Capabilities string
// M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>- * M117 - display message
// M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) * M119 - Output Endstop status to serial port
// M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!! * M120 - Enable endstop detection
// M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec * M121 - Disable endstop detection
// M204 - Set default acceleration: P for Printing moves, R for Retract only (no X, Y, Z) moves and T for Travel (non printing) moves (ex. M204 P800 T3000 R9000) in mm/sec^2 * M126 - Solenoid Air Valve Open (BariCUDA support by jmil)
// 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 * M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil)
// M206 - Set additional homing offset * M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil)
// M207 - Set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting * M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil)
// M208 - Set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec] * M140 - Set bed target temp
// 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. * M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work.
// M218 - Set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y> * M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating
// M220 - Set speed factor override percentage: S<factor in percent> * Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
// M221 - Set extrude factor override percentage: S<factor in percent> * M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>-
// M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state> * M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
// M240 - Trigger a camera to take a photograph * M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
// M250 - Set LCD contrast C<contrast value> (value 0..63) * M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec
// M280 - Set servo position absolute. P: servo index, S: angle or microseconds * M204 - Set default acceleration: P for Printing moves, R for Retract only (no X, Y, Z) moves and T for Travel (non printing) moves (ex. M204 P800 T3000 R9000) in mm/sec^2
// M300 - Play beep sound S<frequency Hz> P<duration ms> * 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
// M301 - Set PID parameters P I and D * M206 - Set additional homing offset
// M302 - Allow cold extrudes, or set the minimum extrude S<temperature>. * M207 - Set retract length S[positive mm] F[feedrate mm/min] Z[additional zlift/hop], stays in mm regardless of M200 setting
// M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C) * M208 - Set recover=unretract length S[positive mm surplus to the M207 S*] F[feedrate mm/sec]
// M304 - Set bed PID parameters P I and D * 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.
// M380 - Activate solenoid on active extruder * M218 - Set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y>
// M381 - Disable all solenoids * M220 - Set speed factor override percentage: S<factor in percent>
// M400 - Finish all moves * M221 - Set extrude factor override percentage: S<factor in percent>
// M401 - Lower z-probe if present * M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state>
// M402 - Raise z-probe if present * M240 - Trigger a camera to take a photograph
// M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters * M250 - Set LCD contrast C<contrast value> (value 0..63)
// M405 - Turn on Filament Sensor extrusion control. Optional D<delay in cm> to set delay in centimeters between sensor and extruder * M280 - Set servo position absolute. P: servo index, S: angle or microseconds
// M406 - Turn off Filament Sensor extrusion control * M300 - Play beep sound S<frequency Hz> P<duration ms>
// M407 - Display measured filament diameter * M301 - Set PID parameters P I and D
// M500 - Store parameters in EEPROM * M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
// M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily). * M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
// M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. * M304 - Set bed PID parameters P I and D
// M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings. * M380 - Activate solenoid on active extruder
// M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) * M381 - Disable all solenoids
// M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] * M400 - Finish all moves
// M665 - Set delta configurations: L<diagonal rod> R<delta radius> S<segments/s> * M401 - Lower z-probe if present
// M666 - Set delta endstop adjustment * M402 - Raise z-probe if present
// M605 - Set dual x-carriage movement mode: S<mode> [ X<duplication x-offset> R<duplication temp offset> ] * M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
// M907 - Set digital trimpot motor current using axis codes. * M405 - Turn on Filament Sensor extrusion control. Optional D<delay in cm> to set delay in centimeters between sensor and extruder
// M908 - Control digital trimpot directly. * M406 - Turn off Filament Sensor extrusion control
// M350 - Set microstepping mode. * M407 - Display measured filament diameter
// M351 - Toggle MS1 MS2 pins directly. * M500 - Store parameters in EEPROM
* M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily).
// ************ SCARA Specific - This can change to suit future G-code regulations * M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
// M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration) * M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings.
// M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree) * M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
// M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration) * M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
// M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree) * M665 - Set delta configurations: L<diagonal rod> R<delta radius> S<segments/s>
// M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position) * M666 - Set delta endstop adjustment
// M365 - SCARA calibration: Scaling factor, X, Y, Z axis * M605 - Set dual x-carriage movement mode: S<mode> [ X<duplication x-offset> R<duplication temp offset> ]
//************* SCARA End *************** * M907 - Set digital trimpot motor current using axis codes.
* M908 - Control digital trimpot directly.
// M928 - Start SD logging (M928 filename.g) - ended by M29 * M350 - Set microstepping mode.
// M999 - Restart after being stopped by error * M351 - Toggle MS1 MS2 pins directly.
*
* ************ SCARA Specific - This can change to suit future G-code regulations
* M360 - SCARA calibration: Move to cal-position ThetaA (0 deg calibration)
* M361 - SCARA calibration: Move to cal-position ThetaB (90 deg calibration - steps per degree)
* M362 - SCARA calibration: Move to cal-position PsiA (0 deg calibration)
* M363 - SCARA calibration: Move to cal-position PsiB (90 deg calibration - steps per degree)
* M364 - SCARA calibration: Move to cal-position PSIC (90 deg to Theta calibration position)
* M365 - SCARA calibration: Scaling factor, X, Y, Z axis
* ************* SCARA End ***************
*
* M928 - Start SD logging (M928 filename.g) - ended by M29
* M999 - Restart after being stopped by error
*/
#ifdef SDSUPPORT #ifdef SDSUPPORT
CardReader card; CardReader card;
@ -210,12 +223,16 @@ static float destination[NUM_AXIS] = { 0.0 };
bool axis_known_position[3] = { false }; bool axis_known_position[3] = { false };
static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0; static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
static int cmd_queue_index_r = 0;
static int cmd_queue_index_w = 0;
static int commands_in_queue = 0;
static char command_queue[BUFSIZE][MAX_CMD_SIZE];
float homing_feedrate[] = HOMING_FEEDRATE; float homing_feedrate[] = HOMING_FEEDRATE;
bool axis_relative_modes[] = AXIS_RELATIVE_MODES; bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
int feedmultiply = 100; //100->1 200->2 int feedrate_multiplier = 100; //100->1 200->2
int saved_feedmultiply; int saved_feedrate_multiplier;
int extruder_multiply[EXTRUDERS] = ARRAY_BY_EXTRUDERS(100, 100, 100, 100); int extruder_multiply[EXTRUDERS] = ARRAY_BY_EXTRUDERS(100, 100, 100, 100);
bool volumetric_enabled = false; bool volumetric_enabled = false;
float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA); float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA);
@ -234,9 +251,6 @@ const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
static float offset[3] = { 0 }; static float offset[3] = { 0 };
static bool relative_mode = false; //Determines Absolute or Relative Coordinates static bool relative_mode = false; //Determines Absolute or Relative Coordinates
static int bufindr = 0;
static int bufindw = 0;
static int buflen = 0;
static char serial_char; static char serial_char;
static int serial_count = 0; static int serial_count = 0;
static boolean comment_mode = false; static boolean comment_mode = false;
@ -247,10 +261,10 @@ const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
millis_t previous_cmd_ms = 0; 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 * 1000L; static millis_t stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME * 1000L;
millis_t starttime = 0; ///< Print job start time millis_t print_job_start_ms = 0; ///< Print job start time
millis_t stoptime = 0; ///< Print job stop time millis_t print_job_stop_ms = 0; ///< Print job stop time
static uint8_t target_extruder; static uint8_t target_extruder;
bool CooldownNoWait = true; bool no_wait_for_cooling = true;
bool target_direction; bool target_direction;
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
@ -357,7 +371,7 @@ bool target_direction;
#endif #endif
#ifdef FILAMENT_RUNOUT_SENSOR #ifdef FILAMENT_RUNOUT_SENSOR
static bool filrunoutEnqued = false; static bool filrunoutEnqueued = false;
#endif #endif
#ifdef SDSUPPORT #ifdef SDSUPPORT
@ -410,8 +424,10 @@ void serial_echopair_P(const char *s_P, unsigned long v) { serialprintPGM(s_P);
} }
#endif //!SDSUPPORT #endif //!SDSUPPORT
//Injects the next command from the pending sequence of commands, when possible /**
//Return false if and only if no command was pending * Inject the next command from the command queue, when possible
* Return false only if no command was pending
*/
static bool drain_queued_commands_P() { static bool drain_queued_commands_P() {
if (!queued_commands_P) return false; if (!queued_commands_P) return false;
@ -434,45 +450,46 @@ static bool drain_queued_commands_P() {
return true; return true;
} }
//Record one or many commands to run from program memory. /**
//Aborts the current queue, if any. * Record one or many commands to run from program memory.
//Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards * Aborts the current queue, if any.
* Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards
*/
void enqueuecommands_P(const char* pgcode) { void enqueuecommands_P(const char* pgcode) {
queued_commands_P = pgcode; queued_commands_P = pgcode;
drain_queued_commands_P(); // first command executed asap (when possible) drain_queued_commands_P(); // first command executed asap (when possible)
} }
//adds a single command to the main command buffer, from RAM /**
//that is really done in a non-safe way. * Copy a command directly into the main command buffer, from RAM.
//needs overworking someday *
//Returns false if it failed to do so * This is done in a non-safe way and needs a rework someday.
bool enqueuecommand(const char *cmd) * Returns false if it doesn't add any command
{ */
if(*cmd==';') bool enqueuecommand(const char *cmd) {
return false;
if(buflen >= BUFSIZE) if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
return false;
//this is dangerous if a mixing of serial and this happens // This is dangerous if a mixing of serial and this happens
strcpy(&(cmdbuffer[bufindw][0]),cmd); char *command = command_queue[cmd_queue_index_w];
strcpy(command, cmd);
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_Enqueing); SERIAL_ECHOPGM(MSG_Enqueueing);
SERIAL_ECHO(cmdbuffer[bufindw]); SERIAL_ECHO(command);
SERIAL_ECHOLNPGM("\""); SERIAL_ECHOLNPGM("\"");
bufindw= (bufindw + 1)%BUFSIZE; cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
buflen += 1; commands_in_queue++;
return true; return true;
} }
void setup_killpin() void setup_killpin() {
{
#if HAS_KILL #if HAS_KILL
SET_INPUT(KILL_PIN); SET_INPUT(KILL_PIN);
WRITE(KILL_PIN, HIGH); WRITE(KILL_PIN, HIGH);
#endif #endif
} }
void setup_filrunoutpin() void setup_filrunoutpin() {
{
#if HAS_FILRUNOUT #if HAS_FILRUNOUT
pinMode(FILRUNOUT_PIN, INPUT); pinMode(FILRUNOUT_PIN, INPUT);
#ifdef ENDSTOPPULLUP_FIL_RUNOUT #ifdef ENDSTOPPULLUP_FIL_RUNOUT
@ -482,8 +499,7 @@ void setup_filrunoutpin()
} }
// Set home pin // Set home pin
void setup_homepin(void) void setup_homepin(void) {
{
#if HAS_HOME #if HAS_HOME
SET_INPUT(HOME_PIN); SET_INPUT(HOME_PIN);
WRITE(HOME_PIN, HIGH); WRITE(HOME_PIN, HIGH);
@ -491,15 +507,13 @@ void setup_homepin(void)
} }
void setup_photpin() void setup_photpin() {
{
#if HAS_PHOTOGRAPH #if HAS_PHOTOGRAPH
OUT_WRITE(PHOTOGRAPH_PIN, LOW); OUT_WRITE(PHOTOGRAPH_PIN, LOW);
#endif #endif
} }
void setup_powerhold() void setup_powerhold() {
{
#if HAS_SUICIDE #if HAS_SUICIDE
OUT_WRITE(SUICIDE_PIN, HIGH); OUT_WRITE(SUICIDE_PIN, HIGH);
#endif #endif
@ -512,15 +526,13 @@ void setup_powerhold()
#endif #endif
} }
void suicide() void suicide() {
{
#if HAS_SUICIDE #if HAS_SUICIDE
OUT_WRITE(SUICIDE_PIN, LOW); OUT_WRITE(SUICIDE_PIN, LOW);
#endif #endif
} }
void servo_init() void servo_init() {
{
#if NUM_SERVOS >= 1 && HAS_SERVO_0 #if NUM_SERVOS >= 1 && HAS_SERVO_0
servos[0].attach(SERVO0_PIN); servos[0].attach(SERVO0_PIN);
#endif #endif
@ -547,6 +559,24 @@ void servo_init()
#endif #endif
} }
/**
* Marlin entry-point: Set up before the program loop
* - Set up the kill pin, filament runout, power hold
* - Start the serial port
* - Print startup messages and diagnostics
* - Get EEPROM or default settings
* - Initialize managers for:
* temperature
* planner
* watchdog
* stepper
* photo pin
* servos
* LCD controller
* Digipot I2C
* Z probe sled
* status LEDs
*/
void setup() { void setup() {
setup_killpin(); setup_killpin();
setup_filrunoutpin(); setup_filrunoutpin();
@ -587,7 +617,7 @@ void setup() {
#ifdef SDSUPPORT #ifdef SDSUPPORT
for (int8_t i = 0; i < BUFSIZE; i++) fromsd[i] = false; for (int8_t i = 0; i < BUFSIZE; i++) fromsd[i] = false;
#endif // !SDSUPPORT #endif
// loads data from EEPROM if available else uses defaults (and resets step acceleration rate) // loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
Config_RetrieveSettings(); Config_RetrieveSettings();
@ -628,36 +658,54 @@ void setup() {
#endif #endif
} }
/**
* The main Marlin program loop
*
* - Save or log commands to SD
* - Process available commands (if not saving)
* - Call heater manager
* - Call inactivity manager
* - Call endstop manager
* - Call LCD update
*/
void loop() { void loop() {
if (buflen < BUFSIZE - 1) get_command(); if (commands_in_queue < BUFSIZE - 1) get_command();
#ifdef SDSUPPORT #ifdef SDSUPPORT
card.checkautostart(false); card.checkautostart(false);
#endif #endif
if (buflen) { if (commands_in_queue) {
#ifdef SDSUPPORT #ifdef SDSUPPORT
if (card.saving) { if (card.saving) {
if (strstr_P(cmdbuffer[bufindr], PSTR("M29")) == NULL) { char *command = command_queue[cmd_queue_index_r];
card.write_command(cmdbuffer[bufindr]); if (strstr_P(command, PSTR("M29"))) {
// M29 closes the file
card.closefile();
SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
}
else {
// Write the string from the read buffer to SD
card.write_command(command);
if (card.logging) if (card.logging)
process_commands(); process_commands(); // The card is saving because it's logging
else else
SERIAL_PROTOCOLLNPGM(MSG_OK); SERIAL_PROTOCOLLNPGM(MSG_OK);
} }
else {
card.closefile();
SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
}
} }
else else
process_commands(); process_commands();
#else #else
process_commands(); process_commands();
#endif // SDSUPPORT #endif // SDSUPPORT
buflen--;
bufindr = (bufindr + 1) % BUFSIZE; commands_in_queue--;
cmd_queue_index_r = (cmd_queue_index_r + 1) % BUFSIZE;
} }
// Check heater every n milliseconds // Check heater every n milliseconds
manage_heater(); manage_heater();
@ -666,12 +714,20 @@ void loop() {
lcd_update(); lcd_update();
} }
/**
* Add to the circular command queue the next command from:
* - The command-injection queue (queued_commands_P)
* - The active serial input (usually USB)
* - The SD card file being actively printed
*/
void get_command() { void get_command() {
if (drain_queued_commands_P()) return; // priority is given to non-serial commands if (drain_queued_commands_P()) return; // priority is given to non-serial commands
while (MYSERIAL.available() > 0 && buflen < BUFSIZE) { while (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
serial_char = MYSERIAL.read(); serial_char = MYSERIAL.read();
if (serial_char == '\n' || serial_char == '\r' || if (serial_char == '\n' || serial_char == '\r' ||
serial_count >= (MAX_CMD_SIZE - 1) serial_count >= (MAX_CMD_SIZE - 1)
) { ) {
@ -680,16 +736,17 @@ void get_command() {
if (!serial_count) return; // shortcut for empty lines if (!serial_count) return; // shortcut for empty lines
cmdbuffer[bufindw][serial_count] = 0; // terminate string char *command = command_queue[cmd_queue_index_w];
command[serial_count] = 0; // terminate string
#ifdef SDSUPPORT #ifdef SDSUPPORT
fromsd[bufindw] = false; fromsd[cmd_queue_index_w] = false;
#endif #endif
if (strchr(cmdbuffer[bufindw], 'N') != NULL) { if (strchr(command, 'N') != NULL) {
strchr_pointer = strchr(cmdbuffer[bufindw], 'N'); strchr_pointer = strchr(command, 'N');
gcode_N = (strtol(strchr_pointer + 1, NULL, 10)); gcode_N = (strtol(strchr_pointer + 1, NULL, 10));
if (gcode_N != gcode_LastN + 1 && strstr_P(cmdbuffer[bufindw], PSTR("M110")) == NULL) { if (gcode_N != gcode_LastN + 1 && strstr_P(command, PSTR("M110")) == NULL) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORPGM(MSG_ERR_LINE_NO); SERIAL_ERRORPGM(MSG_ERR_LINE_NO);
SERIAL_ERRORLN(gcode_LastN); SERIAL_ERRORLN(gcode_LastN);
@ -699,11 +756,11 @@ void get_command() {
return; return;
} }
if (strchr(cmdbuffer[bufindw], '*') != NULL) { if (strchr(command, '*') != NULL) {
byte checksum = 0; byte checksum = 0;
byte count = 0; byte count = 0;
while (cmdbuffer[bufindw][count] != '*') checksum ^= cmdbuffer[bufindw][count++]; while (command[count] != '*') checksum ^= command[count++];
strchr_pointer = strchr(cmdbuffer[bufindw], '*'); strchr_pointer = strchr(command, '*');
if (strtol(strchr_pointer + 1, NULL, 10) != checksum) { if (strtol(strchr_pointer + 1, NULL, 10) != checksum) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
@ -728,7 +785,7 @@ void get_command() {
//if no errors, continue parsing //if no errors, continue parsing
} }
else { // if we don't receive 'N' but still see '*' else { // if we don't receive 'N' but still see '*'
if ((strchr(cmdbuffer[bufindw], '*') != NULL)) { if ((strchr(command, '*') != NULL)) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM); SERIAL_ERRORPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
SERIAL_ERRORLN(gcode_LastN); SERIAL_ERRORLN(gcode_LastN);
@ -737,8 +794,8 @@ void get_command() {
} }
} }
if (strchr(cmdbuffer[bufindw], 'G') != NULL) { if (strchr(command, 'G') != NULL) {
strchr_pointer = strchr(cmdbuffer[bufindw], 'G'); strchr_pointer = strchr(command, 'G');
switch (strtol(strchr_pointer + 1, NULL, 10)) { switch (strtol(strchr_pointer + 1, NULL, 10)) {
case 0: case 0:
case 1: case 1:
@ -755,24 +812,24 @@ void get_command() {
} }
// If command was e-stop process now // If command was e-stop process now
if (strcmp(cmdbuffer[bufindw], "M112") == 0) kill(); if (strcmp(command, "M112") == 0) kill();
bufindw = (bufindw + 1) % BUFSIZE; cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
buflen += 1; commands_in_queue += 1;
serial_count = 0; //clear buffer serial_count = 0; //clear buffer
} }
else if (serial_char == '\\') { // Handle escapes else if (serial_char == '\\') { // Handle escapes
if (MYSERIAL.available() > 0 && buflen < BUFSIZE) { if (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
// if we have one more character, copy it over // if we have one more character, copy it over
serial_char = MYSERIAL.read(); serial_char = MYSERIAL.read();
cmdbuffer[bufindw][serial_count++] = serial_char; command_queue[cmd_queue_index_w][serial_count++] = serial_char;
} }
// otherwise do nothing // otherwise do nothing
} }
else { // its not a newline, carriage return or escape char else { // its not a newline, carriage return or escape char
if (serial_char == ';') comment_mode = true; if (serial_char == ';') comment_mode = true;
if (!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char; if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
} }
} }
@ -785,9 +842,9 @@ void get_command() {
// this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing // this character _can_ occur 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 (commands_in_queue == 0) stop_buffering = false;
while (!card.eof() && buflen < BUFSIZE && !stop_buffering) { while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) {
int16_t n = card.get(); int16_t n = card.get();
serial_char = (char)n; serial_char = (char)n;
if (serial_char == '\n' || serial_char == '\r' || if (serial_char == '\n' || serial_char == '\r' ||
@ -796,9 +853,9 @@ void get_command() {
) { ) {
if (card.eof()) { if (card.eof()) {
SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
stoptime = millis(); print_job_stop_ms = millis();
char time[30]; char time[30];
millis_t t = (stoptime - starttime) / 1000; millis_t t = (print_job_stop_ms - print_job_start_ms) / 1000;
int hours = t / 60 / 60, minutes = (t / 60) % 60; int hours = t / 60 / 60, minutes = (t / 60) % 60;
sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes); sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes);
SERIAL_ECHO_START; SERIAL_ECHO_START;
@ -813,18 +870,18 @@ void get_command() {
comment_mode = false; //for new command comment_mode = false; //for new command
return; //if empty line return; //if empty line
} }
cmdbuffer[bufindw][serial_count] = 0; //terminate string command_queue[cmd_queue_index_w][serial_count] = 0; //terminate string
// if (!comment_mode) { // if (!comment_mode) {
fromsd[bufindw] = true; fromsd[cmd_queue_index_w] = true;
buflen += 1; commands_in_queue += 1;
bufindw = (bufindw + 1)%BUFSIZE; cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
// } // }
comment_mode = false; //for new command comment_mode = false; //for new command
serial_count = 0; //clear buffer serial_count = 0; //clear buffer
} }
else { else {
if (serial_char == ';') comment_mode = true; if (serial_char == ';') comment_mode = true;
if (!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char; if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
} }
} }
@ -854,7 +911,7 @@ long code_value_long() { return strtol(strchr_pointer + 1, NULL, 10); }
int16_t code_value_short() { return (int16_t)strtol(strchr_pointer + 1, NULL, 10); } int16_t code_value_short() { return (int16_t)strtol(strchr_pointer + 1, NULL, 10); }
bool code_seen(char code) { bool code_seen(char code) {
strchr_pointer = strchr(cmdbuffer[bufindr], code); strchr_pointer = strchr(command_queue[cmd_queue_index_r], code);
return (strchr_pointer != NULL); //Return True if a character was found return (strchr_pointer != NULL); //Return True if a character was found
} }
@ -1023,7 +1080,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
void prepare_move_raw() { void prepare_move_raw() {
refresh_cmd_timeout(); refresh_cmd_timeout();
calculate_delta(destination); calculate_delta(destination);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder); plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedrate_multiplier/100.0), active_extruder);
set_current_to_destination(); set_current_to_destination();
} }
#endif #endif
@ -1176,8 +1233,8 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
static void setup_for_endstop_move() { static void setup_for_endstop_move() {
saved_feedrate = feedrate; saved_feedrate = feedrate;
saved_feedmultiply = feedmultiply; saved_feedrate_multiplier = feedrate_multiplier;
feedmultiply = 100; feedrate_multiplier = 100;
refresh_cmd_timeout(); refresh_cmd_timeout();
enable_endstops(true); enable_endstops(true);
} }
@ -1187,7 +1244,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
enable_endstops(false); enable_endstops(false);
#endif #endif
feedrate = saved_feedrate; feedrate = saved_feedrate;
feedmultiply = saved_feedmultiply; feedrate_multiplier = saved_feedrate_multiplier;
refresh_cmd_timeout(); refresh_cmd_timeout();
} }
@ -1610,12 +1667,12 @@ static void homeaxis(AxisEnum axis) {
#define SLED_DOCKING_OFFSET 0 #define SLED_DOCKING_OFFSET 0
#endif #endif
// /**
// Method to dock/undock a sled designed by Charles Bell. * Method to dock/undock a sled designed by Charles Bell.
// *
// dock[in] If true, move to MAX_X and engage the electromagnet * dock[in] If true, move to MAX_X and engage the electromagnet
// offset[in] The additional distance to move to adjust docking location * offset[in] The additional distance to move to adjust docking location
// */
static void dock_sled(bool dock, int offset=0) { static void dock_sled(bool dock, int offset=0) {
if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) { if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN); LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
@ -1649,9 +1706,10 @@ static void homeaxis(AxisEnum axis) {
inline void gcode_G0_G1() { inline void gcode_G0_G1() {
if (IsRunning()) { if (IsRunning()) {
get_coordinates(); // For X Y Z E F get_coordinates(); // For X Y Z E F
#ifdef FWRETRACT #ifdef FWRETRACT
if (autoretract_enabled)
if (!(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { if (autoretract_enabled && !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
float echange = destination[E_AXIS] - current_position[E_AXIS]; float echange = destination[E_AXIS] - current_position[E_AXIS];
// Is this move an attempt to retract or recover? // Is this move an attempt to retract or recover?
if ((echange < -MIN_RETRACT && !retracted[active_extruder]) || (echange > MIN_RETRACT && retracted[active_extruder])) { if ((echange < -MIN_RETRACT && !retracted[active_extruder]) || (echange > MIN_RETRACT && retracted[active_extruder])) {
@ -1661,7 +1719,9 @@ inline void gcode_G0_G1() {
return; return;
} }
} }
#endif //FWRETRACT #endif //FWRETRACT
prepare_move(); prepare_move();
//ClearToSend(); //ClearToSend();
} }
@ -1758,8 +1818,8 @@ inline void gcode_G28() {
#endif #endif
saved_feedrate = feedrate; saved_feedrate = feedrate;
saved_feedmultiply = feedmultiply; saved_feedrate_multiplier = feedrate_multiplier;
feedmultiply = 100; feedrate_multiplier = 100;
refresh_cmd_timeout(); refresh_cmd_timeout();
enable_endstops(true); enable_endstops(true);
@ -2013,7 +2073,7 @@ inline void gcode_G28() {
#endif #endif
feedrate = saved_feedrate; feedrate = saved_feedrate;
feedmultiply = saved_feedmultiply; feedrate_multiplier = saved_feedrate_multiplier;
refresh_cmd_timeout(); refresh_cmd_timeout();
endstops_hit_on_purpose(); // clear endstop hit flags endstops_hit_on_purpose(); // clear endstop hit flags
} }
@ -2659,7 +2719,7 @@ inline void gcode_M17() {
*/ */
inline void gcode_M24() { inline void gcode_M24() {
card.startFileprint(); card.startFileprint();
starttime = millis(); print_job_start_ms = millis();
} }
/** /**
@ -2691,7 +2751,7 @@ inline void gcode_M17() {
char* codepos = strchr_pointer + 4; char* codepos = strchr_pointer + 4;
char* starpos = strchr(codepos, '*'); char* starpos = strchr(codepos, '*');
if (starpos) { if (starpos) {
char* npos = strchr(cmdbuffer[bufindr], 'N'); char* npos = strchr(command_queue[cmd_queue_index_r], 'N');
strchr_pointer = strchr(npos, ' ') + 1; strchr_pointer = strchr(npos, ' ') + 1;
*(starpos) = '\0'; *(starpos) = '\0';
} }
@ -2714,7 +2774,7 @@ inline void gcode_M17() {
card.closefile(); card.closefile();
char* starpos = strchr(strchr_pointer + 4, '*'); char* starpos = strchr(strchr_pointer + 4, '*');
if (starpos) { if (starpos) {
char* npos = strchr(cmdbuffer[bufindr], 'N'); char* npos = strchr(command_queue[cmd_queue_index_r], 'N');
strchr_pointer = strchr(npos, ' ') + 1; strchr_pointer = strchr(npos, ' ') + 1;
*(starpos) = '\0'; *(starpos) = '\0';
} }
@ -2728,8 +2788,8 @@ inline void gcode_M17() {
* M31: Get the time since the start of SD Print (or last M109) * M31: Get the time since the start of SD Print (or last M109)
*/ */
inline void gcode_M31() { inline void gcode_M31() {
stoptime = millis(); print_job_stop_ms = millis();
millis_t t = (stoptime - starttime) / 1000; millis_t t = (print_job_stop_ms - print_job_start_ms) / 1000;
int min = t / 60, sec = t % 60; int min = t / 60, sec = t % 60;
char time[30]; char time[30];
sprintf_P(time, PSTR("%i min, %i sec"), min, sec); sprintf_P(time, PSTR("%i min, %i sec"), min, sec);
@ -2769,7 +2829,7 @@ inline void gcode_M31() {
card.startFileprint(); card.startFileprint();
if (!call_procedure) if (!call_procedure)
starttime = millis(); //procedure calls count as normal print time. print_job_start_ms = millis(); //procedure calls count as normal print time.
} }
} }
@ -2779,7 +2839,7 @@ inline void gcode_M31() {
inline void gcode_M928() { inline void gcode_M928() {
char* starpos = strchr(strchr_pointer + 5, '*'); char* starpos = strchr(strchr_pointer + 5, '*');
if (starpos) { if (starpos) {
char* npos = strchr(cmdbuffer[bufindr], 'N'); char* npos = strchr(command_queue[cmd_queue_index_r], 'N');
strchr_pointer = strchr(npos, ' ') + 1; strchr_pointer = strchr(npos, ' ') + 1;
*(starpos) = '\0'; *(starpos) = '\0';
} }
@ -3185,8 +3245,8 @@ inline void gcode_M109() {
LCD_MESSAGEPGM(MSG_HEATING); LCD_MESSAGEPGM(MSG_HEATING);
CooldownNoWait = code_seen('S'); no_wait_for_cooling = code_seen('S');
if (CooldownNoWait || code_seen('R')) { if (no_wait_for_cooling || code_seen('R')) {
float temp = code_value(); float temp = code_value();
setTargetHotend(temp, target_extruder); setTargetHotend(temp, target_extruder);
#ifdef DUAL_X_CARRIAGE #ifdef DUAL_X_CARRIAGE
@ -3218,7 +3278,7 @@ inline void gcode_M109() {
while((!cancel_heatup)&&((residency_start_ms == -1) || while((!cancel_heatup)&&((residency_start_ms == -1) ||
(residency_start_ms >= 0 && (((unsigned int) (millis() - residency_start_ms)) < (TEMP_RESIDENCY_TIME * 1000UL)))) ) (residency_start_ms >= 0 && (((unsigned int) (millis() - residency_start_ms)) < (TEMP_RESIDENCY_TIME * 1000UL)))) )
#else #else
while ( target_direction ? (isHeatingHotend(target_extruder)) : (isCoolingHotend(target_extruder)&&(CooldownNoWait==false)) ) while ( target_direction ? (isHeatingHotend(target_extruder)) : (isCoolingHotend(target_extruder)&&(no_wait_for_cooling==false)) )
#endif //TEMP_RESIDENCY_TIME #endif //TEMP_RESIDENCY_TIME
{ // while loop { // while loop
@ -3258,7 +3318,7 @@ inline void gcode_M109() {
LCD_MESSAGEPGM(MSG_HEATING_COMPLETE); LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
refresh_cmd_timeout(); refresh_cmd_timeout();
starttime = previous_cmd_ms; print_job_start_ms = previous_cmd_ms;
} }
#if HAS_TEMP_BED #if HAS_TEMP_BED
@ -3269,8 +3329,8 @@ inline void gcode_M109() {
*/ */
inline void gcode_M190() { inline void gcode_M190() {
LCD_MESSAGEPGM(MSG_BED_HEATING); LCD_MESSAGEPGM(MSG_BED_HEATING);
CooldownNoWait = code_seen('S'); no_wait_for_cooling = code_seen('S');
if (CooldownNoWait || code_seen('R')) if (no_wait_for_cooling || code_seen('R'))
setTargetBed(code_value()); setTargetBed(code_value());
millis_t temp_ms = millis(); millis_t temp_ms = millis();
@ -3278,7 +3338,7 @@ inline void gcode_M109() {
cancel_heatup = false; cancel_heatup = false;
target_direction = isHeatingBed(); // true if heating, false if cooling target_direction = isHeatingBed(); // true if heating, false if cooling
while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) { while ((target_direction && !cancel_heatup) ? isHeatingBed() : isCoolingBed() && !no_wait_for_cooling) {
millis_t ms = millis(); millis_t ms = millis();
if (ms > temp_ms + 1000UL) { //Print Temp Reading every 1 second while heating up. if (ms > temp_ms + 1000UL) { //Print Temp Reading every 1 second while heating up.
temp_ms = ms; temp_ms = ms;
@ -3371,7 +3431,7 @@ inline void gcode_M140() {
* This code should ALWAYS be available for EMERGENCY SHUTDOWN! * This code should ALWAYS be available for EMERGENCY SHUTDOWN!
*/ */
inline void gcode_M81() { inline void gcode_M81() {
disable_heater(); disable_all_heaters();
st_synchronize(); st_synchronize();
disable_e0(); disable_e0();
disable_e1(); disable_e1();
@ -3803,7 +3863,7 @@ inline void gcode_M206() {
default: default:
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND); SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND);
SERIAL_ECHO(cmdbuffer[bufindr]); SERIAL_ECHO(command_queue[cmd_queue_index_r]);
SERIAL_ECHOLNPGM("\""); SERIAL_ECHOLNPGM("\"");
return; return;
} }
@ -3849,7 +3909,7 @@ inline void gcode_M206() {
* M220: Set speed percentage factor, aka "Feed Rate" (M220 S95) * M220: Set speed percentage factor, aka "Feed Rate" (M220 S95)
*/ */
inline void gcode_M220() { inline void gcode_M220() {
if (code_seen('S')) feedmultiply = code_value(); if (code_seen('S')) feedrate_multiplier = code_value();
} }
/** /**
@ -4485,7 +4545,7 @@ inline void gcode_M503() {
#endif #endif
#ifdef FILAMENT_RUNOUT_SENSOR #ifdef FILAMENT_RUNOUT_SENSOR
filrunoutEnqued = false; filrunoutEnqueued = false;
#endif #endif
} }
@ -4619,6 +4679,9 @@ inline void gcode_M999() {
FlushSerialRequestResend(); FlushSerialRequestResend();
} }
/**
* T0-T3: Switch tool, usually switching extruders
*/
inline void gcode_T() { inline void gcode_T() {
int tmp_extruder = code_value(); int tmp_extruder = code_value();
if (tmp_extruder >= EXTRUDERS) { if (tmp_extruder >= EXTRUDERS) {
@ -5208,7 +5271,7 @@ void process_commands() {
else { else {
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND); SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND);
SERIAL_ECHO(cmdbuffer[bufindr]); SERIAL_ECHO(command_queue[cmd_queue_index_r]);
SERIAL_ECHOLNPGM("\""); SERIAL_ECHOLNPGM("\"");
} }
@ -5216,7 +5279,7 @@ void process_commands() {
} }
void FlushSerialRequestResend() { void FlushSerialRequestResend() {
//char cmdbuffer[bufindr][100]="Resend:"; //char command_queue[cmd_queue_index_r][100]="Resend:";
MYSERIAL.flush(); MYSERIAL.flush();
SERIAL_PROTOCOLPGM(MSG_RESEND); SERIAL_PROTOCOLPGM(MSG_RESEND);
SERIAL_PROTOCOLLN(gcode_LastN + 1); SERIAL_PROTOCOLLN(gcode_LastN + 1);
@ -5226,7 +5289,7 @@ void FlushSerialRequestResend() {
void ClearToSend() { void ClearToSend() {
refresh_cmd_timeout(); refresh_cmd_timeout();
#ifdef SDSUPPORT #ifdef SDSUPPORT
if (fromsd[bufindr]) return; if (fromsd[cmd_queue_index_r]) return;
#endif #endif
SERIAL_PROTOCOLLNPGM(MSG_OK); SERIAL_PROTOCOLLNPGM(MSG_OK);
} }
@ -5470,7 +5533,7 @@ void prepare_move() {
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); } if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
if (cartesian_mm < 0.000001) { return; } if (cartesian_mm < 0.000001) { return; }
float seconds = 6000 * cartesian_mm / feedrate / feedmultiply; float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier;
int steps = max(1, int(scara_segments_per_second * seconds)); int steps = max(1, int(scara_segments_per_second * seconds));
//SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm); //SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
@ -5489,7 +5552,7 @@ void prepare_move() {
//SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]); //SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
//SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]); //SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedmultiply/100.0, active_extruder); plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder);
} }
#endif // SCARA #endif // SCARA
@ -5502,7 +5565,7 @@ void prepare_move() {
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]); if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
if (cartesian_mm < 0.000001) return; if (cartesian_mm < 0.000001) return;
float seconds = 6000 * cartesian_mm / feedrate / feedmultiply; float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier;
int steps = max(1, int(delta_segments_per_second * seconds)); int steps = max(1, int(delta_segments_per_second * seconds));
// SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm); // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
@ -5516,7 +5579,7 @@ void prepare_move() {
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
adjust_delta(destination); adjust_delta(destination);
#endif #endif
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedmultiply/100.0, active_extruder); plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder);
} }
#endif // DELTA #endif // DELTA
@ -5556,16 +5619,16 @@ void prepare_move() {
#endif // DUAL_X_CARRIAGE #endif // DUAL_X_CARRIAGE
#if !defined(DELTA) && !defined(SCARA) #if !defined(DELTA) && !defined(SCARA)
// Do not use feedmultiply for E or Z only moves // Do not use feedrate_multiplier for E or Z only moves
if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) { if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) {
line_to_destination(); line_to_destination();
} }
else { else {
#ifdef MESH_BED_LEVELING #ifdef MESH_BED_LEVELING
mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder); mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedrate_multiplier/100.0), active_extruder);
return; return;
#else #else
line_to_destination(feedrate * feedmultiply / 100.0); line_to_destination(feedrate * feedrate_multiplier / 100.0);
#endif // MESH_BED_LEVELING #endif // MESH_BED_LEVELING
} }
#endif // !(DELTA || SCARA) #endif // !(DELTA || SCARA)
@ -5577,7 +5640,7 @@ void prepare_arc_move(char isclockwise) {
float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc
// Trace the arc // Trace the arc
mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedmultiply/60/100.0, r, isclockwise, active_extruder); mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedrate_multiplier/60/100.0, r, isclockwise, active_extruder);
// As far as the parser is concerned, the position is now == target. In reality the // 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 // motion control system might still be processing the action and the real tool position
@ -5762,7 +5825,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
filrunout(); filrunout();
#endif #endif
if (buflen < BUFSIZE - 1) get_command(); if (commands_in_queue < BUFSIZE - 1) get_command();
millis_t ms = millis(); millis_t ms = millis();
@ -5898,7 +5961,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
void kill() void kill()
{ {
cli(); // Stop interrupts cli(); // Stop interrupts
disable_heater(); disable_all_heaters();
disable_all_steppers(); disable_all_steppers();
@ -5919,18 +5982,18 @@ void kill()
} }
#ifdef FILAMENT_RUNOUT_SENSOR #ifdef FILAMENT_RUNOUT_SENSOR
void filrunout()
{ void filrunout() {
if (filrunoutEnqued == false) { if (!filrunoutEnqueued) {
filrunoutEnqued = true; filrunoutEnqueued = true;
enqueuecommand("M600"); enqueuecommand("M600");
} }
} }
#endif #endif
void Stop() void Stop() {
{ disable_all_heaters();
disable_heater();
if (IsRunning()) { if (IsRunning()) {
Running = false; Running = false;
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart

@ -110,7 +110,7 @@
// Serial Console Messages (do not translate those!) // Serial Console Messages (do not translate those!)
#define MSG_Enqueing "enqueing \"" #define MSG_Enqueueing "enqueueing \""
#define MSG_POWERUP "PowerUp" #define MSG_POWERUP "PowerUp"
#define MSG_EXTERNAL_RESET " External Reset" #define MSG_EXTERNAL_RESET " External Reset"
#define MSG_BROWNOUT_RESET " Brown out Reset" #define MSG_BROWNOUT_RESET " Brown out Reset"

@ -269,8 +269,8 @@ static void lcd_implementation_status_screen() {
} }
u8g.setPrintPos(80,48); u8g.setPrintPos(80,48);
if (starttime != 0) { if (print_job_start_ms != 0) {
uint16_t time = (millis() - starttime) / 60000; uint16_t time = (millis() - print_job_start_ms) / 60000;
lcd_print(itostr2(time/60)); lcd_print(itostr2(time/60));
lcd_print(':'); lcd_print(':');
lcd_print(itostr2(time%60)); lcd_print(itostr2(time%60));
@ -337,7 +337,7 @@ static void lcd_implementation_status_screen() {
lcd_print(LCD_STR_FEEDRATE[0]); lcd_print(LCD_STR_FEEDRATE[0]);
lcd_setFont(FONT_STATUSMENU); lcd_setFont(FONT_STATUSMENU);
u8g.setPrintPos(12,49); u8g.setPrintPos(12,49);
lcd_print(itostr3(feedmultiply)); lcd_print(itostr3(feedrate_multiplier));
lcd_print('%'); lcd_print('%');
// Status line // Status line

@ -110,7 +110,7 @@
// Serial Console Messages (do not translate those!) // Serial Console Messages (do not translate those!)
#define MSG_Enqueing "enqueing \"" #define MSG_Enqueueing "enqueueing \""
#define MSG_POWERUP "PowerUp" #define MSG_POWERUP "PowerUp"
#define MSG_EXTERNAL_RESET " External Reset" #define MSG_EXTERNAL_RESET " External Reset"
#define MSG_BROWNOUT_RESET " Brown out Reset" #define MSG_BROWNOUT_RESET " Brown out Reset"

@ -219,7 +219,7 @@ void PID_autotune(float temp, int extruder, int ncycles)
SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START); SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
disable_heater(); // switch off all heaters. disable_all_heaters(); // switch off all heaters.
if (extruder < 0) if (extruder < 0)
soft_pwm_bed = bias = d = MAX_BED_POWER / 2; soft_pwm_bed = bias = d = MAX_BED_POWER / 2;
@ -458,11 +458,11 @@ inline void _temp_error(int e, const char *msg1, const char *msg2) {
} }
void max_temp_error(uint8_t e) { void max_temp_error(uint8_t e) {
disable_heater(); disable_all_heaters();
_temp_error(e, PSTR(MSG_MAXTEMP_EXTRUDER_OFF), PSTR(MSG_ERR_MAXTEMP)); _temp_error(e, PSTR(MSG_MAXTEMP_EXTRUDER_OFF), PSTR(MSG_ERR_MAXTEMP));
} }
void min_temp_error(uint8_t e) { void min_temp_error(uint8_t e) {
disable_heater(); disable_all_heaters();
_temp_error(e, PSTR(MSG_MINTEMP_EXTRUDER_OFF), PSTR(MSG_ERR_MINTEMP)); _temp_error(e, PSTR(MSG_MINTEMP_EXTRUDER_OFF), PSTR(MSG_ERR_MINTEMP));
} }
void bed_max_temp_error(void) { void bed_max_temp_error(void) {
@ -579,6 +579,14 @@ float get_pid_output(int e) {
} }
#endif #endif
/**
* Manage heating activities for extruder hot-ends and a heated bed
* - Acquire updated temperature readings
* - Invoke thermal runaway protection
* - Manage extruder auto-fan
* - Apply filament width to the extrusion rate (may move)
* - Update the heated bed PID output value
*/
void manage_heater() { void manage_heater() {
if (!temp_meas_ready) return; if (!temp_meas_ready) return;
@ -623,7 +631,7 @@ void manage_heater() {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) { if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
disable_heater(); disable_all_heaters();
_temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP)); _temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP));
} }
#endif // TEMP_SENSOR_1_AS_REDUNDANT #endif // TEMP_SENSOR_1_AS_REDUNDANT
@ -637,6 +645,21 @@ void manage_heater() {
} }
#endif #endif
// Control the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR
if (filament_sensor) {
meas_shift_index = delay_index1 - meas_delay_cm;
if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
// Get the delayed info and add 100 to reconstitute to a percent of
// the nominal filament diameter then square it to get an area
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
float vm = pow((measurement_delay[meas_shift_index] + 100.0) / 100.0, 2);
if (vm < 0.01) vm = 0.01;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
}
#endif //FILAMENT_SENSOR
#ifndef PIDTEMPBED #ifndef PIDTEMPBED
if (ms < next_bed_check_ms) return; if (ms < next_bed_check_ms) return;
next_bed_check_ms = ms + BED_CHECK_INTERVAL; next_bed_check_ms = ms + BED_CHECK_INTERVAL;
@ -653,22 +676,22 @@ void manage_heater() {
soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0; soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0;
#elif !defined(BED_LIMIT_SWITCHING) #elif defined(BED_LIMIT_SWITCHING)
// Check if temperature is within the correct range // Check if temperature is within the correct band
if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) { if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0; if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS)
soft_pwm_bed = 0;
else if (current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
soft_pwm_bed = MAX_BED_POWER >> 1;
} }
else { else {
soft_pwm_bed = 0; soft_pwm_bed = 0;
WRITE_HEATER_BED(LOW); WRITE_HEATER_BED(LOW);
} }
#else //#ifdef BED_LIMIT_SWITCHING #else // BED_LIMIT_SWITCHING
// Check if temperature is within the correct band // Check if temperature is within the correct range
if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) { if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS) soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0;
soft_pwm_bed = 0;
else if (current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
soft_pwm_bed = MAX_BED_POWER >> 1;
} }
else { else {
soft_pwm_bed = 0; soft_pwm_bed = 0;
@ -676,32 +699,17 @@ void manage_heater() {
} }
#endif #endif
#endif //TEMP_SENSOR_BED != 0 #endif //TEMP_SENSOR_BED != 0
// Control the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR
if (filament_sensor) {
meas_shift_index = delay_index1 - meas_delay_cm;
if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
// Get the delayed info and add 100 to reconstitute to a percent of
// the nominal filament diameter then square it to get an area
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
float vm = pow((measurement_delay[meas_shift_index] + 100.0) / 100.0, 2);
if (vm < 0.01) vm = 0.01;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
}
#endif //FILAMENT_SENSOR
} }
#define PGM_RD_W(x) (short)pgm_read_word(&x) #define PGM_RD_W(x) (short)pgm_read_word(&x)
// Derived from RepRap FiveD extruder::getTemperature() // Derived from RepRap FiveD extruder::getTemperature()
// For hot end temperature measurement. // For hot end temperature measurement.
static float analog2temp(int raw, uint8_t e) { static float analog2temp(int raw, uint8_t e) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (e > EXTRUDERS) if (e > EXTRUDERS)
#else #else
if (e >= EXTRUDERS) if (e >= EXTRUDERS)
#endif #endif
{ {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERROR((int)e); SERIAL_ERROR((int)e);
@ -709,23 +717,18 @@ static float analog2temp(int raw, uint8_t e) {
kill(); kill();
return 0.0; return 0.0;
} }
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
if (e == 0) if (e == 0) return 0.25 * raw;
{
return 0.25 * raw;
}
#endif #endif
if(heater_ttbl_map[e] != NULL) if (heater_ttbl_map[e] != NULL) {
{
float celsius = 0; float celsius = 0;
uint8_t i; uint8_t i;
short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
for (i=1; i<heater_ttbllen_map[e]; i++) for (i = 1; i < heater_ttbllen_map[e]; i++) {
{ if (PGM_RD_W((*tt)[i][0]) > raw) {
if (PGM_RD_W((*tt)[i][0]) > raw)
{
celsius = PGM_RD_W((*tt)[i-1][1]) + celsius = PGM_RD_W((*tt)[i-1][1]) +
(raw - PGM_RD_W((*tt)[i-1][0])) * (raw - PGM_RD_W((*tt)[i-1][0])) *
(float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) / (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
@ -749,10 +752,8 @@ static float analog2tempBed(int raw) {
float celsius = 0; float celsius = 0;
byte i; byte i;
for (i=1; i<BEDTEMPTABLE_LEN; i++) for (i = 1; i < BEDTEMPTABLE_LEN; i++) {
{ if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) {
if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw)
{
celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) + celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
(raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) * (raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) *
(float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) / (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) /
@ -816,11 +817,11 @@ static void updateTemperaturesFromRawValues() {
#endif #endif
/**
* Initialize the temperature manager
* The manager is implemented by periodic calls to manage_heater()
void tp_init() */
{ void tp_init() {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
//disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector //disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=BIT(JTD); MCUCR=BIT(JTD);
@ -1059,7 +1060,7 @@ void setWatch() {
SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP); SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id); if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id);
LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY); LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
disable_heater(); disable_all_heaters();
disable_all_steppers(); disable_all_steppers();
for (;;) { for (;;) {
manage_heater(); manage_heater();
@ -1070,7 +1071,7 @@ void setWatch() {
#endif // HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION #endif // HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
void disable_heater() { void disable_all_heaters() {
for (int i=0; i<EXTRUDERS; i++) setTargetHotend(0, i); for (int i=0; i<EXTRUDERS; i++) setTargetHotend(0, i);
setTargetBed(0); setTargetBed(0);
@ -1208,11 +1209,15 @@ static void set_current_temp_raw() {
temp_meas_ready = true; temp_meas_ready = true;
} }
// /**
// Timer 0 is shared with millies * Timer 0 is shared with millies
// * - Manage PWM to all the heaters and fan
* - Update the raw temperature values
* - Check new temperature values for MIN/MAX errors
* - Step the babysteps value for each axis towards 0
*/
ISR(TIMER0_COMPB_vect) { ISR(TIMER0_COMPB_vect) {
//these variables are only accesible from the ISR, but static, so they don't lose their value
static unsigned char temp_count = 0; static unsigned char temp_count = 0;
static TempState temp_state = StartupDelay; static TempState temp_state = StartupDelay;
static unsigned char pwm_count = BIT(SOFT_PWM_SCALE); static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
@ -1414,6 +1419,7 @@ ISR(TIMER0_COMPB_vect) {
#define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin) #define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif #endif
// Prepare or measure a sensor, each one every 12th frame
switch(temp_state) { switch(temp_state) {
case PrepareTemp_0: case PrepareTemp_0:
#if HAS_TEMP_0 #if HAS_TEMP_0
@ -1582,16 +1588,16 @@ ISR(TIMER0_COMPB_vect) {
} // temp_count >= OVERSAMPLENR } // temp_count >= OVERSAMPLENR
#ifdef BABYSTEPPING #ifdef BABYSTEPPING
for (uint8_t axis=X_AXIS; axis<=Z_AXIS; axis++) { for (uint8_t axis = X_AXIS; axis <= Z_AXIS; axis++) {
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance int curTodo = babystepsTodo[axis]; //get rid of volatile for performance
if (curTodo > 0) { if (curTodo > 0) {
babystep(axis,/*fwd*/true); babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time babystepsTodo[axis]--; //fewer to do next time
} }
else if(curTodo < 0) { else if (curTodo < 0) {
babystep(axis,/*fwd*/false); babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time babystepsTodo[axis]++; //fewer to do next time
} }
} }
#endif //BABYSTEPPING #endif //BABYSTEPPING

@ -129,7 +129,7 @@ HOTEND_ROUTINES(0);
#endif #endif
int getHeaterPower(int heater); int getHeaterPower(int heater);
void disable_heater(); void disable_all_heaters();
void setWatch(); void setWatch();
void updatePID(); void updatePID();

@ -152,10 +152,10 @@ static void lcd_status_screen();
* lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause) * lcd_implementation_drawmenu_function(sel, row, PSTR(MSG_PAUSE_PRINT), lcd_sdcard_pause)
* menu_action_function(lcd_sdcard_pause) * menu_action_function(lcd_sdcard_pause)
* *
* MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999) * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999)
* MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedmultiply, 10, 999) * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
* lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedmultiply, 10, 999) * lcd_implementation_drawmenu_setting_edit_int3(sel, row, PSTR(MSG_SPEED), PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
* menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedmultiply, 10, 999) * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
* *
*/ */
#define MENU_ITEM(type, label, args...) do { \ #define MENU_ITEM(type, label, args...) do { \
@ -328,28 +328,28 @@ static void lcd_status_screen() {
#ifdef ULTIPANEL_FEEDMULTIPLY #ifdef ULTIPANEL_FEEDMULTIPLY
// Dead zone at 100% feedrate // Dead zone at 100% feedrate
if ((feedmultiply < 100 && (feedmultiply + int(encoderPosition)) > 100) || if ((feedrate_multiplier < 100 && (feedrate_multiplier + int(encoderPosition)) > 100) ||
(feedmultiply > 100 && (feedmultiply + int(encoderPosition)) < 100)) { (feedrate_multiplier > 100 && (feedrate_multiplier + int(encoderPosition)) < 100)) {
encoderPosition = 0; encoderPosition = 0;
feedmultiply = 100; feedrate_multiplier = 100;
} }
if (feedmultiply == 100) { if (feedrate_multiplier == 100) {
if (int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE) { if (int(encoderPosition) > ENCODER_FEEDRATE_DEADZONE) {
feedmultiply += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE; feedrate_multiplier += int(encoderPosition) - ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0; encoderPosition = 0;
} }
else if (int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE) { else if (int(encoderPosition) < -ENCODER_FEEDRATE_DEADZONE) {
feedmultiply += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE; feedrate_multiplier += int(encoderPosition) + ENCODER_FEEDRATE_DEADZONE;
encoderPosition = 0; encoderPosition = 0;
} }
} }
else { else {
feedmultiply += int(encoderPosition); feedrate_multiplier += int(encoderPosition);
encoderPosition = 0; encoderPosition = 0;
} }
#endif // ULTIPANEL_FEEDMULTIPLY #endif // ULTIPANEL_FEEDMULTIPLY
feedmultiply = constrain(feedmultiply, 10, 999); feedrate_multiplier = constrain(feedrate_multiplier, 10, 999);
#endif //ULTIPANEL #endif //ULTIPANEL
} }
@ -456,7 +456,7 @@ void lcd_set_home_offsets() {
static void lcd_tune_menu() { static void lcd_tune_menu() {
START_MENU(); START_MENU();
MENU_ITEM(back, MSG_MAIN, lcd_main_menu); MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
MENU_ITEM_EDIT(int3, MSG_SPEED, &feedmultiply, 10, 999); MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999);
#if TEMP_SENSOR_0 != 0 #if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15); MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP - 15);
#endif #endif

@ -550,7 +550,7 @@ static void lcd_implementation_status_screen() {
lcd.setCursor(0, 2); lcd.setCursor(0, 2);
lcd.print(LCD_STR_FEEDRATE[0]); lcd.print(LCD_STR_FEEDRATE[0]);
lcd.print(itostr3(feedmultiply)); lcd.print(itostr3(feedrate_multiplier));
lcd.print('%'); lcd.print('%');
#if LCD_WIDTH > 19 && defined(SDSUPPORT) #if LCD_WIDTH > 19 && defined(SDSUPPORT)
@ -567,8 +567,8 @@ static void lcd_implementation_status_screen() {
lcd.setCursor(LCD_WIDTH - 6, 2); lcd.setCursor(LCD_WIDTH - 6, 2);
lcd.print(LCD_STR_CLOCK[0]); lcd.print(LCD_STR_CLOCK[0]);
if (starttime != 0) { if (print_job_start_ms != 0) {
uint16_t time = millis()/60000 - starttime/60000; uint16_t time = millis()/60000 - print_job_start_ms/60000;
lcd.print(itostr2(time/60)); lcd.print(itostr2(time/60));
lcd.print(':'); lcd.print(':');
lcd.print(itostr2(time%60)); lcd.print(itostr2(time%60));

Loading…
Cancel
Save