Umrüstung CNC-Fräse zu CNC-Laser-Cutter

Hallo,

ich fange gerade ein neues Projekt an.
Vielleicht hat ja jemand von Euch auch schon mal so etwas in der Art gemacht und kann mir helfen mich nicht gleich zu verrennen. Oder kann Tips geben.

Ansonsten ist dies als Doku für Nachfolgende gedacht die ähnliches for haben.

Zum Projekt:
Ich habe eine kleine Tisch-CNC Fräse.

Deren Z-Achse möchte ich nun umrüsten, so dass die Eingangs-Steuerimpulse für den dortigen Schrittmotor von einem Arduino aufbereitet werden um dann als TTL-Pegel für einen Laser zur Verfügung stehen.

Die CNC funktioniert im Moment wunderbar mit X, Y und Z über einen Kasten der am Parallelport des Rechners hängt.
Von dort bekommen die drei Achsen jeweils (Step, Richtung) über den LPT-Port und werden auf die drei Schrittmotoren gegeben.

Mein Plan (A) ist nun…
nur die LPT-Port Signale für die Z-Achse abfangen und über einen Arduino in einen TTL-Wert umwandeln.

der Plan (B) wäre…
Komplett alles auf Arduino um zu stellen.
Z.B. mit einem Stepper-Shield für die noch verbleibenden X/Y Achsen.

Plan A hätte den Vorteil, dass ich meine Software (Kcam4) weiterhin benutzen kann und der Z-Wert (höhe) die Stärke des Lasers bestimmt.

Für Plan B bräuchte ich wahrscheinlich eine neue Software um mit der CNC zu steuern.
Denn das Kcam4 macht zwar G-Code, aber gibt eben auf LPT aus.

Langfristig wäre eine komplette Umstellung auf Arduino schon schick! Noch dazu weil ich da noch ein cooles Display mit einbinden könnte das auch sehr informativ die jeweiligen Zustände anzeigen kann.

Hat jemand ne Idee?

Das hab ich mir mal aus den Fingern gezogen, aber noch nicht aufgebaut oder getestet. (ist halt mal ein Anfang für Plan A)

/*

CNC-Laser Steuerung
Input  = Z-Achse vom Parallelport, gesteuert über CNC-Software
Output = TTL-Pegel für Laser-Treiber

*/

/*
CHANGELOG:
2010_10_05-v2 unsinn mit dem hoch und runterzählen entfernt.
              ttl port gleich im setup definiert gesetzt

2010_10_05 Initiales Proggy

*/
 

// Konstanten
const int  inStep = 2;          // Step Eingang (Interupt 0)
const int  inDirection = 3;     // Richtungs Eingang
const int  outPower = 4;        // TTL-Ausgang - für Laser-Treiber

// Maximalwerte
const int  minPower = 0;        // Minimale Laser-Leistung
const int  maxPower = 255;      // Maximale Laser-Leistung

// Variablen
int Power = 0;                  // Laser-Power Level
int Step = 0;                   // Schritt Handler
int Direction = 0;              // Richtungs Handler

void setup() {
  Serial.begin(9600);
  pinMode(inStep, INPUT);
  pinMode(inDirection, INPUT);
  pinMode(outPower, OUTPUT);
  analogWrite(outPower, Power);
  attachInterrupt(0, step, RISING);
}


void loop() {
  if ( Step == 1 ) {
    Direction = digitalRead(inDirection);
    if ( Direction == HIGH && Power < maxPower ) {
      Power++;
      // serialPrint("Laserpower = ");
      Serial.print(Power);
    }
    if ( Direction == LOW && Power > minPower ) {
      Power--;
      // serialPrint("Laserpower = ");
      Serial.print(Power);
    }
    analogWrite(outPower, Power);
    Step = 0;
  }
}


void step() {
Step = 1;
}

Ich hoffe mal, dass die Steps langsamer kommen als sie der Arduino verarbeiten kann. Genaueres werde ich schreiben wenn ich es ausprobiert habe.

Grüße…
…eok

edit: sketch überarbeitet und gröbste fehler selbst gefunden. ::slight_smile:

Hast Du den Laser schon? Ist ein leistungfähiger Laser nicht etwas teuer? Grüße Uwe

Hi Uwe,

den neuen 1w Laser habe ich noch nicht hier. (unter 150? komplett) Aber mit einigen 100/200mw Lasern habe ich schon versuche gemacht. Da ich aber die bisher über einen Reed-Schalter mit einem Magneten an der Z-Achse ein und ausgeschaltet habe ist es nun mit der TTL Möglichkeit des neuen an der Zeit etwas neues zu bauen.

Hier ein kleines Demovideo, was ich für den Lasershop gemacht habe, mit dem "alten". http://www.youtube.com/v/bMYrmvnIfiw?fs=1&hl=de_DE

Im Video ist noch eine mechanische blende. Die ist inzwischen gegen den Reed-Schalter ausgetauscht worden. Aber auch das reicht nun mit dem neuen Laser nicht mehr um sinnvoll damit zu arbeiten.

Und um bösen Mails vor zu beugen. Ja, ich habe passenden Augenschutz und lichtdichte Abdeckungen für den Normalbetrieb. Die Laser sind definitiv KEIN Spielzeug und sollten demnach auch nicht zum spielen verwendet werden.

...eok

Hallo eok, das sieht ja wirklich imposant aus!

Verrätst Du mir, wo man solch eine Fräse herbekommt, ich würd sowas liebend gern zur Platinenherstellung verwenden. Aber all das, was ich bisher gesehen habe, war entweder zu groß oder zu teuer :-)

hallo wennjo,

leider gibt es den Hersteller nicht mehr. Das war so ein 1-mann Ingeneurbüro der die aus Spass an der Freude in kleinserie gebaut hat.
Hat damals so knapp 1000? gekostet alles in allem. Drunter wirds nicht viel geben wenn es “sinnvoll” funktionieren soll.

Deswegen versuche ich nun ja auch den damals mitgelieferten Controler gegen etwas aus zu tauschen was ich im Zweifelsfall auch selbst umprogrammieren/reparieren/erweitern/etc. kann.

Hier gibt es aber auch ähnliches was auch nicht schlecht ausschaut:
http://www.contraptor.org/contraptions

Von denen habe ich noch nichts bestellt und kenne auch nur die YouTube Videos…
Aber man kann da die Mechanik, die Elektronik und die Motoren getrennt bestellen. Wenn man also schon Motoren und Treiber zu hause hat… kann man sparen.
Wenn ich noch keine CNC hätte, würde ich dort mal schauen.

Grüße…
…eok

Danke für die Antwort, werde da mal reinschauen.

  1. Rückschlag!

Ich habe mir das “Motor Shield” bestellt.
Es geht gut, nur leider kann man nur jeweils einen der beiden Schrittmotoren ansteuern.
Wenn man mit beiden gleichzeitig fahren will, am Ende noch mit unterschiedlichen Geschwindigkeiten, wird es arg komplex.
Und keine der fertigen Sketches unterstützt das.

Somit werde ich das Shield für ein anderes Projekt nutzen und mir Pololu A4983 Treiber bestellen.

Schade, aber nur ein kurzer Rückschlag!

Dafür habe ich am Code gearbeitet:

/*

CNC-Laser Steuerung
Input  = Z-Achse vom Parallelport, gesteuert über CNC-Software
Output = TTL-Pegel für Laser-Treiber

*/

/*
CHANGELOG:
2010_10_15 zähler in den interupt verlagert
           eine lcd zustands anzeige integriert

2010_10_05-v2 unsinn mit dem hoch und runterzählen entfernt.
          ttl port gleich im setup definiert gesetzt

2010_10_05 Initiales Proggy

*/

#include <NewSoftSerial.h>
NewSoftSerial mySerial(12, 13);   // LCD an Pin 13

// Konstanten
const int  inStep = 2;        // Step Eingang (Interupt 0)
const int  inDirection = 3;     // Richtungs Eingang
const int  outPower = 9;      // TTL-Ausgang - für Laser-Treiber

// Maximalwerte
const int  minPower = 0;      // Minimale Laser-Leistung
const int  maxPower = 255;    // Maximale Laser-Leistung

// Variablen
int Power = 0;            // Laser-Power Level
int Direction = 0;          // Richtungs Handler

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  clearLCD();
  backlightOn();
  pinMode(inStep, INPUT);
  pinMode(inDirection, INPUT);
  pinMode(outPower, OUTPUT);
  analogWrite(outPower, Power);
  attachInterrupt(0, step, RISING);
  goTo(5);
  mySerial.print("Laserpower");
}


void loop() {
//    Direction = digitalRead(inDirection);
    analogWrite(outPower, Power);
    goTo(44);
    mySerial.print("Power = ");
    mySerial.print(Power);
    mySerial.print("  ");
    goTo(63);
    mySerial.print("Direction = ");
    mySerial.print(Direction);
  }


void step() {
    Direction = digitalRead(inDirection);
    if ( Direction == HIGH && Power < maxPower ) {
    Power++;
    }
    if ( Direction == LOW && Power > minPower ) {
    Power--;
    }
}
 
/********************************************/
// LCD Subs
/********************************************/
void clearLCD(){
   mySerial.print(0xFE, BYTE);   //command flag
   mySerial.print(0x01, BYTE);   //clear command.
   delay(50);
}
void goTo(int position) { //position = line 1: 0-19, line 2: 20-39, etc, 79+ defaults back to 0
if (position<20){ mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128), BYTE);    //position
}else if (position<40){mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128+64-20), BYTE);    //position 
}else if (position<60){mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128+20-40), BYTE);    //position
}else if (position<80){mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128+84-60), BYTE);    //position              
} else { goTo(0); }
delay(50);
}
void backlightOn(){  //turns on the backlight
    mySerial.print(0x7C, BYTE);   //command flag for backlight stuff
    mySerial.print(157, BYTE);    //light level.
    delay(50);
}

Läuft, soweit ich heute testen konnte zufriedenstellend… :slight_smile:


Arduino-Laser-TTL-Adapter by eok.gnah, on Flickr

…eok

Update…

Und weiter gehts… :slight_smile:

Hier die neue Software:

/*

CNC-Laser Steuerung
Input  = Z-Achse vom Parallelport, gesteuert über CNC-Software
Output = TTL-Pegel für Laser-Treiber

*/

/*
CHANGELOG:
2010_10_23 min/max potis mit feineinstellung hinzugefügt
           er schaltet nun gleich ON/OFF mit den min/max werten
           custom ttl-lasersteuer shield gebaut
           
2010_10_15 zähler in den interupt verlagert
           eine lcd zustands anzeige integriert

2010_10_05-v2 unsinn mit dem hoch und runterzählen entfernt.
              ttl port gleich im setup definiert gesetzt

2010_10_05 Initiales Proggy

*/

#include <NewSoftSerial.h>
NewSoftSerial mySerial(12, 13);   // LCD an Pin 13

// Konstanten
const int  inStep = 2;          // Step Eingang (Interupt 0)
const int  inDirection = 3;     // Richtungs Eingang
const int  outPower = 9;        // TTL-Ausgang - für Laser-Treiber
const int  minPin = A4 ;       // A4
const int  maxPin = A5 ;       // A5

// Maximalwerte
const int  minPower = 0;        // Minimale Laser-Leistung
const int  maxPower = 255;      // Maximale Laser-Leistung

// Variablen
int Power = 0;                  // Laser-Power Level
int Step = 0;                   // Schritt Handler
int Direction = 0;              // Richtungs Handler
int inMinimal = 0;              // Poti-Eingang Minimal
int inMaximal = 1023;              // Poti-Eingang Maximal

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  clearLCD();
  backlightOn();
  pinMode(inStep, INPUT);
  pinMode(inDirection, INPUT);
  pinMode(outPower, OUTPUT);
  analogWrite(outPower, Power);
  attachInterrupt(0, step, RISING);
  goTo(5);
  mySerial.print("Laserpower");
}


void loop() {
//    Direction = digitalRead(inDirection);
    analogWrite(outPower, Power);

    inMinimal = analogRead(minPin);
    inMaximal = analogRead(maxPin);
    inMinimal = map(inMinimal, 0, 1023, minPower, maxPower);
    inMaximal = map(inMaximal, 0, 1023, minPower, maxPower);
    if ( inMinimal > inMaximal ) { inMinimal = inMaximal; }
    if ( inMaximal < inMinimal ) { inMaximal = inMinimal; }
    if ( Power < inMinimal ) { Power = inMinimal; analogWrite(outPower, Power); }
    if ( Power > inMaximal ) { Power = inMaximal; analogWrite(outPower, Power); }
    
    goTo(20);
    mySerial.print("min=");
    mySerial.print(inMinimal);
    mySerial.print("  ");
    
    goTo(33);
    mySerial.print("max=");
    mySerial.print(inMaximal);
    mySerial.print("  ");
    

    goTo(44);
    mySerial.print("Power = ");
    mySerial.print(Power);
    mySerial.print("  ");
    goTo(63);
    mySerial.print("Direction = ");
    mySerial.print(Direction);
  }


void step() {
    Direction = digitalRead(inDirection);
    if ( Direction == HIGH && Power < inMaximal ) {
      Power = inMaximal;
        analogWrite(outPower, Power);
    }
    if ( Direction == LOW && Power > inMinimal ) {
      Power = inMinimal;
        analogWrite(outPower, Power);
    }
}
 
/********************************************/
// LCD Subs
/********************************************/
void clearLCD(){
   mySerial.print(0xFE, BYTE);   //command flag
   mySerial.print(0x01, BYTE);   //clear command.
   delay(50);
}
void goTo(int position) { //position = line 1: 0-19, line 2: 20-39, etc, 79+ defaults back to 0
if (position<20){ mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128), BYTE);    //position
}else if (position<40){mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128+64-20), BYTE);    //position 
}else if (position<60){mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128+20-40), BYTE);    //position
}else if (position<80){mySerial.print(0xFE, BYTE);   //command flag
              mySerial.print((position+128+84-60), BYTE);    //position              
} else { goTo(0); }
delay(50);
}
void backlightOn(){  //turns on the backlight
    mySerial.print(0x7C, BYTE);   //command flag for backlight stuff
    mySerial.print(157, BYTE);    //light level.
    delay(50);
}

So sieht das Shield aus, das ich nun dazu gebaut habe…
Die Zeit des Proto-Shields mit all den Steckkabeln ist nun hierfür vorbei.


cnc laser shield by eok.gnah, on Flickr

Der Laser…


laser by eok.gnah, on Flickr

Hier die CNC bei der Arbeit…


laser by eok.gnah, on Flickr

Und hier die ersten Materialtests…


Schneidetest by eok.gnah, on Flickr

Es wird… :smiley:

Und immer schön Schutz- :sunglasses: tragen!

…eok

Wie wird den bei dem Laser sichergestellt das er nur das Zielmaterial schneidet aber nicht die Unterlage der Frässe/CNC Cutter selber ?

@Megaionstorm... zum einen durch fokussierung (der laser schneidet am besten da wo er am dünnsten ist) zum anderen durch geeignete (unschneidbare) untergründe.

wenn ich mal raus habe wie man das teil beim lasern filmen kann ohne dass die kamera komplett überfordert wird werde ich ein kleines filmchen machen.

Echt super das Projekt. Von wo hast du die Diode gekauft?

Ich wurde das "unschneidbare" Material als untergrund benutzen.

@eok

Vielleicht zum Schutz der Kamera eine Laserschutzbrille zwischen Laserstrahl und Kamera stellen. Nach dem Prinzip einer Sonnenbrille oder Schweisserbrille !

@Shebu: hab dir eine PM geschickt.

Welche Farbe und Wellenlänge hat die Laserwumme den ? Vermute mal das es sich um einen Laser der Klasse 4 handelt.

blau 445nm

Was würde den passieren wenn der Laserstrahl durch eine spiegelnde Oberfläche in den Laseremitter hinein zurück reflektiert würde ? Ist immerhin ein Klasse 4 Laser !

äh.. keine ahnung? wenn ich pech habe wirds dunkel werden.. oder?

Ich vermute mal das sich der Laseremitter in dem Fall selber zerlegt, genauso wie er ansonsten Metall schneidet !

Wurde von dem Ding aber gerne mal ein Video sehen, beim Metalschneiden !

nee mit einem watt kannst noch lange kein metall beeindrucken. da passiert garnix. balsaholz ist auch ungünstig.. er schneidet zwar "durch" wenn man nur langsam genug, bzw ein paarmal drüber geht... aber dann sind die ränder so verkokelt, dass man es auch nicht mehr sinnvoll gebrauchen kann. so oberflächliche gravuren wie man sie so mit lötkolben auf holzteller und so in der weihnachtszeit macht gehen aber problemlos. habe auch einen spiegel (von hinten) gelasert und somit ist er an den stellen durchscheinend geworden... idt ein netter halloween effekt... nen geist rein lasern und von hinten mit einer EL folie beleuchten. schaut dann aus wie ein glühendes gespenst im spiegel.. ;-)

Man könnte also mit dem Laser in eine Glasscheibe eine Gravur einbringen ? Also ein schwarz/weiss umgerechtetes Bild spiegelverkehrt auf der Rückseite des Glases ?

Wenn man danach die Ruckseite mit Silberfarbe lackiert müsste man doch ein Spiegel ähnliches Glasbild haben !

Das währe vermutlich sogar ein schönes Weihnachtsgeschenk für die Verwandschaft !