Read GCODE from a laptop and parse it into usable structures.

Dependencies:   MODSERIAL mbed

Dependents:   DrawBot

Fork of gCodeParser by Alejandro Jimenez

Revision:
0:fa0891ea897b
Child:
1:7818b02dde4b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gparser.cpp	Mon Apr 14 05:03:29 2014 +0000
@@ -0,0 +1,173 @@
+/*
+ * mbed GCode parsing Library
+ *
+ */
+#include "gparser.h"
+#include "mbed.h"
+#include "MODSERIAL.h"
+#include <ctype.h>
+
+#define TEST
+
+#ifdef TEST
+#include "uLCD_4DGL.h"
+uLCD_4DGL uLCD(p9,p10,p11);
+#endif
+
+#define FEEDME 10
+#define END_OF_TRANSMISSION 23
+extern MODSERIAL gpc;
+
+/************VARS*******************************/
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here
+
+// buffer used to transfer the serial buffer contents and parse them into cmd structure
+char rx_buff[CMD_BUFFER_SIZE];
+
+volatile bool received;     // indicates when a new cmd is available in the serial buffer
+bool endTransmission;       // indicates that all the commands have been sent from the pc
+
+int list_position;  // counter to index the array of command structures
+
+
+/* This initializes the serial port params to match the PC application
+ * the interrupt handlers are also initialized here
+ */
+void parserInit()
+{
+    list_position = 0;
+    received = false;
+    endTransmission = false;
+    gpc.baud(921600);
+    gpc.autoDetectChar('\0');  //<--to catch the null terminator at the end
+    gpc.attach(&cmd_Received, MODSERIAL::RxAutoDetect); // declares callback for when cmd is ready
+    gpc.rxBufferFlush();    // flush the buffer just in case
+}
+
+/* Parses the received messages into a G_cmd structure
+ * it waits for the serial buffer to contain an entire command,
+ * parses the gcode and sends the FEEDME command
+ * to the pc to request another gcode line
+ * returns a pointer to the allocated list of commands.
+ */
+G_cmd* fillInCmdList()
+{
+    //list_position = 0;      // incremented by parseGcode at the end
+
+    // end_flag_received should be detected in parseGcode()
+    while(endTransmission == false) {
+        // Light up LED1 to indicate the mbed is ready to receive Serial commands
+        led1 = 1;
+        if(received == true) {  //if the buffer has received the null terminator
+
+            // Signal that we are now parsing by lighting LED2
+            //led1 = 0;
+            led2 = 1;
+            parseGcode();
+            gpc.rxBufferFlush();        // flushing the buffer just in case
+            received = false;
+            gpc.putc(FEEDME);           // requesting next command from the pc
+            led2 = 0;                   // parsing stage is over
+        }
+    }
+    uLCD.printf("Commands copied %d\n", list_position);
+    
+    for(int i = (list_position - 4); i < list_position; i++) {
+        uLCD.printf("%d X:%f Y:%f Z:%f F:%f.\r\n", gcmd_list[i].G, gcmd_list[i].X, gcmd_list[i].Y, gcmd_list[i].Z, gcmd_list[i].F);       
+    }
+    
+    led1 = 1;
+    wait(0.5);
+    led1 = 0;
+    led2 = 1;
+    wait(0.5);
+    led2 = 0;
+    led3 = 1;
+    wait(0.5);
+    led3 = 0;
+    led1 = 1;
+    wait(0.5);
+    led3 = 1;
+    led2 = 1;
+    return gcmd_list;
+}
+
+//interrupt routine called when the null terminator is received
+void cmd_Received(MODSERIAL_IRQ_INFO *q)
+{
+    MODSERIAL *sys = q->serial;
+    sys->move(rx_buff, CMD_BUFFER_SIZE);;
+    received = true;
+}
+//TODO: Detect the connection finish characters and set a flag so fillInCmdBuff can return
+// Parses the received message and populates the structure
+void parseGcode()
+{
+    // checking for the termination of connection
+    if(rx_buff[0] == END_OF_TRANSMISSION) {
+        led4 = 1;       //received end of transmission from pc
+        endTransmission = true;
+        return;
+    }
+
+    // in case there are leading spaces
+    char* cmdP = strtok(rx_buff, " G");
+
+    //uLCD.printf("cmdP is pointing now to %s\n", cmdP);
+
+    char coord_label[2];
+
+    //int g = atoi(cmdP);
+
+    //uLCD.printf("list pos is: %d\n", list_position);
+
+    //fill out the command number field
+    gcmd_list[list_position].G = atoi(cmdP);
+
+    //uLCD.printf("%d: ", gcmd_list[list_position].G);
+
+    // Looping to get the arguments
+    while (cmdP != NULL) {
+        // Retrieve the next Label
+        cmdP = strtok (NULL, " G");
+        // cmdP should be pointing to a letter now
+        //uLCD.printf("Coord: %s.\n", cmdP);
+        coord_label[0] = cmdP[0];
+        coord_label[1] = cmdP[1];
+
+        // retrieve the number after the letter
+        cmdP = strtok (NULL, " G");
+
+        // now print the number
+        //uLCD.printf("%s ", cmdP);
+        switch(coord_label[0]) {
+            case 'X':
+                gcmd_list[list_position].X = atof(cmdP);
+                break;
+            case 'Y':
+                gcmd_list[list_position].Y = atof(cmdP);
+                break;
+            case 'Z':
+                gcmd_list[list_position].Z = atof(cmdP);
+                break;
+            case 'F':
+                gcmd_list[list_position].F = atof(cmdP);
+                break;
+            case 'I':
+                gcmd_list[list_position].I = atof(cmdP);
+                break;
+            case 'J':
+                gcmd_list[list_position].J = atof(cmdP);
+                break;
+            default:
+        
+                break;
+        }// switch
+    } // while
+    list_position++;
+}
\ No newline at end of file