第1步:簡介
會嘗試解釋如何使用Arduino Nano和DVD驅動器步進電機制造自己的 CNC機器。如今,對于創建者而言,CNC機床已經成為一個非常有趣的話題。
在開始構建過程之前,這個可指導的項目由JLCPCB贊助。我已經訂購了JLCPCB的現成PCB,價格僅為2美元。
步驟2:必需的零件
要制造此數控機床,我使用了以下零件:
1)1 x Arduino Nano
3)1 x LM7805穩壓器 =它為電路板提供5伏電源。
4)2 x 16引腳IC基座
5)1個 1K電阻
6)1個 LED
7)2 x DVD驅動器步進電機 =您可以從舊的DVD驅動器中獲得步進電機。
8)1 x Tower Pro SG90微型伺服電機
9)2 x 15個2.54mm母頭連接器
10)1 x 3針2.54mm母頭連接器
11)2 x 4針Relimate插頭連接器
12)2 x 4針Relimate插頭連接器
13)2 x 2針Relimate公頭連接器
注意:圖庫中列出了所有必需的部件,因此請務必將其檢出!
步驟3:電路圖和PCB制作
電路圖如圖所示。為該電路制作PCB時,我使用JLCPCB網站從其網站上訂購在線PCB,
首先轉到JLCPCB,然后單擊立即購買,然后上傳您的Gerber文件,我已提供了Gerber文件供打印。上傳完成后,您可以檢查PCB的外觀。然后進一步處理以訂購 PCB(僅售2美元)。而已。
步驟4:構建過程
在印刷電路板上,首先將所有零件安裝在其位置,然后將它們焊接在正確的位置,如圖所示。如圖所示,將四線焊接到連接器的步進電機上。焊接完成后,現在您可以安裝其他組件,例如Arduino Nano,驅動器IC和連接器,如圖所示。
將DVD步進電機,伺服電機和電源線的公連接器連接到PCB上正確的母連接器中。
現在是時候將代碼上傳到 Arduino Nano 。
第5步:將代碼上傳到Arduino Nano
首先從Arduino網站下載Arduino IDE軟件。然后打開Arduino IDE軟件。并復制粘貼代碼。
然后轉到工具》選擇 Arduino開發板,在本例中為Arduino Nano。
,然后從工具菜單中選擇正確的端口。
完成將您的代碼上傳到Arduino Nano。
#include
#include
#define LINE_BUFFER_LENGTH 512
const int penZUp = 80;
const int penZDown = 40;
const int penServoPin = 6;
const int stepsPerRevolution = 20;
Servo penServo;
Stepper myStepperY(stepsPerRevolution, 2,3,4,5);
Stepper myStepperX(stepsPerRevolution, 8,9,10,11);
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() {
Serial.begin( 9600 );
penServo.attach(penServoPin);
penServo.write(penZUp);
delay(200);
myStepperX.setSpeed(250);
myStepperY.setSpeed(250);
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 == ‘ ’) || (c == ‘ ’) ) {
if ( lineIndex 》 0 ) {
line[ lineIndex ] = ‘’;
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) ) { // Throw away all comment characters
if ( c == ‘)’ ) lineIsComment = false; // End of comment. Resume line.
}
else {
if ( c 《= ‘ ’ ) { // Throw away whitepace and control characters
}
else if ( c == ‘/’ ) { // Block delete not supported. Ignore character.
}
else if ( c == ‘(’ ) { // Enable comments flag and ignore all characters until ‘)’ or EOL.
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’ ) { // 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 for 1 parameter
struct point newPos;
newPos.x = 0.0;
newPos.y = 0.0;
// Needs to interpret
// G1 for moving
// G4 P300 (wait 150ms)
// G1 X60 Y30
// G1 X30 Y50
// M300 S30 (pen down)
// M300 S50 (pen up)
// Discard anything 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 works with 2 digit commands
// buffer[1] = line[ currentIndex++ ];
// buffer[2] = ‘’;
buffer[1] = ‘’;
switch ( atoi( buffer ) ){ // Select G command
case 0: // G00 & G01 - Movement or fast movement. Same here
case 1:
// /! Dirty - Suppose that X is before Y
char* indexX = strchr( line+currentIndex, ‘X’ ); // Get X/Y 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 = ‘’;
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++ ]; // /! Dirty - Only works with 3 digit commands
buffer[1] = line[ currentIndex++ ];
buffer[2] = line[ currentIndex++ ];
buffer[3] = ‘’;
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 position
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(“”);
}
// Convert coordinates to steps
x1 = (int)(x1*StepsPerMillimeterX);
y1 = (int)(y1*StepsPerMillimeterY);
float x0 = Xpos;
float y0 = Ypos;
// Let‘s find out the change for the coordinates
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;
myStepperY.step(sy);
}
delay(StepDelay);
}
}
else {
for (i=0; i=dy) {
over-=dy;
myStepperX.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() {
penServo.write(penZUp);
delay(LineDelay);
Zpos=Zmax;
if (verbose) {
Serial.println(“Pen up!”);
}
}
void penDown() {
penServo.write(penZDown);
delay(LineDelay);
Zpos=Zmin;
if (verbose) {
Serial.println(“Pen down.”);
}
}
第6步:下載處理軟件
首先從It’s網站下載處理軟件。
復制將以下代碼粘貼到處理軟件中。
然后運行程序。您會看到新對話框打開。現在將arduino nano連接到臺式機。
按P按鈕選擇您的arduino nano板可用的端口。
然后按G按鈕上傳測試Gerber文件。
import java.awt.event.KeyEvent;
import javax.swing.JOptionPane;
import processing.serial.*;
Serial port = null;
// select and modify the appropriate line for your operating system
// leave as null to use interactive port (press ‘p’ in the program)
String portname = null;
//String portname = Serial.list()[0]; // Mac OS X
//String portname = “/dev/ttyUSB0”; // Linux
//String portname = “COM6”; // Windows
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(‘ ’);
}
void selectSerialPort()
{
String result = (String) JOptionPane.showInputDialog(frame,
“Select the serial port that corresponds to your Arduino board.”,
“Select serial port”,
JOptionPane.QUESTION_MESSAGE,
null,
Serial.list(),
0);
if (result != null) {
portname = result;
openSerialPort();
}
}
void setup()
{
size(600, 400);
openSerialPort();
}
void draw()
{
background(155);
fill(0);
int y = 24, dy = 12;
text(“INSTRUCTIONS”, 12, y); y += dy;
text(“p: select serial port”, 12, y); y += dy;
text(“1: set speed to 0.001 inches (1 mil) per jog”, 12, y); y += dy;
text(“2: set speed to 0.010 inches (10 mil) per jog”, 12, y); y += dy;
text(“3: set speed to 0.100 inches (100 mil) per jog”, 12, y); y += dy;
text(“arrow keys: jog in x-y plane”, 12, y); y += dy;
text(“page up & page down: jog in z axis”, 12, y); y += dy;
text(“$: display grbl settings”, 12, y); y+= dy;
text(“h: go home”, 12, y); y += dy;
text(“0: zero machine (set home to the current location)”, 12, y); y += dy;
text(“g: stream a g-code file”, 12, y); y += dy;
text(“x: stop streaming g-code (this is NOT immediate)”, 12, y); y += dy;
y = height - dy;
text(“current jog speed: ” + speed + “ inches per step”, 12, y); y -= dy;
text(“current 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 G20 G00 X-” + speed + “ Y0.000 Z0.000 ”);
if (keyCode == RIGHT) port.write(“G91 G20 G00 X” + speed + “ Y0.000 Z0.000 ”);
if (keyCode == UP) port.write(“G91 G20 G00 X0.000 Y” + speed + “ Z0.000 ”);
if (keyCode == DOWN) port.write(“G91 G20 G00 X0.000 Y-” + speed + “ Z0.000 ”);
if (keyCode == KeyEvent.VK_PAGE_UP) port.write(“G91 G20 G00 X0.000 Y0.000 Z” + speed + “ ”);
if (keyCode == KeyEvent.VK_PAGE_DOWN) port.write(“G91 G20 G00 X0.000 Y0.000 Z-” + speed + “ ”);
if (key == ‘h’) port.write(“G90 G20 G00 X0.000 Y0.000 Z0.000 ”);
if (key == ‘v’) port.write(“$0=75 $1=74 $2=75 ”);
//if (key == ‘v’) port.write(“$0=100 $1=74 $2=75 ”);
if (key == ‘s’) port.write(“$3=10 ”);
if (key == ‘e’) port.write(“$16=1 ”);
if (key == ‘d’) port.write(“$16=0 ”);
if (key == ‘0’) openSerialPort();
if (key == ‘p’) selectSerialPort();
if (key == ‘) port.write(“$ ”);
}
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] + ’ ‘);
i++;
}
void serialEvent(Serial p)
{
String s = p.readStringUntil(’ ‘);
println(s.trim());
if (s.trim().startsWith(“ok”)) stream();
if (s.trim().startsWith(“error”)) stream(); // XXX: really?
}
步驟7:將Gerber文件上傳到Arduino開發板
按下G按鈕后,您可以將Gerber文件上傳到開發板上。而已。現在您的CNC機床將完成其工作。
步驟8:CNC機床
就是這樣。這是CNC機床的最終結果。
-
步進電機
+關注
關注
151文章
3120瀏覽量
147865 -
CNC
+關注
關注
7文章
316瀏覽量
35336 -
Arduino
+關注
關注
188文章
6477瀏覽量
187879
發布評論請先 登錄
相關推薦
評論