Final code for our 4180 Drawing Robot!

Dependencies:   4DGL-uLCD-SE gCodeParser mbed

Revision:
1:ad895d72e9ed
Parent:
0:40576dfac535
--- a/main.cpp	Tue Apr 29 21:51:29 2014 +0000
+++ b/main.cpp	Wed Apr 30 01:47:43 2014 +0000
@@ -4,15 +4,14 @@
 #include "motor.h"
 #include "drawBot.h"
 #include "uLCD_4DGL.h"
-
-#define CMD_LIST_SIZE 512
+#include <ctype.h>
 
 MODSERIAL gpc(USBTX, USBRX);
 uLCD_4DGL uLCD(p9, p10, p11);
-//G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here
 
-extern G_cmd* gcmd_list;
-extern list_position;
+G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here
+
+extern int list_position;
 
 Motor mL(p29, p30, p26, p27, p28, p25, RIGHT_MOTOR);
 Motor mR(p12, p13, p16, p15, p14, p17, LEFT_MOTOR);
@@ -22,33 +21,36 @@
         
         parserInit();
     
-        int list_pos = fillInCmdList();
-        uLCD.printf("%d\r\n",list_pos);
+        fillInCmdList();
+        uLCD.printf("Commands copied %d\n", list_position);
         
-        for(int c=0; c<list_pos; c++) {
-            G_cmd* next = gcmd_list+c;
-            uLCD.printf("G:%d X%.2f Y%.2f Z%.2f I%.2f J%.2f\n",next->X, next->Y, next->Z, next->I,next->J,next->F);
-            wait(10);
-            uLCD.cls();              
-            switch(next->G) {
+        for(int i=0; i<list_position; i++) {           
+            //uLCD.printf("G:%d X:%.2f Y:%.2f Z:%.2f I:%.2f J:%.2f F:%.2f\r\n", gcmd_list[i].G, gcmd_list[i].X, gcmd_list[i].Y, gcmd_list[i].Z, gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].F);
+            //wait(10);
+            //uLCD.cls();              
+            switch(gcmd_list[i].G) {
                 case 0:
                 case 1:
                     //Draw a line.
-                    if(next->X != -1 && next->Y != -1) {
-                        bot.line_safe(next->X, next->Y);
+                    if(gcmd_list[i].X != -1 && gcmd_list[i].Y != -1) {
+                        //uLCD.printf("Going to: %.2f, %.2f\n",gcmd_list[i].X,gcmd_list[i].Y);
+                        bot.line_safe(gcmd_list[i].X, -1*gcmd_list[i].Y+20);
                     }
-                    if(next->Z > 0) {
+                    if(gcmd_list[i].Z > 0) {
+                        //uLCD.printf("PEN UP\n");
                         bot.pen_up();    
-                    }else if(next->Z == 0) {
+                    }else if(gcmd_list[i].Z < 0) {
+                        //uLCD.printf("PEN DOWN\n");
                         bot.pen_down();    
                     }
                 break;
                 case 2:
                     //Draw an arc or something.
-                    //bot->arc(px+i, py+j, next_cmd->X, next_cmd->Z);
+                    bot.arc(gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].X, gcmd_list[i].Y, CCW_ARC);
                 break;
                 case 3:
                     //Draw a different arc or something.
+                    bot.arc(gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].X, gcmd_list[i].Y, CW_ARC);
                 break;
                 default:
                 break;
@@ -56,4 +58,180 @@
             }
         }   
         bot.disable();
-}
\ No newline at end of file
+}
+
+//===================================================
+/*
+ * mbed GCode parsing Library
+ *
+ */
+
+
+
+#define FEEDME 10
+#define END_OF_TRANSMISSION 23
+//extern MODSERIAL gpc;
+
+/************VARS*******************************/
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+// 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.
+ */
+int fillInCmdList()
+{
+    // 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 = 0; i < list_position; i++) {
+    //    uLCD.printf("G:%d X:%.2f Y:%.2f Z:%.2f I:%.2f J:%.2f F:%.2f\r\n", gcmd_list[i].G, gcmd_list[i].X, gcmd_list[i].Y, gcmd_list[i].Z, gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].F);
+    //wait(10);
+    //uLCD.cls();
+    //}
+    
+    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 (list_position);
+}
+
+//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");
+
+    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);
+    gcmd_list[list_position].X = -1;
+    gcmd_list[list_position].Y = -1;
+    gcmd_list[list_position].Z = 0; 
+    gcmd_list[list_position].F = -1;
+    gcmd_list[list_position].I = -1;
+    gcmd_list[list_position].J = -1;
+
+    //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);
+        /*
+        gcmd_list[list_position].X = -1;
+        gcmd_list[list_position].Y = -1;
+        gcmd_list[list_position].Z = -2;
+        gcmd_list[list_position].F = -1;
+        gcmd_list[list_position].I = -1;
+        gcmd_list[list_position].J = -1;
+        */
+        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++;
+}