Fall 2012: Project 2: CNC

Background: A computer numerical control (CNC) machine is a machine that cuts/assembles material using computer automation. Once the designs are drawn in a computer aided drafting program like AutoCAD, the computer instructs the machine head where to move (x, y, z coordinates) and what to do when it gets there (speed, cutting action, etc.).


Design: The design for our CNC mill will consist of three parts: platform, electronics, and software. (The hardware design is based on the work of Tom McWire.)



Platform: The platform consists of two horizontal layers - one which moves in the x-direction and the other in the y-direction - and a motor mounted on an arm capable of moving vertically in the z-direction. Each layer moves on rails and is pulled by a stepper motor. From left to right, the base with arm, x-direction platform, y-direction platform, and z-direction platform with motor.


Electronics: The motor is an old food blender. The platforms will be moved using bi-polar stepper motors with threaded rods attached to their shafts. A L298N Dual H-Bridge will be used to power the motors with the Arduino board providing control. (The motor control circuit is based on the work of Lewis Loflin.)


 
Program: A complete CNC program will not be produced for the project. A simple CNC program will be written in Excel which will then convert the code into x, y, and z coordinates. The Arduino can read input through a serial port and then output the required motor controls. Stepper motors are controlled by alternating the polarity of the motor's windings. Using the circuit diagram above, the bi-polar step motor can be controlled in three ways by changing the polarity. If the polarity is changed in sequence going down, the motor turns one direction, and if the polarity is changed in sequence going up, the motor turns in the opposite direction. (More can be read about step motors at Stepperworld.)

Wave Drive, One-Phase
(consumes the least power)
Black
Yellow
Brown
Orange
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-

Hi-Torque, Two-Phase
 (improved speed and torque)
Black
Yellow
Brown
Orange
-
-
+
+
-
+
+
-
+
+
-
-
+
-
-
+
  
Half-Step
(doubles stepping resolution)
Black
Yellow
Brown
Orange
-
-
-
+
-
-
+
+
-
-
+
-
-
+
+
-
-
+
-
-
+
+
-
-
+
-
-
-
+
-
-
+

Here is the code to be used for the Arduino:


#ifndef Motor_h
#define Motor_h

#include "Arduino.h"

class Motor
{
  public:
    Motor(int en, int coil_1, int coil_2);
    float drive(float inches);
  private:
    int _en;
    int _coil_1;
    int _coil_2;
    int STEPS; //steps per inch
    int DELAY_TIME; //delay time per step
    int sequence; //step motor is at this step in sequence of polarity
};

#endif



#include "Arduino.h"
#include "Motor.h"

Motor::Motor(int en, int coil_1, int coil_2)
{
  pinMode(en, OUTPUT);
  pinMode(coil_1, OUTPUT);
  pinMode(coil_2, OUTPUT);
  _en = en;
  _coil_1 = coil_1;
  _coil_2 = coil_2;
  STEPS = 4000; //steps per inch
  DELAY_TIME = 10; //delay time per step
  sequence = 0;
}

float Motor::drive(float inches)
{
  int POLARITY[2][4] = {1, 1, 1, 0, 0, 0, 0, 1};

  //motor makes discrete moves, this is the remainder it didn't turn
  float remainder;

  //negative inches to move backward
  int i = 1; //increment polarity sequence
  if (inches < 0) i = -1; //move backward through sequence if negative
 
  int turnCounter = abs(inches * STEPS); //total number of steps needed
  remainder = inches - turnCounter * STEPS;

  digitalWrite(_en, HIGH); //turn output to stepper on

  while (1){
    digitalWrite(_coil_1, POLARITY[sequence][1]);
    digitalWrite(_coil_2, POLARITY[sequence][2]);
    delay(DELAY_TIME); 
    turnCounter--; //turn completed
    //polarity pattern moves to next pattern in sequence
    sequence = (sequence + i) % 4;
   
    if (turnCounter == 0) break; //if finished turning, stop loop
  }
 
  digitalWrite(_en, LOW); //turn output to stepper off

  return remainder;
}

/*
This code uses a L298N dual H-bridge to operate three 4-wire,
1.8 degree/step, bi-polar stepper motors in high torque,
two-phase mode. Each motor is attached to a 20 thread/inch rod.
Therefore, it takes 4000 steps for the nut on the rod
to progress 1 inch.

The circuit diagram at csmengineeringclub.blogspot.com
shows the pin connections for the L298N. Pins 5 and 7
control coil 1 and are linked together with an inverter
on pin 7. Pins 10 and 12 control coil 2 and are linked
together with an inverter on pin 12.

L298N Pins      Function      
5, 7            Coil 1                     
10, 12          Coil 2        
6, 11           Enable High (EN)

Arduino digital pins control the stepper motors.

Ardunio Digital Pins
13 - ENa
12 - Coil 1a
11 - Coil 2a
10 - ENb
9 - Coil 1b
8 - Coil 2b
7 - ENc
6 - Coil 1c
5 - Coil 2c

Arduino analog in-pins control the calibration buttons.

Arduino Analog In-Pins
0 - x+
1 - x-
2 - y+
3 - y-
4 - z+
5 - z-

The program reads a comma deliminated text file of x, y, and z
coordinates entered through the serial port. The origin is at the
bottom left corner of the platform.
*/

#include <Motor.h>

// create 3 motor objects
Motor myMotorX(13, 12, 11);
Motor myMotorY(10, 9, 8);
Motor myMotorZ(7, 6, 5);

void setup(){ 
  Serial.begin(9600);// initialize the serial port
  for (int i = 5; i <= 13; i++){
    pinMode(i, OUTPUT);
  }
}//end setup

void loop(){
  Serial.println("Is the machine calibrated? (Y/N)");
  int selection;
 
  if (Serial.available() > 0){// user has typed something
    selection = Serial.read();
   
    if (selection == 'y' || selection == 'Y'){
      Serial.println("Enter coordinates.");
      drill();
    }
    else {
      Serial.println("Finished calibrating? (Y)");
     
      // if buttons are pushed down, move platform in that direction
      while (Serial.available() <= 0){
  // keep moving until user has typed something
         if (analogRead(A0) > 500) myMotorX.drive(0.001);
         if (analogRead(A1) > 500) myMotorX.drive(-0.001);
         if (analogRead(A2) > 500) myMotorY.drive(0.001);
         if (analogRead(A3) > 500) myMotorY.drive(-0.001);
         if (analogRead(A4) > 500) myMotorZ.drive(0.001);
         if (analogRead(A5) > 500) myMotorZ.drive(-0.001);
      }// end while
    }// end if
  }// end if
}//end loop

void drill(){
  // drill will be moving between points 1 and 2
  float x1, x2;
  float y1, y2;
  float z1, z2;
 
  // if coordinates available, read it
  if (Serial.available() > 0) {
    // look for the next valid float in the incoming serial stream:
    x1 = Serial.parseFloat();
    // do it again:
    y1 = Serial.parseFloat();
    // do it again:
    z1 = Serial.parseFloat();
  }
 
  while (Serial.available() > 0) {
    // look for second coordinate
    x2 = Serial.parseFloat();
    y2 = Serial.parseFloat();
    z2 = Serial.parseFloat();
   
    // the smallest distance a platform can move is 1/4000 inch, so to
    // calculate the smallest increment the motor should take to get the
    // smoothest linear interpolation, the shortest distance in each
    // direction is calculated and then multipled by a number less than
    // 4000 steps/inch
   
    int n = min (min( abs(x2 - x1), abs(y2 - y1)) , abs(z2 - z1) ) * 3000; 
    for (int i = 0; i < n; i++){// move platforms
      // new coordinate becomes old coordinate so drill can move to the
      // next coordinate
      x1 = x2 - myMotorX.drive( (x2 - x1) / n );
      y1 = y2 - myMotorY.drive( (y2 - y1) / n );
      z1 = z2 - myMotorZ.drive( (z2 - z1) / n );
    }

    // look for the newline that marks the end of coordinate data
    if (Serial.peek() == '\n') break;

  }//end while
}// end input

#######################################
# Syntax Coloring Map Motor
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

Motor    KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

drive    KEYWORD2
  

 Parts:


Base
Quantity
Unit Price
Total
Store
Plywood 1/2"
1
$0.00
$0.00
Own
Stud 2" x 4"
2
$0.00
$0.00
Own
MDF 1/2"
1
$0.00
$0.00
Own
Aluminum L-Channel 3/4" x 96" x 1/20"
1
$9.96
$9.96
Home Depot
Aluminum C-Channel 3/4" x 96" x 1/16"
1
$0.00
$0.00
Own
1", 1-1/2" Screws

$0.00
$0.00
Own




Arm
Quantity
Unit Price
Total
Store
3/4" Floor Flange Pipe
2
$2.19
$4.38
Home Depot
3/4" Elbow Pipe
1
$2.37
$2.37
Home Depot
3/4" x 6" Pipe
1
$2.26
$2.26
Home Depot
3/4" x 12" Pipe
1
$4.45
$4.45
Home Depot




Movement Mechanism
Quantity
Unit Price
Total
Store
1/4" x 7/8" Ball Bearing (2x)
3
$2.37
$7.11
Home Depot
Extension Springs, 1/4" x 1”
3
$0.00
$0.00
Own
1-1/2" Slotted Truss, Angle Bracket
2
$0.00
$0.00
Own
1” x 1” Angle Bracket
4
$0.00
$0.00
Own
1/4" Hex Nut
15
$0.06
$0.90
Home Depot
Washers

$0.00
$0.00
Own
Binder Clips
3
$0.00
$0.00
Own
1/4"-20 x 7/8" Coupling Nut (3x)
1
$1.24
$1.24
Home Depot
1/4"-20 x 36" Threaded Rod
2
$1.97
$3.94
Home Depot
Electrical Tape

$0.00
$0.00
Own




Drill
Quantity
Unit Price
Total
Store
Motor
1
$0.00
$0.00
Own
Dremel 1/8 in. Multipurpose Cutting Bit
1
$5.20
$5.20
Home Depot
3/4" x 10' Metal Hanger Strap
1
$0.00
$0.00
Own
Metal Epoxy
1
$0.00
$0.00
Own
Drill Chuck
1
$0.00
$0.00
Ow




Electronics
Quantity
Unit Price
Total
Store
Arduino
1
$0.00
$0.00
Own
Stepper Motor 24V, 1.8 Degree, 1.2A (x3)
1
$32.99
$32.99
Ebay
Hex Inverter 74LS04N
3
$0.49
$1.47
Jameco
0.1uF Capacitor
10
$0.07
$0.70
Jameco
Dual Full Bridge Driver L298N
3
$2.75
$8.25
Jameco
Schottky Diode 1N5822
30
$0.16
$4.80
Jameco
AWG26 Wire
0
$0.00
$0.00
Own




Totals
Subtotal
Tax, S/H
Total

Home Depot
$41.40
$3.48
$44.88

Jameco
$15.22
$1.26
$16.48

Ebay
$32.99
$6.99
$39.98







Grand Total:
$101.34



No comments:

Post a Comment