Ana Sayfa Arduino Lazer İşleme Makinesi Yapımı

Lazer İşleme Makinesi Yapımı

185 min read
9
4
21,405

Merhaba arkadaşlar,bu projemizde sizlerle birlikte lazer işleme makinesi yapımını göreceğiz.İngilizce olarak ‘laser engraving’ adıyla aratıldığında farklı örneklerde bulunabiliyor.Lazer işleme makinesi yaparak herhangi bir tahta , metal vb.malzemeler üzerine işleme yapabiliyoruz.Metal,plexi vb.kesmek için ise lazerin şiddetiyle oynamak gerekiyor.Mesela 2,5 watt ile tahta üzerine bir resim işleyebilirsiniz fakat metal üzerine işlemek için gücü arttırmak gerekiyor.

ptr

Araştırdığımıza göre de metal kesmek için yaklaşık olarak 3-4 kw gücünde lazer kullanmak gerekiyor.Tasarımı kendimize ait olan makinemizin yapım bilgileri aşağıdadır.İlk önce malzemeleri tanımak gerekirse ;

Kullanılan Malzemeler

  • Arduino Uno
  • CNC Shield
  • 2,5 Watt Lazer
  • Nema 17 Step Motor x 2 adet
  • 8 çapında 350 mm indüksiyonlu mil x 2 adet
  • 8 çapında 335 mm indüksiyonlu mil x 2 adet
  • SK-8 Mil Tutucu x 2 adet
  • SHF-8 Mil Tutucu x 2 adet
  • GT 2 Rulmanlı Kasnak 20 Diş 5 mm Mil Çapı x 2 adet
  • GT 2 Rulmanlı Kasnak Dişsiz 5 mm Mil Çapı x 4 adet
  • GT 2 Kasnak 20 Diş 5mm Mil Çapı x 2 adet
  • M5x70 Saplama x 2 adet
  • M5x80 Saplama x 4 adet
  • SCE-8UU Lineer Rulman x 6 adet
  • GT2 Kayış
  • M5x16 İmbus Civata x 32 adet
  • M4x12 İmbus Civata x 24 adet
  • M3x10 İmbus Civata x 10 adet
  • M5 Somun x 55 adet
  • M3 Somun x 2 adet
  • M4 Somun x 2 adet

Arduino Kodları

<br>
#include <config.h><br>
#include <coolant_control.h><br>
#include <cpu_map.h><br>
#include <defaults.h><br>
#include <eeprom.h><br>
#include <gcode.h><br>
#include <grbl.h><br>
#include <limits.h><br>
#include <motion_control.h><br>
#include <nuts_bolts.h><br>
#include <planner.h><br>
#include <print.h><br>
#include <probe.h><br>
#include <protocol.h><br>
#include <report.h><br>
#include <serial.h><br>
#include <settings.h><br>
#include <spindle_control.h><br>
#include <stepper.h><br>
#include <system.h></p>
<p>#include <config.h><br>
#include <coolant_control.h><br>
#include <cpu_map.h><br>
#include <defaults.h><br>
#include <eeprom.h><br>
#include <gcode.h><br>
#include <grbl.h><br>
#include <limits.h><br>
#include <motion_control.h><br>
#include <nuts_bolts.h><br>
#include <planner.h><br>
#include <print.h><br>
#include <probe.h><br>
#include <protocol.h><br>
#include <report.h><br>
#include <serial.h><br>
#include <settings.h><br>
#include <spindle_control.h><br>
#include <stepper.h><br>
#include <system.h></p>
<p>#include <config.h><br>
#include <coolant_control.h><br>
#include <cpu_map.h><br>
#include <defaults.h><br>
#include <eeprom.h><br>
#include <gcode.h><br>
#include <grbl.h><br>
#include <limits.h><br>
#include <motion_control.h><br>
#include <nuts_bolts.h><br>
#include <planner.h><br>
#include <print.h><br>
#include <probe.h><br>
#include <protocol.h><br>
#include <report.h><br>
#include <serial.h><br>
#include <settings.h><br>
#include <spindle_control.h><br>
#include <stepper.h><br>
#include <system.h></p>
<p>/**********************************************************************<br>
CoreXY PLOTTER<br>
Code by lingib<br>
Last update 6 October 2017</p>
<p>This program controls the stepping motors in a CoreXY or H-Bot plotter.</p>
<p>----------<br>
COPYRIGHT<br>
----------<br>
This code is free software: you can redistribute it and/or<br>
modify it under the terms of the GNU General Public License as published<br>
by the Free Software Foundation, either version 3 of the License, or<br>
(at your option) any later version.</p>
<p>This software is distributed in the hope that it will be useful,<br>
but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
GNU General Public License for more details.</p>
<p>You should have received a copy of the GNU General Public License. If<br>
not, see <http://www.gnu.org/licenses/>.<br>
***************************************************************************/</p>
<p>// -------------------------------<br>
// GLOBALS<br>
// -------------------------------</p>
<p>// ----- constants<br>
#define PI 3.1415926535897932384626433832795<br>
#define HALF_PI 1.5707963267948966192313216916398<br>
#define TWO_PI 6.283185307179586476925286766559<br>
#define DEG_TO_RAD 0.017453292519943295769236907684886<br>
#define RAD_TO_DEG 57.295779513082320876798154814105</p>
<p>// ----- Bit set/clear/check/toggle macros<br>
#define SET(x,y) (x |=(1<<y))<br>
#define CLR(x,y) (x &= (~(1<<y)))<br>
#define CHK(x,y) (x & (1<<y))<br>
#define TOG(x,y) (x^=(1<<y))</p>
<p>// ----- motor definitions<br>
#define STEPS_PER_MM 200*16/40      //200steps/rev; 16 x microstepping; 40mm/rev<br>
#define NUDGE STEPS_PER_MM*5        //move pen 5mm (change number to suit)<br>
#define DIR1 8                      //arduino ports<br>
#define DIR2 10<br>
#define STEP1 9<br>
#define STEP2 11</p>
<p>bool<br>
CW = true,                          //flag ... does not affect motor direction<br>
CCW = false,                        //flag ... does not affect motor direction<br>
DIRECTION1,                         //motor directions can be changed in step_motors()<br>
DIRECTION2;</p>
<p>long<br>
PULSE_WIDTH = 2,                    //easydriver step pulse-width (uS)<br>
DELAY = 250;                        //delay (uS) between motor steps (controls speed)</p>
<p>// ----- plotter definitions<br>
#define BAUD 9600<br>
#define XOFF 0x13                   //pause transmission (19 decimal)<br>
#define XON 0x11                    //resume transmission (17 decimal)<br>
#define PEN 3</p>
<p>float<br>
SCALE_FACTOR = 1.0,                 //drawing scale (1 = 100%)<br>
ARC_MAX = 2.0;                      //maximum arc-length (controls smoothness)</p>
<p>int<br>
/*<br>
XY plotters only deal in integer steps.<br>
*/<br>
THIS_X = 0,                         //"scaled" x co-ordinate (rounded)<br>
THIS_Y = 0,                         //"scaled" y co-ordinate (rounded)<br>
LAST_X = 0,                         //"scaled" x co-ordinate (rounded)<br>
LAST_Y = 0;                         //"scaled" y co-ordinate (rounded)</p>
<p>// ----- gcode definitions<br>
#define STRING_SIZE 128             //string size</p>
<p>char<br>
BUFFER[STRING_SIZE + 1],<br>
INPUT_CHAR;</p>
<p>String<br>
INPUT_STRING,<br>
SUB_STRING;</p>
<p>int<br>
INDEX = 0,                        //buffer index<br>
START,                            //used for sub_string extraction<br>
FINISH;</p>
<p>float<br>
X,                                //gcode float values held here<br>
Y,<br>
I,<br>
J;</p>
<p>// -----------------------<br>
// SETUP<br>
// -----------------------<br>
void setup()<br>
{<br>
// ----- initialise motor1<br>
pinMode(DIR1, OUTPUT);<br>
pinMode(STEP1, OUTPUT);<br>
digitalWrite(DIR1, CW);<br>
delayMicroseconds(PULSE_WIDTH);<br>
digitalWrite(STEP1, LOW);</p>
<p>// ----- initialise motor2<br>
pinMode(DIR2, OUTPUT);<br>
pinMode(STEP2, OUTPUT);<br>
digitalWrite(DIR2, CW);<br>
delayMicroseconds(PULSE_WIDTH);<br>
digitalWrite(STEP2, LOW);</p>
<p>// ----- pen-lift<br>
pinMode(PEN, OUTPUT);                                       //D3<br>
TCCR2A = _BV(COM2B1) | _BV(COM2B0) | _BV(WGM20);            //PWM<br>
TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20);    //div 1024<br>
OCR2A = 156;                                                //20mS period<br>
OCR2B = 148;                                                //2mS period (pen-up)</p>
<p>/*<br>
The above pen-lift comprises a standard servo which requires a 1 mS pulse<br>
for pen down, or a 2mS pulse for pen up, with a fixed period of 20mS.</p>
<p>The Arduino "bit value" macro, #define _BV(x) (1 << x), is used to<br>
set the Timer2 mode to "phase-correct PWM" with a variable "top-limit".<br>
In this mode the timer counts up to the value entered into register OCR2A<br>
then back down to zero.</p>
<p>The following values were used to obtain a 20mS period at pin D3:<br>
clock:        16 MHz<br>
prescaler:      1024<br>
top-limit (OCR2A):  156<br>
period:       16MHz/1024/(156*2) = 50Hz (20mS)</p>
<p>If you enter a value into register OCR2B that is LESS than the value in<br>
register OCR2A then timer2 will will pass through the value in OCR2B<br>
twice ... once on the way up ... and once on the way down. The duration<br>
of the output pulse on pin D3 is the time that the count in OCR2A is<br>
greater than the value in OCR2B.</p>
<p>A value of 148 entered into OCR2B creates a 1mS pulse:<br>
period:       156-148)*20mS/156 = 1mS (pen-up)</p>
<p>A value of 140 entered into OCR2B creates a 2mS pulse):<br>
period:     156-140)*20mS/156 = 2mS (pen-down)<br>
*/</p>
<p>// ----- plotter setup<br>
memset(BUFFER, '\0', sizeof(BUFFER));     //fill with string terminators<br>
INPUT_STRING.reserve(STRING_SIZE);<br>
INPUT_STRING = "";</p>
<p>// ----- establish serial link<br>
Serial.begin(BAUD);</p>
<p>// ----- flush the buffers<br>
Serial.flush();                           //clear TX buffer<br>
while (Serial.available()) Serial.read(); //clear RX buffer</p>
<p>// ----- display commands<br>
menu();<br>
}</p>
<p>//--------------------------------------------------------------------------<br>
// MAIN LOOP<br>
//--------------------------------------------------------------------------<br>
void loop() {</p>
<p>// ----- get the next instruction<br>
while (Serial.available()) {<br>
INPUT_CHAR = (char)Serial.read();         //read character<br>
Serial.write(INPUT_CHAR);                 //echo character to the screen<br>
BUFFER[INDEX++] = INPUT_CHAR;             //add char to buffer<br>
if (INPUT_CHAR == '\n') {                 //check for line feed<br>
Serial.flush();                         //clear TX buffer<br>
Serial.write(XOFF);                     //pause transmission<br>
INPUT_STRING = BUFFER;                  //convert to string<br>
process(INPUT_STRING);                  //interpret string and perform task<br>
memset(BUFFER, '\0', sizeof(BUFFER));   //fill buffer with string terminators<br>
INDEX = 0;                              //point to buffer start<br>
INPUT_STRING = "";                      //empty string<br>
Serial.flush();                         //clear TX buffer<br>
Serial.write(XON);                      //resume transmission<br>
}<br>
}<br>
}</p>
<p>//---------------------------------------------------------------------------<br>
// MENU<br>
//---------------------------------------------------------------------------<br>
/*<br>
The Arduino F() flash macro is used to conserve RAM.<br>
*/<br>
void menu() {<br>
Serial.println(F(""));<br>
Serial.println(F("  ------------------------------------------------------"));<br>
Serial.println(F("                         MENU"));<br>
Serial.println(F("  ------------------------------------------------------"));<br>
Serial.println(F("    MENU ............... menu"));<br>
Serial.println(F("    G00 X## Y## ........ goto XY (pen-up)"));<br>
Serial.println(F("    G01 X## Y## ........ goto XY (pen-down)"));<br>
Serial.println(F("    T1 ................. move pen to 0,0"));<br>
Serial.println(F("    T2 S##.## .......... set drawing Scale (1=100%)"));<br>
Serial.println(F("    T3 ................. pen up"));<br>
Serial.println(F("    T4 ................. pen down"));<br>
Serial.println(F("    T5 ................. test pattern: ABC"));<br>
Serial.println(F("    T6 ................. test pattern: target"));<br>
Serial.println(F("    T7 ................. test pattern: radials"));<br>
Serial.println(F("  ------------------------------------------------------"));<br>
}</p>
<p>//--------------------------------------------------------------------------<br>
// PROCESS<br>
//--------------------------------------------------------------------------<br>
void process(String string) {</p>
<p>// ----- convert string to upper case<br>
INPUT_STRING = string;<br>
INPUT_STRING.toUpperCase();</p>
<p>// ----------------------------------<br>
// G00   linear move with pen_up<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("G00")) {</p>
<p>// ----- extract X<br>
START = INPUT_STRING.indexOf('X');<br>
if (!(START < 0)) {<br>
FINISH = START + 8;<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 1);<br>
X = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract Y<br>
START = INPUT_STRING.indexOf('Y');<br>
if (!(START < 0)) {<br>
FINISH = START + 8;<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 1);<br>
Y = SUB_STRING.toFloat();<br>
}</p>
<p>pen_up();<br>
move_to(X, Y);<br>
}</p>
<p>// ----------------------------------<br>
// G01   linear move with pen_down<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("G01")) {</p>
<p>// ----- extract X<br>
START = INPUT_STRING.indexOf('X');<br>
if (!(START < 0)) {<br>
FINISH = START + 8;<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 1);<br>
X = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract Y<br>
START = INPUT_STRING.indexOf('Y');<br>
if (!(START < 0)) {<br>
FINISH = START + 8;<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 1);<br>
Y = SUB_STRING.toFloat();<br>
}</p>
<p>pen_down();<br>
move_to(X, Y);<br>
}</p>
<p>// ----------------------------------<br>
// G02   clockwise arc with pen_down<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("G02")) {</p>
<p>// ----- extract X<br>
START = INPUT_STRING.indexOf('X');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('X'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
X = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract Y<br>
START = INPUT_STRING.indexOf('Y');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('Y'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
Y = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract I<br>
START = INPUT_STRING.indexOf('I');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('I'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
I = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract J<br>
START = INPUT_STRING.indexOf('J');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('J'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
J = SUB_STRING.toFloat();<br>
}</p>
<p>pen_down();<br>
draw_arc_cw(X, Y, I, J);<br>
}</p>
<p>// ------------------------------------------<br>
// G03   counter-clockwise arc with pen_down<br>
// ------------------------------------------<br>
if (INPUT_STRING.startsWith("G03")) {</p>
<p>// ----- extract X<br>
START = INPUT_STRING.indexOf('X');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('X'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
X = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract Y<br>
START = INPUT_STRING.indexOf('Y');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('Y'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
Y = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract I<br>
START = INPUT_STRING.indexOf('I');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('I'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
I = SUB_STRING.toFloat();<br>
}</p>
<p>// ----- extract J<br>
START = INPUT_STRING.indexOf('J');<br>
if (!(START < 0)) {<br>
FINISH = INPUT_STRING.indexOf('.', INPUT_STRING.indexOf('J'));<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH + 7);<br>
J = SUB_STRING.toFloat();<br>
}</p>
<p>pen_down();<br>
draw_arc_ccw(X, Y, I, J);<br>
}</p>
<p>// ----------------------------------<br>
// MENU<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("MENU")) {<br>
menu();<br>
}</p>
<p>// ----------------------------------<br>
// T1   position the pen over 0,0<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T1")) {</p>
<p>// ----- variables<br>
int step;           //loop counter<br>
int steps = NUDGE;  //steps motor is to rotate</p>
<p>// ----- instructions<br>
Serial.println(F(""));<br>
Serial.println(F("  ----------------------------------------------"));<br>
Serial.println(F("    Position the pen over the 0,0 co-ordinate:"));<br>
Serial.println(F("  ----------------------------------------------"));<br>
Serial.println(F("    X-axis:             Y-axis:"));<br>
Serial.println(F("   'A'  'S'            'K'  'L'"));<br>
Serial.println(F("   <-    ->            <-    ->"));<br>
Serial.println(F("    Exit = 'E'"));</p>
<p>// ----- flush the buffer<br>
while (Serial.available() > 0) Serial.read();</p>
<p>// ----- control motors with 'A', 'S', 'K', and 'L' keys</p>
<p>char keystroke = ' ';<br>
while (keystroke != 'E') {  //press 'E' key to exit</p>
<p>// ----- check for keypress<br>
if (Serial.available() > 0) {<br>
keystroke = (char) Serial.read();<br>
}</p>
<p>// ----- select task<br>
switch (keystroke) {<br>
case 'a':<br>
case 'A': {<br>
// ----- rotate motor1 CW<br>
for (step = 0; step < steps; step++) {<br>
left();<br>
}<br>
keystroke = ' ';    //otherwise motor will continue to rotate<br>
break;<br>
}<br>
case 's':<br>
case 'S': {<br>
// ------ rotate motor1 CCW<br>
for (step = 0; step < steps; step++) {<br>
right();<br>
}<br>
keystroke = ' ';<br>
break;<br>
}<br>
case 'k':<br>
case 'K': {<br>
// ----- rotate motor2 CW<br>
for (step = 0; step < steps; step++) {<br>
up();<br>
}<br>
keystroke = ' ';<br>
break;<br>
}<br>
case 'l':<br>
case 'L': {<br>
// ----- rotate motor2 CCW<br>
for (step = 0; step < steps; step++) {<br>
down();<br>
}<br>
keystroke = ' ';<br>
break;<br>
}<br>
case 'e':<br>
case 'E': {<br>
// ----- exit<br>
Serial.println(F(" "));<br>
Serial.println(F("  Calibration complete ..."));<br>
keystroke = 'E';<br>
break;<br>
}<br>
// ----- default for keystroke<br>
default: {<br>
break;<br>
}<br>
}<br>
}</p>
<p>// ----- initialise counters for co-ordinate (0,0)<br>
THIS_X = 0;                   //current X co-ordinate<br>
THIS_Y = 0;                   //current Y co-ordinate<br>
LAST_X = 0;                   //previous X co-ordinate<br>
LAST_Y = 0;                   //previous Y-co-ordinate<br>
}</p>
<p>// ----------------------------------<br>
// T2   set scale factor<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T2")) {<br>
Serial.println("T2");</p>
<p>START = INPUT_STRING.indexOf('S');<br>
if (!(START < 0)) {<br>
FINISH = START + 6;<br>
SUB_STRING = INPUT_STRING.substring(START + 1, FINISH);<br>
SCALE_FACTOR = SUB_STRING.toFloat();<br>
Serial.print(F("Drawing now ")); Serial.print(SCALE_FACTOR * 100); Serial.println(F("%"));<br>
}<br>
else {<br>
Serial.println(F("Invalid scale factor ... try again. (1 = 100%)"));<br>
}<br>
}</p>
<p>// ----------------------------------<br>
// T3   pen up<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T3")) {<br>
pen_up();<br>
}</p>
<p>// ----------------------------------<br>
// T4   pen down<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T4")) {<br>
pen_down();<br>
}</p>
<p>// ----------------------------------<br>
// T5   ABC test pattern<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T5")) {<br>
abc();<br>
}</p>
<p>// ----------------------------------<br>
// T6   target test pattern<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T6")) {<br>
target();<br>
}</p>
<p>// ----------------------------------<br>
// T7   radial line test pattern<br>
// ----------------------------------<br>
if (INPUT_STRING.startsWith("T7")) {<br>
radials();<br>
}<br>
}</p>
<p>// -------------------------------<br>
// MOVE_TO<br>
// -------------------------------<br>
/*<br>
Assume that our sheet of paper has been<br>
"scaled" to match the stepping motors.<br>
*/<br>
void move_to(float x, float y) {                        //x,y are absolute co-ordinates</p>
<p>// ----- apply scale factor<br>
THIS_X = round(x * STEPS_PER_MM * SCALE_FACTOR);      //scale x and y<br>
THIS_Y = round(y * STEPS_PER_MM * SCALE_FACTOR);</p>
<p>// ----- draw a line between these "scaled" co-ordinates<br>
draw_line(LAST_X, LAST_Y, THIS_X, THIS_Y);</p>
<p>// ----- remember last "scaled" co-ordinate<br>
LAST_X = THIS_X;<br>
LAST_Y = THIS_Y;<br>
}</p>
<p>// ------------------------------------------------------------------------<br>
// DRAW LINE<br>
// ------------------------------------------------------------------------<br>
/*<br>
This routine assumes that motor1 controls the x-axis and that motor2 controls<br>
the y-axis.</p>
<p>The algorithm automatically maps all "octants" to "octant 0" and<br>
automatically swaps the XY coordinates if dY is greater than dX. A swap<br>
flag determines which motor moves for any combination X,Y inputs. The swap<br>
algorithm is further optimised by realising that dY is always positive<br>
in quadrants 0,1 and that dX is always positive in "quadrants" 0,3.</p>
<p>Each intermediate XY co-ordinate is plotted which results in a straight line<br>
*/<br>
void draw_line(int x1, int y1, int x2, int y2) {          //these are "scaled" co-ordinates</p>
<p>// ----- locals<br>
int<br>
x = x1,                               //current "scaled" X-axis position<br>
y = y1,                               //current "scaled" Y-axis position<br>
dy,                                   //line slope<br>
dx,<br>
slope,<br>
longest,                              //axis lengths<br>
shortest,<br>
maximum,<br>
error,                                //bresenham thresholds<br>
threshold;</p>
<p>// ----- find longest and shortest axis<br>
dy = y2 - y1;                         //vertical distance<br>
dx = x2 - x1;                         //horizontal distance<br>
longest = max(abs(dy), abs(dx));      //longest axis<br>
shortest = min(abs(dy), abs(dx));     //shortest axis</p>
<p>// ----- scale Bresenham values by 2*longest<br>
error = -longest;                     //add offset to so we can test at zero<br>
threshold = 0;                        //test now done at zero<br>
maximum = (longest << 1);             //multiply by two<br>
slope = (shortest << 1);              //multiply by two ... slope equals (shortest*2/longest*2)</p>
<p>// ----- initialise the swap flag<br>
/*<br>
The XY axes are automatically swapped by using "longest" in<br>
the "for loop". XYswap is used to decode the motors.<br>
*/<br>
bool XYswap = true;                    //used for motor decoding<br>
if (abs(dx) >= abs(dy)) XYswap = false;</p>
<p>// ----- pretend we are always in octant 0<br>
/*<br>
The current X-axis and Y-axis positions will now be incremented (decremented) each time<br>
through the loop. These intermediate steps are parsed to the plot(x,y) function which calculates<br>
the number of steps required to reach each of these intermediate co-ordinates. This effectively<br>
linearises the plotter and eliminates unwanted curves.<br>
*/<br>
for (int i = 0; i < longest; i++) {</p>
<p>// ----- move left/right along X axis<br>
if (XYswap) {   //swap<br>
if (dy < 0) {<br>
y--;<br>
down();                         //move pen 1 step down<br>
} else {<br>
y++;<br>
up();                           //move pen 1 step up<br>
}<br>
} else {    //no swap<br>
if (dx < 0) {<br>
x--;<br>
left();                         //move pen 1 step left<br>
} else {<br>
x++;<br>
right();                        //move pen 1 step right<br>
}<br>
}</p>
<p>// ----- move up/down Y axis<br>
error += slope;<br>
if (error > threshold) {<br>
error -= maximum;</p>
<p>// ----- move up/down along Y axis<br>
if (XYswap) {  //swap<br>
if (dx < 0) {<br>
x--;<br>
left();                         //move pen 1 step left<br>
} else {<br>
x++;<br>
right();                        //move pen 1 step right<br>
}<br>
} else {  //no swap<br>
if (dy < 0) {<br>
y--;<br>
down();                         //move pen 1 step down<br>
} else {<br>
y++;<br>
up();                           //move pen 1 step up<br>
}<br>
}<br>
}<br>
}<br>
}</p>
<p>//--------------------------------------------------------------------<br>
// LEFT()           (move the pen 1 step left)<br>
//--------- -----------------------------------------------------------<br>
void left() {<br>
DIRECTION1 = CCW;<br>
DIRECTION2 = CCW;<br>
step_motors();<br>
}</p>
<p>//--------------------------------------------------------------------<br>
// RIGHT()           (move the pen 1 step right)<br>
//--------- -----------------------------------------------------------<br>
void right() {<br>
DIRECTION1 = CW;<br>
DIRECTION2 = CW;<br>
step_motors();<br>
}</p>
<p>//--------------------------------------------------------------------<br>
// UP()               (move the pen 1 step up)<br>
//--------- -----------------------------------------------------------<br>
void up() {<br>
DIRECTION1 = CW;<br>
DIRECTION2 = CCW;<br>
step_motors();<br>
}</p>
<p>//--------------------------------------------------------------------<br>
// DOWN()             (move the pen 1 step down)<br>
//--------- -----------------------------------------------------------<br>
void down() {<br>
DIRECTION1 = CCW;<br>
DIRECTION2 = CW;<br>
step_motors();<br>
}</p>
<p>//----------------------------------------------------------------------------------------<br>
// STEP MOTORS<br>
//----------------------------------------------------------------------------------------<br>
void step_motors() {</p>
<p>// ----- locals<br>
enum {dir1, step1, dir2, step2};                                //define bit positions<br>
byte pattern = PORTB;                                           //read current state PORTB</p>
<p>// ----- set motor directions<br>
//(DIRECTION1 == CW) ? SET(pattern, dir1) : CLR(pattern, dir1); //normal motor direction<br>
//(DIRECTION2 == CW) ? SET(pattern, dir2) : CLR(pattern, dir2); //normal motor direction<br>
(DIRECTION1 == CCW) ? SET(pattern, dir1) : CLR(pattern, dir1);  //motor windings reversed<br>
(DIRECTION2 == CCW) ? SET(pattern, dir2) : CLR(pattern, dir2);  //motor windings reversed<br>
PORTB = pattern;<br>
delayMicroseconds(PULSE_WIDTH);                                 //wait for direction lines to stabilise</p>
<p>// ----- create leading edge of step pulse(s)<br>
pattern = SET(pattern, step1);                                  //prepare step pulse<br>
pattern = SET(pattern, step2);<br>
PORTB = pattern;                                                //step the motors<br>
delayMicroseconds(PULSE_WIDTH);                                 //mandatory delay</p>
<p>// ----- create trailing-edge of step-pulse(s)<br>
pattern = CLR(pattern, step1);<br>
pattern = CLR(pattern, step2);<br>
PORTB = pattern;</p>
<p>// ----- determines plotting speed<br>
delayMicroseconds(DELAY);<br>
}</p>
<p>//----------------------------------------------------------------------------<br>
// DRAW ARC CLOCKWISE (G02)<br>
//----------------------------------------------------------------------------<br>
void draw_arc_cw(float x, float y, float i, float j) {</p>
<p>// ----- inkscape sometimes produces some crazy values for i,j<br>
if ((i < -100) || (i > 100) || (j < -100) || (j > 100)) {<br>
move_to(x, y);<br>
} else {</p>
<p>// ----- variables<br>
float<br>
thisX = LAST_X / (STEPS_PER_MM * SCALE_FACTOR), //current unscaled X co-ordinate<br>
thisY = LAST_Y / (STEPS_PER_MM * SCALE_FACTOR), //current unscaled Y co-ordinate<br>
nextX = x,                    //next X co-ordinate<br>
nextY = y,                    //next Y co-ordinate<br>
newX,                         //interpolated X co-ordinate<br>
newY,                         //interpolated Y co-ordinate<br>
I = i,                        //horizontal distance thisX from circle center<br>
J = j,                        //vertical distance thisY from circle center<br>
circleX = thisX + I,          //circle X co-ordinate<br>
circleY = thisY + J,          //circle Y co-ordinate<br>
delta_x,                      //horizontal distance between thisX and nextX<br>
delta_y,                      //vertical distance between thisY and nextY<br>
chord,                        //line_length between lastXY and nextXY<br>
radius,                       //circle radius<br>
alpha,                        //interior angle of arc<br>
beta,                         //fraction of alpha<br>
arc,                          //subtended by alpha<br>
current_angle,                //measured CCW from 3 o'clock<br>
next_angle;                   //measured CCW from 3 o'clock</p>
<p>// ----- calculate arc<br>
delta_x = thisX - nextX;<br>
delta_y = thisY - nextY;<br>
chord = sqrt(delta_x * delta_x + delta_y * delta_y);<br>
radius = sqrt(I * I + J * J);<br>
alpha = 2 * asin(chord / (2 * radius)); //see construction lines<br>
arc = alpha * radius;         //radians</p>
<p>// ----- sub-divide alpha<br>
int segments = 1;<br>
if (arc > ARC_MAX) {<br>
segments = (int)(arc / ARC_MAX);<br>
beta = alpha / segments;<br>
} else {<br>
beta = alpha;<br>
}</p>
<p>// ----- calculate current angle<br>
/*<br>
atan2() angles between 0 and PI are CCW +ve from 3 o'clock.<br>
atan2() angles between 2*PI and PI are CW -ve relative to 3 o'clock<br>
*/<br>
current_angle = atan2(-J, -I);<br>
if (current_angle <= 0) current_angle += 2 * PI;        //angles now 360..0 degrees CW</p>
<p>// ----- plot intermediate CW co-ordinates<br>
next_angle = current_angle;                             //initialise angle<br>
for (int segment = 1; segment < segments; segment++) {<br>
next_angle -= beta;                                   //move CW around circle<br>
if (next_angle < 0) next_angle += 2 * PI;             //check if angle crosses zero<br>
newX = circleX + radius * cos(next_angle);            //standard circle formula<br>
newY = circleY + radius * sin(next_angle);<br>
move_to(newX, newY);<br>
}</p>
<p>// ----- draw final line<br>
move_to(nextX, nextY);<br>
}<br>
}</p>
<p>//----------------------------------------------------------------------------<br>
// DRAW ARC COUNTER-CLOCKWISE (G03)<br>
//----------------------------------------------------------------------------<br>
/*<br>
We know the start and finish co-ordinates which allows us to calculate the<br>
chord length. We can also calculate the radius using the biarc I,J values.<br>
If we bisect the chord the center angle becomes 2*asin(chord/(2*radius)).<br>
The arc length may now be calculated using the formula arc_length = radius*angle.<br>
*/<br>
void draw_arc_ccw(float x, float y, float i, float j) {</p>
<p>// ----- inkscape sometimes produces some crazy values for i,j<br>
if ((i < -100) || (i > 100) || (j < -100) || (j > 100)) {<br>
move_to(x, y);<br>
} else {</p>
<p>// ----- variables<br>
float<br>
thisX = LAST_X / SCALE_FACTOR,  //current unscaled X co-ordinate<br>
thisY = LAST_Y / SCALE_FACTOR,  //current unscaled Y co-ordinate<br>
nextX = x,                      //next X co-ordinate<br>
nextY = y,                      //next Y co-ordinate<br>
newX,                           //interpolated X co-ordinate<br>
newY,                           //interpolated Y co-ordinate<br>
I = i,                          //horizontal distance thisX from circle center<br>
J = j,                          //vertical distance thisY from circle center<br>
circleX = thisX + I,            //circle X co-ordinate<br>
circleY = thisY + J,            //circle Y co-ordinate<br>
delta_x,                        //horizontal distance between thisX and nextX<br>
delta_y,                        //vertical distance between thisY and nextY<br>
chord,                          //line_length between lastXY and nextXY<br>
radius,                         //circle radius<br>
alpha,                          //interior angle of arc<br>
beta,                           //fraction of alpha<br>
arc,                            //subtended by alpha<br>
current_angle,                  //measured CCW from 3 o'clock<br>
next_angle;                     //measured CCW from 3 o'clock</p>
<p>// ----- calculate arc<br>
delta_x = thisX - nextX;<br>
delta_y = thisY - nextY;<br>
chord = sqrt(delta_x * delta_x + delta_y * delta_y);<br>
radius = sqrt(I * I + J * J);<br>
alpha = 2 * asin(chord / (2 * radius));     //see construction lines<br>
arc = alpha * radius;                       //radians</p>
<p>// ----- sub-divide alpha<br>
int segments = 1;<br>
if (arc > ARC_MAX) {<br>
segments = (int)(arc / ARC_MAX);<br>
beta = alpha / segments;<br>
} else {<br>
beta = alpha;<br>
}</p>
<p>// ----- calculate current angle<br>
/*<br>
tan2() angles between 0 and PI are CCW +ve from 3 o'clock.<br>
atan2() angles between 2*PI and PI are CW -ve relative to 3 o'clock<br>
*/<br>
current_angle = atan2(-J, -I);<br>
if (current_angle <= 0) current_angle += 2 * PI;        //angles now 360..0 degrees CW</p>
<p>// ----- plot intermediate CCW co-ordinates<br>
next_angle = current_angle;                             //initialise angle<br>
for (int segment = 1; segment < segments; segment++) {<br>
next_angle += beta;                                   //move CCW around circle<br>
if (next_angle > 2 * PI) next_angle -= 2 * PI;        //check if angle crosses zero<br>
newX = circleX + radius * cos(next_angle);            //standard circle formula<br>
newY = circleY + radius * sin(next_angle);<br>
move_to(newX, newY);<br>
}</p>
<p>// ----- draw final line<br>
move_to(nextX, nextY);<br>
}<br>
}</p>
<p>//---------------------------------------------------------------------------<br>
// PEN_UP<br>
// Raise the pen<br>
// Changing the value in OCR2B changes the pulse-width to the SG-90 servo<br>
//---------------------------------------------------------------------------<br>
void pen_up() {<br>
OCR2B = 148;                //1mS pulse<br>
delay(250);                 //give pen-lift time to respond<br>
}</p>
<p>//---------------------------------------------------------------------------<br>
// PEN_DOWN<br>
// Lower the pen<br>
// Changing the value in OCR2B changes the pulse-width to the SG-90 servo<br>
//---------------------------------------------------------------------------<br>
void pen_down() {<br>
OCR2B = 140;                //2mS pulse<br>
delay(250);                 //give pen-lift time to respond<br>
}</p>
<p>// ----------------------------------------<br>
// ABC<br>
// ----------------------------------------<br>
void abc() {<br>
process(F("T2 S3"));<br>
process(F("G00 X50.600359 Y23.420344"));<br>
process(F("G02 X50.752716 Y22.976260 I-3.135884 J-1.324038"));<br>
process(F("G02 X50.785093 Y22.730023 I-0.920147 J-0.246237"));<br>
process(F("G02 X50.395324 Y21.695296 I-1.568337 J0.000000"));<br>
process(F("G02 X48.616901 Y20.260423 I-5.033669 J4.419324"));<br>
process(F("G02 X46.381993 Y19.348409 I-4.838496 J8.662483"));<br>
process(F("G02 X44.183295 Y19.054795 I-2.198698 J8.085548"));<br>
process(F("G02 X41.865268 Y19.467670 I0.000000 J6.713555"));<br>
process(F("G02 X40.245550 Y20.503495 I1.545608 J4.201152"));<br>
process(F("G02 X39.219290 Y22.122336 I3.157768 J3.136575"));<br>
process(F("G02 X38.806572 Y24.470408 I6.473066 J2.348072"));<br>
process(F("G02 X39.490101 Y28.182255 I10.420197 J0.000000"));<br>
process(F("G02 X41.412290 Y31.305554 I9.193131 J-3.504638"));<br>
process(F("G02 X44.336973 Y33.441702 I6.709781 J-6.116396"));<br>
process(F("G02 X47.644620 Y34.164064 I3.307648 J-7.211572"));<br>
process(F("G02 X49.085783 Y34.013721 I-0.000000 J-6.982526"));<br>
process(F("G02 X50.133662 Y33.639032 I-0.850084 J-4.030028"));<br>
process(F("G02 X50.927697 Y32.982080 I-1.126976 J-2.170474"));<br>
process(F("G02 X51.144836 Y32.355618 I-0.795126 J-0.626462"));<br>
process(F("G02 X50.979946 Y31.746676 I-1.206859 J0.000000"));<br>
process(F("G02 X50.269784 Y30.858305 I-3.386486 J1.979114"));<br>
process(F("G03 X48.739474 Y32.638692 I-4.305181 J-2.152593"));<br>
process(F("G03 X46.934854 Y33.211228 I-1.804620 J-2.557788"));<br>
process(F("G03 X44.865511 Y32.640761 I-0.000000 J-4.038459"));<br>
process(F("G03 X42.812375 Y30.751354 I3.496454 J-5.859673"));<br>
process(F("G03 X41.521944 Y28.150097 I7.294760 J-5.239488"));<br>
process(F("G03 X41.052544 Y25.024608 I10.170799 J-3.125489"));<br>
process(F("G03 X41.358190 Y23.047268 I6.548917 J0.000000"));<br>
process(F("G03 X42.102608 Y21.709126 I3.656766 J1.158154"));<br>
process(F("G03 X43.314946 Y20.829195 I2.521185 J2.198476"));<br>
process(F("G03 X44.961119 Y20.493773 I1.646173 J3.871797"));<br>
process(F("G03 X47.727663 Y21.168894 I0.000000 J6.006005"));<br>
process(F("G03 X50.600359 Y23.420344 I-4.544548 J8.756936"));<br>
process(F("G01 X50.600359 Y23.420344"));<br>
process(F("G00 X23.454230 Y28.699836"));<br>
process(F("G02 X23.258509 Y29.247403 I2.678175 J1.266042"));<br>
process(F("G02 X23.201437 Y29.711010 I1.854425 J0.463606"));<br>
process(F("G02 X23.715287 Y31.069809 I2.053497 J0.000000"));<br>
process(F("G02 X25.904382 Y32.773699 I5.614239 J-4.954789"));<br>
process(F("G02 X28.704691 Y33.800933 I5.587639 J-10.901752"));<br>
process(F("G02 X31.854753 Y34.164064 I3.150061 J-13.481375"));<br>
process(F("G02 X33.604787 Y33.959798 I0.000000 J-7.598769"));<br>
process(F("G02 X34.771598 Y33.473743 I-0.900681 J-3.805687"));<br>
process(F("G02 X35.615458 Y32.630428 I-1.363090 J-2.207829"));<br>
process(F("G02 X35.889723 Y31.665300 I-1.560988 J-0.965128"));<br>
process(F("G02 X35.303747 Y29.921282 I-2.888311 J0.000000"));<br>
process(F("G02 X32.943707 Y27.776167 I-6.918162 J5.240505"));<br>
process(F("G02 X34.567939 Y27.139583 I-2.104158 J-7.759112"));<br>
process(F("G02 X35.636931 Y26.366360 I-2.132406 J-4.073640"));<br>
process(F("G02 X36.379807 Y25.321353 I-2.380949 J-2.479122"));<br>
process(F("G02 X36.618935 Y24.227336 I-2.383015 J-1.094017"));<br>
process(F("G02 X36.026166 Y22.197076 I-3.773251 J0.000000"));<br>
process(F("G02 X34.061832 Y20.221533 I-5.518247 J3.522571"));<br>
process(F("G02 X31.369264 Y19.027768 I-5.128625 J7.934286"));<br>
process(F("G02 X27.868393 Y18.568653 I-3.500871 J13.117974"));<br>
process(F("G02 X25.793101 Y19.167138 I0.000000 J3.897363"));<br>
process(F("G02 X25.194616 Y20.250700 I0.681659 J1.083563"));<br>
process(F("G02 X25.225337 Y20.646314 I2.562654 J-0.000000"));<br>
process(F("G02 X25.486301 Y22.117485 I35.898712 J-5.609165"));<br>
process(F("G01 X26.857219 Y29.010969"));<br>
process(F("G03 X26.998207 Y29.839815 I-14.262137 J2.852427"));<br>
process(F("G03 X27.022507 Y30.187429 I-2.474194 J0.347614"));<br>
process(F("G03 X26.964582 Y30.506866 I-0.909758 J0.000000"));<br>
process(F("G03 X26.789159 Y30.809689 I-0.989871 J-0.371202"));<br>
process(F("G02 X28.084797 Y31.229045 I4.918140 J-12.983875"));<br>
process(F("G02 X28.587881 Y31.295831 I0.503083 J-1.861405"));<br>
process(F("G02 X29.002366 Y31.107501 I0.000000 J-0.550275"));<br>
process(F("G02 X29.190696 Y30.605510 I-0.574861 J-0.501991"));<br>
process(F("G02 X29.174585 Y30.432163 I-0.940630 J0.000000"));<br>
process(F("G02 X28.869843 Y28.894292 I-74.974595 J14.057713"));<br>
process(F("G01 X27.596154 Y22.506398"));<br>
process(F("G03 X27.407065 Y21.395624 I25.119200 J-4.847563"));<br>
process(F("G03 X27.382252 Y21.057695 I2.288700 J-0.337928"));<br>
process(F("G03 X27.843772 Y20.294140 I0.862387 J0.000000"));<br>
process(F("G03 X29.715731 Y19.832619 I1.871959 J3.565639"));<br>
process(F("G03 X31.526735 Y20.128159 I0.000000 J5.696494"));<br>
process(F("G03 X32.992323 Y20.931299 I-1.502222 J4.480076"));<br>
process(F("G03 X34.026640 Y22.200410 I-2.503366 J3.096265"));<br>
process(F("G03 X34.363240 Y23.585630 I-2.682024 J1.385220"));<br>
process(F("G03 X34.148489 Y24.695436 I-2.975045 J-0.000000"));<br>
process(F("G03 X33.604861 Y25.471860 I-1.940658 J-0.780263"));<br>
process(F("G03 X32.768796 Y25.999000 I-1.964159 J-2.188645"));<br>
process(F("G03 X31.076926 Y26.521924 I-3.621282 J-8.717909"));<br>
process(F("G02 X30.432077 Y26.335937 I-1.252000 J3.130013"));<br>
process(F("G02 X29.696283 Y26.269132 I-0.735794 J4.018591"));<br>
process(F("G02 X29.445459 Y26.286414 I0.000000 J1.828837"));<br>
process(F("G02 X29.064300 Y26.356635 I0.596050 J4.304919"));<br>
process(F("G02 X29.438640 Y27.338746 I5.106656 J-1.384047"));<br>
process(F("G02 X29.764344 Y27.756722 I1.202868 J-0.601434"));<br>
process(F("G02 X30.234517 Y28.000252 I0.776340 J-0.923211"));<br>
process(F("G02 X31.135261 Y28.116468 I0.900744 J-3.432550"));<br>
process(F("G02 X31.378139 Y28.111033 I0.000000 J-5.429361"));<br>
process(F("G02 X31.786692 Y28.087298 I-0.689212 J-15.391372"));<br>
process(F("G03 X33.457741 Y29.806863 I-4.247308 J5.799206"));<br>
process(F("G03 X33.857653 Y31.091652 I-1.863851 J1.284789"));<br>
process(F("G03 X33.240526 Y32.234356 I-1.366508 J-0.000000"));<br>
process(F("G03 X31.174154 Y32.851482 I-2.066372 J-3.150932"));<br>
process(F("G03 X27.293198 Y31.874110 I-0.000000 J-8.193950"));<br>
process(F("G03 X23.454230 Y28.699836 I6.012387 J-11.179941"));<br>
process(F("G01 X23.454230 Y28.699836"));<br>
process(F("G00 X12.370209 Y25.345461"));<br>
process(F("G01 X14.334220 Y25.296848"));<br>
process(F("G03 X16.344033 Y25.341207 I0.000000 J45.552596"));<br>
process(F("G03 X17.416355 Y25.432967 I-0.576039 J13.043259"));<br>
process(F("G02 X17.057498 Y28.851447 I66.264688 J8.684258"));<br>
process(F("G02 X16.969105 Y31.091652 I28.343468 J2.240205"));<br>
process(F("G01 X16.978828 Y31.820863"));<br>
process(F("G02 X16.654582 Y31.415231 I-24.362686 J19.142120"));<br>
process(F("G02 X15.539850 Y30.051310 I-276.590024 J224.919481"));<br>
process(F("G03 X13.629409 Y27.498969 I29.639011 J-24.176118"));<br>
process(F("G03 X12.574388 Y25.724652 I13.226843 J-9.065587"));<br>
process(F("G01 X12.370209 Y25.345461"));<br>
process(F("G00 X11.670166 Y24.198168"));<br>
process(F("G01 X11.475709 Y23.828703"));<br>
process(F("G03 X10.453024 Y21.493002 I14.155155 J-7.589567"));<br>
process(F("G03 X10.250633 Y20.289593 I3.476515 J-1.203409"));<br>
process(F("G03 X10.316083 Y19.943208 I0.949331 J-0.000000"));<br>
process(F("G03 X10.532595 Y19.570105 I1.323570 J0.518696"));<br>
process(F("G03 X10.300257 Y19.489445 I3.137841 J-9.413445"));<br>
process(F("G03 X9.482530 Y19.190914 I42.222649 J-116.924015"));<br>
process(F("G02 X9.097875 Y19.086190 I-0.855158 J2.382242"));<br>
process(F("G02 X8.763041 Y19.054795 I-0.334835 J1.769854"));<br>
process(F("G02 X8.277401 Y19.249753 I0.000000 J0.702344"));<br>
process(F("G02 X8.082443 Y19.706223 I0.436907 J0.456470"));<br>
process(F("G02 X8.333756 Y20.987389 I3.391281 J0.000000"));<br>
process(F("G02 X9.764492 Y23.828703 I18.642339 J-7.606424"));<br>
process(F("G01 X10.065899 Y24.324564"));<br>
process(F("G01 X9.570035 Y24.324564"));<br>
process(F("G03 X8.016212 Y24.170112 I-0.000000 J-7.893143"));<br>
process(F("G03 X7.100438 Y23.828703 I0.608728 J-3.031721"));<br>
process(F("G02 X7.932520 Y24.978194 I1.964955 J-0.546467"));<br>
process(F("G02 X9.560313 Y25.471860 I1.627793 J-2.436874"));<br>
process(F("G01 X10.765943 Y25.442689"));<br>
process(F("G01 X11.028459 Y25.831603"));<br>
process(F("G02 X12.621837 Y28.077029 I38.056380 J-25.317154"));<br>
process(F("G02 X15.695415 Y32.005598 I119.673321 J-90.461712"));<br>
process(F("G02 X16.806236 Y33.260000 I14.322595 J-11.564166"));<br>
process(F("G02 X17.280236 Y33.639032 I1.733405 J-1.681816"));<br>
process(F("G02 X17.834414 Y33.882572 I1.177026 J-1.926044"));<br>
process(F("G02 X19.312306 Y34.222402 I3.908941 J-13.616125"));<br>
process(F("G03 X19.095228 Y32.467101 I23.799291 J-3.834329"));<br>
process(F("G03 X19.030344 Y30.965256 I17.348913 J-1.501845"));<br>
process(F("G03 X19.256050 Y26.994264 I35.045048 J-0.000000"));<br>
process(F("G03 X19.954013 Y22.866141 I38.580488 J4.399934"));<br>
process(F("G03 X20.720782 Y20.795305 I8.056900 J1.805858"));<br>
process(F("G03 X21.499942 Y19.959018 I1.953184 J1.038650"));<br>
process(F("G02 X20.521336 Y19.212088 I-3.388359 J3.424790"));<br>
process(F("G02 X19.934567 Y19.054795 I-0.586769 J1.015804"));<br>
process(F("G02 X18.944735 Y19.694699 I-0.000000 J1.085511"));<br>
process(F("G02 X17.562198 Y24.324564 I16.634711 J7.488692"));<br>
process(F("G02 X15.955536 Y24.193605 I-3.198664 J29.321420"));<br>
process(F("G02 X14.324497 Y24.149555 I-1.631039 J30.174575"));<br>
process(F("G01 X11.670166 Y24.198168"));<br>
process(F("G00 X0.0000 Y0.0000"));<br>
process(F("T2 S1"));<br>
}</p>
<p>//----------------------------------------------------------------------------<br>
// TARGET test pattern<br>
//----------------------------------------------------------------------------<br>
void target() {<br>
process(F("T2 S3"));<br>
process(F("G00 X51.309849 Y6.933768"));<br>
process(F("G01 X7.893822 Y50.349788"));<br>
process(F("G00 X7.893823 Y50.349788"));<br>
process(F("G01 X51.309852 Y50.349788"));<br>
process(F("G01 X51.309852 Y6.933760"));<br>
process(F("G01 X7.893823 Y6.933760"));<br>
process(F("G01 X7.893823 Y50.349788"));<br>
process(F("G00 X43.948985 Y28.588440"));<br>
process(F("G02 X39.778044 Y18.518899 I-14.240483 J0.000001"));<br>
process(F("G02 X29.708503 Y14.347958 I-10.069542 J10.069542"));<br>
process(F("G02 X19.638962 Y18.518898 I-0.000000 J14.240483"));<br>
process(F("G02 X15.468020 Y28.588440 I10.069542 J10.069543"));<br>
process(F("G02 X16.552012 Y34.038037 I14.240483 J0.000001"));<br>
process(F("G02 X19.638961 Y38.657983 I13.156491 J-5.449596"));<br>
process(F("G02 X24.258906 Y41.744932 I10.069543 J-10.069542"));<br>
process(F("G02 X29.708503 Y42.828924 I5.449597 J-13.156491"));<br>
process(F("G02 X39.778045 Y38.657982 I-0.000001 J-14.240483"));<br>
process(F("G02 X43.948985 Y28.588440 I-10.069543 J-10.069541"));<br>
process(F("G01 X43.948985 Y28.588440"));<br>
process(F("G00 X51.309849 Y50.349788"));<br>
process(F("G01 X7.893822 Y6.933768"));<br>
process(F("G00 X0.0000 Y0.0000"));<br>
process(F("T2 S1"));<br>
}</p>
<p>//----------------------------------------------------------------------------<br>
// RADIALS test pattern<br>
//----------------------------------------------------------------------------<br>
void radials() {</p>
<p>// ----- move to the centre of the square<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 0 radials<br>
pen_down();<br>
move_to(150, 100);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(150, 125);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(150, 150);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 1 radials<br>
pen_down();<br>
move_to(125, 150);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(100, 150);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 2 radials<br>
pen_down();<br>
move_to(75, 150);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(50, 150);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 3 radials<br>
pen_down();<br>
move_to(50, 125);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(50, 100);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 4 radials<br>
pen_down();<br>
move_to(50, 75);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(50, 50);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 5 radials<br>
pen_down();<br>
move_to(75, 50);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(100, 50);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 6 radials<br>
pen_down();<br>
move_to(125, 50);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>pen_down();<br>
move_to(150, 50);<br>
pen_up();<br>
move_to(100, 100);</p>
<p>// ----- draw octant 7 radials<br>
pen_down();<br>
move_to(150, 75);<br>
pen_up();<br>
move_to(100, 100);<br>
pen_up();</p>
<p>// ----- draw box<br>
move_to(50, 50);<br>
pen_down();<br>
move_to(50, 150);<br>
move_to(150, 150);<br>
move_to(150, 50);<br>
move_to(50, 50);<br>
pen_up();</p>
<p>// home --------------<br>
move_to(0.0000, 0.0000);<br>
}</p>
<p>

Arayüz programı olarak LaserGRBL veya EleksMaker programlarını kullanabilirsiniz.Bu programlar sayesinde herhangi bir tahta vb.üzerine işlemek istediğiniz resim ,yazı vb. yükleyebilirsiniz.Programlar içerisinde kalibrasyon ayarlarını da yapabilirsiniz.LaserGRBL’de hız ayarı yapabiliyoruz.Fazla hızlı yapıldığında fotoğraf bozulabilmektedir.LaserGRBL’de laserin nerede olduğu göz kararı ile yapılabiliyor.Fakat Eleksmaker programında hafif lazer ışığı göndererek lazerimizin konumunu görebiliyoruz.Fotoğraf işlemek için LaserGRBL programı daha kullanışlıdır.Diğer işlemeler için ise Eleksmaker daha kullanışlı görünüyor.LaserGRBL’de lazer şiddetini istediğimiz ayarda yapabilirken Eleksmaker programında 0-1000 arasına izin vermektedir.



Temiz bir görüntü alabilmek için fotoğrafta temizleme işlemi yapılabilir.Resmi temizlemek için Paint.net programını kullanabilirsiniz.

Çalışma Videosu

https://www.youtube.com/watch?v=8zgNmdNpEvo&feature=youtu.be

 

Buna Benzer Yazılar Göster !
Daha Fazlasını Yükle - Konuk Yazar
Daha Fazla Göster -  Arduino

9 Yorumlar

  1. Ufuk SARNIK

    11 Temmuz 2018 at 22:48

    Merhaba

    Fiyat bilgisi alabilirmiyim

    Reply

    • Bilal Kaya

      12 Temmuz 2018 at 07:02

      Merhaba makine komple fiyatı 1250 Tl’dir.

      Reply

  2. mustafa

    11 Temmuz 2018 at 23:49

    hem x hem y eksenleri aynı kayışa bağlı gördüm..sadece x veya sadece y de hareket gerekince nasıl sağlanıyor çözemedim?

    Reply

    • Bilal Kaya

      12 Temmuz 2018 at 07:03

      Bu SİSTEM CORE X Y sistemidir.Detaylı incelediğinizde sistemi anlayacaksınız.

      Reply

  3. Sukru Kaya

    14 Temmuz 2018 at 13:37

    Okulda yapmak istiyoruz bağlantı şemasını gönderebilir misiniz saygılar…

    Reply

  4. Mehmet Topuz

    25 Temmuz 2018 at 16:29

    Bu makine ile pcb çizimi yapılabilir mi? Yapılabilirse minimum yol kalınğı ne kadara kadar indirilebilir.?

    Reply

  5. arduino

    26 Şubat 2019 at 18:30

    Merhaba arduino’da kullanılan kütüphaneler nelerdir?

    Reply

  6. Uğur

    1 Mart 2019 at 22:40

    Kayışı lazer ile nasıl bağladınız.

    Reply

  7. MUhammet Ali

    23 Eylül 2019 at 10:58

    lazer sürücü arduinoya nasıl bağlandı ve lazer sürücüyü neye göre belirlediniz nereden aldınız bahsedermisiniz.

    Reply

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bak Bakalım ?

Can Kurtaran Drone Projesi – Bölüm 2

Tekrar Merhabalar, İlk bölümdeki yazımızda Can Kurtaran Drone projemizin elemanlarını tanı…