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:
parent
559feb97e2
commit
5dd6d90122
2
config.h
2
config.h
@ -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
20
gcode.c
@ -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
11
gcode.h
@ -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}
|
||||
|
@ -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
|
||||
|
17
nuts_bolts.h
17
nuts_bolts.h
@ -69,14 +69,15 @@
|
||||
// Define system state bit map. The state variable primarily tracks the individual functions
|
||||
// of Grbl to manage each without overlapping. It is also used as a messaging flag for
|
||||
// critical events.
|
||||
#define STATE_IDLE 0 // Must be zero.
|
||||
#define STATE_INIT 1 // Initial power up state.
|
||||
#define STATE_QUEUED 2 // Indicates buffered blocks, awaiting cycle start.
|
||||
#define STATE_CYCLE 3 // Cycle is running
|
||||
#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_IDLE 0 // Must be zero.
|
||||
#define STATE_INIT 1 // Initial power up state.
|
||||
#define STATE_QUEUED 2 // Indicates buffered blocks, awaiting cycle start.
|
||||
#define STATE_CYCLE 3 // Cycle is running
|
||||
#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_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 {
|
||||
|
58
protocol.c
58
protocol.c
@ -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++) {
|
||||
@ -323,11 +316,8 @@ void protocol_process()
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
} else if (c == '/') {
|
||||
// Block delete not supported. Ignore character.
|
||||
} else if (c == '(') {
|
||||
// Enable comments flag and ignore all characters until ')' or EOL.
|
||||
iscomment = true;
|
||||
|
41
report.c
41
report.c
@ -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) {
|
||||
@ -268,15 +265,7 @@ void report_gcode_modes()
|
||||
printPgmString(PSTR(" F"));
|
||||
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"));
|
||||
}
|
||||
|
2
report.h
2
report.h
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user