Final code for our 4180 Drawing Robot!

Dependencies:   4DGL-uLCD-SE gCodeParser mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "gparser.h"
00003 #include "MODSERIAL.h"
00004 #include "motor.h"
00005 #include "drawBot.h"
00006 #include "uLCD_4DGL.h"
00007 #include <ctype.h>
00008 
00009 MODSERIAL gpc(USBTX, USBRX);
00010 uLCD_4DGL uLCD(p9, p10, p11);
00011 
00012 G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here
00013 
00014 extern int list_position;
00015 
00016 Motor mL(p29, p30, p26, p27, p28, p25, RIGHT_MOTOR);
00017 Motor mR(p12, p13, p16, p15, p14, p17, LEFT_MOTOR);
00018 DrawBot bot(&mL, &mR, p21, 0.5, 45.125);
00019 
00020 int main() {
00021         
00022         parserInit();
00023     
00024         fillInCmdList();
00025         uLCD.printf("Commands copied %d\n", list_position);
00026         
00027         for(int i=0; i<list_position; i++) {           
00028             //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);
00029             //wait(10);
00030             //uLCD.cls();              
00031             switch(gcmd_list[i].G) {
00032                 case 0:
00033                 case 1:
00034                     //Draw a line.
00035                     if(gcmd_list[i].X != -1 && gcmd_list[i].Y != -1) {
00036                         //uLCD.printf("Going to: %.2f, %.2f\n",gcmd_list[i].X,gcmd_list[i].Y);
00037                         bot.line_safe(gcmd_list[i].X, -1*gcmd_list[i].Y+20);
00038                     }
00039                     if(gcmd_list[i].Z > 0) {
00040                         //uLCD.printf("PEN UP\n");
00041                         bot.pen_up();    
00042                     }else if(gcmd_list[i].Z < 0) {
00043                         //uLCD.printf("PEN DOWN\n");
00044                         bot.pen_down();    
00045                     }
00046                 break;
00047                 case 2:
00048                     //Draw an arc or something.
00049                     bot.arc(gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].X, gcmd_list[i].Y, CCW_ARC);
00050                 break;
00051                 case 3:
00052                     //Draw a different arc or something.
00053                     bot.arc(gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].X, gcmd_list[i].Y, CW_ARC);
00054                 break;
00055                 default:
00056                 break;
00057                 
00058             }
00059         }   
00060         bot.disable();
00061 }
00062 
00063 //===================================================
00064 /*
00065  * mbed GCode parsing Library
00066  *
00067  */
00068 
00069 
00070 
00071 #define FEEDME 10
00072 #define END_OF_TRANSMISSION 23
00073 //extern MODSERIAL gpc;
00074 
00075 /************VARS*******************************/
00076 DigitalOut led1(LED1);
00077 DigitalOut led2(LED2);
00078 DigitalOut led3(LED3);
00079 DigitalOut led4(LED4);
00080 
00081 // buffer used to transfer the serial buffer contents and parse them into cmd structure
00082 char rx_buff[CMD_BUFFER_SIZE];
00083 
00084 volatile bool received;     // indicates when a new cmd is available in the serial buffer
00085 bool endTransmission;       // indicates that all the commands have been sent from the pc
00086 
00087 int list_position;  // counter to index the array of command structures
00088 
00089 
00090 /* This initializes the serial port params to match the PC application
00091  * the interrupt handlers are also initialized here
00092  */
00093 void parserInit()
00094 {
00095     list_position = 0;
00096     received = false;
00097     endTransmission = false;
00098     gpc.baud(921600);
00099     gpc.autoDetectChar('\0');  //<--to catch the null terminator at the end
00100     gpc.attach(&cmd_Received, MODSERIAL::RxAutoDetect); // declares callback for when cmd is ready
00101     gpc.rxBufferFlush();    // flush the buffer just in case
00102 }
00103 
00104 /* Parses the received messages into a G_cmd structure
00105  * it waits for the serial buffer to contain an entire command,
00106  * parses the gcode and sends the FEEDME command
00107  * to the pc to request another gcode line
00108  * returns a pointer to the allocated list of commands.
00109  */
00110 int fillInCmdList()
00111 {
00112     // end_flag_received should be detected in parseGcode()
00113     while(endTransmission == false) {
00114         // Light up LED1 to indicate the mbed is ready to receive Serial commands
00115         led1 = 1;
00116         if(received == true) {  //if the buffer has received the null terminator
00117 
00118             // Signal that we are now parsing by lighting LED2
00119             //led1 = 0;
00120             led2 = 1;
00121             parseGcode();
00122             gpc.rxBufferFlush();        // flushing the buffer just in case
00123             received = false;
00124             gpc.putc(FEEDME);           // requesting next command from the pc
00125             led2 = 0;                   // parsing stage is over
00126         }
00127     }
00128     
00129     //uLCD.printf("Commands copied %d\n", list_position);
00130     //for(int i = 0; i < list_position; i++) {
00131     //    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);
00132     //wait(10);
00133     //uLCD.cls();
00134     //}
00135     
00136     led1 = 1;
00137     wait(0.5);
00138     led1 = 0;
00139     led2 = 1;
00140     wait(0.5);
00141     led2 = 0;
00142     led3 = 1;
00143     wait(0.5);
00144     led3 = 0;
00145     led1 = 1;
00146     wait(0.5);
00147     led3 = 1;
00148     led2 = 1;
00149     return (list_position);
00150 }
00151 
00152 //interrupt routine called when the null terminator is received
00153 void cmd_Received(MODSERIAL_IRQ_INFO *q)
00154 {
00155     MODSERIAL *sys = q->serial;
00156     sys->move(rx_buff, CMD_BUFFER_SIZE);;
00157     received = true;
00158 }
00159 //TODO: Detect the connection finish characters and set a flag so fillInCmdBuff can return
00160 // Parses the received message and populates the structure
00161 void parseGcode()
00162 {
00163     // checking for the termination of connection
00164     if(rx_buff[0] == END_OF_TRANSMISSION) {
00165         led4 = 1;       //received end of transmission from pc
00166         endTransmission = true;
00167         return;
00168     }
00169 
00170     // in case there are leading spaces
00171     char* cmdP = strtok(rx_buff, " G");
00172 
00173     char coord_label[2];
00174 
00175     //int g = atoi(cmdP);
00176 
00177     //uLCD.printf("list pos is: %d\n", list_position);
00178 
00179     //fill out the command number field
00180     gcmd_list[list_position].G = atoi(cmdP);
00181     gcmd_list[list_position].X = -1;
00182     gcmd_list[list_position].Y = -1;
00183     gcmd_list[list_position].Z = 0; 
00184     gcmd_list[list_position].F = -1;
00185     gcmd_list[list_position].I = -1;
00186     gcmd_list[list_position].J = -1;
00187 
00188     //uLCD.printf("%d: ", gcmd_list[list_position].G);
00189 
00190     // Looping to get the arguments
00191     while (cmdP != NULL) {
00192         // Retrieve the next Label
00193         cmdP = strtok (NULL, " G");
00194         // cmdP should be pointing to a letter now
00195         //uLCD.printf("Coord: %s.\n", cmdP);
00196         coord_label[0] = cmdP[0];
00197         coord_label[1] = cmdP[1];
00198 
00199         // retrieve the number after the letter
00200         cmdP = strtok (NULL, " G");
00201 
00202         // now print the number
00203         //uLCD.printf("%s ", cmdP);
00204         /*
00205         gcmd_list[list_position].X = -1;
00206         gcmd_list[list_position].Y = -1;
00207         gcmd_list[list_position].Z = -2;
00208         gcmd_list[list_position].F = -1;
00209         gcmd_list[list_position].I = -1;
00210         gcmd_list[list_position].J = -1;
00211         */
00212         switch(coord_label[0]) {
00213             case 'X':
00214                 gcmd_list[list_position].X = atof(cmdP);
00215                 break;
00216             case 'Y':
00217                 gcmd_list[list_position].Y = atof(cmdP);
00218                 break;
00219             case 'Z':
00220                 gcmd_list[list_position].Z = atof(cmdP);
00221                 break;
00222             case 'F':
00223                 gcmd_list[list_position].F = atof(cmdP);
00224                 break;
00225             case 'I':
00226                 gcmd_list[list_position].I = atof(cmdP);
00227                 break;
00228             case 'J':
00229                 gcmd_list[list_position].J = atof(cmdP);
00230                 break;
00231             default:
00232 
00233                 break;
00234         }// switch
00235     } // while
00236     list_position++;
00237 }