Introduction: Arduino Mini CNC

About: Mechanical engineer, Entrepreneur, Maker, robotic systems expert and founder of Robimek and RobiBot

Hi friends, in this project we will talk about making corrupted DVD and cd-rom drives recycled and producing cnc at low cost. Let's start building the mini cnc project that draws

Step 1: Materials

  1. Arduino (can be nano, uno or mega)
  2. Damaged DVD or CD-ROM (the stepper motor inside will be running)
  3. 2 pieces of damaged dvd or cd-rom (the stepper motor inside will be running)
  4. Servo motor (Mg90 is enough)
  5. 5v 2 amp battery or adapter
  6. Plexi plate with 20 x 16 cm and 5 mm thickness to hold the X axis.
  7. Plexi plate 15 x 16 cm and thickness 5 mm to secure the Y axis
  8. You can use a plexi plate of 75 × 75 mm and a thickness of 5 mm for the drawing surface.
  9. 1 piece M5 bolt nut (to fix the plate)
  10. 14 pieces M4 bolt nut

Step 2: Front and Rear Overview of the Mini Cnc and Explanations of Its Parts

  1. X plane Plexi Plate (200x150x3 mm)
  2. Y plane Plexi Plate (200x150x3 mm)
  3. X-axis movement mechanism (dvd drive yard mechanism)
  4. Y-axis movement mechanism (dvd drive yard mechanism)
  5. Z plane section
  6. Servo-motor
  7. Pen Holder
  8. Pen fixing nut - screw arrangement (1 piece M5 bolt nut)
  9. Pen
  10. Drawing table (75x75x5 mm plexi plate)
  11. Axis supports and screw nuts
  12. Stepping motor for X-axis motion
  13. Stepping motor for Y-axis movement
  14. Paper clips to secure the paper
  15. 14 pieces M4 bolt nut
  16. Pen holder support
  17. Z-axis
  18. Cables
  19. 4 Angles
  20. The control unit (Arduino uno, 2 l239d, pertinaks, energy input jack)
  21. Usb cable for computer connection

Step 3: Mechanical Part

We will use the part with the mechanical part DVD or the rail system inside the Cd-R0m drive.In this section the stepper motor is connected to the worm screw shaft and moves the part of the laser reader which is connected to the shaft by turning the shaft. We are removing this part without harm. In the same way, the other driver is also dismantled and a total of two stepper motor systems are installed. If you use DVD-Rom, you can also make laser cutter with its laser diodes. These are the mechanical parts that move the axes. We will extract other mechanical parts from the 3d printer.

You can download parts stl files here >> http://www.thingiverse.com/thing:1372864

Step 4: Electronic Section

In our electronic system we will connect the two stepper motors which will move the x and y axis and one servo motor which will lift and lower the die.

Step 5: Arduino Code Part

#include <Servo.h>

#include <Stepper.h>

#define LINE_BUFFER_LENGTH 512

const int kalem_kaldir = 130;

const int kalem_indir = 40;

const int kalem_servo_pin = 12;

const int adim_sayisi = 20;

const int hareket_hizi = 250;

Servo kalem_servo;

Stepper y_ekseni(adim_sayisi, 3,4,5,6);

Stepper x_ekseni(adim_sayisi, 9,10,11,12);

float x_adim_mm = 6.0;

float y_adim_mm = 6.0;

struct point { float x; float y; float z; };

struct point actuatorPos;

float StepInc = 1;

int StepDelay = 0;

int LineDelay = 50;

int penDelay = 50;

float Xmin = 0;

float Xmax = 40;

float Ymin = 0;

float Ymax = 40;

float Zmin = 0;

float Zmax = 1;

float Xpos = Xmin;

float Ypos = Ymin;

float Zpos = Zmax;

boolean verbose = false;

void setup() { // Setup

Serial.begin( 9600 );

kalem_servo.attach(kalem_servo_pin);

kalem_servo.write(kalem_kaldir);

delay(200);

x_ekseni.setSpeed(hareket_hizi);

y_ekseni.setSpeed(hareket_hizi);

Serial.println("Çizim Yapan Mini CNC!");

Serial.print("X min ");

Serial.print(Xmin);

Serial.print(" den ");

Serial.print(Xmax);

Serial.println(" mm.");

Serial.print("Y min ");

Serial.print(Ymin);

Serial.print(" den ");

Serial.print(Ymax);

Serial.println(" mm.");

}

void loop() {

delay(200);

char line[ LINE_BUFFER_LENGTH ];

char c; int lineIndex;

bool lineIsComment, lineSemiColon;

lineIndex = 0;

lineSemiColon = false;

lineIsComment = false;

while (1) {

while ( Serial.available()>0 ) {

c = Serial.read();

if (( c == '\n') || (c == '\r') ) {

if ( lineIndex > 0 ) {

line[ lineIndex ] = '\0';

if (verbose) {

Serial.print( "Alıcı : ");

Serial.println( line );

}

processIncomingLine( line, lineIndex );

lineIndex = 0; }

else {

// Empty or comment line. Skip block.

}

lineIsComment = false;

lineSemiColon = false;

Serial.println("ok");

}

else {

if ( (lineIsComment) || (lineSemiColon) ) {

if ( c == ')' ) lineIsComment = false;

} else {

if ( c <= ' ' ) {

}

else if ( c == '/' ) {

}

else if ( c == '(' ) {

lineIsComment = true;

}

else if ( c == ';' ) {

lineSemiColon = true;

}

else if ( lineIndex >= LINE_BUFFER_LENGTH-1 ) {

Serial.println( "Yazma Hatası" );

lineIsComment = false;

lineSemiColon = false;

} else if ( c >= 'a' && c <= 'z' ) {

line[ lineIndex++ ] = c-'a'+'A';

} else {

line[ lineIndex++ ] = c; } } } } } }

void processIncomingLine( char* line, int charNB ) {

int currentIndex = 0; char buffer[ 64 ];

struct point newPos;

newPos.x = 0.0;

newPos.y = 0.0;

while( currentIndex < charNB ) {

switch ( line[ currentIndex++ ] ) {

case 'U':

penUp();

break;

case 'D':

penDown();

break;

case 'G':

buffer[0] = line[ currentIndex++ ];

buffer[1] = '\0';

switch ( atoi( buffer ) ){

case 0:

case 1:

char* indexX = strchr( line+currentIndex, 'X' );

char* indexY = strchr( line+currentIndex, 'Y' );

if ( indexY <= 0 ) {

newPos.x = atof( indexX + 1);

newPos.y = actuatorPos.y;

} else if ( indexX <= 0 ) {

newPos.y = atof( indexY + 1);

newPos.x = actuatorPos.x; }

else { newPos.y = atof( indexY + 1);

indexY = '\0'; newPos.x = atof( indexX + 1); }

drawLine(newPos.x, newPos.y );

// Serial.println("ok");

actuatorPos.x = newPos.x;

actuatorPos.y = newPos.y;

break; }

break; case 'M':

buffer[0] = line[ currentIndex++ ];

buffer[1] = line[ currentIndex++ ];

buffer[2] = line[ currentIndex++ ];

buffer[3] = '\0'; switch ( atoi( buffer ) ){

case 300: { char* indexS = strchr( line+currentIndex, 'S' );

float Spos = atof( indexS + 1);

if (Spos == 30) { penDown();

} if (Spos == 50) {

penUp(); } break;

} case 114:

Serial.print( "Tam Pozisyon : X = " );

Serial.print( actuatorPos.x );

Serial.print( " - Y = " );

Serial.println( actuatorPos.y );

break; default:

Serial.print( "Komut Tanınmadı : M");

Serial.println( buffer ); } } }

}

void drawLine(float x1, float y1) {

if (verbose) { Serial.print("fx1, fy1: ");

Serial.print(x1); Serial.print(",");

Serial.print(y1); Serial.println(""); }

if (x1 >= Xmax) { x1 = Xmax; }

if (x1 <= Xmin) { x1 = Xmin; }

if (y1 >= Ymax) { y1 = Ymax; }

if (y1 <= Ymin) { y1 = Ymin; }

if (verbose) { Serial.print("Xpos, Ypos: ");

Serial.print(Xpos); Serial.print(",");

Serial.print(Ypos); Serial.println(""); }

if (verbose) { Serial.print("x1, y1: ");

Serial.print(x1); Serial.print(",");

Serial.print(y1); Serial.println(""); }

x1 = (int)(x1*x_adim_mm); y1 = (int)(y1*y_adim_mm);

float x0 = Xpos; float y0 = Ypos; long dx = abs(x1-x0); long dy = abs(y1-y0); int sx = x0

long i; long over = 0;

if (dx > dy) { for (i=0; i=dx) { over-=dx; y_ekseni.step(sy); }

delay(StepDelay); } } else { for (i=0; i=dy) { over-=dy; x_ekseni.step(sx); } delay(StepDelay); } }

if (verbose) { Serial.print("dx, dy:"); Serial.print(dx); Serial.print(",");

Serial.print(dy); Serial.println(""); }

if (verbose) { Serial.print("Going to ("); Serial.print(x0); Serial.print(","); Serial.print(y0); Serial.println(")"); }

delay(LineDelay);

Xpos = x1; Ypos = y1; }

void penUp() { kalem_servo.write(kalem_kaldir); delay(LineDelay);

Zpos=Zmax; if (verbose) { Serial.println("Pen up!"); } }

void penDown() { kalem_servo.write(kalem_indir);

delay(LineDelay); Zpos=Zmin; if (verbose) {

Serial.println("Pen down."); } }

Step 6: Processing Code

import java.awt.event.KeyEvent;
import javax.swing.JOptionPane;

import processing.serial.*;

Serial port = null;

String portname = null;

boolean streaming = false;

float speed = 0.001;

String[] gcode; int i = 0;

void openSerialPort() {

if (portname == null) return;

if (port != null) port.stop(); port = new Serial(this, portname, 9600); port.bufferUntil('\n'); }

void selectSerialPort() {

String result = (String) JOptionPane.showInputDialog(frame, "Select the serial port that corresponds to your Arduino board.", "serial port seç", JOptionPane.QUESTION_MESSAGE, null, Serial.list(), 0);

if (result != null) { portname = result; openSerialPort(); } }

void setup() { size(500, 250); openSerialPort(); }

void draw() { background(0);

fill(255); int y = 24, dy = 12; text("Menuler", 12, y);

y += dy; text("p: serial port seç", 12, y); y += dy;

text("1: hız 0.001 inch", 12, y); y += dy; text("2: hız 0.010 inch", 12, y); y += dy;

text("3: hız 0.100 inch", 12, y); y += dy; text("Yön Tuşları: x-y Düzlemi", 12, y);

y += dy; text("Sayfa aşağı-yukarı: z eksen ", 12, y); y += dy;

text("$: grbl ayarlar", 12, y); y+= dy; text("h: Başlangıç Konumu", 12, y); y += dy;

text("0: Güncel Konum", 12, y); y += dy; text("g: g-code dosya seç ", 12, y);

y += dy; text("x: Çizimi Durdur", 12, y); y += dy; y = height - dy;

text("güncel hız: " + speed + " adım", 12, y); y -= dy;

text("güncel serial port: " + portname, 12, y); y -= dy; }

void keyPressed() { if (key == '1') speed = 0.001; if (key == '2') speed = 0.01;

if (key == '3') speed = 0.1; if (!streaming) {

if (keyCode == LEFT) port.write("G91\nG20\nG00 X-" + speed + " Y0.000 Z0.000\n");

if (keyCode == RIGHT) port.write("G91\nG20\nG00 X" + speed + " Y0.000 Z0.000\n");

if (keyCode == UP) port.write("G91\nG20\nG00 X0.000 Y" + speed + " Z0.000\n");

if (keyCode == DOWN) port.write("G91\nG20\nG00 X0.000 Y-" + speed + " Z0.000\n");

if (keyCode == KeyEvent.VK_PAGE_UP) port.write("G91\nG20\nG00 X0.000 Y0.000 Z" + speed + "\n");

if (keyCode == KeyEvent.VK_PAGE_DOWN) port.write("G91\nG20\nG00 X0.000 Y0.000 Z-" + speed + "\n");

if (key == 'h') port.write("G90\nG20\nG00 X0.000 Y0.000 Z0.000\n"); if (key == 'v') port.write("$0=75\n$1=74\n$2=75\n"); //if (key == 'v') port.write("$0=100\n$1=74\n$2=75\n");

if (key == 's') port.write("$3=10\n"); if (key == 'e') port.write("$16=1\n"); if (key == 'd') port.write("$16=0\n");

if (key == '0') openSerialPort(); if (key == 'p') selectSerialPort(); if (key == '$') port.write("$$\n"); }

if (!streaming && key == 'g') { gcode = null; i = 0; File file = null; println("Loading file..."); selectInput("Select a file to process:", "fileSelected", file); } if (key == 'x') streaming = false; }

void fileSelected(File selection) { if (selection == null) { println("Window was closed or the user hit cancel."); }

else { println("User selected " + selection.getAbsolutePath());

gcode = loadStrings(selection.getAbsolutePath()); if (gcode == null) return;

streaming = true; stream(); } }

void stream() { if (!streaming) return; while (true) { if (i == gcode.length) {

streaming = false; return; } if (gcode[i].trim().length() == 0) i++; else break; }

println(gcode[i]); port.write(gcode[i] + '\n'); i++; }

void serialEvent(Serial p) { String s = p.readStringUntil('\n'); println(s.trim());

if (s.trim().startsWith("ok")) stream();

if (s.trim().startsWith("error")) stream(); // XXX: really? }

Step 7: INKSCAPE SETTINGS

To get gccode output with INKSCAPE, first download the makerbot unicorn G-code plugin here >> Inkscape gcode plugin

İnkscape full setting and details of the project >> Arduino cnc project

Step 8: Please, Vote on the Project :)

I joined the competition in the CNC and 3D Design CONTEST 2016 . I'm waiting for your vote. You can vote by clicking the "vote" button on the top right.Thank you in advance :)