Minor updates to line number feature.

- Changed line number integer types from unsigned to signed int32.
G-code mandates values cannot exceed 99999. Negative values can be used
to indicate certain modes.

- Homing cycle line number changed to -1, as an indicator.

- Fixed a reporting define for the spindle states that was broken by
the last merge.
This commit is contained in:
Sonny Jeon 2014-02-19 07:48:09 -07:00
parent 9c95c1439f
commit 1fd45791a5
8 changed files with 72 additions and 70 deletions

View File

@ -28,10 +28,6 @@
#ifndef config_h #ifndef config_h
#define 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 // Default settings. Used when resetting EEPROM. Change to desired name in defaults.h
#define DEFAULTS_SHERLINE_5400 #define DEFAULTS_SHERLINE_5400
@ -88,6 +84,10 @@
// parser state depending on user preferences. // parser state depending on user preferences.
#define N_STARTUP_LINE 2 // Integer (1-3) #define N_STARTUP_LINE 2 // Integer (1-3)
// 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
// Enables a second coolant control pin via the mist coolant g-code command M7 on the Arduino Uno // Enables a second coolant control pin via the mist coolant g-code command M7 on the Arduino Uno
// analog pin 5. Only use this option if you require a second coolant control pin. // analog pin 5. Only use this option if you require a second coolant control pin.
// NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless.

View File

@ -101,7 +101,7 @@ uint8_t gc_execute_line(char *line)
float target[N_AXIS]; float target[N_AXIS];
clear_vector(target); // XYZ(ABC) axes parameters. clear_vector(target); // XYZ(ABC) axes parameters.
uint32_t line_number = 0; int32_t line_number = 0;
gc.arc_radius = 0; gc.arc_radius = 0;
clear_vector(gc.arc_offset); // IJK Arc offsets are incremental. Value of zero indicates no change. clear_vector(gc.arc_offset); // IJK Arc offsets are incremental. Value of zero indicates no change.

View File

@ -85,11 +85,11 @@ void limits_disable()
// limit setting if their limits are constantly triggering after a reset and move their axes. // 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)) { if (bit_isfalse(sys.execute,EXEC_ALARM)) {
mc_reset(); // Initiate system kill. mc_reset(); // Initiate system kill.
sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event
}
} }
} }
}
#else // OPTIONAL: Software debounce limit pin routine. #else // OPTIONAL: Software debounce limit pin routine.
// Upon limit pin change, enable watchdog timer to create a short delay. // Upon limit pin change, enable watchdog timer to create a short delay.
ISR(LIMIT_INT_vect) { if (!(WDTCSR & (1<<WDIE))) { WDTCSR |= (1<<WDIE); } } ISR(LIMIT_INT_vect) { if (!(WDTCSR & (1<<WDIE))) { WDTCSR |= (1<<WDIE); } }
@ -102,11 +102,11 @@ void limits_disable()
// Check limit pin state. // Check limit pin state.
if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; } if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
if (bits & LIMIT_MASK) { if (bits & LIMIT_MASK) {
mc_reset(); // Initiate system kill. mc_reset(); // Initiate system kill.
sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event
} }
} }
} }
} }
#endif #endif
@ -142,58 +142,58 @@ void limits_go_home(uint8_t cycle_mask)
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { invert_pin = approach; } if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { invert_pin = approach; }
else { invert_pin = !approach; } else { invert_pin = !approach; }
// Set target location and rate for active axes. // Set target location and rate for active axes.
uint8_t n_active_axis = 0; uint8_t n_active_axis = 0;
for (idx=0; idx<N_AXIS; idx++) { for (idx=0; idx<N_AXIS; idx++) {
if (bit_istrue(cycle_mask,bit(idx))) { if (bit_istrue(cycle_mask,bit(idx))) {
n_active_axis++; n_active_axis++;
if (!approach) { target[idx] = -max_travel; } if (!approach) { target[idx] = -max_travel; }
else { target[idx] = max_travel; } else { target[idx] = max_travel; }
} else { } else {
target[idx] = 0.0; 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<<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<<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<<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. // Reset homing axis locks based on cycle mask.
uint8_t axislock = 0; uint8_t axislock = 0;
if (bit_istrue(cycle_mask,bit(X_AXIS))) { axislock |= (1<<X_STEP_BIT); } 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(Y_AXIS))) { axislock |= (1<<Y_STEP_BIT); }
if (bit_istrue(cycle_mask,bit(Z_AXIS))) { axislock |= (1<<Z_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, 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; 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, 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_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. 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. // Check only for user reset. No time to run protocol_execute_runtime() in this loop.
if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; } if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; }
} while (STEP_MASK & axislock); } while (STEP_MASK & axislock);
st_reset(); // Immediately force kill steppers and reset step segment buffer. st_reset(); // Immediately force kill steppers and reset step segment buffer.
plan_reset(); // Reset planner buffer. Zero planner positions. 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). // Reverse direction and reset homing rate for locate cycle(s).
homing_rate = settings.homing_feed_rate; homing_rate = settings.homing_feed_rate;

View File

@ -39,7 +39,7 @@
// segments, must pass through this routine before being passed to the planner. The seperation of // 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 // 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. // 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, uint32_t line_number) void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number)
{ {
// If enabled, check for soft limit violations. Placed here all line motions are picked up // If enabled, check for soft limit violations. Placed here all line motions are picked up
// from everywhere in Grbl. // from everywhere in Grbl.
@ -87,7 +87,7 @@ void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t
// of each segment is configured in settings.arc_tolerance, which is defined to be the maximum normal // 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. // 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, 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, uint32_t line_number) uint8_t axis_linear, float feed_rate, uint8_t invert_feed_rate, float radius, uint8_t isclockwise, int32_t line_number)
{ {
float center_axis0 = position[axis_0] + offset[axis_0]; float center_axis0 = position[axis_0] + offset[axis_0];
float center_axis1 = position[axis_1] + offset[axis_1]; float center_axis1 = position[axis_1] + offset[axis_1];

View File

@ -22,19 +22,20 @@
#ifndef motion_control_h #ifndef motion_control_h
#define motion_control_h #define motion_control_h
#define HOMING_CYCLE_LINE_NUMBER 1000000000 #define HOMING_CYCLE_LINE_NUMBER -1
// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second // 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 // unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
// (1 minute)/feed_rate time. // (1 minute)/feed_rate time.
void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t line_number); void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number);
// Execute an arc in offset mode format. position == current xyz, target == target xyz, // 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 // 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 // the direction of helical travel, radius == circle radius, isclockwise boolean. Used
// for vector transformation direction. // for vector transformation direction.
void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8_t axis_1, 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, uint32_t line_number); uint8_t axis_linear, float feed_rate, uint8_t invert_feed_rate, float radius, uint8_t isclockwise, int32_t line_number);
// Dwell for a specific number of seconds // Dwell for a specific number of seconds
void mc_dwell(float seconds); void mc_dwell(float seconds);

View File

@ -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 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 is true, or as seek/rapids rate if the feed_rate value is negative (and
invert_feed_rate always false). */ invert_feed_rate always false). */
void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_t line_number) void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number)
{ {
// Prepare and initialize new block // Prepare and initialize new block
plan_block_t *block = &block_buffer[block_buffer_head]; plan_block_t *block = &block_buffer[block_buffer_head];
@ -267,9 +267,10 @@ void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate,
block->millimeters = 0; block->millimeters = 0;
block->direction_bits = 0; block->direction_bits = 0;
block->acceleration = SOME_LARGE_VALUE; // Scaled down to maximum acceleration later block->acceleration = SOME_LARGE_VALUE; // Scaled down to maximum acceleration later
#ifdef USE_LINE_NUMBERS #ifdef USE_LINE_NUMBERS
block->line_number = line_number; block->line_number = line_number;
#endif #endif
// Compute and store initial move distance data. // 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 // 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. // to try to keep these types of things completely separate from the planner for portability.

View File

@ -51,9 +51,10 @@ typedef struct {
float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2) float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2)
float millimeters; // The remaining distance for this block to be executed in (mm) 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 // uint8_t max_override; // Maximum override value based on axis speed limits
#ifdef USE_LINE_NUMBERS
uint32_t line_number; #ifdef USE_LINE_NUMBERS
#endif int32_t line_number;
#endif
} plan_block_t; } plan_block_t;
@ -63,7 +64,7 @@ void plan_reset();
// Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position // 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 // 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. // 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, uint32_t line_number); void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number);
// Called when the current block is no longer needed. Discards the block and makes the memory // Called when the current block is no longer needed. Discards the block and makes the memory
// availible for new blocks. // availible for new blocks.

View File

@ -262,9 +262,9 @@ void report_gcode_modes()
} }
switch (gc.spindle_direction) { switch (gc.spindle_direction) {
case 1 : printPgmString(PSTR(" M3")); break; case SPINDLE_ENABLE_CW : printPgmString(PSTR(" M3")); break;
case -1 : printPgmString(PSTR(" M4")); break; case SPINDLE_ENABLE_CCW : printPgmString(PSTR(" M4")); break;
case 0 : printPgmString(PSTR(" M5")); break; case SPINDLE_DISABLE : printPgmString(PSTR(" M5")); break;
} }
switch (gc.coolant_mode) { switch (gc.coolant_mode) {
@ -353,9 +353,8 @@ void report_realtime_status()
#ifdef USE_LINE_NUMBERS #ifdef USE_LINE_NUMBERS
// Report current line number // Report current line number
printPgmString(PSTR(",")); printPgmString(PSTR(",Ln:"));
printPgmString(PSTR("Ln:")); int32_t ln=0;
uint32_t ln=0;
plan_block_t * pb = plan_get_current_block(); plan_block_t * pb = plan_get_current_block();
if(pb != NULL) { if(pb != NULL) {
ln = pb->line_number; ln = pb->line_number;