From 0170ba0dc54f5c4124fbccb17c4bf22e7e10f5c1 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Fri, 18 Jun 2010 21:45:17 +0200 Subject: [PATCH 1/9] updated readme --- readme.txt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/readme.txt b/readme.txt index f04bebf..06ffc67 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,6 @@ -Grbl - An embedded rs274/ngc (g-code) interpreter and motion-controller for the Arduino/AVR328 microcontroller -The goal: A no-compromise, high performance, low cost alternative to parallel-port based motion control for CNC milling +Grbl - an open source, embedded high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino. + +Documentation: http://dank.bengler.no/-/page/show/5470_grbl Status: * Ready for production, but probably rough around the edges still @@ -12,6 +13,11 @@ Status: * Configuration parameters stored in EEPROM and set via simple commands * Tested on very few (two) CNC rigs +Limitations by design: +* Limited GCode-support. Focus on the kind of GCode produced by CAM tools. Leave human GCoders frustrated. +* No support for tool offsets (typically handled by CAM-tool) +* No rotation axes, only x, y and z. + Prioritized to-do: * Accelleration/decelleration * Spindle control @@ -21,9 +27,4 @@ Prioritized to-do: * Support for a alphanumeric LCD readout, a joystick and a few buttons for program control * Support "headless" fabrication by buffering all code to SD-card or similar -Limitations by design: -* Limited GCode-support. Focus on the kind of GCode produced by CAM tools. Leave human GCoders frustrated. -* No support for tool offsets (typically handled by CAM-tool) -* No rotation axes, only x, y and z. - The project was initially inspired by the Arduino GCode Interpreter by Mike Ellery From 5613aa706fa66171f50c2b9dd28b3513e3ac8e07 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Fri, 18 Jun 2010 21:47:45 +0200 Subject: [PATCH 2/9] the stream script will no longer reset the arduino before it completes the last couple of operation in a g-code-file --- script/stream.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/stream.rb b/script/stream.rb index 778ac03..87fae6d 100644 --- a/script/stream.rb +++ b/script/stream.rb @@ -44,4 +44,6 @@ SerialPort.open('/dev/tty.FireFly-A964-SPP-1', 115200) do |sp| end end end + puts "Done." + sleep 500 end \ No newline at end of file From 287310735e85473e00d6b95f3fb95e2a5b8fc4b2 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Fri, 2 Jul 2010 22:40:26 +0200 Subject: [PATCH 3/9] added twitter link --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 06ffc67..de8012b 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,7 @@ Grbl - an open source, embedded high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino. Documentation: http://dank.bengler.no/-/page/show/5470_grbl +Dev announcments on twitter @grblcnc: http://twitter.com/grblcnc Status: * Ready for production, but probably rough around the edges still From 2f847a1f3349c81c86f442f710f39ac8749b5387 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Fri, 2 Jul 2010 23:23:32 +0200 Subject: [PATCH 4/9] support both CR and LF and CRLF line termination --- serial_protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serial_protocol.c b/serial_protocol.c index 3e246f1..1557f53 100644 --- a/serial_protocol.c +++ b/serial_protocol.c @@ -50,7 +50,7 @@ void sp_process() char c; while((c = serialRead()) != -1) { - if((c == '\n')) { // Line is complete. Then execute! + if((char_counter > 0) && ((c == '\n') || (c == '\r'))) { // Line is complete. Then execute! line[char_counter] = 0; printString(line); printPgmString(PSTR("\r\n")); gc_execute_line(line); From f93d0e8132b6eef2e18bf13c0521b7e0cb9d7508 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Sat, 3 Jul 2010 00:04:10 +0200 Subject: [PATCH 5/9] completed support for separate feed-rate for G0-operations --- gcode.c | 99 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/gcode.c b/gcode.c index 1931a58..b178231 100644 --- a/gcode.c +++ b/gcode.c @@ -21,27 +21,6 @@ /* This code is inspired by the Arduino GCode Interpreter by Mike Ellery and the NIST RS274/NGC Interpreter by Kramer, Proctor and Messina. */ -/* Intentionally not supported: - - Canned cycles - - Tool radius compensation - - A,B,C-axes - - Multiple coordinate systems - - Evaluation of expressions - - Variables - - Multiple home locations - - Probing - - Override control -*/ - -/* - Omitted for the time being: - group 0 = {G10, G28, G30, G92, G92.1, G92.2, G92.3} (Non modal G-codes) - group 8 = {M7, M8, M9} coolant (special case: M7 and M8 may be active at the same time) - group 9 = {M48, M49} enable/disable feed and speed override switches - group 12 = {G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3} coordinate system selection - group 13 = {G61, G61.1, G64} path control mode -*/ - #include "gcode.h" #include #include @@ -57,7 +36,7 @@ #define NEXT_ACTION_DWELL 1 #define NEXT_ACTION_GO_HOME 2 -#define MOTION_MODE_RAPID_LINEAR 0 // G0 +#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 @@ -77,7 +56,7 @@ struct ParserState { uint8_t status_code; - uint8_t motion_mode; /* {G0, G1, G2, G3, G38.2, G80, G81, G82, G83, G84, G85, G86, G87, G88, G89} */ + 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} */ @@ -95,10 +74,10 @@ struct ParserState gc; #define FAIL(status) gc.status_code = status; int read_double(char *line, // <- string: line of RS274/NGC code being processed - int *counter, // <- pointer to a counter for position on the line + int *char_counter, // <- pointer to a counter for position on the line double *double_ptr); // <- pointer to double to be read -int next_statement(char *letter, double *double_ptr, char *line, int *counter); +int next_statement(char *letter, double *double_ptr, char *line, int *char_counter); void select_plane(uint8_t axis_0, uint8_t axis_1, uint8_t axis_2) @@ -140,7 +119,7 @@ double theta(double x, double y) // Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase // characters and signed floats (no whitespace). uint8_t gc_execute_line(char *line) { - int counter = 0; + int char_counter = 0; char letter; double value; double unit_converted_value; @@ -148,7 +127,7 @@ uint8_t gc_execute_line(char *line) { int radius_mode = FALSE; uint8_t absolute_override = FALSE; /* 1 = absolute motion for this block only {G53} */ - uint8_t next_action = NEXT_ACTION_DEFAULT; /* One of the NEXT_ACTION_-constants */ + uint8_t next_action = NEXT_ACTION_DEFAULT; /* The action that will be taken by the parsed line */ double target[3], offset[3]; @@ -163,25 +142,25 @@ uint8_t gc_execute_line(char *line) { /* First: parse all statements */ if (line[0] == '(') { return(gc.status_code); } - if (line[0] == '/') { counter++; } // ignore block delete + if (line[0] == '/') { char_counter++; } // ignore block delete if (line[0] == '$') { // This is a parameter line intended to change EEPROM-settings // Parameter lines are on the form '$4=374.3' or '$' to dump current settings - counter = 1; - if(line[counter] == 0) { dump_settings(); return(GCSTATUS_OK); } - read_double(line, &counter, &p); - if(line[counter++] != '=') { return(GCSTATUS_UNSUPPORTED_STATEMENT); } - read_double(line, &counter, &value); - if(line[counter] != 0) { return(GCSTATUS_UNSUPPORTED_STATEMENT); } + char_counter = 1; + if(line[char_counter] == 0) { dump_settings(); return(GCSTATUS_OK); } + read_double(line, &char_counter, &p); + if(line[char_counter++] != '=') { return(GCSTATUS_UNSUPPORTED_STATEMENT); } + read_double(line, &char_counter, &value); + if(line[char_counter] != 0) { return(GCSTATUS_UNSUPPORTED_STATEMENT); } store_setting(p, value); } // Pass 1: Commands - while(next_statement(&letter, &value, line, &counter)) { + while(next_statement(&letter, &value, line, &char_counter)) { int_value = trunc(value); switch(letter) { case 'G': switch(int_value) { - case 0: gc.motion_mode = MOTION_MODE_RAPID_LINEAR; break; + case 0: gc.motion_mode = MOTION_MODE_SEEK; break; case 1: gc.motion_mode = MOTION_MODE_LINEAR; break; case 2: gc.motion_mode = MOTION_MODE_CW_ARC; break; case 3: gc.motion_mode = MOTION_MODE_CCW_ARC; break; @@ -220,12 +199,12 @@ uint8_t gc_execute_line(char *line) { // If there were any errors parsing this line, we will return right away with the bad news if (gc.status_code) { return(gc.status_code); } - counter = 0; + char_counter = 0; clear_vector(offset); - memcpy(target, gc.position, sizeof(target)); // target = gc.position + memcpy(target, gc.position, sizeof(target)); // i.e. target = gc.position // Pass 2: Parameters - while(next_statement(&letter, &value, line, &counter)) { + while(next_statement(&letter, &value, line, &char_counter)) { int_value = trunc(value); unit_converted_value = to_millimeters(value); switch(letter) { @@ -267,7 +246,9 @@ uint8_t gc_execute_line(char *line) { case NEXT_ACTION_DEFAULT: switch (gc.motion_mode) { case MOTION_MODE_CANCEL: break; - case MOTION_MODE_RAPID_LINEAR: + case MOTION_MODE_SEEK: + mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], gc.seek_rate, FALSE); + break; case MOTION_MODE_LINEAR: 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); @@ -415,28 +396,28 @@ uint8_t gc_execute_line(char *line) { // Parses the next statement and leaves the counter on the first character following // the statement. Returns 1 if there was a statements, 0 if end of string was reached // or there was an error (check state.status_code). -int next_statement(char *letter, double *double_ptr, char *line, int *counter) { - if (line[*counter] == 0) { +int next_statement(char *letter, double *double_ptr, char *line, int *char_counter) { + if (line[*char_counter] == 0) { return(0); // No more statements } - *letter = line[*counter]; + *letter = line[*char_counter]; if((*letter < 'A') || (*letter > 'Z')) { FAIL(GCSTATUS_EXPECTED_COMMAND_LETTER); return(0); } - (*counter)++; - if (!read_double(line, counter, double_ptr)) { + (*char_counter)++; + if (!read_double(line, char_counter, double_ptr)) { return(0); }; return(1); } int read_double(char *line, //!< string: line of RS274/NGC code being processed - int *counter, //!< pointer to a counter for position on the line + int *char_counter, //!< pointer to a counter for position on the line double *double_ptr) //!< pointer to double to be read { - char *start = line + *counter; + char *start = line + *char_counter; char *end; *double_ptr = strtod(start, &end); @@ -445,6 +426,28 @@ int read_double(char *line, //!< string: line of RS274/NGC code being processed return(0); }; - *counter = end - line; + *char_counter = end - line; return(1); } + +/* Intentionally not supported: + - Canned cycles + - Tool radius compensation + - A,B,C-axes + - Multiple coordinate systems + - Evaluation of expressions + - Variables + - Multiple home locations + - Probing + - Override control +*/ + +/* + Omitted for the time being: + group 0 = {G10, G28, G30, G92, G92.1, G92.2, G92.3} (Non modal G-codes) + group 8 = {M7, M8, M9} coolant (special case: M7 and M8 may be active at the same time) + group 9 = {M48, M49} enable/disable feed and speed override switches + group 12 = {G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3} coordinate system selection + group 13 = {G61, G61.1, G64} path control mode +*/ + From d0f64d8f65923be9abd16139f185ce2d374ecaba Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Sat, 3 Jul 2010 00:23:28 +0200 Subject: [PATCH 6/9] fixed the inches->mm conversion bug and some general cleanup --- config.h | 2 -- gcode.c | 4 +++- serial_protocol.h | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/config.h b/config.h index 0c5c64f..8c8c7e1 100644 --- a/config.h +++ b/config.h @@ -110,6 +110,4 @@ void store_setting(int parameter, double value); #define STEPPING_MASK (STEP_MASK | DIRECTION_MASK) // All stepping-related bits (step/direction) #define LIMIT_MASK ((1<>>" -// A character to acknowledge that the execution has started -#define EXECUTION_MARKER '~' - // Initialize the serial protocol void sp_init(); + // Read command lines from the serial port and execute them as they // come in. Blocks until the serial buffer is emptied. void sp_process(); From 0ac1731488e31737384db1146b9d3e498bd123c3 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Thu, 8 Jul 2010 14:55:43 +0200 Subject: [PATCH 7/9] minor edits --- config.h | 4 ++-- gcode.c | 16 ++++++++++------ script/console | 5 +++-- script/stream | 2 +- script/stream.rb | 4 +++- todo.txt | 5 ----- 6 files changed, 19 insertions(+), 17 deletions(-) delete mode 100644 todo.txt diff --git a/config.h b/config.h index 8c8c7e1..ff399d5 100644 --- a/config.h +++ b/config.h @@ -25,8 +25,8 @@ // Settings that can only be set at compile-time: -// #define BAUD_RATE 9600 -#define BAUD_RATE 115200 +#define BAUD_RATE 9600 +//#define BAUD_RATE 115200 #define STEPPERS_ENABLE_DDR DDRD #define STEPPERS_ENABLE_PORT PORTD diff --git a/gcode.c b/gcode.c index 73edefe..251e109 100644 --- a/gcode.c +++ b/gcode.c @@ -141,11 +141,13 @@ uint8_t gc_execute_line(char *line) { gc.status_code = GCSTATUS_OK; - /* First: parse all statements */ - + // Disregard comments and block delete if (line[0] == '(') { return(gc.status_code); } if (line[0] == '/') { char_counter++; } // ignore block delete - if (line[0] == '$') { // This is a parameter line intended to change EEPROM-settings + + + // If the line starts with an '$' it is a configuration-command + if (line[0] == '$') { // Parameter lines are on the form '$4=374.3' or '$' to dump current settings char_counter = 1; if(line[char_counter] == 0) { dump_settings(); return(GCSTATUS_OK); } @@ -156,6 +158,8 @@ uint8_t gc_execute_line(char *line) { store_setting(p, value); } + /* We'll handle this as g-code. First: parse all statements */ + // Pass 1: Commands while(next_statement(&letter, &value, line, &char_counter)) { int_value = trunc(value); @@ -415,9 +419,9 @@ int next_statement(char *letter, double *double_ptr, char *line, int *char_count return(1); } -int read_double(char *line, //!< string: line of RS274/NGC code being processed - int *char_counter, //!< pointer to a counter for position on the line - double *double_ptr) //!< pointer to double to be read +int read_double(char *line, //!< string: line of RS274/NGC code being processed + int *char_counter, //!< pointer to a counter for position on the line + double *double_ptr) //!< pointer to double to be read { char *start = line + *char_counter; char *end; diff --git a/script/console b/script/console index c68c823..13fe75e 100755 --- a/script/console +++ b/script/console @@ -1,3 +1,4 @@ -# socat -d -d READLINE /dev/tty.usbserial-A9007QcR,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1 -socat -d -d READLINE /dev/tty.FireFly-A964-SPP-1,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1 +# socat -d -d READLINE /dev/tty.usbserial-FTE3HK2C,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1 +socat -d -d READLINE /dev/tty.usbserial-A9007QcR,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1 +# socat -d -d READLINE /dev/tty.FireFly-A964-SPP-1,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1 diff --git a/script/stream b/script/stream index 89dc0d7..93c73ed 100755 --- a/script/stream +++ b/script/stream @@ -1,2 +1,2 @@ -#!/opt/local/bin/ruby +#!/usr/bin/ruby require 'script/stream' \ No newline at end of file diff --git a/script/stream.rb b/script/stream.rb index 87fae6d..536f431 100644 --- a/script/stream.rb +++ b/script/stream.rb @@ -24,7 +24,9 @@ if ARGV.empty? exit end -SerialPort.open('/dev/tty.FireFly-A964-SPP-1', 115200) do |sp| + +SerialPort.open('/dev/tty.usbserial-A9007QcR', 9600) do |sp| +#SerialPort.open('/dev/tty.usbserial-FTE3HK2C', 9600) do |sp| sp.write("\r\n\r\n"); sleep 1 ARGV.each do |file| diff --git a/todo.txt b/todo.txt deleted file mode 100644 index 029be3a..0000000 --- a/todo.txt +++ /dev/null @@ -1,5 +0,0 @@ -* Complete support for using and setting separate seek-rate for G0-commnads -* Implement limit switch support in stepper.c (use port-triggered interrupts?) -* Implement homing cycle in stepper.c -* Path Control Modes -* Spindle speed support From 2f18cf90b472209232463b61466a26dcdaac0280 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Mon, 17 Jan 2011 19:29:47 +0100 Subject: [PATCH 8/9] added DS_Store to gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1102503..8278395 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.hex *.o -*.elf \ No newline at end of file +*.elf +*.DS_Store \ No newline at end of file From b33cf8b746dff9e764a95c03d5f50010614289e5 Mon Sep 17 00:00:00 2001 From: Simen Svale Skogsrud Date: Mon, 17 Jan 2011 21:21:08 +0100 Subject: [PATCH 9/9] added note about fuses in Makefile --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 90742cc..cfaf568 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,8 @@ OBJECTS = main.o motion_control.o gcode.o spindle_control.o wiring_serial.o s eeprom.o config.o # FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m +# update that line with this when programmer is back up: +# FUSES = -U hfuse:w:0xd7:m -U lfuse:w:0xff:m # Tune the lines below only if you know what you are doing: