CNC Plotter |
You need some components to make this
Apparatus
1.ARDUINO UNO BOARD
ARDUINO UNO BORD |
2.MOTOR DRIVE (L293D)
MOTOR DRIVE |
3.SERVO MOTOR
SERVO MOTOR |
4.JUMPING CABLE
JUMPING CABLE |
5.DVD ROM(2 DVD ROM STEPPER MOTOR )
- You can find a DVD from an old computer
Connection diagram
Connection diagram |
You can test the motor using this code before you work with the motor. You can check
1. Make sure the motor is properly connected
2. Whether or not the motor axis rotates well
Motor test
#include<Servo.h>
Servo name;
#include <AFMotor.h>
void setup() {
AF_Stepper motor(200, 2);
Serial.begin(9600); // set up Serial library at 9600 bps
name.attach(10);
Serial.println("Stepper test!");
motor.setSpeed(100); // 10 rpm
motor.step(500, FORWARD, SINGLE);
motor.release();
name.write(150);
delay(1000);
}
void loop() {
const int stepsPerRevolution = 300;
AF_Stepper myStepperY(stepsPerRevolution,1);
AF_Stepper myStepperX(stepsPerRevolution, 1);
Main code
#include <AFMotor.h>
#include <Servo.h>
#define LINE_BUFFER_LENGTH 512
char STEP = MICROSTEP;
//Servo position dor up down
const int penZup = 90;
const int penZdown = 50;
//servo on PWM pin 10
const int penServoPin = 10;
//should be right for dvd steppers , but is not too important here
const int stepsPerRevolution = 100;
//creat servo object to control a servo
Servo penServo;
//initiate steppers for x-and y-axis using this ardiuno pins for the l293d H-bridge
AF_Stepper myStepperY(stepsPerRevolution, 2);
AF_Stepper myStepperX(stepsPerRevolution, 1);
/* Structure , globle variables */
struct point {
float x;
float y;
float z;
};
//current position of plothead structy
struct point actuatorPos;
//Drawing settings, should be OK
float Steplnc = 1;
int stepDelay = 1;
int LineDelay = 2;
int penDelay = 50;
//Motor steps to go 1 milimeter
//use test sketch to go 100 steps. measure the length of line
//calculate steps per mm. Enter hear
float StepsPerMillimeterX = 100.0;
float StepsPerMillimeterY = 100.0;
//Drawing robot limits , in mm
//Ok to start with. could go up to 50 mm if calibrated well
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;
//set to true to get debug output
boolean verbose = false;
//need to intrupt
//g1 for moving
//g4 p300(wait 150ms)
//M300 S30(per down)
//M300 S50(per up)
//discard anything with a(
//discard any other cammand!
void setup() {
Serial.begin(9600);
penServo.attach(penServoPin);
penServo.write(penZup);
delay(100);
//Decrease if necessary
myStepperX.setSpeed(600);
myStepperY.setSpeed(600);
//set & move to initial default position
//TBD
//Notification
Serial.println("Mini CNC Plotter alive and kicking");
Serial.print("X range is from");
Serial.print("Xmin");
Serial.print("to");
Serial.print("X max");
Serial.println("mm");
Serial.print("Y range is from");
Serial.print("Ymin");
Serial.print("to");
Serial.print("Y max");
Serial.println("mm");
}
void loop() {
delay(100);
char line[LINE_BUFFER_LENGTH];
char c;
int lineindex;
bool linelsComment, lineSemiColon;
lineindex = 0;
lineSemiColon = false;
linelsComment = false;
while (1) {
//Serial reception-Mostly from grbl, add semicolon support
while (Serial.available() > 0) {
c = Serial.read();
if ((c == '\n') || (c == '\r')) {
//end of the line reach
if (lineindex > 0) {
//line is complet then execute
line[lineindex] = '\0';
//terminate string
if (verbose) {
Serial.print("Received");
Serial.println(line);
}
processIncomingLine(line, lineindex);
lineindex = 0;
}
else {
//empty or comment line. skip block
}
lineSemiColon = false;
linelsComment = false;
Serial.println("ok");
}
else {
if ((linelsComment) || (lineSemiColon)) {
// throw away all comment characters
if (c == ')') linelsComment = false;
//end comment . resume line.
}
else {
if (c <= ' ') {
//throw away whitepace and control characters
}
else if (c == '/') {
//block delete not supported. ignore cheracter.
}
else if (c == '(') {
//enable comments flag and ignor all charcters until ' 0' or EOL.
linelsComment = true;
}
else if (c == ';') {
lineSemiColon = true;
}
else if (lineindex >= LINE_BUFFER_LENGTH - 1) {
Serial.println("ERROR-line Buffer overflow");
lineSemiColon = false;
linelsComment = false;
}
else if (c >= 'a' && c <= 'z') {
//upcase lowercase
line[ lineindex++] = c - 'a' + 'A';
}
else {
line[ lineindex++] = c;
}
}
}
}
}
}
void processIncomingLine(char*line, int charNB) {
int currentIndex = 0;
char buffer[64];
//hope that 64 is enough ffor 1 parameter
struct point newPos;
newPos.x = 0.0;
newPos.y = 0.0;
//Need to interpret
//G1 for moving
//G4P300(wait 150ms)
//G1 x1 x60 y30
//G1 x30 50
//M300 S30(pen down)
//M300 S50(pen up)
//Discard anyting with a (
//Discard any other command
while (currentIndex < charNB) {
switch (line[currentIndex++]) {
//Select command, if any
case 'U':
penUp();
break;
case 'D':
penDown();
break;
case 'G':
buffer[0] = line[currentIndex++];
// \!/ Dirty-Only work with 2 digit commands
//buffer[1]=line[currentIndex++];
//buffer[2]='\0';
buffer[1] = '\0';
switch (atoi(buffer)) {
//Select G command
case 0:
//G00 &G01 - Movement or fast movement. same here
case 1:
// /!\ Dirty - Suppose that X is befor Y
char*indexX = strchr(line + currentIndex, 'X');
//Get position in the string(if any)
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.print("ok");
actuatorPos.x = newPos.x;
actuatorPos.y = newPos.y;
break;
}
break;
case 'M':
buffer[0] = line[currentIndex++];
// /!\ Dirt - only works with 3 digit commands
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);
// Serial.println("ok")
if (Spos == 30) {
penDown();
}
if (Spos == 50) {
penUp();
}
break;
}
case 114:
//M114 Repport possition
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.print("");
}
//Bring instction within limits
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("");
}
//convert cordinates to steps
x1 = (int)(x1 * StepsPerMillimeterX);
y1 = (int)(y1 * StepsPerMillimeterY);
float x0 = Xpos;
float y0 = Ypos;
//Let's find out the change for the coordinate
long dx = abs(x1 - 10);
long dy = abs(y1 - y0);
int sx = x0 < x1 ? Steplnc : - Steplnc;
int sy = y0 < y1 ? Steplnc : - Steplnc;
long i;
long over = 0;
if (dx > dy) {
for (i = 0; i < dx; ++i) {
myStepperX.onestep(sx, STEP);
over += dy;
if (over >= dx) {
over -= dx;
myStepperY.onestep(sy, STEP);
}
delay(stepDelay);
}
}
else {
for (i = 0; i < dy; ++i) {
myStepperX.onestep(sx, STEP);
over += dx;
if (over >= dy) {
over -= dy;
myStepperX.onestep(sx, STEP);
}
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 befor any next lines are submitted
delay(LineDelay);
// update the positions
Xpos = x1;
Ypos = y1;
}
// Raises pen
void penUp() {
penServo.write(penZup);
delay(penDelay);
Zpos = Zmax;
digitalWrite(15, LOW);
digitalWrite(16, HIGH);
if (verbose) {
Serial.println("Pen Up!");
}
}
//Lower pen
void penDown() {
penServo.write(penZdown);
delay(penDelay);
Zpos = Zmin;
digitalWrite(15, HIGH);
digitalWrite(16, LOW);
if (verbose) {
Serial.println("Pen down!");
}
}
0 Comments