diff --git a/config.h b/config.h index 0c5c64f..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 @@ -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< #include @@ -53,11 +32,13 @@ #include "errno.h" #include "serial_protocol.h" +#define MM_PER_INCH (25.4) + #define NEXT_ACTION_DEFAULT 0 #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 +58,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 +76,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) @@ -117,7 +98,7 @@ void gc_init() { } inline float to_millimeters(double value) { - return(gc.inches_mode ? (value * INCHES_PER_MM) : value); + return(gc.inches_mode ? (value * MM_PER_INCH) : value); } // Find the angle in radians of deviance from the positive y axis. negative angles to the left of y-axis, @@ -140,7 +121,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 +129,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]; @@ -160,28 +141,32 @@ 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] == '/') { counter++; } // ignore block delete - if (line[0] == '$') { // This is a parameter line intended to change EEPROM-settings + if (line[0] == '/') { char_counter++; } // ignore block delete + + + // 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 - 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); } + /* We'll handle this as g-code. First: parse all statements */ + // 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 +205,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 +252,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 +402,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 - 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 + *counter; + char *start = line + *char_counter; char *end; *double_ptr = strtod(start, &end); @@ -445,6 +432,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 +*/ + 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/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); diff --git a/serial_protocol.h b/serial_protocol.h index 16bb448..c7abdc7 100644 --- a/serial_protocol.h +++ b/serial_protocol.h @@ -20,13 +20,9 @@ #ifndef serial_h #define serial_h -// A string to let the client know we are ready for a new command -#define PROMPT "\r\n>>>" -// 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(); 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