Merge pull request #356 from robgrz/dev

Line number reporting as compile-time option.
This commit is contained in:
Sonny Jeon 2014-02-19 07:32:51 -07:00
commit 9c95c1439f
8 changed files with 97 additions and 68 deletions

View File

@ -28,6 +28,10 @@
#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

14
gcode.c
View File

@ -101,6 +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;
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.
@ -215,7 +216,7 @@ uint8_t gc_execute_line(char *line)
char_counter = 0; char_counter = 0;
while(next_statement(&letter, &value, line, &char_counter)) { while(next_statement(&letter, &value, line, &char_counter)) {
switch(letter) { 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': case 'F':
if (value <= 0) { FAIL(STATUS_INVALID_STATEMENT); } // Must be greater than zero if (value <= 0) { FAIL(STATUS_INVALID_STATEMENT); } // Must be greater than zero
if (gc.inverse_feed_rate_mode) { if (gc.inverse_feed_rate_mode) {
@ -226,6 +227,7 @@ uint8_t gc_execute_line(char *line)
break; break;
case 'I': case 'J': case 'K': gc.arc_offset[letter-'I'] = to_millimeters(value); break; case 'I': case 'J': case 'K': gc.arc_offset[letter-'I'] = to_millimeters(value); break;
case 'L': l = trunc(value); break; case 'L': l = trunc(value); break;
case 'N': line_number = trunc(value); break;
case 'P': p = value; break; case 'P': p = value; break;
case 'R': gc.arc_radius = to_millimeters(value); break; case 'R': gc.arc_radius = to_millimeters(value); break;
case 'S': case 'S':
@ -329,7 +331,7 @@ uint8_t gc_execute_line(char *line)
target[idx] = gc.position[idx]; 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 // Retreive G28/30 go-home position data (in machine coordinates) from EEPROM
float coord_data[N_AXIS]; float coord_data[N_AXIS];
@ -338,7 +340,7 @@ uint8_t gc_execute_line(char *line)
} else { } else {
if (!settings_read_coord_data(SETTING_INDEX_G30,coord_data)) { return(STATUS_SETTING_READ_FAIL); } 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[]; 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. axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags.
break; break;
@ -409,7 +411,7 @@ uint8_t gc_execute_line(char *line)
break; break;
case MOTION_MODE_SEEK: case MOTION_MODE_SEEK:
if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);} if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);}
else { mc_line(target, -1.0, false); } else { mc_line(target, -1.0, false, line_number); }
break; break;
case MOTION_MODE_LINEAR: case MOTION_MODE_LINEAR:
// TODO: Inverse time requires F-word with each statement. Need to do a check. Also need // 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 // and after an inverse time move and then check for non-zero feed rate each time. This
// should be efficient and effective. // should be efficient and effective.
if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);} 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; break;
case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: 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 // 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 // Trace the arc
mc_arc(gc.position, target, gc.arc_offset, gc.plane_axis_0, gc.plane_axis_1, gc.plane_axis_2, 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.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; break;
} }

View File

@ -168,7 +168,7 @@ void limits_go_home(uint8_t cycle_mask)
// Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle. // Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
uint8_t limit_state; uint8_t limit_state;
plan_buffer_line(target, homing_rate, false); // Bypass mc_line(). Directly plan homing motion. 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_prep_buffer(); // Prep and fill segment buffer from newly planned block.
st_wake_up(); // Initiate motion st_wake_up(); // Initiate motion
do { do {
@ -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_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. // Initiate pull-off using main motion control routines.
// TODO : Clean up state routines so that this motion still shows homing state. // TODO : Clean up state routines so that this motion still shows homing state.

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) 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 // If enabled, check for soft limit violations. Placed here all line motions are picked up
// from everywhere in Grbl. // from everywhere in Grbl.
@ -71,7 +71,7 @@ void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate)
else { break; } else { break; }
} while (1); } 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 // If idle, indicate to the system there is now a planned block in the buffer ready to cycle
// start. Otherwise ignore and continue on. // start. Otherwise ignore and continue on.
@ -87,7 +87,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 // 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) 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_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];
@ -183,14 +183,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_0] = center_axis0 + r_axis0;
arc_target[axis_1] = center_axis1 + r_axis1; arc_target[axis_1] = center_axis1 + r_axis1;
arc_target[axis_linear] += linear_per_segment; 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. // Bail mid-circle on system abort. Runtime command check already performed by mc_line.
if (sys.abort) { return; } if (sys.abort) { return; }
} }
} }
// Ensure last segment arrives at target location. // 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);
} }

View File

@ -22,18 +22,19 @@
#ifndef motion_control_h #ifndef motion_control_h
#define 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 // 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); 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, // 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); 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 // 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) void plan_buffer_line(float *target, float feed_rate, uint8_t invert_feed_rate, uint32_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,7 +267,9 @@ 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
block->line_number = line_number;
#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

@ -26,8 +26,12 @@
// The number of linear motions that can be in the plan at any give time // The number of linear motions that can be in the plan at any give time
#ifndef BLOCK_BUFFER_SIZE #ifndef BLOCK_BUFFER_SIZE
#ifdef USE_LINE_NUMBERS
#define BLOCK_BUFFER_SIZE 16
#else
#define BLOCK_BUFFER_SIZE 18 #define BLOCK_BUFFER_SIZE 18
#endif #endif
#endif
// This struct stores a linear movement of a g-code block motion with its critical "nominal" values // This struct stores a linear movement of a g-code block motion with its critical "nominal" values
// are as specified in the source g-code. // are as specified in the source g-code.
@ -47,6 +51,9 @@ 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;
#endif
} plan_block_t; } 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 // 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); 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 // 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

@ -32,6 +32,7 @@
#include "settings.h" #include "settings.h"
#include "gcode.h" #include "gcode.h"
#include "coolant_control.h" #include "coolant_control.h"
#include "planner.h"
#include "spindle_control.h" #include "spindle_control.h"
@ -261,9 +262,9 @@ void report_gcode_modes()
} }
switch (gc.spindle_direction) { switch (gc.spindle_direction) {
case SPINDLE_ENABLE_CW : printPgmString(PSTR(" M3")); break; case 1 : printPgmString(PSTR(" M3")); break;
case SPINDLE_ENABLE_CCW : printPgmString(PSTR(" M4")); break; case -1 : printPgmString(PSTR(" M4")); break;
case SPINDLE_DISABLE : printPgmString(PSTR(" M5")); break; case 0 : printPgmString(PSTR(" M5")); break;
} }
switch (gc.coolant_mode) { switch (gc.coolant_mode) {
@ -350,5 +351,17 @@ void report_realtime_status()
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); } 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")); printPgmString(PSTR(">\r\n"));
} }