Final code for our 4180 Drawing Robot!
Dependencies: 4DGL-uLCD-SE gCodeParser mbed
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 }
Generated on Thu Jul 21 2022 12:50:48 by 1.7.2