Minor bug fixes and updates. Line number tracking.

- Line number tracking was getting truncated at 255, since it was using
wrong variable type. Fixed it with a trunc().

- Increased the max number line allowed by Grbl to 9999999 from the
g-code standard 99999. The latter seems to be an arbitrary number, so
we are allowing larger ones for at least one known use case scenario.

- Created a new test directory to contain some testing g-code to proof
the firmware. Only got started with one test case so far. More will be
inserted as needed.

- Some other commenting updates to clarify certain aspects of the code.
This commit is contained in:
Sonny Jeon 2014-07-02 08:39:19 -06:00
parent 79e0e45826
commit 1ef5a45479
4 changed files with 56 additions and 15 deletions

25
gcode.c
View File

@ -29,7 +29,10 @@
#include "probe.h" #include "probe.h"
#include "report.h" #include "report.h"
#define MAX_LINE_NUMBER 99999 // NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an
// arbitrary value, and some GUIs may require more. So we increased it based on a max safe
// value when converting a float (7.2 digit precision)s to an integer.
#define MAX_LINE_NUMBER 9999999
#define AXIS_COMMAND_NONE 0 #define AXIS_COMMAND_NONE 0
#define AXIS_COMMAND_NON_MODAL 1 #define AXIS_COMMAND_NON_MODAL 1
@ -91,8 +94,8 @@ uint8_t gc_execute_line(char *line)
memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes
uint8_t axis_explicit = AXIS_COMMAND_NONE; uint8_t axis_explicit = AXIS_COMMAND_NONE;
uint8_t axis_0, axis_1, axis_linear; uint8_t axis_0, axis_1, axis_linear;
float coordinate_data[N_AXIS]; float coordinate_data[N_AXIS]; // Multi-use variable to store coordinate data for execution
float parameter_data[N_AXIS]; float parameter_data[N_AXIS]; // Multi-use variable to store parameter data for execution
// Initialize bitflag tracking variables for axis indices compatible operations. // Initialize bitflag tracking variables for axis indices compatible operations.
uint8_t axis_words = 0; // XYZ tracking uint8_t axis_words = 0; // XYZ tracking
@ -305,7 +308,7 @@ uint8_t gc_execute_line(char *line)
case 'J': word_bit = WORD_J; gc_block.values.ijk[Y_AXIS] = value; ijk_words |= (1<<Y_AXIS); break; case 'J': word_bit = WORD_J; gc_block.values.ijk[Y_AXIS] = value; ijk_words |= (1<<Y_AXIS); break;
case 'K': word_bit = WORD_K; gc_block.values.ijk[Z_AXIS] = value; ijk_words |= (1<<Z_AXIS); break; case 'K': word_bit = WORD_K; gc_block.values.ijk[Z_AXIS] = value; ijk_words |= (1<<Z_AXIS); break;
case 'L': word_bit = WORD_L; gc_block.values.l = int_value; break; case 'L': word_bit = WORD_L; gc_block.values.l = int_value; break;
case 'N': word_bit = WORD_N; gc_block.values.n = int_value; break; case 'N': word_bit = WORD_N; gc_block.values.n = trunc(value); break;
case 'P': word_bit = WORD_P; gc_block.values.p = value; break; case 'P': word_bit = WORD_P; gc_block.values.p = value; break;
// NOTE: For certain commands, P value must be an integer, but none of these commands are supported. // NOTE: For certain commands, P value must be an integer, but none of these commands are supported.
// case 'Q': // Not supported // case 'Q': // Not supported
@ -738,15 +741,19 @@ uint8_t gc_execute_line(char *line)
} }
} }
// Arc radius from center to target
x -= gc_block.values.ijk[axis_0]; // Delta x between circle center and target x -= gc_block.values.ijk[axis_0]; // Delta x between circle center and target
y -= gc_block.values.ijk[axis_1]; // Delta y between circle center and target y -= gc_block.values.ijk[axis_1]; // Delta y between circle center and target
float target_r = hypot_f(x,y); float target_r = hypot_f(x,y);
gc_block.values.r = hypot_f(gc_block.values.ijk[axis_0], gc_block.values.ijk[axis_1]); // Compute arc radius for mc_arc
target_r = fabs(target_r-gc_block.values.r); // Compute arc radius for mc_arc. Defined from current location to center.
if (target_r > 0.005) { gc_block.values.r = hypot_f(gc_block.values.ijk[axis_0], gc_block.values.ijk[axis_1]);
if (target_r > 0.5) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error]
if (target_r > 0.001*gc_block.values.r) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] // Compute difference between current location and target radii for final error-checks.
float delta_r = fabs(target_r-gc_block.values.r);
if (delta_r > 0.005) {
if (delta_r > 0.5) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.5mm
if (delta_r > (0.001*gc_block.values.r)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Arc definition error] > 0.005mm AND 0.1% radius
} }
} }
break; break;

View File

@ -151,6 +151,7 @@ uint8_t get_direction_mask(uint8_t axis_idx)
return(axis_mask); return(axis_mask);
} }
float hypot_f(float x, float y) float hypot_f(float x, float y)
{ {
return(sqrt(x*x + y*y)); return(sqrt(x*x + y*y));

View File

@ -61,7 +61,7 @@ static void protocol_execute_line(char *line)
/* /*
GRBL MAIN LOOP: GRBL PRIMARY LOOP:
*/ */
void protocol_main_loop() void protocol_main_loop()
{ {
@ -81,9 +81,9 @@ void protocol_main_loop()
system_execute_startup(line); // Execute startup script. system_execute_startup(line); // Execute startup script.
} }
// ------------------------------------------------------------------------------ // ---------------------------------------------------------------------------------
// Main loop! Upon a system abort, this exits back to main() to reset the system. // Primary loop! Upon a system abort, this exits back to main() to reset the system.
// ------------------------------------------------------------------------------ // ---------------------------------------------------------------------------------
uint8_t iscomment = false; uint8_t iscomment = false;
uint8_t char_counter = 0; uint8_t char_counter = 0;
@ -92,6 +92,14 @@ void protocol_main_loop()
// Process one line of incoming serial data, as the data becomes available. Performs an // Process one line of incoming serial data, as the data becomes available. Performs an
// initial filtering by removing spaces and comments and capitalizing all letters. // initial filtering by removing spaces and comments and capitalizing all letters.
// NOTE: While comment, spaces, and block delete(if supported) handling should technically
// be done in the g-code parser, doing it here helps compress the incoming data into Grbl's
// line buffer, which is limited in size. The g-code standard actually states a line can't
// exceed 256 characters, but the Arduino Uno does not have the memory space for this.
// With a better processor, it would be very easy to pull this initial parsing out as a
// seperate task to be shared by the g-code parser and Grbl's system commands.
while((c = serial_read()) != SERIAL_NO_DATA) { while((c = serial_read()) != SERIAL_NO_DATA) {
if ((c == '\n') || (c == '\r')) { // End of line reached if ((c == '\n') || (c == '\r')) { // End of line reached
line[char_counter] = 0; // Set string termination character. line[char_counter] = 0; // Set string termination character.

25
test/test.py Normal file
View File

@ -0,0 +1,25 @@
import random
import serial
import time
ser = serial.Serial('/dev/tty.usbmodem24111', 115200, timeout=0.001)
time.sleep(1)
outstanding = 0
data = ''
while True:
time.sleep(0.1)
data += ser.read()
pos = data.find('\n')
if pos == -1:
line = ''
else:
line = data[0:pos + 1]
data = data[pos + 1:]
if line == '' and outstanding < 3:
while outstanding < 3:
ser.write("G0 Z%0.3f\n" % (0.01 * (random.random() - 0.5)))
#ser.write("M3\n")
outstanding += 1
continue
if line == 'ok\r\n':
outstanding -= 1
print outstanding, repr(line.rstrip())