Add CNC-like G-code options
This commit is contained in:
parent
33056046a3
commit
e09c144674
4 changed files with 136 additions and 29 deletions
|
@ -1776,4 +1776,13 @@
|
||||||
// Enable Marlin dev mode which adds some special commands
|
// Enable Marlin dev mode which adds some special commands
|
||||||
//#define MARLIN_DEV_MODE
|
//#define MARLIN_DEV_MODE
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CNC Parsing options
|
||||||
|
*
|
||||||
|
* These options increase marlin's acceptance of non reprap dialects more in line with what laser cutter or drawing machine cams produce
|
||||||
|
*/
|
||||||
|
//#define PARENTHESE_COMMENTS // Enable Marlin to interpret parenthese delimited comments as such and ignore them
|
||||||
|
//#define STICKY_MOVE_MODE // Enable marlin to keep the current move mode (G0 G1 G2 G3 G5 G38.X) and use it even if receiving only parameters (X Y Z E F etc.)
|
||||||
|
|
||||||
#endif // CONFIGURATION_ADV_H
|
#endif // CONFIGURATION_ADV_H
|
||||||
|
|
|
@ -53,6 +53,13 @@ int GCodeParser::codenum;
|
||||||
#if USE_GCODE_SUBCODES
|
#if USE_GCODE_SUBCODES
|
||||||
uint8_t GCodeParser::subcode;
|
uint8_t GCodeParser::subcode;
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLED(STICKY_MOVE_MODE)
|
||||||
|
int GCodeParser::current_motion_mode_codenum;
|
||||||
|
#if USE_GCODE_SUBCODES
|
||||||
|
uint8_t GCodeParser::current_motion_mode_subcode;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if ENABLED(FASTER_GCODE_PARSER)
|
#if ENABLED(FASTER_GCODE_PARSER)
|
||||||
// Optimized Parameters
|
// Optimized Parameters
|
||||||
|
@ -118,36 +125,81 @@ void GCodeParser::parse(char *p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bail if the letter is not G, M, or T
|
// Bail if the letter is not G, M, or T
|
||||||
switch (letter) { case 'G': case 'M': case 'T': break; default: return; }
|
switch(letter) {
|
||||||
|
case 'G':
|
||||||
|
case 'M':
|
||||||
|
case 'T':
|
||||||
|
|
||||||
|
// Skip spaces to get the numeric part
|
||||||
|
while (*p == ' ') p++;
|
||||||
|
|
||||||
// Skip spaces to get the numeric part
|
// Bail if there's no command code number
|
||||||
while (*p == ' ') p++;
|
if (!NUMERIC(*p)) return;
|
||||||
|
|
||||||
// Bail if there's no command code number
|
// Save the command letter at this point
|
||||||
if (!NUMERIC(*p)) return;
|
// A '?' signifies an unknown command
|
||||||
|
command_letter = letter;
|
||||||
|
|
||||||
// Save the command letter at this point
|
// Get the code number - integer digits only
|
||||||
// A '?' signifies an unknown command
|
codenum = 0;
|
||||||
command_letter = letter;
|
do {
|
||||||
|
codenum *= 10, codenum += *p++ - '0';
|
||||||
|
} while (NUMERIC(*p));
|
||||||
|
|
||||||
// Get the code number - integer digits only
|
// Allow for decimal point in command
|
||||||
codenum = 0;
|
#if USE_GCODE_SUBCODES
|
||||||
do {
|
if (*p == '.') {
|
||||||
codenum *= 10, codenum += *p++ - '0';
|
p++;
|
||||||
} while (NUMERIC(*p));
|
while (NUMERIC(*p))
|
||||||
|
|
||||||
// Allow for decimal point in command
|
|
||||||
#if USE_GCODE_SUBCODES
|
|
||||||
if (*p == '.') {
|
|
||||||
p++;
|
|
||||||
while (NUMERIC(*p))
|
|
||||||
subcode *= 10, subcode += *p++ - '0';
|
subcode *= 10, subcode += *p++ - '0';
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Skip all spaces to get to the first argument, or nul
|
// Skip all spaces to get to the first argument, or nul
|
||||||
while (*p == ' ') p++;
|
while (*p == ' ') p++;
|
||||||
|
|
||||||
|
#if ENABLED(STICKY_MOVE_MODE)
|
||||||
|
if( letter == 'G' && (codenum < 4 || codenum == 5 || codenum == 38 || (codenum>=80 &&codenum < 90 ))) {
|
||||||
|
current_motion_mode_codenum = codenum;
|
||||||
|
#if USE_GCODE_SUBCODES
|
||||||
|
current_motion_mode_subcode = subcode;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if ENABLED(STICKY_MOVE_MODE)
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
case 'Q':
|
||||||
|
if (current_motion_mode_codenum != 5)
|
||||||
|
return;
|
||||||
|
case 'I':
|
||||||
|
case 'J':
|
||||||
|
case 'R':
|
||||||
|
if (current_motion_mode_codenum < 2)
|
||||||
|
return;
|
||||||
|
case 'X':
|
||||||
|
case 'Y':
|
||||||
|
case 'Z':
|
||||||
|
case 'E':
|
||||||
|
case 'F':
|
||||||
|
|
||||||
|
command_letter = 'G';
|
||||||
|
codenum = current_motion_mode_codenum;
|
||||||
|
#if USE_GCODE_SUBCODES
|
||||||
|
subcode = current_motion_mode_subcode;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Roll back one character before to use the current arg
|
||||||
|
p--;
|
||||||
|
break;
|
||||||
|
#endif // STICKY_MOVE_MODE
|
||||||
|
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// The command parameters (if any) start here, for sure!
|
// The command parameters (if any) start here, for sure!
|
||||||
|
|
||||||
#if DISABLED(FASTER_GCODE_PARSER)
|
#if DISABLED(FASTER_GCODE_PARSER)
|
||||||
|
|
|
@ -78,12 +78,21 @@ public:
|
||||||
static char *command_ptr, // The command, so it can be echoed
|
static char *command_ptr, // The command, so it can be echoed
|
||||||
*string_arg; // string of command line
|
*string_arg; // string of command line
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char command_letter; // G, M, or T
|
static char command_letter; // G, M, or T
|
||||||
static int codenum; // 123
|
static int codenum; // 123
|
||||||
#if USE_GCODE_SUBCODES
|
#if USE_GCODE_SUBCODES
|
||||||
static uint8_t subcode; // .1
|
static uint8_t subcode; // .1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(STICKY_MOVE_MODE)
|
||||||
|
static int current_motion_mode_codenum;
|
||||||
|
#if USE_GCODE_SUBCODES
|
||||||
|
static uint8_t current_motion_mode_subcode;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||||
static void debug();
|
static void debug();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -283,6 +283,9 @@ static int read_serial(const int index) {
|
||||||
inline void get_serial_commands() {
|
inline void get_serial_commands() {
|
||||||
static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
|
static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
|
||||||
static bool serial_comment_mode[NUM_SERIAL] = { false };
|
static bool serial_comment_mode[NUM_SERIAL] = { false };
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
static bool serial_comment_paranthese_mode[NUM_SERIAL] = { false };
|
||||||
|
#endif
|
||||||
|
|
||||||
// If the command buffer is empty for too long,
|
// If the command buffer is empty for too long,
|
||||||
// send "wait" to indicate Marlin is still waiting.
|
// send "wait" to indicate Marlin is still waiting.
|
||||||
|
@ -311,6 +314,9 @@ inline void get_serial_commands() {
|
||||||
if (serial_char == '\n' || serial_char == '\r') {
|
if (serial_char == '\n' || serial_char == '\r') {
|
||||||
|
|
||||||
serial_comment_mode[i] = false; // end of line == end of comment
|
serial_comment_mode[i] = false; // end of line == end of comment
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
serial_comment_paranthese_mode[i] = false; // end of line == end of comment
|
||||||
|
#endif
|
||||||
|
|
||||||
// Skip empty lines and comments
|
// Skip empty lines and comments
|
||||||
if (!serial_count[i]) { thermalManager.manage_heater(); continue; }
|
if (!serial_count[i]) { thermalManager.manage_heater(); continue; }
|
||||||
|
@ -404,12 +410,24 @@ inline void get_serial_commands() {
|
||||||
}
|
}
|
||||||
else if (serial_char == '\\') { // Handle escapes
|
else if (serial_char == '\\') { // Handle escapes
|
||||||
// if we have one more character, copy it over
|
// if we have one more character, copy it over
|
||||||
if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i])
|
if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i]
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
&& ! serial_comment_paranthese_mode[i]
|
||||||
|
#endif
|
||||||
|
)
|
||||||
serial_line_buffer[i][serial_count[i]++] = (char)c;
|
serial_line_buffer[i][serial_count[i]++] = (char)c;
|
||||||
}
|
}
|
||||||
else { // it's not a newline, carriage return or escape char
|
else { // it's not a newline, carriage return or escape char
|
||||||
if (serial_char == ';') serial_comment_mode[i] = true;
|
if (serial_char == ';') serial_comment_mode[i] = true;
|
||||||
if (!serial_comment_mode[i]) serial_line_buffer[i][serial_count[i]++] = serial_char;
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
else if (serial_char == '(') serial_comment_paranthese_mode[i] = true;
|
||||||
|
else if (serial_char == ')') serial_comment_paranthese_mode[i] = false;
|
||||||
|
#endif
|
||||||
|
else if (!serial_comment_mode[i]
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
&& ! serial_comment_paranthese_mode[i]
|
||||||
|
#endif
|
||||||
|
) serial_line_buffer[i][serial_count[i]++] = serial_char;
|
||||||
}
|
}
|
||||||
} // for NUM_SERIAL
|
} // for NUM_SERIAL
|
||||||
} // queue has space, serial has data
|
} // queue has space, serial has data
|
||||||
|
@ -426,6 +444,9 @@ inline void get_serial_commands() {
|
||||||
static bool stop_buffering = false,
|
static bool stop_buffering = false,
|
||||||
sd_comment_mode = false;
|
sd_comment_mode = false;
|
||||||
|
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
static bool sd_comment_parenthese_mode = false;
|
||||||
|
#endif
|
||||||
if (!IS_SD_PRINTING) return;
|
if (!IS_SD_PRINTING) return;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -445,7 +466,11 @@ inline void get_serial_commands() {
|
||||||
card_eof = card.eof();
|
card_eof = card.eof();
|
||||||
if (card_eof || n == -1
|
if (card_eof || n == -1
|
||||||
|| sd_char == '\n' || sd_char == '\r'
|
|| sd_char == '\n' || sd_char == '\r'
|
||||||
|| ((sd_char == '#' || sd_char == ':') && !sd_comment_mode)
|
|| ((sd_char == '#' || sd_char == ':') && !sd_comment_mode
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
&& ! sd_comment_parenthese_mode
|
||||||
|
#endif
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
if (card_eof) {
|
if (card_eof) {
|
||||||
|
|
||||||
|
@ -481,6 +506,9 @@ inline void get_serial_commands() {
|
||||||
if (sd_char == '#') stop_buffering = true;
|
if (sd_char == '#') stop_buffering = true;
|
||||||
|
|
||||||
sd_comment_mode = false; // for new command
|
sd_comment_mode = false; // for new command
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
sd_comment_parenthese_mode = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Skip empty lines and comments
|
// Skip empty lines and comments
|
||||||
if (!sd_count) { thermalManager.manage_heater(); continue; }
|
if (!sd_count) { thermalManager.manage_heater(); continue; }
|
||||||
|
@ -497,8 +525,17 @@ inline void get_serial_commands() {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (sd_char == ';') sd_comment_mode = true;
|
if (sd_char == ';') sd_comment_mode = true;
|
||||||
if (!sd_comment_mode) command_queue[cmd_queue_index_w][sd_count++] = sd_char;
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
else if (sd_char == '(') sd_comment_parenthese_mode = true;
|
||||||
|
else if (sd_char == ')') sd_comment_parenthese_mode = false;
|
||||||
|
#endif
|
||||||
|
else if (!sd_comment_mode
|
||||||
|
#if ENABLED(PARENTHESE_COMMENTS)
|
||||||
|
&& ! sd_comment_parenthese_mode
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
command_queue[cmd_queue_index_w][sd_count++] = sd_char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue