diff --git a/config.h b/config.h index 214c8e5..2972d80 100644 --- a/config.h +++ b/config.h @@ -85,9 +85,9 @@ #define N_STARTUP_LINE 2 // Integer (1-3) // Number of floating decimal points printed by Grbl for certain value types. These settings are -// determined by realistic and commonly values observed in CNC machines. For example, position -// values cannot be less than 0.001mm or 0.0001in, because machines are never more precise than -// this. So, there is likely no need to change these, but you can if you need to here. +// determined by realistic and commonly observed values in CNC machines. For example, position +// values cannot be less than 0.001mm or 0.0001in, because machines can not be physically more +// precise this. So, there is likely no need to change these, but you can if you need to here. // NOTE: Must be an integer value from 0 to ~4. More than 4 may exhibit round-off errors. #define N_DECIMAL_COORDVALUE_INCH 4 // Coordinate or position value in inches #define N_DECIMAL_COORDVALUE_MM 3 // Coordinate or position value in mm @@ -128,6 +128,11 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. +// Sets which axis the tool length offset is applied. Assumes the spindle is always parallel with +// the selected axis with the tool oriented toward the negative direction. In other words, a positive +// tool length offset value is subtracted from the current location. +#define TOOL_LENGTH_OFFSET_AXIS Z_AXIS // Default z-axis. Valid values are X_AXIS, Y_AXIS, or Z_AXIS. + // Enables variable spindle output voltage for different RPM values. On the Arduino Uno, the spindle // enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled. // NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch! diff --git a/gcode.c b/gcode.c index 8ffdbcc..9c9110c 100644 --- a/gcode.c +++ b/gcode.c @@ -119,6 +119,7 @@ uint8_t gc_execute_line(char *line) uint8_t int_value = 0; uint8_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. + while (line[char_counter] != 0) { // Loop until no more g-code words in line. // Import the next g-code word, expecting a letter followed by a value. Otherwise, error out. @@ -135,7 +136,8 @@ uint8_t gc_execute_line(char *line) // we would simply need to change the mantissa to int16, but this add compiled flash space. // Maybe update this later. int_value = trunc(value); - mantissa = trunc(100*(value - int_value)); // Compute mantissa for Gxx.x commands + mantissa = round(100*(value - int_value)); // Compute mantissa for Gxx.x commands. + // NOTE: Rounding must be used to catch small floating point errors. // Check if the g-code word is supported or errors due to modal group violations or has // been repeated in the g-code block. If ok, update the command or record its value. @@ -239,16 +241,18 @@ uint8_t gc_execute_line(char *line) break; case 43: case 49: word_bit = MODAL_GROUP_G8; - if (int_value == 49) { + // NOTE: The NIST g-code standard vaguely states that when a tool length offset is changed, + // there cannot be any axis motion or coordinate offsets updated. Meaning G43, G43.1, and G49 + // all are explicit axis commands, regardless if they require axis words or not. + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] } + axis_command = AXIS_COMMAND_TOOL_LENGTH_OFFSET; + if (int_value == 49) { // G49 gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_CANCEL; - // Else command is G43. Only G43.1 is supported. G43 is NOT. - } else if (mantissa == 1) { - // * G43.1 is requires an axis word to operate and cannot exist with other axis - // commands in the same line. However, it's not explicitly defined this way. - if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] } - axis_command = AXIS_COMMAND_TOOL_LENGTH_OFFSET; + } else if (mantissa == 10) { // G43.1 gc_block.modal.tool_length = TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC; } else { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [Unsupported G43.x command] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + break; case 54: case 55: case 56: case 57: case 58: case 59: // NOTE: G59.x are not supported. (But their int_values would be 60, 61, and 62.) word_bit = MODAL_GROUP_G12; @@ -483,7 +487,15 @@ uint8_t gc_execute_line(char *line) // [13. Cutter radius compensation ]: NOT SUPPORTED. Error, if G53 is active. // [14. Cutter length compensation ]: G43 NOT SUPPORTED, but G43.1 and G49 are. - // G43.1 Error with motion command in same line. (Already done by axis command checks in parser.) + // [G43.1 Errors]: Motion command in same line. + // NOTE: Although not explicitly stated so, G43.1 should be applied to only one valid + // axis that is configured (in config.h). There should be an error if the configured axis + // is absent or if any of the other axis words are present. + if (axis_command == AXIS_COMMAND_TOOL_LENGTH_OFFSET ) { // Indicates called in block. + if (gc_block.modal.tool_length == TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC) { + if (axis_words ^ (1<