Merge branch 'bugfixes'

This commit is contained in:
Simen Svale Skogsrud 2010-07-08 14:55:53 +02:00
commit 23da1ffa46
8 changed files with 74 additions and 73 deletions

View File

@ -25,8 +25,8 @@
// Settings that can only be set at compile-time: // Settings that can only be set at compile-time:
// #define BAUD_RATE 9600 #define BAUD_RATE 9600
#define BAUD_RATE 115200 //#define BAUD_RATE 115200
#define STEPPERS_ENABLE_DDR DDRD #define STEPPERS_ENABLE_DDR DDRD
#define STEPPERS_ENABLE_PORT PORTD #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 STEPPING_MASK (STEP_MASK | DIRECTION_MASK) // All stepping-related bits (step/direction)
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits #define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
#define INCHES_PER_MM (1.0/25.4) // A conversion rate
#endif #endif

113
gcode.c
View File

@ -21,27 +21,6 @@
/* This code is inspired by the Arduino GCode Interpreter by Mike Ellery and the NIST RS274/NGC Interpreter /* This code is inspired by the Arduino GCode Interpreter by Mike Ellery and the NIST RS274/NGC Interpreter
by Kramer, Proctor and Messina. */ 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 "gcode.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -53,11 +32,13 @@
#include "errno.h" #include "errno.h"
#include "serial_protocol.h" #include "serial_protocol.h"
#define MM_PER_INCH (25.4)
#define NEXT_ACTION_DEFAULT 0 #define NEXT_ACTION_DEFAULT 0
#define NEXT_ACTION_DWELL 1 #define NEXT_ACTION_DWELL 1
#define NEXT_ACTION_GO_HOME 2 #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_LINEAR 1 // G1
#define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CW_ARC 2 // G2
#define MOTION_MODE_CCW_ARC 3 // G3 #define MOTION_MODE_CCW_ARC 3 // G3
@ -77,7 +58,7 @@
struct ParserState { struct ParserState {
uint8_t status_code; 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 inverse_feed_rate_mode; /* G93, G94 */
uint8_t inches_mode; /* 0 = millimeter mode, 1 = inches mode {G20, G21} */ 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 absolute_mode; /* 0 = relative motion, 1 = absolute motion {G90, G91} */
@ -95,10 +76,10 @@ struct ParserState gc;
#define FAIL(status) gc.status_code = status; #define FAIL(status) gc.status_code = status;
int read_double(char *line, // <- string: line of RS274/NGC code being processed 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 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) 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) { 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, // 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 // Executes one line of 0-terminated G-Code. The line is assumed to contain only uppercase
// characters and signed floats (no whitespace). // characters and signed floats (no whitespace).
uint8_t gc_execute_line(char *line) { uint8_t gc_execute_line(char *line) {
int counter = 0; int char_counter = 0;
char letter; char letter;
double value; double value;
double unit_converted_value; double unit_converted_value;
@ -148,7 +129,7 @@ uint8_t gc_execute_line(char *line) {
int radius_mode = FALSE; int radius_mode = FALSE;
uint8_t absolute_override = FALSE; /* 1 = absolute motion for this block only {G53} */ 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]; double target[3], offset[3];
@ -160,28 +141,32 @@ uint8_t gc_execute_line(char *line) {
gc.status_code = GCSTATUS_OK; gc.status_code = GCSTATUS_OK;
/* First: parse all statements */ // Disregard comments and block delete
if (line[0] == '(') { return(gc.status_code); } 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
// 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 // Parameter lines are on the form '$4=374.3' or '$' to dump current settings
counter = 1; char_counter = 1;
if(line[counter] == 0) { dump_settings(); return(GCSTATUS_OK); } if(line[char_counter] == 0) { dump_settings(); return(GCSTATUS_OK); }
read_double(line, &counter, &p); read_double(line, &char_counter, &p);
if(line[counter++] != '=') { return(GCSTATUS_UNSUPPORTED_STATEMENT); } if(line[char_counter++] != '=') { return(GCSTATUS_UNSUPPORTED_STATEMENT); }
read_double(line, &counter, &value); read_double(line, &char_counter, &value);
if(line[counter] != 0) { return(GCSTATUS_UNSUPPORTED_STATEMENT); } if(line[char_counter] != 0) { return(GCSTATUS_UNSUPPORTED_STATEMENT); }
store_setting(p, value); store_setting(p, value);
} }
/* We'll handle this as g-code. First: parse all statements */
// Pass 1: Commands // Pass 1: Commands
while(next_statement(&letter, &value, line, &counter)) { while(next_statement(&letter, &value, line, &char_counter)) {
int_value = trunc(value); int_value = trunc(value);
switch(letter) { switch(letter) {
case 'G': case 'G':
switch(int_value) { 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 1: gc.motion_mode = MOTION_MODE_LINEAR; break;
case 2: gc.motion_mode = MOTION_MODE_CW_ARC; break; case 2: gc.motion_mode = MOTION_MODE_CW_ARC; break;
case 3: gc.motion_mode = MOTION_MODE_CCW_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 there were any errors parsing this line, we will return right away with the bad news
if (gc.status_code) { return(gc.status_code); } if (gc.status_code) { return(gc.status_code); }
counter = 0; char_counter = 0;
clear_vector(offset); 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 // Pass 2: Parameters
while(next_statement(&letter, &value, line, &counter)) { while(next_statement(&letter, &value, line, &char_counter)) {
int_value = trunc(value); int_value = trunc(value);
unit_converted_value = to_millimeters(value); unit_converted_value = to_millimeters(value);
switch(letter) { switch(letter) {
@ -267,7 +252,9 @@ uint8_t gc_execute_line(char *line) {
case NEXT_ACTION_DEFAULT: case NEXT_ACTION_DEFAULT:
switch (gc.motion_mode) { switch (gc.motion_mode) {
case MOTION_MODE_CANCEL: break; 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: case MOTION_MODE_LINEAR:
mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], 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); (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 // 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 // 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). // or there was an error (check state.status_code).
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) {
if (line[*counter] == 0) { if (line[*char_counter] == 0) {
return(0); // No more statements return(0); // No more statements
} }
*letter = line[*counter]; *letter = line[*char_counter];
if((*letter < 'A') || (*letter > 'Z')) { if((*letter < 'A') || (*letter > 'Z')) {
FAIL(GCSTATUS_EXPECTED_COMMAND_LETTER); FAIL(GCSTATUS_EXPECTED_COMMAND_LETTER);
return(0); return(0);
} }
(*counter)++; (*char_counter)++;
if (!read_double(line, counter, double_ptr)) { if (!read_double(line, char_counter, double_ptr)) {
return(0); return(0);
}; };
return(1); return(1);
} }
int read_double(char *line, //!< string: line of RS274/NGC code being processed 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 double *double_ptr) //!< pointer to double to be read
{ {
char *start = line + *counter; char *start = line + *char_counter;
char *end; char *end;
*double_ptr = strtod(start, &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); return(0);
}; };
*counter = end - line; *char_counter = end - line;
return(1); 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
*/

View File

@ -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.usbserial-FTE3HK2C,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-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

View File

@ -1,2 +1,2 @@
#!/opt/local/bin/ruby #!/usr/bin/ruby
require 'script/stream' require 'script/stream'

View File

@ -24,7 +24,9 @@ if ARGV.empty?
exit exit
end 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"); sp.write("\r\n\r\n");
sleep 1 sleep 1
ARGV.each do |file| ARGV.each do |file|

View File

@ -50,7 +50,7 @@ void sp_process()
char c; char c;
while((c = serialRead()) != -1) 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; line[char_counter] = 0;
printString(line); printPgmString(PSTR("\r\n")); printString(line); printPgmString(PSTR("\r\n"));
gc_execute_line(line); gc_execute_line(line);

View File

@ -20,13 +20,9 @@
#ifndef serial_h #ifndef serial_h
#define 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 // Initialize the serial protocol
void sp_init(); void sp_init();
// Read command lines from the serial port and execute them as they // Read command lines from the serial port and execute them as they
// come in. Blocks until the serial buffer is emptied. // come in. Blocks until the serial buffer is emptied.
void sp_process(); void sp_process();

View File

@ -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