Introduction: Arduino Mini CNC
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
- Arduino (can be nano, uno or mega)
- Damaged DVD or CD-ROM (the stepper motor inside will be running)
- 2 pieces of damaged dvd or cd-rom (the stepper motor inside will be running)
- Servo motor (Mg90 is enough)
- 5v 2 amp battery or adapter
- Plexi plate with 20 x 16 cm and 5 mm thickness to hold the X axis.
- Plexi plate 15 x 16 cm and thickness 5 mm to secure the Y axis
- You can use a plexi plate of 75 × 75 mm and a thickness of 5 mm for the drawing surface.
- 1 piece M5 bolt nut (to fix the plate)
- 14 pieces M4 bolt nut
Step 2: Front and Rear Overview of the Mini Cnc and Explanations of Its Parts
- X plane Plexi Plate (200x150x3 mm)
- Y plane Plexi Plate (200x150x3 mm)
- X-axis movement mechanism (dvd drive yard mechanism)
- Y-axis movement mechanism (dvd drive yard mechanism)
- Z plane section
- Servo-motor
- Pen Holder
- Pen fixing nut - screw arrangement (1 piece M5 bolt nut)
- Pen
- Drawing table (75x75x5 mm plexi plate)
- Axis supports and screw nuts
- Stepping motor for X-axis motion
- Stepping motor for Y-axis movement
- Paper clips to secure the paper
- 14 pieces M4 bolt nut
- Pen holder support
- Z-axis
- Cables
- 4 Angles
- The control unit (Arduino uno, 2 l239d, pertinaks, energy input jack)
- 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 :)

Participated in the
Design Now: 3D Design Contest 2016

Participated in the
CNC Contest 2016
11 Comments
6 years ago
Burada İngilizce kaynak o kadar çok ki.Bir Türkün yaptığı ve burada paylaştığı projeyi görünce önce sevindim ama bana hiç yardımcı olmadı diğer kaynaklar gibi.
Sanki kopyala yapıştır yapmış her açıklama İngilizce.
6 years ago
Can I do this in proteus software? I mean that without real boards
6 years ago
Hi sezgingul. Nice project.
I would just like to point out 1 little thing which is incorrect.You say that if you use a DVD Rom you can use the laser.
But a DVD Rom is only a DVD reader. The laser is not strong enough to burn because it only has to read the DVD's not change them.
You need the laser from a DVD Writer / Burner which is more powerful.
Reply 6 years ago
The DVD Rom laser does not have the burning power . You need to make a laser diode boost circuit for burning.
This project using dvd laser diode >> https://www.instructables.com/id/Pocket-laser-engraver/
Reply 6 years ago
You still need the laser diode from a DVD BURNER/WRITER). Boosting the current in to a laser diode from a DVD player (DVD ROM) will probably only burn it out and turn it in to an led.
Reply 6 years ago
that's not boost circuit. that is laser driver to limit circuit. laser diod need a driver to not burn.
Reply 6 years ago
Sorry I missed it. Yes it has to be a limiting circuit. The LM317t voltage regulator can be used for this.
6 years ago
tabiki bir türke ve onun cnc makinasına oy atacağız
Reply 6 years ago
DenizG1 Teşekkürler :)
6 years ago
ahmet_024102 rica ederim
6 years ago
teşekkürler sezgin güzel proje.