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

Dependencies:   MODSERIAL mbed

Dependents:   DrawBot

Fork of gCodeParser by Alejandro Jimenez

Files at this revision

API Documentation at this revision

Comitter:
ajb88
Date:
Mon Apr 14 05:03:29 2014 +0000
Child:
1:7818b02dde4b
Commit message:
Working version of gcode parser using MODSERIAL library. Code needs to be cleaned up and library and classes created. Needs refining of the logic so it can be requested to refill a circular buffer

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.lib Show annotated file Show diff for this revision Revisions of this file
gparser.cpp Show annotated file Show diff for this revision Revisions of this file
gparser.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/4DGL-uLCD-SE.lib	Mon Apr 14 05:03:29 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MODSERIAL.lib	Mon Apr 14 05:03:29 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gparser.h	Mon Apr 14 05:03:29 2014 +0000
@@ -0,0 +1,26 @@
+#ifndef PARSER_H
+#define PARSER_H
+
+#include "MODSERIAL.h"
+
+#define CMD_BUFFER_SIZE 200
+#define CMD_LIST_SIZE 512
+
+// struct to hold a Gcode command
+typedef struct {
+    int G;
+    float X;
+    float Y;
+    float Z;
+    float F;
+    float I;
+    float J;
+}G_cmd;
+
+
+void parseGcode();
+void parserInit();
+G_cmd* fillInCmdList();
+void cmd_Received(MODSERIAL_IRQ_INFO *q);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Apr 14 05:03:29 2014 +0000
@@ -0,0 +1,17 @@
+#include "mbed.h"
+#include "gparser.h"
+#include "MODSERIAL.h"
+
+
+#define CMD_LIST_SIZE 512
+
+MODSERIAL gpc(USBTX, USBRX);
+
+extern G_cmd* gcmd_list;
+
+
+int main()
+{
+    parserInit();
+    fillInCmdList();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Apr 14 05:03:29 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6473597d706e
\ No newline at end of file