I am trying to inject a custom Gcode command in Marlin Arduino with Ramps board.
I created a custom G140 and when I send the G140 the one liner command works however when I try to send more than one Gcode command the rest get ignored, how do I add the rest of the Gcode commands to the queue to execute one after the other?
The below single command executes no problem:
void GcodeSuite::G140() { //Custom G140
queue.enqueue_now_P(PSTR("G28 Y"));
}
If I add multiple commands to execute it does not:
void GcodeSuite::G140() { //Custom G140
queue.enqueue_now_P(PSTR("M119"));
queue.enqueue_now_P(PSTR("G28 Y"));
queue.enqueue_now_P(PSTR("G21"));
queue.enqueue_now_P(PSTR("G90"));
queue.enqueue_now_P(PSTR("G64"));
}
Serial monitor shows
---- Sent utf8 encoded message: "G140\r\n" ----
echo:enqueueing "M119"
echo:enqueueing "G28 Y"
echo:enqueueing "G21"
echo:busy: processing
echo:busy: processing
echo:busy: processing
The complete Gcode line I want to execute (one example):
#define STRING_A char *Str1[] = {"G21", "G90", "G64", "G0 Z 0.000", "G0 X 183.690 Y 16.834", "G0 Z 0.000", "M3 M8", "G0 Z -0.500", "G2 X 186.024 Y 19.168 I 1.167 J 1.167", "G2 X 183.690 Y 16.834 I -1.167 J -1.167", "G0 Z 0.000M9 M5", "G0 X 27.690 Y 16.834", "G0 Z 0.000", "M3 M8", "G0 Z -0.500", "G2 X 27.690 Y 16.834 I -1.167 J -1.167", "G2 X 30.024 Y 19.168 I 1.167 J 1.167", "G0 Z 0.000", "M9 M5", "G0 X 0.000 Y 0.000"};
The reason why I want to embed the Gcode file(s) inside the Marlin code is that this Gcode will never change, this is one of multiple Gcodes I want to run from a Python app, if I send the multiple files repeatedly from Python , the serial comms get blogged and slow.
My idea was to create 10 custom Gcodes and run the embedded Gcode with each receipt of the Gcode from the Python app.
I can add that I have done this successfully using an Arduino Gcode interpreter, I embedded the Gcode scripts in the Arduino code and send a letter from the Python app to Arduino and it works great. Reason why I want to use the Marlin software is for better queue handling and better execution of the Gcode, the Arduino interpreter is very basic and lack stability and reliability.
#define FIRMWARE_VERSION "v1.4"
// our point structure to make things nice
//========================================
struct LongPoint {
long x;
long y;
long z;
long e;
};
struct FloatPoint {
float x;
float y;
float z;
float e;
};
// our command string
//===================
#define COMMAND_SIZE 128
char aWord[COMMAND_SIZE];
char buffer[128];
int sofar;
long serial_count;
long no_data = 0;
// to decode serial data
String serData = "";
boolean newData = false;
// used to decode commands
//========================
char c;
char gcode;
long code;
long line;
long LastLine = 0;
char *Str1[] = {"G21", "G90", "G64", "G0 Z 0.000", "G0 X 183.690 Y 16.834", "G0 Z 0.000", "M3 M8", "G0 Z -0.500", "G2 X 186.024 Y 19.168 I 1.167 J 1.167", "G2 X 183.690 Y 16.834 I -1.167 J -1.167", "G0 Z 0.000M9 M5", "G0 X 27.690 Y 16.834", "G0 Z 0.000", "M3 M8", "G0 Z -0.500", "G2 X 27.690 Y 16.834 I -1.167 J -1.167", "G2 X 30.024 Y 19.168 I 1.167 J 1.167", "G0 Z 0.000", "M9 M5", "G0 X 0.000 Y 0.000", "M2"};
char *Str2[] = {"G21 ", "G90 ", "G0 Z0.000 ", "M9 ", "M5 ", "G28 ", "M3 ", "M8 ", "G0 Z-0.500 ", "G1 X4.200 Y0.000 ", "G3 X5.754 Y0.412 I-0.211 J3.931 ", "G2 X7.307 Y0.824 I1.869 J-3.912 ", "G1 X52.500 Y0.825 ", "G2 X54.053 Y0.413 I-0.211 J-3.931 ", "G3 X55.607 Y0.001 I1.869 J3.912 ", "G1 X59.707 Y0.001 ", "G3 X63.274 Y1.711 I-0.350 J5.306 ", "G2 X70.740 Y1.711 I3.733 J-4.308 ", "G3 X74.307 Y0.001 I3.917 J3.596 ", "G1 X78.307 Y0.001 ", "G3 X81.874 Y1.711 I-0.350 J5.306 ", "G2 X89.340 Y1.711 I3.733 J-4.308 ", "G3 X92.907 Y0.001 I3.917 J3.596 ", "G1 X121.807 Y0.001 ", "G3 X125.374 Y1.711 I-0.350 J5.306 ", "G2 X132.840 Y1.711 I3.733 J-4.308 ", "G3 X136.407 Y0.001 I3.917 J3.596 ", "G1 X140.407 Y0.001 ", "G3 X143.974 Y1.711 I-0.350 J5.306 ", "G2 X151.440 Y1.711 I3.733 J-4.308 ", "G3 X155.007 Y0.001 I3.917 J3.596 ", "G1 X159.107 Y0.001 ", "G3 X160.660 Y0.413 I-0.315 J4.324 ", "G2 X162.214 Y0.825 I1.765 J-3.519 ", "G1 X207.406 Y0.825 ", "G2 X208.960 Y0.412 I-0.211 J-3.931 ", "G3 X210.514 Y0.000 I1.869 J3.912 ", "G1 X214.714 Y0.000 ", "G0 Z0.000 ", "M9 ", "M5 ", "G28 ", "M2 "};
char *Str3[] = {"G21 ", "G90 ", "M9 ", "M5 ", "M2 ", "G1 X20.00 Y20.000 ", "G28 ", "M114 "};
char *StrG28[] = {"G21 ", "G1 X-400.00 Y-400.000 ", "G92 ", "G1 X5.00 Y5.000 ", "G1 X-100.00 Y-100.000 ", "G92 "}; // Q
char *StrM114[] = {"M114 "}; //M
// coordinate mode
//================
boolean abs_mode = true;
// measurement mode
//=================
boolean inches = false;
// steppers state
//===============
boolean steppers = false;
boolean e_can_step;
#define E0_ENABLE_PIN 24
#define E0_STEP_PIN 26
#define E0_DIR_PIN 28
int DebugLevel = 0;
int xx = 500; //Stepper E speed
const int LINE_BUFFER_SIZE = 128; // max line length is one less than this
float value = 58284; //34285; //3035; //Preload timer value (3035 for 4 seconds)
void setup()
{
Serial.begin(115200);
// Initialize serial command buffer.
Serial.print("start");
sofar=0;
init_process_string();
init_steppers();
}
void loop()
{
// listen for serial commands
while(Serial.available() > 0) {
buffer[sofar++]=Serial.read();
if(buffer[sofar-1]==';') break; // in case there are multiple instructions
}
// digitalWrite(E0_ENABLE_PIN, LOW); // enable roll motor
// if we hit a semi-colon, assume end of instruction.
if(sofar>0 && buffer[sofar-1]==';') {
Serial.print("Command received: ");
Serial.println(buffer[sofar-2]);
switch (buffer[sofar-2]) {
case 'A':
Serial.println("D received");
run_this(Str1, sizeof(Str1)/sizeof(Str1[0]));
break;
case 'B':
Serial.println("SH received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'C':
Serial.println("B received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'D':
Serial.println("WH received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'E':
Serial.println("WN received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'F':
Serial.println("LN received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'G':
Serial.println("S received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'H':
Serial.println("ET received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'J':
Serial.println("BT received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'K':
Serial.println("BC received");
run_this(Str2, sizeof(Str2)/sizeof(Str2[0]));
break;
case 'L':
Serial.println("EC received");
run_this(Str3, sizeof(Str3)/sizeof(Str3[0]));
break;
case 'Q':
Serial.println("Home XYZ");
run_this(StrG28, sizeof(StrG28)/sizeof(StrG28[0]));
break;
case 'M':
Serial.println("GP");
run_this(StrM114, sizeof(StrM114)/sizeof(StrM114[0]));
break;
default:
Serial.println("Nothing to process");
}
return;
buffer[sofar]=0;
}
else {
// start counting no-data clicks to timeout steppers
//==================================================
no_data++;
delayMicroseconds(25);
}
}
void run_this(char *gcode[], int bufsize)
{
// e_can_step = true;
for (int i = 0; i < bufsize; i++) {
strcpy(aWord, gcode[i]);
serial_count = strlen(aWord);
Serial.println(aWord);
no_data = 0;
// if we got a command, do it
//===========================
if (serial_count) {
process_string(aWord, serial_count-1);
LastLine = line;
}
init_process_string();
no_data = 0;
// reset the buffer
sofar = 0;
}
if (no_data > 10000)
disable_steppers();
}
Any direction on how to send the multiple commands inside the Marlin Gcode line consecutive will be appreciated