Added block delete, opt stop, single block mode. New parser state and parameter feedback. Overhauled '$' command.

NOTE: Another incremental update. Likely buggy, still a ways to go
before everything is installed, such as startup blocks.

- Changed the '$' command to print help. '$$' now prints Grbl settings.
The help now instructs the user of runtime commands, switch toggling,
homing, etc. Jogging will be added to these in v0.9.

- Added switches: block delete, opt stop, and single block mode.

- Now can print the g-code parser state and persistent parameters
(coord sys) to view what Grbl has internally.

- Made the gc struct in the g-code parser global to be able to print
the states. Also moved coordinate system tracking from sys to gc struct.

- Changed up the welcome flag and updated version to v0.8c.

- Removed spindle speed from gcode parser. Not used.
This commit is contained in:
Sonny Jeon 2012-11-01 19:48:55 -06:00
parent e0a9054e32
commit 303cf59f52
11 changed files with 570 additions and 448 deletions

View File

@ -149,7 +149,7 @@
// TODO: The following options are set as compile-time options for now, until the next EEPROM // TODO: The following options are set as compile-time options for now, until the next EEPROM
// settings version has solidified. This is to prevent having to support dozens of different // settings version has solidified. This is to prevent having to support dozens of different
// incremental settings versions. // incremental settings versions.
#define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing // -> NOW CODED INTO SETTINGS #define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing
// This parameter sets the delay time before disabling the steppers after the final block of movement. // This parameter sets the delay time before disabling the steppers after the final block of movement.
// A short delay ensures the steppers come to a complete stop and the residual inertial force in the // A short delay ensures the steppers come to a complete stop and the residual inertial force in the

106
gcode.c
View File

@ -34,62 +34,8 @@
#include "protocol.h" #include "protocol.h"
#include "report.h" #include "report.h"
// Define modal group internal numbers for checking multiple command violations and tracking the // Declare gc extern struct
// type of command that is called in the block. A modal group is a group of g-code commands that are parser_state_t gc;
// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute
// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online,
// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc).
#define MODAL_GROUP_NONE 0
#define MODAL_GROUP_0 1 // [G4,G10,G28,G30,G53,G92,G92.1] Non-modal
#define MODAL_GROUP_1 2 // [G0,G1,G2,G3,G80] Motion
#define MODAL_GROUP_2 3 // [G17,G18,G19] Plane selection
#define MODAL_GROUP_3 4 // [G90,G91] Distance mode
#define MODAL_GROUP_4 5 // [M0,M1,M2,M30] Stopping
#define MODAL_GROUP_5 6 // [G93,G94] Feed rate mode
#define MODAL_GROUP_6 7 // [G20,G21] Units
#define MODAL_GROUP_7 8 // [M3,M4,M5] Spindle turning
#define MODAL_GROUP_12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
// internally by the parser to know which command to execute.
#define MOTION_MODE_SEEK 0 // G0
#define MOTION_MODE_LINEAR 1 // G1
#define MOTION_MODE_CW_ARC 2 // G2
#define MOTION_MODE_CCW_ARC 3 // G3
#define MOTION_MODE_CANCEL 4 // G80
#define PROGRAM_FLOW_RUNNING 0
#define PROGRAM_FLOW_PAUSED 1 // M0, M1
#define PROGRAM_FLOW_COMPLETED 2 // M2, M30
#define NON_MODAL_NONE 0
#define NON_MODAL_DWELL 1 // G4
#define NON_MODAL_SET_COORDINATE_DATA 2 // G10
#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
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}
uint8_t absolute_mode; // 0 = relative motion, 1 = absolute motion {G90, G91}
uint8_t program_flow; // {M0, M1, M2, M30}
int8_t spindle_direction; // 1 = CW, -1 = CCW, 0 = Stop {M3, M4, M5}
uint8_t coolant_mode; // 0 = Disable, 1 = Flood Enable {M8, M9}
float feed_rate, seek_rate; // Millimeters/second
float position[3]; // Where the interpreter considers the tool to be at this point in the code
uint8_t tool;
uint16_t spindle_speed; // RPM/100
uint8_t plane_axis_0,
plane_axis_1,
plane_axis_2; // The axes of the selected plane
} parser_state_t;
static parser_state_t gc;
#define FAIL(status) gc.status_code = status; #define FAIL(status) gc.status_code = status;
@ -105,10 +51,15 @@ static void select_plane(uint8_t axis_0, uint8_t axis_1, uint8_t axis_2)
void gc_init() void gc_init()
{ {
memset(&gc, 0, sizeof(gc)); memset(&gc, 0, sizeof(gc));
gc.feed_rate = settings.default_feed_rate; gc.feed_rate = settings.default_feed_rate; // Should be zero at initialization.
select_plane(X_AXIS, Y_AXIS, Z_AXIS); select_plane(X_AXIS, Y_AXIS, Z_AXIS);
gc.absolute_mode = true; gc.absolute_mode = true;
// Load default G54 coordinate system.
if (!(settings_read_coord_data(gc.coord_select,gc.coord_system))) {
report_status_message(STATUS_SETTING_READ_FAIL);
}
// protocol_status_message(settings_execute_startup()); // protocol_status_message(settings_execute_startup());
} }
@ -186,9 +137,8 @@ uint8_t gc_execute_line(char *line)
case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); break; case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); break;
case 20: gc.inches_mode = true; break; case 20: gc.inches_mode = true; break;
case 21: gc.inches_mode = false; break; case 21: gc.inches_mode = false; break;
// NOTE: G28.1, G30.1 sets home position parameters. Not currently supported.
case 28: case 30: case 28: case 30:
int_value = trunc(10*value); // Multiply by 10 to pick up G92.1 int_value = trunc(10*value); // Multiply by 10 to pick up Gxx.1
switch(int_value) { switch(int_value) {
case 280: non_modal_action = NON_MODAL_GO_HOME_0; break; case 280: non_modal_action = NON_MODAL_GO_HOME_0; break;
case 281: non_modal_action = NON_MODAL_SET_HOME_0; break; case 281: non_modal_action = NON_MODAL_SET_HOME_0; break;
@ -199,7 +149,7 @@ uint8_t gc_execute_line(char *line)
break; break;
case 53: absolute_override = true; break; case 53: absolute_override = true; break;
case 54: case 55: case 56: case 57: case 58: case 59: case 54: case 55: case 56: case 57: case 58: case 59:
sys.coord_select = int_value-54; gc.coord_select = int_value-54;
break; break;
case 80: gc.motion_mode = MOTION_MODE_CANCEL; break; case 80: gc.motion_mode = MOTION_MODE_CANCEL; break;
case 90: gc.absolute_mode = true; break; case 90: gc.absolute_mode = true; break;
@ -226,10 +176,11 @@ uint8_t gc_execute_line(char *line)
// Set 'M' commands // Set 'M' commands
switch(int_value) { switch(int_value) {
case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
case 1: // Program pause with optional stop on case 1: // Program pause with optional stop on, otherwise do nothing.
// if (sys.opt_stop) { // TODO: Add system variable for optional stop. if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) {
gc.program_flow = PROGRAM_FLOW_PAUSED; break; gc.program_flow = PROGRAM_FLOW_PAUSED;
// } }
break;
case 2: case 30: gc.program_flow = PROGRAM_FLOW_COMPLETED; break; // Program end and reset case 2: case 30: gc.program_flow = PROGRAM_FLOW_COMPLETED; break; // Program end and reset
case 3: gc.spindle_direction = 1; break; case 3: gc.spindle_direction = 1; break;
case 4: gc.spindle_direction = -1; break; case 4: gc.spindle_direction = -1; break;
@ -280,7 +231,8 @@ uint8_t gc_execute_line(char *line)
case 'R': r = to_millimeters(value); break; case 'R': r = to_millimeters(value); break;
case 'S': case 'S':
if (value < 0) { FAIL(STATUS_INVALID_STATEMENT); } // Cannot be negative if (value < 0) { FAIL(STATUS_INVALID_STATEMENT); } // Cannot be negative
gc.spindle_speed = value; // TBD: Spindle speed not supported due to PWM issues, but may come back once resolved.
// gc.spindle_speed = value;
break; break;
case 'T': case 'T':
if (value < 0) { FAIL(STATUS_INVALID_STATEMENT); } // Cannot be negative if (value < 0) { FAIL(STATUS_INVALID_STATEMENT); } // Cannot be negative
@ -304,7 +256,7 @@ uint8_t gc_execute_line(char *line)
// ([M6]: Tool change should be executed here.) // ([M6]: Tool change should be executed here.)
// [M3,M4,M5]: Update spindle state // [M3,M4,M5]: Update spindle state
spindle_run(gc.spindle_direction, gc.spindle_speed); spindle_run(gc.spindle_direction); //, gc.spindle_speed);
// [*M7,M8,M9]: Update coolant state // [*M7,M8,M9]: Update coolant state
coolant_run(gc.coolant_mode); coolant_run(gc.coolant_mode);
@ -312,8 +264,8 @@ uint8_t gc_execute_line(char *line)
// [G54,G55,...,G59]: Coordinate system selection // [G54,G55,...,G59]: Coordinate system selection
if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block
float coord_data[N_AXIS]; float coord_data[N_AXIS];
if (!(settings_read_coord_data(sys.coord_select,coord_data))) { return(STATUS_SETTING_READ_FAIL); } if (!(settings_read_coord_data(gc.coord_select,coord_data))) { return(STATUS_SETTING_READ_FAIL); }
memcpy(sys.coord_system,coord_data,sizeof(coord_data)); memcpy(gc.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. // [G4,G10,G28,G30,G92,G92.1]: Perform dwell, set coordinate system data, homing, or set axis offsets.
@ -338,7 +290,7 @@ uint8_t gc_execute_line(char *line)
if (l == 20) { if (l == 20) {
settings_write_coord_data(int_value,gc.position); settings_write_coord_data(int_value,gc.position);
// Update system coordinate system if currently active. // Update system coordinate system if currently active.
if (sys.coord_select == int_value) { memcpy(sys.coord_system,gc.position,sizeof(gc.position)); } if (gc.coord_select == int_value) { memcpy(gc.coord_system,gc.position,sizeof(gc.position)); }
} else { } else {
float coord_data[N_AXIS]; float coord_data[N_AXIS];
if (!settings_read_coord_data(int_value,coord_data)) { return(STATUS_SETTING_READ_FAIL); } if (!settings_read_coord_data(int_value,coord_data)) { return(STATUS_SETTING_READ_FAIL); }
@ -349,7 +301,7 @@ uint8_t gc_execute_line(char *line)
} }
settings_write_coord_data(int_value,coord_data); settings_write_coord_data(int_value,coord_data);
// Update system coordinate system if currently active. // Update system coordinate system if currently active.
if (sys.coord_select == int_value) { memcpy(sys.coord_system,coord_data,sizeof(coord_data)); } if (gc.coord_select == int_value) { memcpy(gc.coord_system,coord_data,sizeof(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.
@ -363,7 +315,7 @@ uint8_t gc_execute_line(char *line)
for (i=0; i<N_AXIS; 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 ( bit_istrue(axis_words,bit(i)) ) {
if (gc.absolute_mode) { if (gc.absolute_mode) {
target[i] += sys.coord_system[i] + sys.coord_offset[i]; target[i] += gc.coord_system[i] + gc.coord_offset[i];
} else { } else {
target[i] += gc.position[i]; target[i] += gc.position[i];
} }
@ -395,14 +347,14 @@ uint8_t gc_execute_line(char *line)
uint8_t i; uint8_t i;
for (i=0; i<=2; i++) { // Axes indices are consistent, so loop may be used. for (i=0; i<=2; i++) { // Axes indices are consistent, so loop may be used.
if (bit_istrue(axis_words,bit(i)) ) { if (bit_istrue(axis_words,bit(i)) ) {
sys.coord_offset[i] = gc.position[i]-sys.coord_system[i]-target[i]; gc.coord_offset[i] = gc.position[i]-gc.coord_system[i]-target[i];
} }
} }
} }
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;
case NON_MODAL_RESET_COORDINATE_OFFSET: case NON_MODAL_RESET_COORDINATE_OFFSET:
clear_vector(sys.coord_offset); // Disable G92 offsets by zeroing offset vector. clear_vector(gc.coord_offset); // Disable G92 offsets by zeroing offset vector.
break; break;
} }
@ -432,7 +384,7 @@ uint8_t gc_execute_line(char *line)
if ( bit_istrue(axis_words,bit(i)) ) { if ( bit_istrue(axis_words,bit(i)) ) {
if (!absolute_override) { // Do not update target in absolute override mode if (!absolute_override) { // Do not update target in absolute override mode
if (gc.absolute_mode) { if (gc.absolute_mode) {
target[i] += sys.coord_system[i] + sys.coord_offset[i]; // Absolute mode target[i] += gc.coord_system[i] + gc.coord_offset[i]; // Absolute mode
} else { } else {
target[i] += gc.position[i]; // Incremental mode target[i] += gc.position[i]; // Incremental mode
} }
@ -585,9 +537,9 @@ uint8_t gc_execute_line(char *line)
// M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may // 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. // refill and can only be resumed by the cycle start run-time command.
if (gc.program_flow) { if (gc.program_flow || bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) {
plan_synchronize(); // Finish all remaining buffered motions. Program paused when complete. plan_synchronize(); // Finish all remaining buffered motions. Program paused when complete.
sys.auto_start = false; // Disable auto cycle start. sys.auto_start = false; // Disable auto cycle start. Forces pause until cycle start issued.
// If complete, reset to reload defaults (G92.2,G54,G17,G90,G94,M48,G40,M5,M9). Otherwise, // If complete, reset to reload defaults (G92.2,G54,G17,G90,G94,M48,G40,M5,M9). Otherwise,
// re-enable program flow after pause complete, where cycle start will resume the program. // re-enable program flow after pause complete, where cycle start will resume the program.
@ -628,7 +580,6 @@ static int next_statement(char *letter, float *float_ptr, char *line, uint8_t *c
- A,B,C-axes - A,B,C-axes
- Evaluation of expressions - Evaluation of expressions
- Variables - Variables
- Multiple home locations
- Probing - Probing
- Override control - Override control
- Tool changes - Tool changes
@ -639,6 +590,5 @@ static int next_statement(char *letter, float *float_ptr, char *line, uint8_t *c
group 6 = {M6} (Tool change) group 6 = {M6} (Tool change)
group 8 = {*M7} enable mist coolant group 8 = {*M7} enable mist coolant
group 9 = {M48, M49} enable/disable feed and speed override switches group 9 = {M48, M49} enable/disable feed and speed override switches
group 12 = {*G55, *G56, *G57, *G58, *G59, G59.1, G59.2, G59.3} coordinate system selection
group 13 = {G61, G61.1, G64} path control mode group 13 = {G61, G61.1, G64} path control mode
*/ */

64
gcode.h
View File

@ -19,10 +19,72 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>. along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef gcode_h #ifndef gcode_h
#define gcode_h #define gcode_h
#include <avr/io.h> #include <avr/io.h>
#include "nuts_bolts.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
// mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute
// a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online,
// and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc).
#define MODAL_GROUP_NONE 0
#define MODAL_GROUP_0 1 // [G4,G10,G28,G30,G53,G92,G92.1] Non-modal
#define MODAL_GROUP_1 2 // [G0,G1,G2,G3,G80] Motion
#define MODAL_GROUP_2 3 // [G17,G18,G19] Plane selection
#define MODAL_GROUP_3 4 // [G90,G91] Distance mode
#define MODAL_GROUP_4 5 // [M0,M1,M2,M30] Stopping
#define MODAL_GROUP_5 6 // [G93,G94] Feed rate mode
#define MODAL_GROUP_6 7 // [G20,G21] Units
#define MODAL_GROUP_7 8 // [M3,M4,M5] Spindle turning
#define MODAL_GROUP_12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
// Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
// internally by the parser to know which command to execute.
#define MOTION_MODE_SEEK 0 // G0
#define MOTION_MODE_LINEAR 1 // G1
#define MOTION_MODE_CW_ARC 2 // G2
#define MOTION_MODE_CCW_ARC 3 // G3
#define MOTION_MODE_CANCEL 4 // G80
#define PROGRAM_FLOW_RUNNING 0
#define PROGRAM_FLOW_PAUSED 1 // M0, M1
#define PROGRAM_FLOW_COMPLETED 2 // M2, M30
#define NON_MODAL_NONE 0
#define NON_MODAL_DWELL 1 // G4
#define NON_MODAL_SET_COORDINATE_DATA 2 // G10
#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
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}
uint8_t absolute_mode; // 0 = relative motion, 1 = absolute motion {G90, G91}
uint8_t program_flow; // {M0, M1, M2, M30}
int8_t spindle_direction; // 1 = CW, -1 = CCW, 0 = Stop {M3, M4, M5}
uint8_t coolant_mode; // 0 = Disable, 1 = Flood Enable {M8, M9}
float feed_rate; // Millimeters/min
float position[3]; // Where the interpreter considers the tool to be at this point in the code
uint8_t tool;
// uint16_t spindle_speed; // RPM/100
uint8_t plane_axis_0,
plane_axis_1,
plane_axis_2; // The axes of the selected plane
uint8_t coord_select; // Active work coordinate system number. Default: 0=G54.
float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine
// position in mm. Loaded from EEPROM when called.
float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to
// machine zero in mm. Non-persistent. Cleared upon reset and boot.
} parser_state_t;
extern parser_state_t gc;
// Initialize the parser // Initialize the parser
void gc_init(); void gc_init();

View File

@ -35,12 +35,12 @@
#define Y_AXIS 1 #define Y_AXIS 1
#define Z_AXIS 2 #define Z_AXIS 2
#define MM_PER_INCH (25.4) #define MM_PER_INCH (25.40)
#define INCH_PER_MM (0.03937) #define INCH_PER_MM (0.0393701)
// Useful macros // Useful macros
#define clear_vector(a) memset(a, 0, sizeof(a)) #define clear_vector(a) memset(a, 0, sizeof(a))
#define clear_vector_float(a) memset(a, 0.0, sizeof(float)*3) #define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS)
#define max(a,b) (((a) > (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b))
@ -86,20 +86,16 @@ typedef struct {
uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume. uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
// uint8_t switches; // Switches state bitflag variable. For settings not governed by g-code. uint8_t switches; // Switches state bitflag variable. For features not governed by g-code.
int32_t position[3]; // Real-time machine (aka home) position vector in steps. // uint8_t state; // Tracks the current state of Grbl.
// NOTE: This may need to be a volatile variable, if problems arise. // TODO: This may replace the functionality of the feed_hold and cycle_start variables. Need to
// make sure that overall processes don't change.
uint8_t coord_select; // Active work coordinate system number. Default: 0=G54.
float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine
// position in mm. Loaded from EEPROM when called.
float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to
// machine zero in mm.
volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program. volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program.
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks. volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
int32_t position[3]; // Real-time machine (aka home) position vector in steps.
// NOTE: This may need to be a volatile variable, if problems arise.
} system_t; } system_t;
extern system_t sys; extern system_t sys;

View File

@ -135,77 +135,80 @@ uint8_t protocol_execute_line(char *line)
uint8_t char_counter = 1; uint8_t char_counter = 1;
float parameter, value; float parameter, value;
switch( line[char_counter] ) { switch( line[char_counter] ) {
case 0 : case 0 : report_grbl_help(); break;
report_grbl_help(); case '$' : // Prints Grbl settings
return(STATUS_OK); if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
else { report_grbl_settings(); }
break;
case '#' : // Print gcode parameters
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
else { report_gcode_parameters(); }
break;
case 'G' : // Prints gcode parser state
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
else { report_gcode_modes(); }
break; break;
// case '#' :
// if ( line[++char_counter] == 0 ) {
// // Print all parameters
// return(STATUS_OK);
// } else {
// return(STATUS_UNSUPPORTED_STATEMENT);
// }
// case 'G' : // Start up blocks
// if(!read_float(line, &char_counter, &parameter)) { return(STATUS_BAD_NUMBER_FORMAT); }
// if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
// // Extract startup block, execute, and store.
// for (char_counter = 0; char_counter < LINE_BUFFER_SIZE-3; char_counter++) {
// line[char_counter] = line[char_counter+3];
// }
// uint8_t status = gc_execute_line(line);
// if (status) { return(status); }
// else { settings_store_startup_block(line); }
// break;
case 'H' : // Perform homing cycle case 'H' : // Perform homing cycle
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { mc_go_home(); }
mc_go_home(); else { return(STATUS_SETTING_DISABLED); }
return(STATUS_OK);
} else {
return(STATUS_SETTING_DISABLED);
}
break; break;
// // case 'J' : break; // Jogging methods // case 'J' : break; // Jogging methods
// // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be
// // susceptible to other runtime commands except for e-stop. The jogging function is intended to // susceptible to other runtime commands except for e-stop. The jogging function is intended to
// // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped
// // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would
// // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the
// // motion by repeatedly toggling to slow the motion to the desired location. Location data would // motion by repeatedly toggling to slow the motion to the desired location. Location data would
// // need to be updated real-time and supplied to the user through status queries. // need to be updated real-time and supplied to the user through status queries.
// // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are
// // handled by the planner. It would be possible for the jog subprogram to insert blocks into the // 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 // 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. // on its own carefully. This approach could be effective and possibly size/memory efficient.
// case 'P' : // Print g-code parameters and parser state // case 'N' : // Start up blocks
// if(line[char_counter] != 0) { return(STATUS_UNSUPPORTED_STATEMENT); } // if(!read_float(line, &char_counter, &parameter)) { return(STATUS_BAD_NUMBER_FORMAT); }
// // if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
// break; // // Extract startup block, execute, and store.
// case 'S' : // Switch methods // for (char_counter = 0; char_counter < LINE_BUFFER_SIZE-3; char_counter++) {
// // Opt stop and block delete are referred to as switches. // line[char_counter] = line[char_counter+3];
// // How to store home position and work offsets real-time?? // }
// break; // uint8_t status = gc_execute_line(line);
// // Parse $parameter=value settings // if (status) { return(status); }
default : // else { settings_store_startup_block(line); }
if(!read_float(line, &char_counter, &parameter)) { // break;
return(STATUS_BAD_NUMBER_FORMAT); case 'B' : // Toggle block delete
} if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
if(line[char_counter++] != '=') { sys.switches ^= BITFLAG_BLOCK_DELETE;
return(STATUS_UNSUPPORTED_STATEMENT); if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) { report_feedback_message(MESSAGE_SWITCH_ON); }
} else { report_feedback_message(MESSAGE_SWITCH_OFF); }
if(!read_float(line, &char_counter, &value)) { break;
return(STATUS_BAD_NUMBER_FORMAT); case 'S' : // Toggle single block mode
} if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
if(line[char_counter] != 0) { sys.switches ^= BITFLAG_SINGLE_BLOCK;
return(STATUS_UNSUPPORTED_STATEMENT); if (bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) { report_feedback_message(MESSAGE_SWITCH_ON); }
} else { report_feedback_message(MESSAGE_SWITCH_OFF); }
break;
case 'O' : // Toggle optional stop
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
sys.switches ^= BITFLAG_OPT_STOP;
if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) { report_feedback_message(MESSAGE_SWITCH_ON); }
else { report_feedback_message(MESSAGE_SWITCH_OFF); }
break;
default : // Store global setting
if(!read_float(line, &char_counter, &parameter)) { return(STATUS_BAD_NUMBER_FORMAT); }
if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); }
if(line[char_counter] != 0) { return(STATUS_UNSUPPORTED_STATEMENT); }
return(settings_store_global_setting(parameter, value)); return(settings_store_global_setting(parameter, value));
} }
return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
} else { } else {
return(gc_execute_line(line)); // Everything else is gcode return(gc_execute_line(line)); // Everything else is gcode
// TODO: Install option to set system alarm upon any error code received back from the // TODO: Install option to set system alarm upon any error code received back from the
// the g-code parser. This is a common safety feature on CNCs to help prevent crashes // the g-code parser. This is a common safety feature on CNCs to help prevent crashes
// if the g-code doesn't perform as intended. // if the g-code doesn't perform as intended.
} }
} }
@ -246,9 +249,9 @@ void protocol_process()
// Throw away whitepace and control characters // Throw away whitepace and control characters
} else if (c == '/') { } else if (c == '/') {
// Disable block delete and throw away characters. Will ignore until EOL. // Disable block delete and throw away characters. Will ignore until EOL.
#if BLOCK_DELETE_ENABLE if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) {
iscomment = true; iscomment = true;
#endif }
} else if (c == '(') { } else if (c == '(') {
// Enable comments flag and ignore all characters until ')' or EOL. // Enable comments flag and ignore all characters until ')' or EOL.
iscomment = true; iscomment = true;

154
report.c
View File

@ -34,6 +34,8 @@
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "report.h" #include "report.h"
#include "protocol.h" #include "protocol.h"
#include "gcode.h"
#include "coolant_control.h"
// Handles the primary confirmation protocol response for streaming interfaces and human-feedback. // Handles the primary confirmation protocol response for streaming interfaces and human-feedback.
@ -82,12 +84,12 @@ void report_status_message(uint8_t status_code)
// Prints feedback messages. This serves as a centralized method to provide additional // Prints feedback messages. This serves as a centralized method to provide additional
// user feedback for things that are not of the status message response protocol. These // user feedback for things that are not of the status message response protocol. These
// are messages such as setup warnings and how to exit alarms. // are messages such as setup warnings and how to exit alarms.
// NOTE: For interfaces, messages are always placed within parentheses. And if silent mode // NOTE: For interfaces, messages are always placed within chevrons. And if silent mode
// is installed, the message codes are less than zero. // is installed, the message number codes are less than zero.
// TODO: Install silence feedback messages option in settings // TODO: Install silence feedback messages option in settings
void report_feedback_message(int8_t message_code) void report_feedback_message(int8_t message_code)
{ {
printPgmString(PSTR("(")); printPgmString(PSTR("<"));
switch(message_code) { switch(message_code) {
case MESSAGE_SYSTEM_ALARM: case MESSAGE_SYSTEM_ALARM:
printPgmString(PSTR("ALARM: Check and reset Grbl")); break; printPgmString(PSTR("ALARM: Check and reset Grbl")); break;
@ -95,20 +97,37 @@ void report_feedback_message(int8_t message_code)
printPgmString(PSTR("warning: Position may be lost")); break; printPgmString(PSTR("warning: Position may be lost")); break;
case MESSAGE_HOMING_ENABLE: case MESSAGE_HOMING_ENABLE:
printPgmString(PSTR("'$H' to home. Ensure all limit switches are installed")); break; printPgmString(PSTR("'$H' to home. Ensure all limit switches are installed")); break;
case MESSAGE_SWITCH_ON:
printPgmString(PSTR("Switch enabled")); break;
case MESSAGE_SWITCH_OFF:
printPgmString(PSTR("Switch disabled")); break;
} }
printPgmString(PSTR(")\r\n")); printPgmString(PSTR(">\r\n"));
} }
// Welcome message // Welcome message
void report_init_message() void report_init_message()
{ {
// Print grbl initialization message printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n"));
printPgmString(PSTR("\r\nGrbl " GRBL_VERSION));
printPgmString(PSTR("\r\n'$' for help and to view settings\r\n"));
} }
void report_grbl_help() { void report_grbl_help() {
// char st_line[LINE_BUFFER_SIZE];
// printPgmString(PSTR("\r\n\r\n Startup\r\n$100 = ")); printString(settings_read_startup(st_line,0));
// printPgmString(PSTR("\r\n$101 = ")); printString(settings_read_startup(st_line,1));
// char buf[4];
// settings_startup_string((char *)buf);
// printPgmString(PSTR("\r\n Startup: ")); printString(buf);
printPgmString(PSTR("$ (help)\r\n$$ (print Grbl settings)\r\n$# (print gcode parameters)\r\n$G (print gcode parser state)"));
printPgmString(PSTR("\r\n$x=value (store Grbl setting)\r\n$Nx=line (store startup block)\r\n$H (run homing cycle, if enabled)"));
printPgmString(PSTR("\r\n$B (toggle block delete)\r\n$S (toggle single block mode)\r\n$O (toggle opt stop)"));
printPgmString(PSTR("\r\n~ (cycle start)\r\n! (feed hold)\r\n? (current position)\r\n^x (reset Grbl)\r\n"));
}
void report_grbl_settings() {
printPgmString(PSTR("$0 = ")); printFloat(settings.steps_per_mm[X_AXIS]); printPgmString(PSTR("$0 = ")); printFloat(settings.steps_per_mm[X_AXIS]);
printPgmString(PSTR(" (x axis, steps/mm)\r\n$1 = ")); printFloat(settings.steps_per_mm[Y_AXIS]); printPgmString(PSTR(" (x axis, steps/mm)\r\n$1 = ")); printFloat(settings.steps_per_mm[Y_AXIS]);
printPgmString(PSTR(" (y axis, steps/mm)\r\n$2 = ")); printFloat(settings.steps_per_mm[Z_AXIS]); printPgmString(PSTR(" (y axis, steps/mm)\r\n$2 = ")); printFloat(settings.steps_per_mm[Z_AXIS]);
@ -134,29 +153,108 @@ void report_grbl_help() {
printPgmString(PSTR(" (homing pull-off travel, mm)\r\n$20 = ")); printInteger(settings.stepper_idle_lock_time); printPgmString(PSTR(" (homing pull-off travel, mm)\r\n$20 = ")); printInteger(settings.stepper_idle_lock_time);
printPgmString(PSTR(" (stepper idle lock time, msec)\r\n$21 = ")); printInteger(settings.decimal_places); printPgmString(PSTR(" (stepper idle lock time, msec)\r\n$21 = ")); printInteger(settings.decimal_places);
printPgmString(PSTR(" (decimal places, int)\r\n$22 = ")); printInteger(settings.n_arc_correction); printPgmString(PSTR(" (decimal places, int)\r\n$22 = ")); printInteger(settings.n_arc_correction);
// char st_line[LINE_BUFFER_SIZE]; printPgmString(PSTR(" (n arc correction, int)\r\n"));
// printPgmString(PSTR("\r\n\r\n Startup\r\n$100 = ")); printString(settings_read_startup(st_line,0));
// printPgmString(PSTR("\r\n$101 = ")); printString(settings_read_startup(st_line,1));
// char buf[4];
// settings_startup_string((char *)buf);
// printPgmString(PSTR("\r\n Startup: ")); printString(buf);
printPgmString(PSTR("\r\n'$x=value' to store setting"));
// printPgmString(PSTR("\r\n'$Sx' to toggle switch\r\n"));
} }
void report_gcode_parameters()
{
float coord_data[N_AXIS];
uint8_t coord_select, i;
for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) {
if (!(settings_read_coord_data(coord_select,coord_data))) {
report_status_message(STATUS_SETTING_READ_FAIL);
return;
}
switch (coord_select) {
case 0: printPgmString(PSTR("G54")); break;
case 1: printPgmString(PSTR("G55")); break;
case 2: printPgmString(PSTR("G56")); break;
case 3: printPgmString(PSTR("G57")); break;
case 4: printPgmString(PSTR("G58")); break;
case 5: printPgmString(PSTR("G59")); break;
case 6: printPgmString(PSTR("G28")); break;
case 7: printPgmString(PSTR("G30")); break;
// case 8: printPgmString(PSTR("G92")); break; // G92.2, G92.3 currently not supported.
}
printPgmString(PSTR(":["));
for (i=0; i<N_AXIS; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { printFloat(coord_data[i]*INCH_PER_MM); }
else { printFloat(coord_data[i]); }
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }
else { printPgmString(PSTR("]\r\n")); }
}
}
printPgmString(PSTR("G92:[")); // Print G92,G92.1 which are not persistent in memory
for (i=0; i<N_AXIS; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { printFloat(gc.coord_offset[i]*INCH_PER_MM); }
else { printFloat(gc.coord_offset[i]); }
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }
else { printPgmString(PSTR("]\r\n")); }
}
}
void report_gcode_modes()
{
switch (gc.motion_mode) {
case MOTION_MODE_SEEK : printPgmString(PSTR("G0")); break;
case MOTION_MODE_LINEAR : printPgmString(PSTR("G1")); break;
case MOTION_MODE_CW_ARC : printPgmString(PSTR("G2")); break;
case MOTION_MODE_CCW_ARC : printPgmString(PSTR("G3")); break;
case MOTION_MODE_CANCEL : printPgmString(PSTR("G80")); break;
}
// void report_gcode_status() printPgmString(PSTR(" G"));
// { printInteger(gc.coord_select+54);
// // Print gcode parser state
// } if (gc.plane_axis_0 == X_AXIS) {
// if (gc.plane_axis_1 == Y_AXIS) { printPgmString(PSTR(" G17")); }
// void report_gcode_parameters() else { printPgmString(PSTR(" G18")); }
// { } else { printPgmString(PSTR(" G19")); }
// // Print gcode work coordinate offsets?
// } if (gc.inches_mode) { printPgmString(PSTR(" G20")); }
else { printPgmString(PSTR(" G21")); }
if (gc.absolute_mode) { printPgmString(PSTR(" G90")); }
else { printPgmString(PSTR(" G91")); }
if (gc.inverse_feed_rate_mode) { printPgmString(PSTR(" G93")); }
else { printPgmString(PSTR(" G94")); }
// TODO: Check if G92 needs to be here. If so, how to track it.
switch (gc.program_flow) {
case PROGRAM_FLOW_RUNNING : printPgmString(PSTR(" M0")); break;
case PROGRAM_FLOW_PAUSED : printPgmString(PSTR(" M1")); break;
case PROGRAM_FLOW_COMPLETED : printPgmString(PSTR(" M2")); break;
}
switch (gc.spindle_direction) {
case 1 : printPgmString(PSTR(" M3")); break;
case -1 : printPgmString(PSTR(" M4")); break;
case 0 : printPgmString(PSTR(" M5")); break;
}
switch (gc.coolant_mode) {
case COOLANT_DISABLE : printPgmString(PSTR(" M9")); break;
case COOLANT_FLOOD_ENABLE : printPgmString(PSTR(" M8")); break;
// case COOLANT_MIST_ENABLE : printPgmString(PSTR(" M7")); break;
}
printPgmString(PSTR(" T"));
printInteger(gc.tool);
printPgmString(PSTR(" F"));
if (gc.inches_mode) { printFloat(gc.feed_rate*INCH_PER_MM); }
else { printFloat(gc.feed_rate); }
if (sys.switches) {
if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) { printPgmString(PSTR(" $B")); }
if (bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) { printPgmString(PSTR(" $S")); }
if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) { printPgmString(PSTR(" $O")); }
}
printPgmString(PSTR("\r\n"));
}
void report_realtime_status() void report_realtime_status()
@ -198,9 +296,9 @@ void report_realtime_status()
printPgmString(PSTR(",WPos:[")); printPgmString(PSTR(",WPos:["));
for (i=0; i<= 2; i++) { for (i=0; i<= 2; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
print_position[i] -= (sys.coord_system[i]+sys.coord_offset[i])*INCH_PER_MM; print_position[i] -= (gc.coord_system[i]+gc.coord_offset[i])*INCH_PER_MM;
} else { } else {
print_position[i] -= sys.coord_system[i]+sys.coord_offset[i]; print_position[i] -= gc.coord_system[i]+gc.coord_offset[i];
} }
printFloat(print_position[i]); printFloat(print_position[i]);
if (i < 2) { printPgmString(PSTR(",")); } if (i < 2) { printPgmString(PSTR(",")); }

View File

@ -39,7 +39,8 @@
#define MESSAGE_SYSTEM_ALARM -1 #define MESSAGE_SYSTEM_ALARM -1
#define MESSAGE_POSITION_LOST -2 #define MESSAGE_POSITION_LOST -2
#define MESSAGE_HOMING_ENABLE -3 #define MESSAGE_HOMING_ENABLE -3
#define MESSAGE_SWITCH_ON -4
#define MESSAGE_SWITCH_OFF -5
// Prints system status messages. // Prints system status messages.
void report_status_message(uint8_t status_code); void report_status_message(uint8_t status_code);
@ -53,7 +54,14 @@ void report_init_message();
// Prints Grbl help and current global settings // Prints Grbl help and current global settings
void report_grbl_help(); void report_grbl_help();
void report_grbl_settings();
// Prints realtime status report // Prints realtime status report
void report_realtime_status(); void report_realtime_status();
// Prints Grbl persistent coordinate parameters
void report_gcode_parameters();
void report_gcode_modes();
#endif #endif

View File

@ -164,7 +164,7 @@ uint8_t read_global_settings() {
// should be re-written to the default value, if the developmental version number changed. // should be re-written to the default value, if the developmental version number changed.
// Grab settings regardless of error. // Grab settings regardless of error.
memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_v4_t)); memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t));
settings_reset(false); settings_reset(false);
} else { } else {
return(false); return(false);

View File

@ -26,7 +26,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "nuts_bolts.h" #include "nuts_bolts.h"
#define GRBL_VERSION "0.8b" #define GRBL_VERSION "0.8c"
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl // Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
// when firmware is upgraded. Always stored in byte 0 of eeprom // when firmware is upgraded. Always stored in byte 0 of eeprom
@ -39,18 +39,21 @@
#define BITFLAG_HARD_LIMIT_ENABLE bit(3) #define BITFLAG_HARD_LIMIT_ENABLE bit(3)
#define BITFLAG_HOMING_ENABLE bit(4) #define BITFLAG_HOMING_ENABLE bit(4)
// Define EEPROM memory address location values for on-demand settings and parameters // Define EEPROM memory address location values for Grbl settings and parameters
// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and
// the startup script. The lower half contains the global settings and space for future
// developments.
#define EEPROM_ADDR_GLOBAL 1 #define EEPROM_ADDR_GLOBAL 1
#define EEPROM_ADDR_PARAMETERS 512 #define EEPROM_ADDR_PARAMETERS 512
#define EEPROM_ADDR_STARTUP_SCRIPT 768 #define EEPROM_ADDR_STARTUP_SCRIPT 768
// Define EEPROM address indexing for coordinate parameters // Define EEPROM address indexing for coordinate parameters
#define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1) #define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1)
#define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+2 // Total number of system stored (from index 0) #define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+1 // Total number of system stored (from index 0)
// NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59) // NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59)
#define SETTING_INDEX_G28 N_COORDINATE_SYSTEM // Home position 1 #define SETTING_INDEX_G28 N_COORDINATE_SYSTEM // Home position 1
#define SETTING_INDEX_G30 N_COORDINATE_SYSTEM+1 // Home position 2 #define SETTING_INDEX_G30 N_COORDINATE_SYSTEM+1 // Home position 2
#define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset // #define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset (G92.2,G92.3 not supported)
// Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards) // Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards)
typedef struct { typedef struct {
@ -72,6 +75,7 @@ typedef struct {
uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable. uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable.
uint8_t decimal_places; uint8_t decimal_places;
uint8_t n_arc_correction; uint8_t n_arc_correction;
// uint8_t status_report_mask; // Mask to indicate desired report data.
} settings_t; } settings_t;
extern settings_t settings; extern settings_t settings;

View File

@ -43,7 +43,7 @@ void spindle_stop()
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
} }
void spindle_run(int8_t direction, uint16_t rpm) void spindle_run(int8_t direction) //, uint16_t rpm)
{ {
if (direction != current_direction) { if (direction != current_direction) {
plan_synchronize(); plan_synchronize();

View File

@ -3,6 +3,7 @@
Part of Grbl Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2012 Sungeun K. Jeon
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -24,7 +25,7 @@
#include <avr/io.h> #include <avr/io.h>
void spindle_init(); void spindle_init();
void spindle_run(int8_t direction, uint16_t rpm); void spindle_run(int8_t direction); //, uint16_t rpm);
void spindle_stop(); void spindle_stop();
#endif #endif