Final code for our 4180 Drawing Robot!
Dependencies: 4DGL-uLCD-SE gCodeParser mbed
Diff: main.cpp
- 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++; +}