Added Grbl state in status report. Removed switch support.

- Added Grbl state (Idle, Running, Queued, Hold, etc) to the real-time
status reporting feature as feedback to the user of what Grbl is doing.
Updated the help message to reflect this change.

- Removed switches (dry run, block delete, single block mode). To keep
Grbl simple and not muddled up from things that can easily be taken
care of by an external interface, these were removed.

- Check g-code mode was retained, but the command was moved to '$C'
from '$S0'.
This commit is contained in:
Sonny Jeon 2012-11-15 21:53:11 -07:00
parent 559feb97e2
commit 5dd6d90122
8 changed files with 63 additions and 90 deletions

View File

@ -123,7 +123,7 @@
// that do not and must not exist in the streamed g-code program. ASCII control characters may be
// used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in
// g-code programs, maybe selected for interface programs.
// TODO: Solidify these default characters. Temporary for now.
// NOTE: If changed, manually update help message in report.c.
#define CMD_STATUS_REPORT '?'
#define CMD_FEED_HOLD '!'
#define CMD_CYCLE_START '~'

20
gcode.c
View File

@ -60,8 +60,6 @@ void gc_init()
if (!(settings_read_coord_data(gc.coord_select,gc.coord_system))) {
report_status_message(STATUS_SETTING_READ_FAIL);
}
// protocol_status_message(settings_execute_startup());
}
// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard
@ -176,11 +174,7 @@ uint8_t gc_execute_line(char *line)
// Set 'M' commands
switch(int_value) {
case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
case 1: // Program pause with optional stop on, otherwise do nothing.
if (bit_istrue(gc.switches,BITFLAG_OPT_STOP)) {
gc.program_flow = PROGRAM_FLOW_PAUSED;
}
break;
case 1: break; // Optional stop not supported. Ignore.
case 2: case 30: gc.program_flow = PROGRAM_FLOW_COMPLETED; break; // Program end and reset
case 3: gc.spindle_direction = 1; break;
case 4: gc.spindle_direction = -1; break;
@ -260,10 +254,10 @@ uint8_t gc_execute_line(char *line)
// ([M6]: Tool change should be executed here.)
// [M3,M4,M5]: Update spindle state
if (!(gc.switches & BITFLAG_CHECK_GCODE)) { spindle_run(gc.spindle_direction); }
if (sys.state != STATE_CHECK_MODE) { spindle_run(gc.spindle_direction); }
// [*M7,M8,M9]: Update coolant state
if (!(gc.switches & BITFLAG_CHECK_GCODE)) { coolant_run(gc.coolant_mode); }
if (sys.state != STATE_CHECK_MODE) { 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
@ -281,7 +275,7 @@ uint8_t gc_execute_line(char *line)
FAIL(STATUS_INVALID_STATEMENT);
} else {
// Ignore dwell in check gcode modes
if (!(gc.switches & BITFLAG_CHECK_GCODE)) { mc_dwell(p); }
if (sys.state != STATE_CHECK_MODE) { mc_dwell(p); }
}
break;
case NON_MODAL_SET_COORDINATE_DATA:
@ -544,7 +538,7 @@ uint8_t gc_execute_line(char *line)
// M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may
// refill and can only be resumed by the cycle start run-time command.
if (gc.program_flow || bit_istrue(gc.switches,BITFLAG_SINGLE_BLOCK)) {
if (gc.program_flow) {
plan_synchronize(); // Finish all remaining buffered motions. Program paused when complete.
sys.auto_start = false; // Disable auto cycle start. Forces pause until cycle start issued.
@ -588,12 +582,14 @@ static int next_statement(char *letter, float *float_ptr, char *line, uint8_t *c
- Evaluation of expressions
- Variables
- Probing
- Override control
- Override control (TBD)
- Tool changes
- Switches
(*) Indicates optional parameter, enabled through config.h and re-compile
group 0 = {G92.2, G92.3} (Non modal: Cancel and re-enable G92 offsets)
group 1 = {G38.2, G81 - G89} (Motion modes: straight probe, canned cycles)
group 4 = {M1} (Optional stop, ignored)
group 6 = {M6} (Tool change)
group 8 = {*M7} enable mist coolant
group 9 = {M48, M49} enable/disable feed and speed override switches

11
gcode.h
View File

@ -62,19 +62,8 @@
#define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92
#define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1
// Define bit flag masks for gc.switches. (8 flag limit)
#define BITFLAG_CHECK_GCODE bit(0)
#define BITFLAG_BLOCK_DELETE bit(1)
#define BITFLAG_SINGLE_BLOCK bit(2)
#define BITFLAG_OPT_STOP bit(3)
// #define bit(4)
// #define bit(5)
// #define bit(6)
// #define bit(7)
typedef struct {
uint8_t status_code; // Parser status for current block
uint8_t switches; // Handles non-gcode switches modes. Set externally by protocol. Default off
uint8_t motion_mode; // {G0, G1, G2, G3, G80}
uint8_t inverse_feed_rate_mode; // {G93, G94}
uint8_t inches_mode; // 0 = millimeter mode, 1 = inches mode {G20, G21}

View File

@ -64,7 +64,7 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat
} while ( plan_check_full_buffer() );
// If in check gcode mode, prevent motion by blocking planner.
if (bit_isfalse(gc.switches,BITFLAG_CHECK_GCODE)) {
if (sys.state != STATE_CHECK_MODE) {
plan_buffer_line(x, y, z, feed_rate, invert_feed_rate);
// If idle, indicate to the system there is now a planned block in the buffer ready to cycle

View File

@ -76,7 +76,8 @@
#define STATE_HOLD 4 // Executing feed hold
#define STATE_HOMING 5 // Performing homing cycle
#define STATE_ALARM 6 // In alarm state. Locks out all g-code processes. Allows settings access.
// #define STATE_JOG 7 // Jogging mode is unique like homing.
#define STATE_CHECK_MODE 7 // G-code check mode. Locks out planner and motion only.
// #define STATE_JOG 8 // Jogging mode is unique like homing.
// Define global system variables
typedef struct {

View File

@ -195,6 +195,28 @@ uint8_t protocol_execute_line(char *line)
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
else { report_gcode_modes(); }
break;
case 'C' : // Set check g-code mode
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
// Perform reset when toggling off. Check g-code mode should only work if Grbl
// is idle and ready, regardless of alarm locks. This is mainly to keep things
// simple and consistent.
if ( sys.state == STATE_CHECK_MODE ) {
mc_reset();
report_feedback_message(MESSAGE_DISABLED);
} else {
if (sys.state) { return(STATUS_IDLE_ERROR); }
sys.state = STATE_CHECK_MODE;
report_feedback_message(MESSAGE_ENABLED);
}
break;
case 'X' : // Disable alarm lock
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
if (sys.state == STATE_ALARM) {
report_feedback_message(MESSAGE_ALARM_UNLOCK);
sys.state = STATE_IDLE;
// Don't run startup script. Prevents stored moves in startup from causing accidents.
}
break;
case 'H' : // Perform homing cycle
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) {
// Only perform homing if Grbl is idle or lost.
@ -216,35 +238,6 @@ uint8_t protocol_execute_line(char *line)
// handled by the planner. It would be possible for the jog subprogram to insert blocks into the
// block buffer without having the planner plan them. It would need to manage de/ac-celerations
// on its own carefully. This approach could be effective and possibly size/memory efficient.
case 'S' : // Switch modes
// Set helper_var as switch bitmask or clearing flag
switch (line[++char_counter]) {
case '0' : helper_var = BITFLAG_CHECK_GCODE; break;
case '1' : helper_var = BITFLAG_BLOCK_DELETE; break;
case '2' : helper_var = BITFLAG_SINGLE_BLOCK; break;
case '3' : helper_var = BITFLAG_OPT_STOP; break;
default : return(STATUS_INVALID_STATEMENT);
}
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
if ( helper_var & BITFLAG_CHECK_GCODE ) {
// Perform reset when toggling off. Check g-code mode should only work if Grbl
// is idle and ready, regardless of homing locks. This is mainly to keep things
// simple and consistent.
if ( bit_istrue(gc.switches,helper_var) ) { mc_reset(); }
else if (sys.state) { return(STATUS_IDLE_ERROR); }
}
gc.switches ^= helper_var;
if (bit_istrue(gc.switches,helper_var)) { report_feedback_message(MESSAGE_ENABLED); }
else { report_feedback_message(MESSAGE_DISABLED); }
break;
case 'X' : // Disable alarm lock
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
if (sys.state == STATE_ALARM) {
report_feedback_message(MESSAGE_ALARM_UNLOCK);
sys.state = STATE_IDLE;
// Don't run startup script. Prevents stored moves in startup from causing accidents.
}
break;
case 'N' : // Startup lines.
if ( line[++char_counter] == 0 ) { // Print startup lines
for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) {
@ -324,10 +317,7 @@ void protocol_process()
if (c <= ' ') {
// Throw away whitepace and control characters
} else if (c == '/') {
// Disable block delete and throw away characters. Will ignore until EOL.
if (bit_istrue(gc.switches,BITFLAG_BLOCK_DELETE)) {
iscomment = true;
}
// Block delete not supported. Ignore character.
} else if (c == '(') {
// Enable comments flag and ignore all characters until ')' or EOL.
iscomment = true;

View File

@ -131,15 +131,12 @@ void report_grbl_help() {
"$N (view startup blocks)\r\n"
"$x=value (save Grbl setting)\r\n"
"$Nx=line (save startup block)\r\n"
"$S0 (toggle check gcode)\r\n"
"$S1 (toggle blk del)\r\n"
"$S2 (toggle single blk)\r\n"
"$S3 (toggle opt stop)\r\n"
"$C (check gcode mode)\r\n"
"$X (kill alarm lock)\r\n"
"$H (run homing cycle)\r\n"
"~ (cycle start)\r\n"
"! (feed hold)\r\n"
"? (position)\r\n"
"? (current status)\r\n"
"ctrl-x (reset Grbl)\r\n"));
}
@ -214,7 +211,7 @@ void report_gcode_parameters()
}
// Print current gcode parser mode state and active switches
// Print current gcode parser mode state
void report_gcode_modes()
{
switch (gc.motion_mode) {
@ -269,14 +266,6 @@ void report_gcode_modes()
if (gc.inches_mode) { printFloat(gc.feed_rate*INCH_PER_MM); }
else { printFloat(gc.feed_rate); }
// Print active switches
if (gc.switches) {
if (bit_istrue(gc.switches,BITFLAG_CHECK_GCODE)) { printPgmString(PSTR(" $S0")); }
if (bit_istrue(gc.switches,BITFLAG_BLOCK_DELETE)) { printPgmString(PSTR(" $S1")); }
if (bit_istrue(gc.switches,BITFLAG_SINGLE_BLOCK)) { printPgmString(PSTR(" $S2")); }
if (bit_istrue(gc.switches,BITFLAG_OPT_STOP)) { printPgmString(PSTR(" $S3")); }
}
printPgmString(PSTR("\r\n"));
}
@ -304,20 +293,29 @@ void report_realtime_status()
memcpy(current_position,sys.position,sizeof(sys.position));
float print_position[3];
// TODO: Add Grbl state feedback, i.e. IDLE, RUN, HOLD, HOME, etc.
// Report current machine state
switch (sys.state) {
case STATE_IDLE: printPgmString(PSTR("[Idle")); break;
// case STATE_INIT: printPgmString(PSTR("[Init")); break; // Never observed
case STATE_QUEUED: printPgmString(PSTR("[Queue")); break;
case STATE_CYCLE: printPgmString(PSTR("[Run")); break;
case STATE_HOLD: printPgmString(PSTR("[Hold")); break;
case STATE_HOMING: printPgmString(PSTR("[Home")); break;
case STATE_ALARM: printPgmString(PSTR("[Alarm")); break;
case STATE_CHECK_MODE: printPgmString(PSTR("[Check")); break;
}
// Report machine position
printPgmString(PSTR("MPos:["));
printPgmString(PSTR(",MPos:"));
for (i=0; i<= 2; i++) {
print_position[i] = current_position[i]/settings.steps_per_mm[i];
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { print_position[i] *= INCH_PER_MM; }
printFloat(print_position[i]);
if (i < 2) { printPgmString(PSTR(",")); }
else { printPgmString(PSTR("]")); }
printPgmString(PSTR(","));
}
// Report work position
printPgmString(PSTR(",WPos:["));
printPgmString(PSTR("WPos:"));
for (i=0; i<= 2; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
print_position[i] -= (gc.coord_system[i]+gc.coord_offset[i])*INCH_PER_MM;
@ -326,8 +324,7 @@ void report_realtime_status()
}
printFloat(print_position[i]);
if (i < 2) { printPgmString(PSTR(",")); }
else { printPgmString(PSTR("]")); }
}
printPgmString(PSTR("\r\n"));
printPgmString(PSTR("]\r\n"));
}

View File

@ -71,7 +71,7 @@ void report_realtime_status();
// Prints Grbl persistent coordinate parameters
void report_gcode_parameters();
// Prints current g-code parser mode state and active switches
// Prints current g-code parser mode state
void report_gcode_modes();
// Prints startup line