CNC Plotter

This mini CNC plotter made from deconstructed DVD drives can draw anything from words to designs. With a similar design to a 3D printer, it has an x, y, and z axis

Engineer

Annika P.

Area of Interest

Engineering

School

Menlo School

Grade

Incoming Freshman

Materials

Materials

screen-shot-2019-07-18-at-3.41.23-pm
screen-shot-2019-07-18-at-3.41.58-pm
screen-shot-2019-07-12-at-2.36.19-pm
screen-shot-2019-07-18-at-3.45.26-pm
Build Plan

Major Steps to complete the project:

  1. Motors
    1. Make sure all parts have arrived as planned
    2. Get two stepper motors to work
      1. Disassemble DVD Drives
        1. Eject disk tray
        2. Disassemble parts
          1. use screwdriver
        3. Now have two stepper motors
          1. Also- save the DC motor with attachments for later
      2. Use multimeter to find which two wires correspond
      3. Cut the Kapton tape in 4 strands where the wires separate on each motors
      4. Solder 4 wires onto each of the strands on each of the motors
      5. Connect the wires using the wiring schematic 
        1. Use arduino, two A4988 stepper motor drivers, half breadboard, and the 9v battery 
      6. Run sample code to test if both stepper motors can run simultaneously
    3. Milestone
  2. X, Y, and Z Axis
    1. X axis
      1. Place on stepper motor with the rails on the big plexiglass piece
      2. Mark it with a pen in order to open the 4 holes for the screws
        1. Use triangle ruler to make sure that it is aligned
      3. Open the holes and mount the motor with nut screws
      4. On one side of it place the four mounting angles
      5. Mark it with a pen in order to open the 8 holes for the screws
        1. The distance between them should be 6mm
      6. Open the 8 holes on the plexiglass
      7. Screw the mounting angles into place
      8. Attach a base (either wood or cardboard or something) on X axis and place paper on top-(4x4cm)
    2. Y axis
      1. Place the other stepper motor on the two smaller plexiglass pieces
      2. Mark them with a pen in order to open the 4 holes for the screws
      3. Use triangle ruler to make sure that it is aligned
      4. Open the holes and mount the motor with nut screws
      5. Place it between the mounting angles
      6. Mark it with a pen in order to open the 4 holes for the screw
      7. Open the holes and screw the Y axis onto the X axis
    3. Z axis
      1. Use the DC motor with attachments from disassembled DVD drive parts
      2. Wire it to the breadboard and use tester code
      3. Attach it onto y axis with cardboard or any other base sideways so that it will be far enough out
      4. Attach pen onto attachment of DC motor with hose clamp
    4. Perfboard
      1. Solder everything that was on the breadboard onto a perfboard
    5. Milestone
  3. Code
    1. Arduino code
      1. Copy arduino code from https://create.arduino.cc/projecthub/Yogeshmodi/sketch-it-cnc-plotter-95019d
      2. Edit the code since I am using motor drivers instead of a motor shield and I am using a DC motor instead of a servo 
      3. Download the code onto your ardino
    2. Processing
      1. Download Processing at https://processing.org/download/
      2. Get the GCTRL.pde code and example gcode files from http://www.ardumotive.com/new-cnc-plotter.html
      3. Press the arrow key to run it.
      4. Then press the p key and select the port 
      5. Then press the g key and select a gcode file.
    3. Inkscape
      1. Download the 0.48 version of inkscape at https://inkscape.org/release/inkscape-0.48/?latest=1
        1. If on a mac download XQuartz here https://www.xquartz.org
      2. Download zip file to allow inkscape to convert into gcode https://github.com/martymcguire/inkscape-unicorn
      3. Control click inscape>show package contents
      4. Contents>resources>extensions
      5. Place all the contents of the src folder
      6. Printing
        1. Setup
          1. File>Document Properties> 4cm x 4cm
        2. Text
          1. Type anything within the dimensions
          2. Click on it 
          3. Path>Object to Path
        3. Image
          1. Import image with transparent background
          2. Path>Trace Bitmap> Brightness Cutoff> update> ok
          3. Drag out the new path and delete the original image
          4. Drag the new path into the square
          5. Click on it
          6. Path> Object to Path
        4. Save
          1. File> Save As> select .gcode>Save
    4. Milestone

 

Wiring Schematics

First Milestone

renderedimage-3

Second Milestone

renderedimage

Final Milestone

screen-shot-2019-07-18-at-3.49.46-pm
Codes

First Milestone Test Code (with or without comments)

Second Milestone Test Code (with or without comments)

Downloads

Download Arduino IDE here.

Download Inkscape here.

Make sure you download the 0.48 version.

For Macs, you will need to use XQuartz which you can download here.

Download the add-on for Inkscape here in order to convert the files into gcode.

There are instructions on how to install it into Inkscape below the download button.

Download Processing here.

Download the GCTRL.pde for Processing on this website.

http://www.ardumotive.com/new-cnc-plotter.html

You can also download example code files on that website.

 

 

Drawings

Drawings Slideshow

Final Milestone

Information
     In my final milestone, I added a modificatication to make my mini CNC plotter wireless.  
     In order to make it wireless, I used the HC-05 bluetooth module. I used another breadboard to connect all of the wires. There are four pins coming out of the bluetooth module that I connected to my arduino. One of them was ground so I connected it another one of the ground pins on the arduino. Another one of the pins was labeled VCC and it needed to be connected to a power source between 3.6 and 6 v. This is where I faced a problem since the 5v pin of my arduino was already connected to my perfboard. I solved this by connecting that wire to my new breadboard and having another wire come from the arduino to the breadboard. I also had to connect the TX pin of the bluetooth module with the RX pin on the arduino and the RX with the TX. I also had to add in some 1K resistors to limit the amount of voltage going into the bluetooth module which could potentially overheat and get damaged. Then I plugged my usb cord into my computer and then went into system preferences and then into bluetooth were I connected my computer to the bluetooth module with the access code 1234. Then I unplugged the usb from my computer and plugged it into my portable charger. When I was in processing and pressed “p” to select port, I selected the bluetooth module. Then my mini CNC plotter could print image wirelessly. After that I soldered all the parts on my new breadboard onto a perfboard. Then I dremeled down the perfboard.
Wiring Schematic

Wiring Schematic

screen-shot-2019-07-18-at-3.49.46-pm

Third Milestone

Information
     In my third milestone, I used Arduino code to run gcode with Processing and Inkscape.
     My first step was to download an example arduino code from the arduino website. This code was designed for a motor shield and servo motor version of the CNC plotter so I had to adapt it to work with a DC motor and motor drivers. I had to delete all of the sections that mentioned the servo. I added all the define and void setup parts from my previous code. Then where the code had the pen up and pen down for the servo, I inputted the code I had for the pen up and pen down motion of my DC motor. I created a function for a step on my stepper motors by inputting the code I had in my for loop of my previous code. I also had to create an if else function so that if it gets a negative number of steps it will take the absolute value of that number and set the direction pin to high so that it goes one way. If the number of steps is positive, the direction pin will be set to low and it will go in the opposite direction. After I had updated the code, I uploaded it onto my arduino.
     The next thing I had to do was download the Processing software. Once I had Processing downloaded I had to download the GCTRL code that allowed me to upload gcode files. I ran the code and then pressed the “p” key to select the port and then I pressed “g” to select the gcode file. I first used example gcode files I found here to test if it worked.
     Then the next thing I did was download Inkscape which is a graphics editor program that can create gcode files. I had a lot of trouble downloading it because I first downloaded the current version which is not compatible with the add-on that allows it to convert the files into gcode. I had to delete the version I had and then redownload the 0.48 version. Since I use a Mac I also had to download XQuartz in order to run Inkscape. Once I had Inkscape open, I had to add an extension so that it could convert the files into gcode. I downloaded the zip from github (here) and then duplicated the src folder. In finder I went to applications and then control clicked inkscape and selected Show Package Contents.  Then I went Contents>Resources>extensions. In the extensions I placed all the contents of the Src folder. After I had added that extension I set the dimensions by going to file to document properties and then setting the dimensions to 4 x 4 cm. Then I typed text in the upper righthand corner within the 2 and 4 markers on the top and the 3 and 4 markers on the side. Then I clicked Path>Object to Path. For putting in an image I clicked File> import and then selected the image. Then I clicked Path>Trace Bitmap. There I turned the brightness cutoff down just before the image disappears. I clicked update to see whether the image was still there. Then once the brightness cutoff was at the right level, I clicked ok and then pressed Object to Path. Then I went File>Save As and saved it as a gcode file. An error occurred that said that I needed to download the latest version of lxml. I fixed this error my installing the lxml file by updating my python, installing pip, and making sure my pip, steptools, and wheel were up to date. I needed to do this because the lxml file came in the wheel package format. Once I fixed this problem, an error still popped up but did not mention the lxml. After that, my Inkscape could create gcode files that would run sucessfully.
     If I have time, I plan to add the modification to make my CNC plotter wireless.
Downloads

Download Inkscape here.

Make sure you download the 0.48 version.

For Macs, you will need to use XQuartz which you can download here.

Download the add-on for Inkscape here in order to convert the files into gcode.

There are instructions on how to install it into Inkscape below the download button.

Download Processing here.

Download the GCTRL.pde for Processing on this website.

http://www.ardumotive.com/new-cnc-plotter.html

You can also download example code files on that website.

 

 

Arduino Code

#define dirPin 2
#define stepPin 3
#define dirPin2 8
#define stepPin2 9
#define MotorPin1 12
#define MotorPin2 11
#define Standby 10
#define PWM 5
#include <Stepper.h>
#define LINE_BUFFER_LENGTH 512
const int penZUp = 80;
const int penZDown = 40;
const int penServoPin = 6;
const int stepsPerRevolution = 20;
struct point {
float x;
float y;
float z;
};
struct point actuatorPos;
float StepInc = 1;
int StepDelay = 0;
int LineDelay = 50;
int penDelay = 50;
float StepsPerMillimeterX = 6.0;
float StepsPerMillimeterY = 6.0;
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() {
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
pinMode(MotorPin1, OUTPUT);
pinMode(MotorPin2, OUTPUT);
pinMode(Standby, OUTPUT);
pinMode(PWM, OUTPUT);
// Setup
Serial.begin( 9600 );

delay(200);
Serial.println(“Mini CNC Plotter alive and kicking!”);
Serial.print(“X range is from “);
Serial.print(Xmin);
Serial.print(” to “);
Serial.print(Xmax);
Serial.println(” mm.”);
Serial.print(“Y range is from “);
Serial.print(Ymin);
Serial.print(” to “);
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( “Received : “);
Serial.println( line );
}
processIncomingLine( line, lineIndex );
lineIndex = 0;
}
else {
}
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( “ERROR – lineBuffer overflow” );
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 );
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( “Absolute position : X = ” );
Serial.print( actuatorPos.x );
Serial.print( ” – Y = ” );
Serial.println( actuatorPos.y );
break;
default:
Serial.print( “Command not recognized : 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*StepsPerMillimeterX);
y1 = (int)(y1*StepsPerMillimeterY);
float x0 = Xpos;
float y0 = Ypos;
long dx = abs(x1-x0);
long dy = abs(y1-y0);
int sx = x0<x1 ? StepInc : -StepInc;
int sy = y0<y1 ? StepInc : -StepInc;

long i;
long over = 0;

if (dx > dy) {
for (i=0; i<dx; ++i) {
Xstep(sx);
over+=dy;
if (over>=dx) {
over-=dx;
Ystep(sy);
}
delay(StepDelay);
}
}
else {
for (i=0; i<dy; ++i) {
Ystep(sy);
over+=dx;
if (over>=dy) {
over-=dy;
Xstep(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() {
digitalWrite(Standby, HIGH);
digitalWrite(MotorPin1, HIGH);
digitalWrite(MotorPin2, LOW);
analogWrite(PWM, 100);
delay(1000);
Zpos=Zmax;
if (verbose) {
Serial.println(“Pen up!”);
}
}
void penDown() {
digitalWrite(Standby, HIGH);
digitalWrite(MotorPin1, LOW);
digitalWrite(MotorPin2, HIGH);
analogWrite(PWM, 100);
delay(1000);
Zpos=Zmin;
if (verbose) {
Serial.println(“Pen down.”);
}
}

void Xstep (int numstep) {

if (numstep < 0) {
numstep = abs(numstep);
digitalWrite(dirPin, HIGH);
}
else {
digitalWrite(dirPin, LOW);
}

for (int i = 0; i <= numstep; i++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin, LOW);
delayMicroseconds(2000);
}

}
void Ystep (int numstep) {

if (numstep < 0) {
numstep = abs(numstep);
digitalWrite(dirPin2, HIGH);

}
else {
digitalWrite(dirPin2, LOW);
}

for (int i = 0; i <=numstep; i++) {
digitalWrite(stepPin2, HIGH);
delayMicroseconds(2000);
digitalWrite(stepPin2, LOW);
delayMicroseconds(2000);

}
}

Inkscape

Video for Printing Text

Video for Printing Videos

Second Milestone

Information
     For my second milestone, I constructed my x, y, and z axes and converted my wiring on the breadboard onto a perfboard.  
     My first step was to create the x and y axes with plexiglass. I used three pieces of plexiglass and four plastic corner braces. I marked the plexiglass where the holes were on the stepper motors and used a drill to open the holes. Then I used nuts and bolts to fasten all the motors and pieces of plexiglass down.
     The next thing I had to do was create my z-axis. I used a DC motor part with attachments from the DVD drives to function as my z-axis. A DC motor is different from a stepper motor because a DC motor runs continuously whereas a stepper runs step by step and a new pulse must be sent out for each step. I attached my DC motor and a pen onto my y-axis with cardboard and hot glue. Then I added my DC motor  and a DC motor driver onto my breadboard. From the motor driver to the arduino there were four wires: two were for the motor, one was for standby, and the fourth was for PWM or pulse width modulation. Then I updated my code so that it could perform the pen up and pen down motion. In the beginning of the void loop, I set the standby to high. Then I set one of the DC motor pins to high and the other to low. Doing this allowed the motor to spin in one direction. Then I set the PWM using analogwrite to 100. For everything else in digitalwrite I have been using high or low, but PWM sets the speed at any number between 0 and 255 which is the max for an 8-bit PWM signal. Then I created the pen down motion by reversing the high and low for the two motor pins. This allowed the DC motor to spin in the opposite direction.
     The next thing I did was solder everything from the breadboard onto a perfboard. This was a pretty difficult part of the project since, unlike a breadboard, on a perfboard you have to make all of the connections yourself by soldering
     For my next milestone, I plan to upload gcode using Inkscape.
Wiring Schematic

Wiring Schematic

renderedimage
Test Code

DC Motor and Stepper Motor Test (with or without comments)

First Milestone

Information
     For my main project, I chose to create a CNC plotter.  In my first milestone, I disassembled the DVD drives and got both of my stepper motors to run. For the disassembly of the DVD drives I found that it was important to eject the disk tray before taking it apart. In the end, I  was left with a two stepper motors with the rails attached. After that I used a multimeter to find out which two wires correspond with one another. Then I had to solder on four wires onto each motor. I found that it was easier to cut the kapton tape with the wires in it so that it would be easier to solder on each wire without accidentally connecting them. Then I used heat shrink tubing around the bunch of wires to keep them secure. 
     The next challenge was to get the motors to run. In order to accomplish that I used a breadboard, two A4988 stepper motor drivers, and an arduino. Each A4988 stepper motor driver has two wires that connect to the arduino. One is for the direction and the other is for the steps. One of my stepper motor drivers goes into pins 8 and 9 and the other goes into pins 2 and 3. In addition, there are also two other wires that connect the ground and power of the arduino with the breadboard. There is a electrolytic capacitor that removes voltage ripples. This is extremely important for stepper motors since they have to be very precise in order to perform their function. These particular stepper motors have around 250 steps, making them very precise and exact. The power supply for the stepper motor drivers is the 9v battery here and the power for the arduino is this portable charger.  
     After I had the wiring configuration set, my next step was to code the arduino in order to run both stepper motors simultaneously.  At the beginning of the void loop, I set the direction pins to high. Then in the for loop I set the step pins to high and then delayed it for a certain time. If you increase the delay time the speed decreases, and if you decrease the delay time the speed will increase. Then I set the step pins to low and delayed it. After that I put an almost identical loop of code but this time I put my direction pins to low to make the stepper motors run in the opposite direction. 
     For my next milestone, I plan to construct my x, y, and z axes.
Wiring Schematic

Wiring Schematic

renderedimage-3
Test Code

Stepper Test Code (with or without comments)

Starter Project: Simon Says Game

For my starter project, I chose the Simon Says Game because it was a good introduction to soldering and the basic parts of a circuit. There are two different switches: one that controls the audio and another that controls the lighting. On the bottom of the board, there is a black microcontroller that acts as a brain for the whole operation and has the program for the game. There is also a circular black buzzer on the bottom of the board which produces the noise for the game. There is a negative and positive side to it, which when a voltage is applied, allow the buzzer to vibrate. The speed of vibrations change based on the change in the frequency of the buzzer. There are also two small yellow pieces called decoupling capacitors, and they have the ability to store energy. They can remove voltage ripples that could potentially harm the microcontroller. There is also a 10k resistor that causes the current to decrease. It is important in ensuring that the correct amount of current is entering the LEDs. The LEDs or light emitting diodes are underneath the white buttons, and they produce the light for the game. On the top side there are two alkaline batteries that together have a voltage of 3 volts.. Both are needed in order to have enough voltage for the LEDs.

STEM Summer Camps Coding & Robotics Classes For Kids San Francisco Coding & Robotics Classes For Kids New York Coding & Robotics Classes For Kids Denver Coding & Robotics Classes For Kids Palo Alto STEM Summer Camps For Kids in New York STEM Summer Camps For Kids in Palo Alto STEM Summer Camps For Kids San Francisco STEM Classes For Kids in New York STEM Classes For Kids in Palo Alto STEM Classes For Kids in San Francisco Code Classes For Kids Code Classes For Kids in New York Code Classes For Kids in Palo Alto Code Classes For Kids in San Francisco STEM Summer Camps For Kids

Leave a Comment

Start typing and press Enter to search