Components and supplies
1
Arduino UNO
1
Dual H-Bridge motor drivers L293D
Apps and platforms
1
Arduino IDE
Project description
Code
untitled
c_cpp
1#include <Servo.h> 2#include <AFMotor.h> 3 4#define LINE_BUFFER_LENGTH 512 5 6char STEP = MICROSTEP ; 7 8// Servo position for Up and Down 9const int penZUp = 115; 10const int penZDown = 83; 11 12// Servo on PWM pin 10 13const int penServoPin =10 ; 14 15// Should be right for DVD steppers, but is not too important here 16const int stepsPerRevolution = 48; 17 18// create servo object to control a servo 19Servo penServo; 20 21// Initialize steppers for X- and Y-axis using this Arduino pins for the L293D H-bridge 22AF_Stepper myStepperY(stepsPerRevolution,1); 23AF_Stepper myStepperX(stepsPerRevolution,2); 24 25/* Structures, global variables */ 26struct point { 27 float x; 28 float y; 29 float z; 30}; 31 32// Current position of plothead 33struct point actuatorPos; 34 35// Drawing settings, should be OK 36float StepInc = 1; 37int StepDelay = 0; 38int LineDelay =0; 39int penDelay = 50; 40 41// Motor steps to go 1 millimeter. 42// Use test sketch to go 100 steps. Measure the length of line. 43// Calculate steps per mm. Enter here. 44float StepsPerMillimeterX = 100.0; 45float StepsPerMillimeterY = 100.0; 46 47// Drawing robot limits, in mm 48// OK to start with. Could go up to 50 mm if calibrated well. 49float Xmin = 0; 50float Xmax = 40; 51float Ymin = 0; 52float Ymax = 40; 53float Zmin = 0; 54float Zmax = 1; 55 56float Xpos = Xmin; 57float Ypos = Ymin; 58float Zpos = Zmax; 59 60// Set to true to get debug output. 61boolean verbose = false; 62 63// Needs to interpret 64// G1 for moving 65// G4 P300 (wait 150ms) 66// M300 S30 (pen down) 67// M300 S50 (pen up) 68// Discard anything with a ( 69// Discard any other command! 70 71/********************** 72 * void setup() - Initialisations 73 ***********************/ 74void setup() { 75 // Setup 76 77 Serial.begin( 9600 ); 78 79 penServo.attach(penServoPin); 80 penServo.write(penZUp); 81 delay(100); 82 83 // Decrease if necessary 84 myStepperX.setSpeed(600); 85 86 myStepperY.setSpeed(600); 87 88 89 // Set & move to initial default position 90 // TBD 91 92 // Notifications!!! 93 Serial.println("Mini CNC Plotter alive and kicking!"); 94 Serial.print("X range is from "); 95 Serial.print(Xmin); 96 Serial.print(" to "); 97 Serial.print(Xmax); 98 Serial.println(" mm."); 99 Serial.print("Y range is from "); 100 Serial.print(Ymin); 101 Serial.print(" to "); 102 Serial.print(Ymax); 103 Serial.println(" mm."); 104} 105 106/********************** 107 * void loop() - Main loop 108 ***********************/ 109void loop() 110{ 111 112 delay(100); 113 char line[ LINE_BUFFER_LENGTH ]; 114 char c; 115 int lineIndex; 116 bool lineIsComment, lineSemiColon; 117 118 lineIndex = 0; 119 lineSemiColon = false; 120 lineIsComment = false; 121 122 while (1) { 123 124 // Serial reception - Mostly from Grbl, added semicolon support 125 while ( Serial.available()>0 ) { 126 c = Serial.read(); 127 if (( c == '\n') || (c == '\r') ) { // End of line reached 128 if ( lineIndex > 0 ) { // Line is complete. Then execute! 129 line[ lineIndex ] = '\\0'; // Terminate string 130 if (verbose) { 131 Serial.print( "Received : "); 132 Serial.println( line ); 133 } 134 processIncomingLine( line, lineIndex ); 135 lineIndex = 0; 136 } 137 else { 138 // Empty or comment line. Skip block. 139 } 140 lineIsComment = false; 141 lineSemiColon = false; 142 Serial.println("ok"); 143 } 144 else { 145 if ( (lineIsComment) || (lineSemiColon) ) { // Throw away all comment characters 146 if ( c == ')' ) lineIsComment = false; // End of comment. Resume line. 147 } 148 else { 149 if ( c <= ' ' ) { // Throw away whitepace and control characters 150 } 151 else if ( c == '/' ) { // Block delete not supported. Ignore character. 152 } 153 else if ( c == '(' ) { // Enable comments flag and ignore all characters until ')' or EOL. 154 lineIsComment = true; 155 } 156 else if ( c == ';' ) { 157 lineSemiColon = true; 158 } 159 else if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) { 160 Serial.println( "ERROR - lineBuffer overflow" ); 161 lineIsComment = false; 162 lineSemiColon = false; 163 } 164 else if ( c >= 'a' && c <= 'z' ) { // Upcase lowercase 165 line[ lineIndex++ ] = c-'a'+'A'; 166 } 167 else { 168 line[ lineIndex++ ] = c; 169 } 170 } 171 } 172 } 173 } 174} 175 176void processIncomingLine( char* line, int charNB ) { 177 int currentIndex = 0; 178 char buffer[ 64 ]; // Hope that 64 is enough for 1 parameter 179 struct point newPos; 180 181 newPos.x = 0.0; 182 newPos.y = 0.0; 183 184 // Needs to interpret 185 // G1 for moving 186 // G4 P300 (wait 150ms) 187 // G1 X60 Y30 188 // G1 X30 Y50 189 // M300 S30 (pen down) 190 // M300 S50 (pen up) 191 // Discard anything with a ( 192 // Discard any other command! 193 194 while( currentIndex < charNB ) { 195 switch ( line[ currentIndex++ ] ) { // Select command, if any 196 case 'U': 197 penUp(); 198 break; 199 case 'D': 200 penDown(); 201 break; 202 case 'G': 203 buffer[0] = line[ currentIndex++ ]; // /!\Dirty - Only works with 2 digit commands 204 // buffer[1] = line[ currentIndex++ ]; 205 // buffer[2] = '\\0'; 206 buffer[1] = '\\0'; 207 208 switch ( atoi( buffer ) ){ // Select G command 209 case 0: // G00 & G01 - Movement or fast movement. Same here 210 case 1: 211 // /!\Dirty - Suppose that X is before Y 212 char* indexX = strchr( line+currentIndex, 'X' ); // Get X/Y position in the string (if any) 213 char* indexY = strchr( line+currentIndex, 'Y' ); 214 if ( indexY <= 0 ) { 215 newPos.x = atof( indexX + 1); 216 newPos.y = actuatorPos.y; 217 } 218 else if ( indexX <= 0 ) { 219 newPos.y = atof( indexY + 1); 220 newPos.x = actuatorPos.x; 221 } 222 else { 223 newPos.y = atof( indexY + 1); 224 indexY = '\\0'; 225 newPos.x = atof( indexX + 1); 226 } 227 drawLine(newPos.x, newPos.y ); 228 // Serial.println("ok"); 229 actuatorPos.x = newPos.x; 230 actuatorPos.y = newPos.y; 231 break; 232 } 233 break; 234 case 'M': 235 buffer[0] = line[ currentIndex++ ]; // /!\Dirty - Only works with 3 digit commands 236 buffer[1] = line[ currentIndex++ ]; 237 buffer[2] = line[ currentIndex++ ]; 238 buffer[3] = '\\0'; 239 switch ( atoi( buffer ) ){ 240 case 300: 241 { 242 char* indexS = strchr( line+currentIndex, 'S' ); 243 float Spos = atof( indexS + 1); 244 // Serial.println("ok"); 245 if (Spos == 30) { 246 penDown(); 247 } 248 if (Spos == 50) { 249 penUp(); 250 } 251 break; 252 } 253 case 114: // M114 - Repport position 254 Serial.print( "Absolute position : X = " ); 255 Serial.print( actuatorPos.x ); 256 Serial.print( " - Y = " ); 257 Serial.println( actuatorPos.y ); 258 break; 259 default: 260 Serial.print( "Command not recognized : M"); 261 Serial.println( buffer ); 262 } 263 } 264 } 265 266 267 268} 269 270 271/********************************* 272 * Draw a line from (x0;y0) to (x1;y1). 273 * int (x1;y1) : Starting coordinates 274 * int (x2;y2) : Ending coordinates 275 **********************************/ 276void drawLine(float x1, float y1) { 277 278 if (verbose) 279 { 280 Serial.print("fx1, fy1: "); 281 Serial.print(x1); 282 Serial.print(","); 283 Serial.print(y1); 284 Serial.println(""); 285 } 286 287 // Bring instructions within limits 288 if (x1 >= Xmax) { 289 x1 = Xmax; 290 } 291 if (x1 <= Xmin) { 292 x1 = Xmin; 293 } 294 if (y1 >= Ymax) { 295 y1 = Ymax; 296 } 297 if (y1 <= Ymin) { 298 y1 = Ymin; 299 } 300 301 if (verbose) 302 { 303 Serial.print("Xpos, Ypos: "); 304 Serial.print(Xpos); 305 Serial.print(","); 306 Serial.print(Ypos); 307 Serial.println(""); 308 } 309 310 if (verbose) 311 { 312 Serial.print("x1, y1: "); 313 Serial.print(x1); 314 Serial.print(","); 315 Serial.print(y1); 316 Serial.println(""); 317 } 318 319 // Convert coordinates to steps 320 x1 = (int)(x1*StepsPerMillimeterX); 321 y1 = (int)(y1*StepsPerMillimeterY); 322 float x0 = Xpos; 323 float y0 = Ypos; 324 325 // Let's find out the change for the coordinates 326 long dx = abs(x1-x0); 327 long dy = abs(y1-y0); 328 int sx = x0<x1 ? StepInc : -StepInc; 329 int sy = y0<y1 ? StepInc : -StepInc; 330 331 long i; 332 long over = 0; 333 334 if (dx > dy) { 335 for (i=0; i<dx; ++i) { 336 myStepperX.onestep(sx,STEP); 337 over+=dy; 338 if (over>=dx) { 339 over-=dx; 340 myStepperY.onestep(sy,STEP); 341 } 342 delay(StepDelay); 343 } 344 } 345 else { 346 for (i=0; i<dy; ++i) { 347 myStepperY.onestep(sy,STEP); 348 over+=dx; 349 if (over>=dy) { 350 over-=dy; 351 myStepperX.onestep(sx,STEP); 352 } 353 delay(StepDelay); 354 } 355 } 356 357 if (verbose) 358 { 359 Serial.print("dx, dy:"); 360 Serial.print(dx); 361 Serial.print(","); 362 Serial.print(dy); 363 Serial.println(""); 364 } 365 366 if (verbose) 367 { 368 Serial.print("Going to ("); 369 Serial.print(x0); 370 Serial.print(","); 371 Serial.print(y0); 372 Serial.println(")"); 373 } 374 375 // Delay before any next lines are submitted 376 delay(LineDelay); 377 // Update the positions 378 Xpos = x1; 379 Ypos = y1; 380} 381 382// Raises pen 383void penUp() { 384 penServo.write(penZUp); 385 delay(penDelay); 386 Zpos=Zmax; 387 digitalWrite(15, LOW); 388 digitalWrite(16, HIGH); 389 if (verbose) { 390 Serial.println("Pen up!"); 391 392 } 393} 394// Lowers pen 395void penDown() { 396 penServo.write(penZDown); 397 delay(penDelay); 398 Zpos=Zmin; 399 digitalWrite(15, HIGH); 400 digitalWrite(16, LOW); 401 if (verbose) { 402 Serial.println("Pen down."); 403 404 405 } 406}
untitled
c_cpp
1#include <Servo.h> 2#include <AFMotor.h> 3 4#define LINE_BUFFER_LENGTH 5 512 6 7char STEP = MICROSTEP ; 8 9// Servo position for Up and Down 10const 11 int penZUp = 115; 12const int penZDown = 83; 13 14// Servo on PWM pin 10 15const 16 int penServoPin =10 ; 17 18// Should be right for DVD steppers, but is not too 19 important here 20const int stepsPerRevolution = 48; 21 22// create servo object 23 to control a servo 24Servo penServo; 25 26// Initialize steppers for X- and 27 Y-axis using this Arduino pins for the L293D H-bridge 28AF_Stepper myStepperY(stepsPerRevolution,1); 29 30AF_Stepper myStepperX(stepsPerRevolution,2); 31 32/* Structures, 33 global variables */ 34struct point { 35 float x; 36 float y; 37 float 38 z; 39}; 40 41// Current position of plothead 42struct point actuatorPos; 43 44// 45 Drawing settings, should be OK 46float StepInc = 1; 47int StepDelay = 0; 48int 49 LineDelay =0; 50int penDelay = 50; 51 52// Motor steps to go 1 millimeter. 53// 54 Use test sketch to go 100 steps. Measure the length of line. 55// Calculate steps 56 per mm. Enter here. 57float StepsPerMillimeterX = 100.0; 58float StepsPerMillimeterY 59 = 100.0; 60 61// Drawing robot limits, in mm 62// OK to start with. Could go 63 up to 50 mm if calibrated well. 64float Xmin = 0; 65float Xmax = 40; 66float 67 Ymin = 0; 68float Ymax = 40; 69float Zmin = 0; 70float Zmax = 1; 71 72float 73 Xpos = Xmin; 74float Ypos = Ymin; 75float Zpos = Zmax; 76 77// Set to true 78 to get debug output. 79boolean verbose = false; 80 81// Needs to interpret 82// 83 G1 for moving 84// G4 P300 (wait 150ms) 85// M300 S30 (pen down) 86// M300 87 S50 (pen up) 88// Discard anything with a ( 89// Discard any other command! 90 91/********************** 92 93 * void setup() - Initialisations 94 ***********************/ 95void setup() { 96 97 // Setup 98 99 Serial.begin( 9600 ); 100 101 penServo.attach(penServoPin); 102 103 penServo.write(penZUp); 104 delay(100); 105 106 // Decrease if necessary 107 108 myStepperX.setSpeed(600); 109 110 myStepperY.setSpeed(600); 111 112 113 // 114 Set & move to initial default position 115 // TBD 116 117 // Notifications!!! 118 119 Serial.println("Mini CNC Plotter alive and kicking!"); 120 Serial.print("X 121 range is from "); 122 Serial.print(Xmin); 123 Serial.print(" to "); 124 125 Serial.print(Xmax); 126 Serial.println(" mm."); 127 Serial.print("Y range 128 is from "); 129 Serial.print(Ymin); 130 Serial.print(" to "); 131 Serial.print(Ymax); 132 133 Serial.println(" mm."); 134} 135 136/********************** 137 * void 138 loop() - Main loop 139 ***********************/ 140void loop() 141{ 142 143 delay(100); 144 145 char line[ LINE_BUFFER_LENGTH ]; 146 char c; 147 int lineIndex; 148 bool lineIsComment, 149 lineSemiColon; 150 151 lineIndex = 0; 152 lineSemiColon = false; 153 lineIsComment 154 = false; 155 156 while (1) { 157 158 // Serial reception - Mostly from Grbl, 159 added semicolon support 160 while ( Serial.available()>0 ) { 161 c = Serial.read(); 162 163 if (( c == '\ 164') || (c == '\ ') ) { // End of line reached 165 166 if ( lineIndex > 0 ) { // Line is complete. Then 167 execute! 168 line[ lineIndex ] = '\\0'; // Terminate 169 string 170 if (verbose) { 171 Serial.print( "Received : "); 172 173 Serial.println( line ); 174 } 175 processIncomingLine( 176 line, lineIndex ); 177 lineIndex = 0; 178 } 179 else { 180 181 // Empty or comment line. Skip block. 182 } 183 lineIsComment 184 = false; 185 lineSemiColon = false; 186 Serial.println("ok"); 187 188 } 189 else { 190 if ( (lineIsComment) || (lineSemiColon) ) { 191 // Throw away all comment characters 192 if ( c == ')' ) lineIsComment 193 = false; // End of comment. Resume line. 194 } 195 else { 196 197 if ( c <= ' ' ) { // Throw away whitepace and 198 control characters 199 } 200 else if ( c == '/' ) { // 201 Block delete not supported. Ignore character. 202 } 203 else 204 if ( c == '(' ) { // Enable comments flag and ignore all characters 205 until ')' or EOL. 206 lineIsComment = true; 207 } 208 else 209 if ( c == ';' ) { 210 lineSemiColon = true; 211 } 212 else 213 if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) { 214 Serial.println( "ERROR 215 - lineBuffer overflow" ); 216 lineIsComment = false; 217 lineSemiColon 218 = false; 219 } 220 else if ( c >= 'a' && c <= 'z' ) { // 221 Upcase lowercase 222 line[ lineIndex++ ] = c-'a'+'A'; 223 } 224 225 else { 226 line[ lineIndex++ ] = c; 227 } 228 229 } 230 } 231 } 232 } 233} 234 235void processIncomingLine( char* 236 line, int charNB ) { 237 int currentIndex = 0; 238 char buffer[ 64 ]; // 239 Hope that 64 is enough for 1 parameter 240 struct point newPos; 241 242 newPos.x 243 = 0.0; 244 newPos.y = 0.0; 245 246 // Needs to interpret 247 // G1 for moving 248 249 // G4 P300 (wait 150ms) 250 // G1 X60 Y30 251 // G1 X30 Y50 252 // M300 253 S30 (pen down) 254 // M300 S50 (pen up) 255 // Discard anything with a ( 256 257 // Discard any other command! 258 259 while( currentIndex < charNB ) { 260 switch 261 ( line[ currentIndex++ ] ) { // Select command, if any 262 case 263 'U': 264 penUp(); 265 break; 266 case 'D': 267 penDown(); 268 269 break; 270 case 'G': 271 buffer[0] = line[ currentIndex++ ]; // 272 /!\Dirty - Only works with 2 digit commands 273 // buffer[1] = line[ 274 currentIndex++ ]; 275 // buffer[2] = '\\0'; 276 buffer[1] = '\\0'; 277 278 279 switch ( atoi( buffer ) ){ // Select G command 280 case 281 0: // G00 & G01 - Movement or fast movement. Same 282 here 283 case 1: 284 // /!\Dirty - Suppose that X is before Y 285 286 char* indexX = strchr( line+currentIndex, 'X' ); // Get X/Y position in 287 the string (if any) 288 char* indexY = strchr( line+currentIndex, 'Y' ); 289 290 if ( indexY <= 0 ) { 291 newPos.x = atof( indexX + 1); 292 newPos.y 293 = actuatorPos.y; 294 } 295 else if ( indexX <= 0 ) { 296 newPos.y 297 = atof( indexY + 1); 298 newPos.x = actuatorPos.x; 299 } 300 else 301 { 302 newPos.y = atof( indexY + 1); 303 indexY = '\\0'; 304 newPos.x 305 = atof( indexX + 1); 306 } 307 drawLine(newPos.x, newPos.y ); 308 309 // Serial.println("ok"); 310 actuatorPos.x = newPos.x; 311 312 actuatorPos.y = newPos.y; 313 break; 314 } 315 break; 316 317 case 'M': 318 buffer[0] = line[ currentIndex++ ]; // /!\Dirty 319 - Only works with 3 digit commands 320 buffer[1] = line[ currentIndex++ ]; 321 322 buffer[2] = line[ currentIndex++ ]; 323 buffer[3] = '\\0'; 324 switch 325 ( atoi( buffer ) ){ 326 case 300: 327 { 328 char* indexS = 329 strchr( line+currentIndex, 'S' ); 330 float Spos = atof( indexS + 1); 331 332 // Serial.println("ok"); 333 if (Spos == 30) { 334 335 penDown(); 336 } 337 if (Spos == 50) { 338 penUp(); 339 340 } 341 break; 342 } 343 case 114: // 344 M114 - Repport position 345 Serial.print( "Absolute position : X = " ); 346 347 Serial.print( actuatorPos.x ); 348 Serial.print( " - Y = " ); 349 350 Serial.println( actuatorPos.y ); 351 break; 352 default: 353 354 Serial.print( "Command not recognized : M"); 355 Serial.println( 356 buffer ); 357 } 358 } 359 } 360 361 362 363} 364 365 366/********************************* 367 368 * Draw a line from (x0;y0) to (x1;y1). 369 * int (x1;y1) : Starting coordinates 370 371 * int (x2;y2) : Ending coordinates 372 **********************************/ 373void 374 drawLine(float x1, float y1) { 375 376 if (verbose) 377 { 378 Serial.print("fx1, 379 fy1: "); 380 Serial.print(x1); 381 Serial.print(","); 382 Serial.print(y1); 383 384 Serial.println(""); 385 } 386 387 // Bring instructions within limits 388 389 if (x1 >= Xmax) { 390 x1 = Xmax; 391 } 392 if (x1 <= Xmin) { 393 x1 394 = Xmin; 395 } 396 if (y1 >= Ymax) { 397 y1 = Ymax; 398 } 399 if (y1 <= 400 Ymin) { 401 y1 = Ymin; 402 } 403 404 if (verbose) 405 { 406 Serial.print("Xpos, 407 Ypos: "); 408 Serial.print(Xpos); 409 Serial.print(","); 410 Serial.print(Ypos); 411 412 Serial.println(""); 413 } 414 415 if (verbose) 416 { 417 Serial.print("x1, 418 y1: "); 419 Serial.print(x1); 420 Serial.print(","); 421 Serial.print(y1); 422 423 Serial.println(""); 424 } 425 426 // Convert coordinates to steps 427 x1 428 = (int)(x1*StepsPerMillimeterX); 429 y1 = (int)(y1*StepsPerMillimeterY); 430 float 431 x0 = Xpos; 432 float y0 = Ypos; 433 434 // Let's find out the change for the 435 coordinates 436 long dx = abs(x1-x0); 437 long dy = abs(y1-y0); 438 int sx = 439 x0<x1 ? StepInc : -StepInc; 440 int sy = y0<y1 ? StepInc : -StepInc; 441 442 long 443 i; 444 long over = 0; 445 446 if (dx > dy) { 447 for (i=0; i<dx; ++i) { 448 449 myStepperX.onestep(sx,STEP); 450 over+=dy; 451 if (over>=dx) { 452 453 over-=dx; 454 myStepperY.onestep(sy,STEP); 455 } 456 delay(StepDelay); 457 458 } 459 } 460 else { 461 for (i=0; i<dy; ++i) { 462 myStepperY.onestep(sy,STEP); 463 464 over+=dx; 465 if (over>=dy) { 466 over-=dy; 467 myStepperX.onestep(sx,STEP); 468 469 } 470 delay(StepDelay); 471 } 472 } 473 474 if (verbose) 475 476 { 477 Serial.print("dx, dy:"); 478 Serial.print(dx); 479 Serial.print(","); 480 481 Serial.print(dy); 482 Serial.println(""); 483 } 484 485 if (verbose) 486 487 { 488 Serial.print("Going to ("); 489 Serial.print(x0); 490 Serial.print(","); 491 492 Serial.print(y0); 493 Serial.println(")"); 494 } 495 496 // Delay before 497 any next lines are submitted 498 delay(LineDelay); 499 // Update the positions 500 501 Xpos = x1; 502 Ypos = y1; 503} 504 505// Raises pen 506void penUp() { 507 penServo.write(penZUp); 508 509 delay(penDelay); 510 Zpos=Zmax; 511 digitalWrite(15, LOW); 512 digitalWrite(16, 513 HIGH); 514 if (verbose) { 515 Serial.println("Pen up!"); 516 517 } 518 519} 520// Lowers pen 521void penDown() { 522 penServo.write(penZDown); 523 524 delay(penDelay); 525 Zpos=Zmin; 526 digitalWrite(15, HIGH); 527 digitalWrite(16, 528 LOW); 529 if (verbose) { 530 Serial.println("Pen down."); 531 532 533 534 } 535}
Comments
Only logged in users can leave comments