Merge commit 'cd71a90ce8a770e0030ed6c9bac805b89724e275' into dev
Conflicts: limits.c motion_control.c report.c
This commit is contained in:
commit
2307563d8a
4
config.h
4
config.h
@ -28,6 +28,10 @@
|
||||
#ifndef config_h
|
||||
#define config_h
|
||||
|
||||
// Allows GRBL to tranck and report gcode line numbers. Enabling this means that the planning buffer
|
||||
// goes from 18 or 16 to make room for the additional line number data in the plan_block_t struct
|
||||
#define USE_LINE_NUMBERS
|
||||
|
||||
// Default settings. Used when resetting EEPROM. Change to desired name in defaults.h
|
||||
#define DEFAULTS_SHERLINE_5400
|
||||
|
||||
|
14
gcode.c
14
gcode.c
@ -101,6 +101,7 @@ uint8_t gc_execute_line(char *line)
|
||||
float target[N_AXIS];
|
||||
clear_vector(target); // XYZ(ABC) axes parameters.
|
||||
|
||||
uint32_t line_number = 0;
|
||||
gc.arc_radius = 0;
|
||||
clear_vector(gc.arc_offset); // IJK Arc offsets are incremental. Value of zero indicates no change.
|
||||
|
||||
@ -215,7 +216,7 @@ uint8_t gc_execute_line(char *line)
|
||||
char_counter = 0;
|
||||
while(next_statement(&letter, &value, line, &char_counter)) {
|
||||
switch(letter) {
|
||||
case 'G': case 'M': case 'N': break; // Ignore command statements and line numbers
|
||||
case 'G': case 'M': break; // Ignore command statements and line numbers
|
||||
case 'F':
|
||||
if (value <= 0) { FAIL(STATUS_INVALID_STATEMENT); } // Must be greater than zero
|
||||
if (gc.inverse_feed_rate_mode) {
|
||||
@ -226,6 +227,7 @@ uint8_t gc_execute_line(char *line)
|
||||
break;
|
||||
case 'I': case 'J': case 'K': gc.arc_offset[letter-'I'] = to_millimeters(value); break;
|
||||
case 'L': l = trunc(value); break;
|
||||
case 'N': line_number = trunc(value); break;
|
||||
case 'P': p = value; break;
|
||||
case 'R': gc.arc_radius = to_millimeters(value); break;
|
||||
case 'S':
|
||||
@ -329,7 +331,7 @@ uint8_t gc_execute_line(char *line)
|
||||
target[idx] = gc.position[idx];
|
||||
}
|
||||
}
|
||||
mc_line(target, -1.0, false);
|
||||
mc_line(target, -1.0, false, line_number);
|
||||
}
|
||||
// Retreive G28/30 go-home position data (in machine coordinates) from EEPROM
|
||||
float coord_data[N_AXIS];
|
||||
@ -338,7 +340,7 @@ uint8_t gc_execute_line(char *line)
|
||||
} else {
|
||||
if (!settings_read_coord_data(SETTING_INDEX_G30,coord_data)) { return(STATUS_SETTING_READ_FAIL); }
|
||||
}
|
||||
mc_line(coord_data, -1.0, false);
|
||||
mc_line(coord_data, -1.0, false, line_number);
|
||||
memcpy(gc.position, coord_data, sizeof(coord_data)); // gc.position[] = coord_data[];
|
||||
axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags.
|
||||
break;
|
||||
@ -409,7 +411,7 @@ uint8_t gc_execute_line(char *line)
|
||||
break;
|
||||
case MOTION_MODE_SEEK:
|
||||
if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);}
|
||||
else { mc_line(target, -1.0, false); }
|
||||
else { mc_line(target, -1.0, false, line_number); }
|
||||
break;
|
||||
case MOTION_MODE_LINEAR:
|
||||
// TODO: Inverse time requires F-word with each statement. Need to do a check. Also need
|
||||
@ -417,7 +419,7 @@ uint8_t gc_execute_line(char *line)
|
||||
// and after an inverse time move and then check for non-zero feed rate each time. This
|
||||
// should be efficient and effective.
|
||||
if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);}
|
||||
else { mc_line(target, (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); }
|
||||
else { mc_line(target, (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode, line_number); }
|
||||
break;
|
||||
case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC:
|
||||
// Check if at least one of the axes of the selected plane has been specified. If in center
|
||||
@ -441,7 +443,7 @@ uint8_t gc_execute_line(char *line)
|
||||
// Trace the arc
|
||||
mc_arc(gc.position, target, gc.arc_offset, gc.plane_axis_0, gc.plane_axis_1, gc.plane_axis_2,
|
||||
(gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode,
|
||||
gc.arc_radius, isclockwise);
|
||||
gc.arc_radius, isclockwise, line_number);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
90
limits.c
90
limits.c
@ -83,13 +83,13 @@ void limits_disable()
|
||||
// moves in the planner and serial buffers are all cleared and newly sent blocks will be
|
||||
// locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
|
||||
// limit setting if their limits are constantly triggering after a reset and move their axes.
|
||||
if (sys.state != STATE_ALARM) {
|
||||
if (sys.state != STATE_ALARM) {
|
||||
if (bit_isfalse(sys.execute,EXEC_ALARM)) {
|
||||
mc_reset(); // Initiate system kill.
|
||||
sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event
|
||||
mc_reset(); // Initiate system kill.
|
||||
sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else // OPTIONAL: Software debounce limit pin routine.
|
||||
// Upon limit pin change, enable watchdog timer to create a short delay.
|
||||
ISR(LIMIT_INT_vect) { if (!(WDTCSR & (1<<WDIE))) { WDTCSR |= (1<<WDIE); } }
|
||||
@ -102,12 +102,12 @@ void limits_disable()
|
||||
// Check limit pin state.
|
||||
if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
|
||||
if (bits & LIMIT_MASK) {
|
||||
mc_reset(); // Initiate system kill.
|
||||
sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event
|
||||
}
|
||||
mc_reset(); // Initiate system kill.
|
||||
sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -120,14 +120,14 @@ void limits_disable()
|
||||
void limits_go_home(uint8_t cycle_mask)
|
||||
{
|
||||
if (sys.abort) { return; } // Block if system reset has been issued.
|
||||
|
||||
|
||||
// Initialize homing in search mode to quickly engage the specified cycle_mask limit switches.
|
||||
bool approach = true;
|
||||
float homing_rate = settings.homing_seek_rate;
|
||||
uint8_t invert_pin, idx;
|
||||
uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
|
||||
float target[N_AXIS];
|
||||
|
||||
|
||||
// Determine travel distance to the furthest homing switch based on user max travel settings.
|
||||
// NOTE: settings.max_travel[] is stored as a negative value.
|
||||
float max_travel = settings.max_travel[X_AXIS];
|
||||
@ -142,58 +142,58 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { invert_pin = approach; }
|
||||
else { invert_pin = !approach; }
|
||||
|
||||
// Set target location and rate for active axes.
|
||||
uint8_t n_active_axis = 0;
|
||||
// Set target location and rate for active axes.
|
||||
uint8_t n_active_axis = 0;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (bit_istrue(cycle_mask,bit(idx))) {
|
||||
n_active_axis++;
|
||||
n_active_axis++;
|
||||
if (!approach) { target[idx] = -max_travel; }
|
||||
else { target[idx] = max_travel; }
|
||||
} else {
|
||||
} else {
|
||||
target[idx] = 0.0;
|
||||
}
|
||||
}
|
||||
if (bit_istrue(settings.homing_dir_mask,(1<<X_DIRECTION_BIT))) { target[X_AXIS] = -target[X_AXIS]; }
|
||||
if (bit_istrue(settings.homing_dir_mask,(1<<Y_DIRECTION_BIT))) { target[Y_AXIS] = -target[Y_AXIS]; }
|
||||
if (bit_istrue(settings.homing_dir_mask,(1<<Z_DIRECTION_BIT))) { target[Z_AXIS] = -target[Z_AXIS]; }
|
||||
}
|
||||
}
|
||||
if (bit_istrue(settings.homing_dir_mask,(1<<X_DIRECTION_BIT))) { target[X_AXIS] = -target[X_AXIS]; }
|
||||
if (bit_istrue(settings.homing_dir_mask,(1<<Y_DIRECTION_BIT))) { target[Y_AXIS] = -target[Y_AXIS]; }
|
||||
if (bit_istrue(settings.homing_dir_mask,(1<<Z_DIRECTION_BIT))) { target[Z_AXIS] = -target[Z_AXIS]; }
|
||||
|
||||
homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate.
|
||||
homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate.
|
||||
|
||||
// Reset homing axis locks based on cycle mask.
|
||||
uint8_t axislock = 0;
|
||||
if (bit_istrue(cycle_mask,bit(X_AXIS))) { axislock |= (1<<X_STEP_BIT); }
|
||||
if (bit_istrue(cycle_mask,bit(Y_AXIS))) { axislock |= (1<<Y_STEP_BIT); }
|
||||
if (bit_istrue(cycle_mask,bit(Z_AXIS))) { axislock |= (1<<Z_STEP_BIT); }
|
||||
sys.homing_axis_lock = axislock;
|
||||
uint8_t axislock = 0;
|
||||
if (bit_istrue(cycle_mask,bit(X_AXIS))) { axislock |= (1<<X_STEP_BIT); }
|
||||
if (bit_istrue(cycle_mask,bit(Y_AXIS))) { axislock |= (1<<Y_STEP_BIT); }
|
||||
if (bit_istrue(cycle_mask,bit(Z_AXIS))) { axislock |= (1<<Z_STEP_BIT); }
|
||||
sys.homing_axis_lock = axislock;
|
||||
|
||||
// Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
|
||||
uint8_t limit_state;
|
||||
plan_buffer_line(target, homing_rate, false); // Bypass mc_line(). Directly plan homing motion.
|
||||
// Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
|
||||
uint8_t limit_state;
|
||||
plan_buffer_line(target, homing_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan homing motion.
|
||||
st_prep_buffer(); // Prep and fill segment buffer from newly planned block.
|
||||
st_wake_up(); // Initiate motion
|
||||
do {
|
||||
// Check limit state. Lock out cycle axes when they change.
|
||||
limit_state = LIMIT_PIN;
|
||||
if (invert_pin) { limit_state ^= LIMIT_MASK; }
|
||||
if (axislock & (1<<X_STEP_BIT)) {
|
||||
if (limit_state & (1<<X_LIMIT_BIT)) { axislock &= ~(1<<X_STEP_BIT); }
|
||||
}
|
||||
if (axislock & (1<<Y_STEP_BIT)) {
|
||||
if (limit_state & (1<<Y_LIMIT_BIT)) { axislock &= ~(1<<Y_STEP_BIT); }
|
||||
}
|
||||
if (axislock & (1<<Z_STEP_BIT)) {
|
||||
if (limit_state & (1<<Z_LIMIT_BIT)) { axislock &= ~(1<<Z_STEP_BIT); }
|
||||
}
|
||||
sys.homing_axis_lock = axislock;
|
||||
st_wake_up(); // Initiate motion
|
||||
do {
|
||||
// Check limit state. Lock out cycle axes when they change.
|
||||
limit_state = LIMIT_PIN;
|
||||
if (invert_pin) { limit_state ^= LIMIT_MASK; }
|
||||
if (axislock & (1<<X_STEP_BIT)) {
|
||||
if (limit_state & (1<<X_LIMIT_BIT)) { axislock &= ~(1<<X_STEP_BIT); }
|
||||
}
|
||||
if (axislock & (1<<Y_STEP_BIT)) {
|
||||
if (limit_state & (1<<Y_LIMIT_BIT)) { axislock &= ~(1<<Y_STEP_BIT); }
|
||||
}
|
||||
if (axislock & (1<<Z_STEP_BIT)) {
|
||||
if (limit_state & (1<<Z_LIMIT_BIT)) { axislock &= ~(1<<Z_STEP_BIT); }
|
||||
}
|
||||
sys.homing_axis_lock = axislock;
|
||||
st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.
|
||||
// Check only for user reset. No time to run protocol_execute_runtime() in this loop.
|
||||
if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; }
|
||||
} while (STEP_MASK & axislock);
|
||||
} while (STEP_MASK & axislock);
|
||||
|
||||
st_reset(); // Force disable steppers and reset step segment buffer. Ensure homing motion is cleared.
|
||||
plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared.
|
||||
|
||||
delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate.
|
||||
delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate.
|
||||
|
||||
// Reverse direction and reset homing rate for locate cycle(s).
|
||||
homing_rate = settings.homing_feed_rate;
|
||||
@ -225,7 +225,7 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
}
|
||||
}
|
||||
plan_sync_position(); // Sync planner position to current machine position for pull-off move.
|
||||
plan_buffer_line(target, settings.homing_seek_rate, false); // Bypass mc_line(). Directly plan motion.
|
||||
plan_buffer_line(target, settings.homing_seek_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan motion.
|
||||
|
||||
// Initiate pull-off using main motion control routines.
|
||||
// TODO : Clean up state routines so that this motion still shows homing state.
|
||||
|
@ -39,7 +39,7 @@
|
||||
// segments, must pass through this routine before being passed to the planner. The seperation of
|
||||
// mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being
|
||||
// in the planner and to let backlash compensation or canned cycle integration simple and direct.
|
||||
void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate)
|
||||
void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t line_number)
|
||||
{
|
||||
// If enabled, check for soft limit violations. Placed here all line motions are picked up
|
||||
// from everywhere in Grbl.
|
||||
@ -68,7 +68,7 @@ void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate)
|
||||
else { break; }
|
||||
} while (1);
|
||||
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate);
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate, line_number);
|
||||
|
||||
// If idle, indicate to the system there is now a planned block in the buffer ready to cycle
|
||||
// start. Otherwise ignore and continue on.
|
||||
@ -84,7 +84,7 @@ void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate)
|
||||
// of each segment is configured in settings.arc_tolerance, which is defined to be the maximum normal
|
||||
// distance from segment to the circle when the end points both lie on the circle.
|
||||
void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1,
|
||||
uint8_t axis_linear, float feed_rate, uint8_t invert_feed_rate, float radius, uint8_t isclockwise)
|
||||
uint8_t axis_linear, float feed_rate, uint8_t invert_feed_rate, float radius, uint8_t isclockwise, uint32_t line_number)
|
||||
{
|
||||
float center_axis0 = position[axis_0] + offset[axis_0];
|
||||
float center_axis1 = position[axis_1] + offset[axis_1];
|
||||
@ -180,14 +180,14 @@ void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8
|
||||
arc_target[axis_0] = center_axis0 + r_axis0;
|
||||
arc_target[axis_1] = center_axis1 + r_axis1;
|
||||
arc_target[axis_linear] += linear_per_segment;
|
||||
mc_line(arc_target, feed_rate, invert_feed_rate);
|
||||
mc_line(arc_target, feed_rate, invert_feed_rate, line_number);
|
||||
|
||||
// Bail mid-circle on system abort. Runtime command check already performed by mc_line.
|
||||
if (sys.abort) { return; }
|
||||
}
|
||||
}
|
||||
// Ensure last segment arrives at target location.
|
||||
mc_line(target, feed_rate, invert_feed_rate);
|
||||
mc_line(target, feed_rate, invert_feed_rate, line_number);
|
||||
}
|
||||
|
||||
|
||||
@ -225,16 +225,16 @@ void mc_homing_cycle()
|
||||
#ifdef HOMING_CYCLE_2
|
||||
limits_go_home(HOMING_CYCLE_2); // Homing cycle 2
|
||||
#endif
|
||||
|
||||
|
||||
protocol_execute_runtime(); // Check for reset and set system abort.
|
||||
if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm.
|
||||
|
||||
// Homing cycle complete! Setup system for normal operation.
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Gcode parser position was circumvented by the limits_go_home() routine, so sync position now.
|
||||
gc_sync_position();
|
||||
|
||||
|
||||
// Set idle state after homing completes and before returning to main program.
|
||||
sys.state = STATE_IDLE;
|
||||
st_go_idle(); // Set idle state after homing completes
|
||||
|
@ -22,18 +22,19 @@
|
||||
#ifndef motion_control_h
|
||||
#define motion_control_h
|
||||
|
||||
#define HOMING_CYCLE_LINE_NUMBER 1000000000
|
||||
|
||||
// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second
|
||||
// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
|
||||
// (1 minute)/feed_rate time.
|
||||
void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate);
|
||||
void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t line_number);
|
||||
|
||||
// Execute an arc in offset mode format. position == current xyz, target == target xyz,
|
||||
// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is
|
||||
// the direction of helical travel, radius == circle radius, isclockwise boolean. Used
|
||||
// for vector transformation direction.
|
||||
void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1,
|
||||
uint8_t axis_linear, float feed_rate, uint8_t invert_feed_rate, float radius, uint8_t isclockwise);
|
||||
uint8_t axis_linear, float feed_rate, uint8_t invert_feed_rate, float radius, uint8_t isclockwise, uint32_t line_number);
|
||||
|
||||
// Dwell for a specific number of seconds
|
||||
void mc_dwell(float seconds);
|
||||
|
@ -259,7 +259,7 @@ uint8_t plan_check_full_buffer()
|
||||
is used in three ways: as a normal feed rate if invert_feed_rate is false, as inverse time if
|
||||
invert_feed_rate is true, or as seek/rapids rate if the feed_rate value is negative (and
|
||||
invert_feed_rate always false). */
|
||||
void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate)
|
||||
void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t line_number)
|
||||
{
|
||||
// Prepare and initialize new block
|
||||
plan_block_t *block = &block_buffer[block_buffer_head];
|
||||
@ -267,7 +267,9 @@ void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate)
|
||||
block->millimeters = 0;
|
||||
block->direction_bits = 0;
|
||||
block->acceleration = SOME_LARGE_VALUE; // Scaled down to maximum acceleration later
|
||||
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
block->line_number = line_number;
|
||||
#endif
|
||||
// Compute and store initial move distance data.
|
||||
// TODO: After this for-loop, we don't touch the stepper algorithm data. Might be a good idea
|
||||
// to try to keep these types of things completely separate from the planner for portability.
|
||||
|
11
planner.h
11
planner.h
@ -26,7 +26,11 @@
|
||||
|
||||
// The number of linear motions that can be in the plan at any give time
|
||||
#ifndef BLOCK_BUFFER_SIZE
|
||||
#define BLOCK_BUFFER_SIZE 18
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
#define BLOCK_BUFFER_SIZE 16
|
||||
#else
|
||||
#define BLOCK_BUFFER_SIZE 18
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This struct stores a linear movement of a g-code block motion with its critical "nominal" values
|
||||
@ -47,6 +51,9 @@ typedef struct {
|
||||
float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2)
|
||||
float millimeters; // The remaining distance for this block to be executed in (mm)
|
||||
// uint8_t max_override; // Maximum override value based on axis speed limits
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
uint32_t line_number;
|
||||
#endif
|
||||
} plan_block_t;
|
||||
|
||||
|
||||
@ -56,7 +63,7 @@ void plan_reset();
|
||||
// Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position
|
||||
// in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
|
||||
// rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
|
||||
void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate);
|
||||
void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t line_number);
|
||||
|
||||
// Called when the current block is no longer needed. Discards the block and makes the memory
|
||||
// availible for new blocks.
|
||||
|
19
report.c
19
report.c
@ -32,6 +32,7 @@
|
||||
#include "settings.h"
|
||||
#include "gcode.h"
|
||||
#include "coolant_control.h"
|
||||
#include "planner.h"
|
||||
#include "spindle_control.h"
|
||||
|
||||
|
||||
@ -261,9 +262,9 @@ void report_gcode_modes()
|
||||
}
|
||||
|
||||
switch (gc.spindle_direction) {
|
||||
case SPINDLE_ENABLE_CW : printPgmString(PSTR(" M3")); break;
|
||||
case SPINDLE_ENABLE_CCW : printPgmString(PSTR(" M4")); break;
|
||||
case SPINDLE_DISABLE : printPgmString(PSTR(" M5")); break;
|
||||
case 1 : printPgmString(PSTR(" M3")); break;
|
||||
case -1 : printPgmString(PSTR(" M4")); break;
|
||||
case 0 : printPgmString(PSTR(" M5")); break;
|
||||
}
|
||||
|
||||
switch (gc.coolant_mode) {
|
||||
@ -350,5 +351,17 @@ void report_realtime_status()
|
||||
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }
|
||||
}
|
||||
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
// Report current line number
|
||||
printPgmString(PSTR(","));
|
||||
printPgmString(PSTR("Ln:"));
|
||||
uint32_t ln=0;
|
||||
plan_block_t * pb = plan_get_current_block();
|
||||
if(pb != NULL) {
|
||||
ln = pb->line_number;
|
||||
}
|
||||
printInteger(ln);
|
||||
#endif
|
||||
|
||||
printPgmString(PSTR(">\r\n"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user