New report module. 6 persistent work coordinates. New G-codes and settings. README and minor bug updates

(NOTE: This push is likely buggy so proceed with caution. Just
uploading to let people know where we're going.)

- New report.c module. Moved all feedback functions into this module to
centralize these processes. Includes realtime status reports, status
messages, feedback messages.

- Official support 6 work coordinate systems (G54-G59), which are
persistently held in EEPROM memory.

- New g-code support: G28.1, G30.1 stores current machine position as a
home position into EEPROM. G10 L20 Px stores current machine position
into work coordinates without needing to explicitly send XYZ words.

- Homing performed with '$H' command. G28/G30 no longer start the
homing cycle. This is how it's supposed to be.

- New settings: Stepper enable invert and n_arc correction installed.

- Updated and changed up some limits and homing functionality. Pull-off
travel will now move after the homing cycle regardless of hard limits
enabled. Fixed direction of pull-off travel (went wrong way).

- Started on designing an internal Grbl command protocol based on the
'$' settings letter. Commands with non numeric characters after '$'
will perform switch commands, homing cycle, jogging, printing
paramters, etc. Much more to do here.

- Updated README to reflect all of the new features.
This commit is contained in:
Sonny Jeon
2012-11-01 09:37:27 -06:00
parent 5d8c3dcbd7
commit e0a9054e32
17 changed files with 847 additions and 621 deletions

92
gcode.c
View File

@@ -32,6 +32,7 @@
#include "coolant_control.h"
#include "errno.h"
#include "protocol.h"
#include "report.h"
// Define modal group internal numbers for checking multiple command violations and tracking the
// type of command that is called in the block. A modal group is a group of g-code commands that are
@@ -64,9 +65,12 @@
#define NON_MODAL_NONE 0
#define NON_MODAL_DWELL 1 // G4
#define NON_MODAL_SET_COORDINATE_DATA 2 // G10
#define NON_MODAL_GO_HOME 3 // G28,G30
#define NON_MODAL_SET_COORDINATE_OFFSET 4 // G92
#define NON_MODAL_RESET_COORDINATE_OFFSET 5 //G92.1
#define NON_MODAL_GO_HOME_0 3 // G28
#define NON_MODAL_SET_HOME_0 4 // G28.1
#define NON_MODAL_GO_HOME_1 5 // G30
#define NON_MODAL_SET_HOME_1 6 // G30.1
#define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92
#define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1
typedef struct {
uint8_t status_code; // Parser status for current block
@@ -182,22 +186,20 @@ uint8_t gc_execute_line(char *line)
case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); break;
case 20: gc.inches_mode = true; break;
case 21: gc.inches_mode = false; break;
// NOTE: G28.1, G30.1 sets home position parameters. Not currently supported.
case 28: case 30:
// NOTE: G28.1, G30.1 sets home position parameters. Not currently supported.
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) {
non_modal_action = NON_MODAL_GO_HOME;
} else {
FAIL(STATUS_SETTING_DISABLED);
int_value = trunc(10*value); // Multiply by 10 to pick up G92.1
switch(int_value) {
case 280: non_modal_action = NON_MODAL_GO_HOME_0; break;
case 281: non_modal_action = NON_MODAL_SET_HOME_0; break;
case 300: non_modal_action = NON_MODAL_GO_HOME_1; break;
case 301: non_modal_action = NON_MODAL_SET_HOME_1; break;
default: FAIL(STATUS_UNSUPPORTED_STATEMENT);
}
break;
case 53: absolute_override = true; break;
case 54: case 55: case 56: case 57: case 58: case 59:
int_value -= 54; // Compute coordinate system row index (0=G54,1=G55,...)
if (int_value < N_COORDINATE_SYSTEM) {
sys.coord_select = int_value;
} else {
FAIL(STATUS_UNSUPPORTED_STATEMENT);
}
sys.coord_select = int_value-54;
break;
case 80: gc.motion_mode = MOTION_MODE_CANCEL; break;
case 90: gc.absolute_mode = true; break;
@@ -307,6 +309,13 @@ uint8_t gc_execute_line(char *line)
// [*M7,M8,M9]: Update coolant state
coolant_run(gc.coolant_mode);
// [G54,G55,...,G59]: Coordinate system selection
if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block
float coord_data[N_AXIS];
if (!(settings_read_coord_data(sys.coord_select,coord_data))) { return(STATUS_SETTING_READ_FAIL); }
memcpy(sys.coord_system,coord_data,sizeof(coord_data));
}
// [G4,G10,G28,G30,G92,G92.1]: Perform dwell, set coordinate system data, homing, or set axis offsets.
// NOTE: These commands are in the same modal group, hence are mutually exclusive. G53 is in this
// modal group and do not effect these actions.
@@ -320,30 +329,41 @@ uint8_t gc_execute_line(char *line)
break;
case NON_MODAL_SET_COORDINATE_DATA:
int_value = trunc(p); // Convert p value to int.
if (l != 2 || (int_value < 1 || int_value > N_COORDINATE_SYSTEM)) { // L2 only. P1=G54, P2=G55, ...
if ((l != 2 && l != 20) || (int_value < 1 || int_value > N_COORDINATE_SYSTEM)) { // L2 and L20. P1=G54, P2=G55, ...
FAIL(STATUS_UNSUPPORTED_STATEMENT);
} else if (!axis_words) { // No axis words.
} else if (!axis_words && l==2) { // No axis words.
FAIL(STATUS_INVALID_STATEMENT);
} else {
int_value--; // Adjust p to be inline with row array index.
// Update axes defined only in block. Always in machine coordinates. Can change non-active system.
uint8_t i;
for (i=0; i<=2; i++) { // Axes indices are consistent, so loop may be used.
if ( bit_istrue(axis_words,bit(i)) ) { sys.coord_system[int_value][i] = target[i]; }
int_value--; // Adjust P index to EEPROM coordinate data indexing.
if (l == 20) {
settings_write_coord_data(int_value,gc.position);
// Update system coordinate system if currently active.
if (sys.coord_select == int_value) { memcpy(sys.coord_system,gc.position,sizeof(gc.position)); }
} else {
float coord_data[N_AXIS];
if (!settings_read_coord_data(int_value,coord_data)) { return(STATUS_SETTING_READ_FAIL); }
// Update axes defined only in block. Always in machine coordinates. Can change non-active system.
uint8_t i;
for (i=0; i<N_AXIS; i++) { // Axes indices are consistent, so loop may be used.
if ( bit_istrue(axis_words,bit(i)) ) { coord_data[i] = target[i]; }
}
settings_write_coord_data(int_value,coord_data);
// Update system coordinate system if currently active.
if (sys.coord_select == int_value) { memcpy(sys.coord_system,coord_data,sizeof(coord_data)); }
}
}
axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags.
break;
case NON_MODAL_GO_HOME:
case NON_MODAL_GO_HOME_0: case NON_MODAL_GO_HOME_1:
// Move to intermediate position before going home. Obeys current coordinate system and offsets
// and absolute and incremental modes.
if (axis_words) {
// Apply absolute mode coordinate offsets or incremental mode offsets.
uint8_t i;
for (i=0; i<=2; i++) { // Axes indices are consistent, so loop may be used.
for (i=0; i<N_AXIS; i++) { // Axes indices are consistent, so loop may be used.
if ( bit_istrue(axis_words,bit(i)) ) {
if (gc.absolute_mode) {
target[i] += sys.coord_system[sys.coord_select][i] + sys.coord_offset[i];
target[i] += sys.coord_system[i] + sys.coord_offset[i];
} else {
target[i] += gc.position[i];
}
@@ -353,9 +373,19 @@ uint8_t gc_execute_line(char *line)
}
mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], settings.default_seek_rate, false);
}
mc_go_home();
// Retreive G28/30 go-home position data (in machine coordinates) from EEPROM
float coord_data[N_AXIS];
uint8_t home_select = SETTING_INDEX_G28;
if (non_modal_action == NON_MODAL_GO_HOME_1) { home_select = SETTING_INDEX_G30; }
if (!settings_read_coord_data(home_select,coord_data)) { return(STATUS_SETTING_READ_FAIL); }
mc_line(coord_data[X_AXIS], coord_data[Y_AXIS], coord_data[Z_AXIS], settings.default_seek_rate, false);
axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags.
break;
break;
case NON_MODAL_SET_HOME_0: case NON_MODAL_SET_HOME_1:
home_select = SETTING_INDEX_G28;
if (non_modal_action == NON_MODAL_SET_HOME_1) { home_select = SETTING_INDEX_G30; }
settings_write_coord_data(home_select,gc.position);
break;
case NON_MODAL_SET_COORDINATE_OFFSET:
if (!axis_words) { // No axis words
FAIL(STATUS_INVALID_STATEMENT);
@@ -365,7 +395,7 @@ uint8_t gc_execute_line(char *line)
uint8_t i;
for (i=0; i<=2; i++) { // Axes indices are consistent, so loop may be used.
if (bit_istrue(axis_words,bit(i)) ) {
sys.coord_offset[i] = gc.position[i]-sys.coord_system[sys.coord_select][i]-target[i];
sys.coord_offset[i] = gc.position[i]-sys.coord_system[i]-target[i];
}
}
}
@@ -402,7 +432,7 @@ uint8_t gc_execute_line(char *line)
if ( bit_istrue(axis_words,bit(i)) ) {
if (!absolute_override) { // Do not update target in absolute override mode
if (gc.absolute_mode) {
target[i] += sys.coord_system[sys.coord_select][i] + sys.coord_offset[i]; // Absolute mode
target[i] += sys.coord_system[i] + sys.coord_offset[i]; // Absolute mode
} else {
target[i] += gc.position[i]; // Incremental mode
}
@@ -421,6 +451,10 @@ uint8_t gc_execute_line(char *line)
else { mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], settings.default_seek_rate, false); }
break;
case MOTION_MODE_LINEAR:
// TODO: Inverse time requires F-word with each statement. Need to do a check. Also need
// to check for initial F-word upon startup. Maybe just set to zero upon initialization
// 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[X_AXIS], target[Y_AXIS], target[Z_AXIS],
(gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); }
@@ -546,7 +580,7 @@ uint8_t gc_execute_line(char *line)
// As far as the parser is concerned, the position is now == target. In reality the
// motion control system might still be processing the action and the real tool position
// in any intermediate location.
memcpy(gc.position, target, sizeof(float)*3); // gc.position[] = target[];
memcpy(gc.position, target, sizeof(target)); // gc.position[] = target[];
}
// M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may