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