Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

DIY 3-Achsen CNC-Fräse (VMC): Präzisions-Fräsmaschine selbst bauen

Komponenten und Materialien

Arduino Nano R3 × 1
Raspberry Pi 3 Model B × 1
SparkFun Stepper-Treiber A4988 × 1
Adafruit Arduino Nano 4-Stepper 1-DC RepRap Shield × 1
OpenBuilds Aluminium-Distanzstücke × 1
Netzteil 12V/5A × 1
OpenBuilds L-Winkel × 1
OpenBuilds M5 T-Nutensteine (10er Pack) × 1
OpenBuilds Flachkopfschrauben M5 (10er Pack) × 1
OpenBuilds Zylinderschrauben M3 × 1
OpenBuilds Gewindestift × 1
OpenBuilds Nutenstein 15×5×2 mm × 1
OpenBuilds Anti-Backlash Mutternblock für 8mm Trapezgewindespindel × 2
OpenBuilds Gewindeplatine für NEMA 17 Schrittmotor × 1
OpenBuilds 8mm Trapezgewindespindel (metrisch) × 1
OpenBuilds Kugellager 625 2RS 5×16×5 × 1
Geführtes Rundstab (Smooth Rod) × 1
BLDC Kühllüfter × 1
DC-Motor (generisch) × 1
Servo Tower Pro MG996R × 1
Texas Instruments Dual H-Brücke L293D × 1

Benötigte Werkzeuge und Maschinen

Apps und Online-Dienste

Über dieses Projekt

Unser Prototyp basiert auf IoT und bietet eine skalierbare Architektur für die Steuerung von praktisch überall mit Internetverbindung. Es handelt sich um eine 350×350 mm CNC mit 250×240 mm Arbeitsbereich, die auf Open-Source-Bewegungssteuerung (GRBL) läuft. Auch die Hardware ist weitgehend Open Source, was die Kosten drastisch senkt. Die Maschine besteht vollständig aus lokal beschafften Teilen und kann Holz, Kunststoffe, Hartgummi, Harz usw. bearbeiten. Hauptziel ist die kostengünstige PCB-Herstellung; auch Holzgravur ist möglich. Geplant ist die Erweiterung um Laserbearbeitung.

Das System ist derzeit über ein lokales WLAN steuerbar; wir streben ein verteiltes Web-Anwendungsmodell an, um ein Ökosystem mehrerer solcher Geräte zu vernetzen – die Möglichkeiten sind unbegrenzt.

Mechanischer Aufbau

Der Grundrahmen besteht aus 2020 T-Nuten-Aluminiumprofilen und L-Verbindern. Die Spindel (DC-geregelt, 2000 U/min) liefert ca. 80–85 W. Die Bewegung erfolgt über Trapezgewindespindeln und Führungswellen mit radial genuteten Kugellagern (Snap-Fit) für alle drei Achsen.

Minimaler Steigungswinkel: 0,8 mm/Umdrehung. Bei 2000 Schritten/Umdrehung ergibt sich eine Auflösung von 1600 Schritten/mm für alle Achsen. Grobe Maschinenmaße: 430×430×330 mm; Arbeitsbereich: ca. 270×170×65 mm; Positionsgenauigkeit: 0,04 mm. Das Z-Portal ist 3D-gedruckt mit doppelter Führungsstange; Z-Verfahrweg 4,8 cm mit montiertem Fräser. Verwendet wird ein 45° V-Bit für PCB-Gravur sowie 0,2–1,8 mm Schaftfräser.

Antrieb: NEMA 23 Schrittmotoren (max. 3 A pro Achse) mit A4988-Treibern (2,5 A, 1/16 Microstepping) für hohe Präzision bei niedrigen Kosten.

IoT / Industry 4.0

Die Steuerung erfolgt über ein kopfloses Display (Smartphone/Tablet als HMI) von überall mit Internetzugang. Ein Raspberry Pi mit Router (Sicherheit) hostet einen Webserver für die drahtlose CNC-Steuerung. Geplant ist die Erfassung von Echtzeitdaten wie Motordrehmoment, Stromaufnahme, Vibration, Geräusch – eine typische Industrial IoT (Industrie 4.0)-Anwendung für bessere Kollaboration.

Code

Beispiel-G-Code (VHDL)

(Scribbled version of C:\Users\ABDERR~1\AppData\Local\Temp\ink_ext_XXXXXX.svgISF45X @ 3000.00)
(unicorn.py --tab="plotter_setup" --pen-up-angle=50 --pen-down-angle=30 --start-delay=160 --stop-delay=150 --xy-feedrate=3000 --z-feedrate=150 --z-height=0 --finished-height=0 --register-pen=true --x-home=0 --y-home=0 --num-copies=1 --continuous=false --pause-on-layer-change=true C:\Users\ABDERR~1\AppData\Local\Temp\ink_ext_XXXXXX.svgISF45X)
G21 (metric ftw)
G90 (absolute mode)
G92 X0.00 Y0.00 Z0.00 (you are here)
M300 S30 (pen down)
G4 P160 (wait 160ms)
M300 S50 (pen up)
G4 P150 (wait 150ms)
M18 (disengage drives)
M01 (Was registration test successful?)
M17 (engage drives if YES, and continue)
M01 (Plotting layer 'Calque 1')
(Polyline consisting of 29 segments.)
G1 X16.85 Y4.97 F3000.00
M300 S30.00 (pen down)
G4 P160 (wait 160ms)
... (Datei gekürzt, vollständigen Inhalt herunterladen)

Stepper-Code (Arduino)

//AMIT
#include <Servo.h>
#include <AFMotor.h>
#define LINE_BUFFER_LENGTH 512
char STEP = MICROSTEP;
const int penZUp = 115;
const int penZDown = 83;
const int penServoPin = 10;
const int stepsPerRevolution = 48;
Servo penServo;
AF_Stepper myStepperY(stepsPerRevolution,1);
AF_Stepper myStepperX(stepsPerRevolution,2);

struct point { float x; float y; float z; };
struct point actuatorPos;
float StepInc = 1;
int StepDelay = 0;
int LineDelay = 0;
int penDelay = 50;
float StepsPerMillimeterX = 100.0;
float StepsPerMillimeterY = 100.0;
float Xmin = 0, Xmax = 40, Ymin = 0, Ymax = 40, Zmin = 0, Zmax = 1;
float Xpos = Xmin, Ypos = Ymin, Zpos = Zmax;
boolean verbose = false;

void setup() {
  Serial.begin(9600);
  penServo.attach(penServoPin);
  penServo.write(penZUp);
  delay(100);
  myStepperX.setSpeed(600);
  myStepperY.setSpeed(600);
  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(100);
  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 { /* Empty or comment line */ }
        lineIsComment = false; lineSemiColon = false;
        Serial.println("ok");
      } else {
        if (lineIsComment || lineSemiColon) {
          if (c == ')') lineIsComment = false;
        } else {
          if (c <= ' ') { /* Throw away whitespace */ }
          else if (c == '/') { /* Block delete not supported */ }
          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: // G00 & G01
            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: // M114 - Report 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(""); }
  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, over = 0;
  if (dx > dy) {
    for (i=0; i= dx) { over -= dx; myStepperY.onestep(sy, STEP); }
      delay(StepDelay);
    }
  } else {
    for (i=0; i= 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(LineDelay);
  Xpos = x1; Ypos = y1;
}

void penUp() {
  penServo.write(penZUp); delay(penDelay); Zpos = Zmax;
  digitalWrite(15, LOW); digitalWrite(16, HIGH);
  if (verbose) Serial.println("Pen up!");
}
void penDown() {
  penServo.write(penZDown); delay(penDelay); Zpos = Zmin;
  digitalWrite(15, HIGH); digitalWrite(16, LOW);
  if (verbose) Serial.println("Pen down.");
}

Bibliotheken (Adafruit Motor Shield Library)

Die Bibliothek AFMotor.h wird für die Ansteuerung der Schrittmotoren über das Adafruit Motor Shield verwendet. Der Code ist Public Domain und unterstützt Microstepping (8 oder 16 Stufen). Enthält PWM-Initialisierung für Timer auf AVR und PIC32, Latch-Steuerung für H-Brücken und Stepper-Logik (Single, Double, Interleave, Microstep).

// Adafruit Motor shield library
// copyright Adafruit Industries LLC, 2009
// this code is public domain, enjoy!
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#if defined(__AVR__)
#include 
#endif
#include "WProgram.h"
#endif
#include "AFMotor.h"
... (vollständiger Bibliothekscode im Original)

Individuelle Teile & Gehäuse

Dateien: cnc_contour_SNa09InGkY.gm1, cnc_coppertop_PIxEVyoMWI.gtl

Schaltpläne

DIY 3-Achsen CNC-Fräse (VMC): Präzisions-Fräsmaschine selbst bauen DIY 3-Achsen CNC-Fräse (VMC): Präzisions-Fräsmaschine selbst bauen DIY 3-Achsen CNC-Fräse (VMC): Präzisions-Fräsmaschine selbst bauen DIY 3-Achsen CNC-Fräse (VMC): Präzisions-Fräsmaschine selbst bauen DIY 3-Achsen CNC-Fräse (VMC): Präzisions-Fräsmaschine selbst bauen

Herstellungsprozess

  1. Eigenen LUMAZOID bauen: DIY Arduino Musik-Visualisierer
  2. Intelligentes Voltmeter mit Arduino & Smartphone bauen – Einfaches DIY-Projekt
  3. DIY VR-Skateboard mit Arduino, Google Cardboard und Bluetooth bauen
  4. Triple CNC-Maschine – Premium-Upgrade mit Brushless-Motor
  5. Zen-Garten-CNC-Beistelltisch: Bauen Sie Ihre eigenen smarten Möbel
  6. DIY Radionik EMR-Behandlungsgerät mit Arduino Nano – Kritische Betrachtung
  7. Eine voll funktionsfähige CNC-Maschine mit Arduino Nano R3 bauen
  8. DIY 2D-Motion-Rennsimulator mit Arduino Nano & SG90 Servos
  9. Vertikales Fräsen & CNC-VMC: Umfassende Einführung
  10. Mini-VMC-Maschine erklärt: Kompaktes CNC-Fräsen für Kleinprojekte