Parses gcode commands sent over serial communication

Dependencies:   4DGL-uLCD-SE MODSERIAL mbed

Committer:
ajb88
Date:
Mon Apr 14 05:03:29 2014 +0000
Revision:
0:fa0891ea897b
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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajb88 0:fa0891ea897b 1 /*
ajb88 0:fa0891ea897b 2 * mbed GCode parsing Library
ajb88 0:fa0891ea897b 3 *
ajb88 0:fa0891ea897b 4 */
ajb88 0:fa0891ea897b 5 #include "gparser.h"
ajb88 0:fa0891ea897b 6 #include "mbed.h"
ajb88 0:fa0891ea897b 7 #include "MODSERIAL.h"
ajb88 0:fa0891ea897b 8 #include <ctype.h>
ajb88 0:fa0891ea897b 9
ajb88 0:fa0891ea897b 10 #define TEST
ajb88 0:fa0891ea897b 11
ajb88 0:fa0891ea897b 12 #ifdef TEST
ajb88 0:fa0891ea897b 13 #include "uLCD_4DGL.h"
ajb88 0:fa0891ea897b 14 uLCD_4DGL uLCD(p9,p10,p11);
ajb88 0:fa0891ea897b 15 #endif
ajb88 0:fa0891ea897b 16
ajb88 0:fa0891ea897b 17 #define FEEDME 10
ajb88 0:fa0891ea897b 18 #define END_OF_TRANSMISSION 23
ajb88 0:fa0891ea897b 19 extern MODSERIAL gpc;
ajb88 0:fa0891ea897b 20
ajb88 0:fa0891ea897b 21 /************VARS*******************************/
ajb88 0:fa0891ea897b 22 DigitalOut led1(LED1);
ajb88 0:fa0891ea897b 23 DigitalOut led2(LED2);
ajb88 0:fa0891ea897b 24 DigitalOut led3(LED3);
ajb88 0:fa0891ea897b 25 DigitalOut led4(LED4);
ajb88 0:fa0891ea897b 26
ajb88 0:fa0891ea897b 27 G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here
ajb88 0:fa0891ea897b 28
ajb88 0:fa0891ea897b 29 // buffer used to transfer the serial buffer contents and parse them into cmd structure
ajb88 0:fa0891ea897b 30 char rx_buff[CMD_BUFFER_SIZE];
ajb88 0:fa0891ea897b 31
ajb88 0:fa0891ea897b 32 volatile bool received; // indicates when a new cmd is available in the serial buffer
ajb88 0:fa0891ea897b 33 bool endTransmission; // indicates that all the commands have been sent from the pc
ajb88 0:fa0891ea897b 34
ajb88 0:fa0891ea897b 35 int list_position; // counter to index the array of command structures
ajb88 0:fa0891ea897b 36
ajb88 0:fa0891ea897b 37
ajb88 0:fa0891ea897b 38 /* This initializes the serial port params to match the PC application
ajb88 0:fa0891ea897b 39 * the interrupt handlers are also initialized here
ajb88 0:fa0891ea897b 40 */
ajb88 0:fa0891ea897b 41 void parserInit()
ajb88 0:fa0891ea897b 42 {
ajb88 0:fa0891ea897b 43 list_position = 0;
ajb88 0:fa0891ea897b 44 received = false;
ajb88 0:fa0891ea897b 45 endTransmission = false;
ajb88 0:fa0891ea897b 46 gpc.baud(921600);
ajb88 0:fa0891ea897b 47 gpc.autoDetectChar('\0'); //<--to catch the null terminator at the end
ajb88 0:fa0891ea897b 48 gpc.attach(&cmd_Received, MODSERIAL::RxAutoDetect); // declares callback for when cmd is ready
ajb88 0:fa0891ea897b 49 gpc.rxBufferFlush(); // flush the buffer just in case
ajb88 0:fa0891ea897b 50 }
ajb88 0:fa0891ea897b 51
ajb88 0:fa0891ea897b 52 /* Parses the received messages into a G_cmd structure
ajb88 0:fa0891ea897b 53 * it waits for the serial buffer to contain an entire command,
ajb88 0:fa0891ea897b 54 * parses the gcode and sends the FEEDME command
ajb88 0:fa0891ea897b 55 * to the pc to request another gcode line
ajb88 0:fa0891ea897b 56 * returns a pointer to the allocated list of commands.
ajb88 0:fa0891ea897b 57 */
ajb88 0:fa0891ea897b 58 G_cmd* fillInCmdList()
ajb88 0:fa0891ea897b 59 {
ajb88 0:fa0891ea897b 60 //list_position = 0; // incremented by parseGcode at the end
ajb88 0:fa0891ea897b 61
ajb88 0:fa0891ea897b 62 // end_flag_received should be detected in parseGcode()
ajb88 0:fa0891ea897b 63 while(endTransmission == false) {
ajb88 0:fa0891ea897b 64 // Light up LED1 to indicate the mbed is ready to receive Serial commands
ajb88 0:fa0891ea897b 65 led1 = 1;
ajb88 0:fa0891ea897b 66 if(received == true) { //if the buffer has received the null terminator
ajb88 0:fa0891ea897b 67
ajb88 0:fa0891ea897b 68 // Signal that we are now parsing by lighting LED2
ajb88 0:fa0891ea897b 69 //led1 = 0;
ajb88 0:fa0891ea897b 70 led2 = 1;
ajb88 0:fa0891ea897b 71 parseGcode();
ajb88 0:fa0891ea897b 72 gpc.rxBufferFlush(); // flushing the buffer just in case
ajb88 0:fa0891ea897b 73 received = false;
ajb88 0:fa0891ea897b 74 gpc.putc(FEEDME); // requesting next command from the pc
ajb88 0:fa0891ea897b 75 led2 = 0; // parsing stage is over
ajb88 0:fa0891ea897b 76 }
ajb88 0:fa0891ea897b 77 }
ajb88 0:fa0891ea897b 78 uLCD.printf("Commands copied %d\n", list_position);
ajb88 0:fa0891ea897b 79
ajb88 0:fa0891ea897b 80 for(int i = (list_position - 4); i < list_position; i++) {
ajb88 0:fa0891ea897b 81 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);
ajb88 0:fa0891ea897b 82 }
ajb88 0:fa0891ea897b 83
ajb88 0:fa0891ea897b 84 led1 = 1;
ajb88 0:fa0891ea897b 85 wait(0.5);
ajb88 0:fa0891ea897b 86 led1 = 0;
ajb88 0:fa0891ea897b 87 led2 = 1;
ajb88 0:fa0891ea897b 88 wait(0.5);
ajb88 0:fa0891ea897b 89 led2 = 0;
ajb88 0:fa0891ea897b 90 led3 = 1;
ajb88 0:fa0891ea897b 91 wait(0.5);
ajb88 0:fa0891ea897b 92 led3 = 0;
ajb88 0:fa0891ea897b 93 led1 = 1;
ajb88 0:fa0891ea897b 94 wait(0.5);
ajb88 0:fa0891ea897b 95 led3 = 1;
ajb88 0:fa0891ea897b 96 led2 = 1;
ajb88 0:fa0891ea897b 97 return gcmd_list;
ajb88 0:fa0891ea897b 98 }
ajb88 0:fa0891ea897b 99
ajb88 0:fa0891ea897b 100 //interrupt routine called when the null terminator is received
ajb88 0:fa0891ea897b 101 void cmd_Received(MODSERIAL_IRQ_INFO *q)
ajb88 0:fa0891ea897b 102 {
ajb88 0:fa0891ea897b 103 MODSERIAL *sys = q->serial;
ajb88 0:fa0891ea897b 104 sys->move(rx_buff, CMD_BUFFER_SIZE);;
ajb88 0:fa0891ea897b 105 received = true;
ajb88 0:fa0891ea897b 106 }
ajb88 0:fa0891ea897b 107 //TODO: Detect the connection finish characters and set a flag so fillInCmdBuff can return
ajb88 0:fa0891ea897b 108 // Parses the received message and populates the structure
ajb88 0:fa0891ea897b 109 void parseGcode()
ajb88 0:fa0891ea897b 110 {
ajb88 0:fa0891ea897b 111 // checking for the termination of connection
ajb88 0:fa0891ea897b 112 if(rx_buff[0] == END_OF_TRANSMISSION) {
ajb88 0:fa0891ea897b 113 led4 = 1; //received end of transmission from pc
ajb88 0:fa0891ea897b 114 endTransmission = true;
ajb88 0:fa0891ea897b 115 return;
ajb88 0:fa0891ea897b 116 }
ajb88 0:fa0891ea897b 117
ajb88 0:fa0891ea897b 118 // in case there are leading spaces
ajb88 0:fa0891ea897b 119 char* cmdP = strtok(rx_buff, " G");
ajb88 0:fa0891ea897b 120
ajb88 0:fa0891ea897b 121 //uLCD.printf("cmdP is pointing now to %s\n", cmdP);
ajb88 0:fa0891ea897b 122
ajb88 0:fa0891ea897b 123 char coord_label[2];
ajb88 0:fa0891ea897b 124
ajb88 0:fa0891ea897b 125 //int g = atoi(cmdP);
ajb88 0:fa0891ea897b 126
ajb88 0:fa0891ea897b 127 //uLCD.printf("list pos is: %d\n", list_position);
ajb88 0:fa0891ea897b 128
ajb88 0:fa0891ea897b 129 //fill out the command number field
ajb88 0:fa0891ea897b 130 gcmd_list[list_position].G = atoi(cmdP);
ajb88 0:fa0891ea897b 131
ajb88 0:fa0891ea897b 132 //uLCD.printf("%d: ", gcmd_list[list_position].G);
ajb88 0:fa0891ea897b 133
ajb88 0:fa0891ea897b 134 // Looping to get the arguments
ajb88 0:fa0891ea897b 135 while (cmdP != NULL) {
ajb88 0:fa0891ea897b 136 // Retrieve the next Label
ajb88 0:fa0891ea897b 137 cmdP = strtok (NULL, " G");
ajb88 0:fa0891ea897b 138 // cmdP should be pointing to a letter now
ajb88 0:fa0891ea897b 139 //uLCD.printf("Coord: %s.\n", cmdP);
ajb88 0:fa0891ea897b 140 coord_label[0] = cmdP[0];
ajb88 0:fa0891ea897b 141 coord_label[1] = cmdP[1];
ajb88 0:fa0891ea897b 142
ajb88 0:fa0891ea897b 143 // retrieve the number after the letter
ajb88 0:fa0891ea897b 144 cmdP = strtok (NULL, " G");
ajb88 0:fa0891ea897b 145
ajb88 0:fa0891ea897b 146 // now print the number
ajb88 0:fa0891ea897b 147 //uLCD.printf("%s ", cmdP);
ajb88 0:fa0891ea897b 148 switch(coord_label[0]) {
ajb88 0:fa0891ea897b 149 case 'X':
ajb88 0:fa0891ea897b 150 gcmd_list[list_position].X = atof(cmdP);
ajb88 0:fa0891ea897b 151 break;
ajb88 0:fa0891ea897b 152 case 'Y':
ajb88 0:fa0891ea897b 153 gcmd_list[list_position].Y = atof(cmdP);
ajb88 0:fa0891ea897b 154 break;
ajb88 0:fa0891ea897b 155 case 'Z':
ajb88 0:fa0891ea897b 156 gcmd_list[list_position].Z = atof(cmdP);
ajb88 0:fa0891ea897b 157 break;
ajb88 0:fa0891ea897b 158 case 'F':
ajb88 0:fa0891ea897b 159 gcmd_list[list_position].F = atof(cmdP);
ajb88 0:fa0891ea897b 160 break;
ajb88 0:fa0891ea897b 161 case 'I':
ajb88 0:fa0891ea897b 162 gcmd_list[list_position].I = atof(cmdP);
ajb88 0:fa0891ea897b 163 break;
ajb88 0:fa0891ea897b 164 case 'J':
ajb88 0:fa0891ea897b 165 gcmd_list[list_position].J = atof(cmdP);
ajb88 0:fa0891ea897b 166 break;
ajb88 0:fa0891ea897b 167 default:
ajb88 0:fa0891ea897b 168
ajb88 0:fa0891ea897b 169 break;
ajb88 0:fa0891ea897b 170 }// switch
ajb88 0:fa0891ea897b 171 } // while
ajb88 0:fa0891ea897b 172 list_position++;
ajb88 0:fa0891ea897b 173 }