📄 my first cnc machine arduino mega controlled.txt
字号:
// Arduino G-code Interpreter
// v1.0 Carlos guilarte y diego colonnello...
// Modificado para manejar tres ejes en un cnc chimbo... jejeje
#include <HardwareSerial.h>
//our command string
#define COMMAND_SIZE 128
char palabra[COMMAND_SIZE];
byte serial_count;
int no_data = 0;
void setup()
{
//Do startup stuff here
Serial.begin(19200);
Serial.println("start");
//other initialization.
init_process_string();
init_steppers();
}
void loop()
{
char c;
//keep it hot!
//read in characters if we got them.
if (Serial.available() > 0)
{
c = Serial.read();
no_data = 0;
//newlines are ends of commands.
if (c != '\n')
{
palabra[serial_count] = c;
serial_count++;
}
}
//mark no data.
else
{
no_data++;
delayMicroseconds(100);
}
//if theres a pause or we got a real command, do it
if (serial_count && (c == '\n' || no_data > 100))
{
//process our command!
process_string(palabra, serial_count);
//clear command.
init_process_string();
}
//no data? turn off steppers
if (no_data > 1000)
disable_steppers();
}
// define the parameters of our machine.
#define X_STEPS_PER_INCH 4800
#define X_STEPS_PER_MM 188.97
#define X_MOTOR_STEPS 200
#define Y_STEPS_PER_INCH 4800
#define Y_STEPS_PER_MM 188.97
#define Y_MOTOR_STEPS 200
#define Z_STEPS_PER_INCH 4800
#define Z_STEPS_PER_MM 188.97
#define Z_MOTOR_STEPS 200
//our maximum feedrates
#define FAST_XY_FEEDRATE 100
#define FAST_Z_FEEDRATE 100
// Units in curve section
#define CURVE_SECTION_INCHES 0.019685
#define CURVE_SECTION_MM 0.5
// Set to one if sensor outputs inverting (ie: 1 means open, 0 means closed)
// RepRap opto endstops are *not* inverting.
#define SENSORS_INVERTING 0
// How many temperature samples to take. each sample takes about 100 usecs.
/****************************************************************************************
* digital i/o pin assignment
*
* this uses the undocumented feature of Arduino - pins 14-19 correspond to analog 0-5
****************************************************************************************/
//cartesian bot pins
#define X_STEP_PIN 8
#define X_DIR_PIN 9
#define X_MIN_PIN 4
#define X_MAX_PIN 2
#define X_ENABLE_PIN 15
#define Y_STEP_PIN 10
#define Y_DIR_PIN 11
#define Y_MIN_PIN 3
#define Y_MAX_PIN 5
#define Y_ENABLE_PIN 15
#define Z_STEP_PIN 12
#define Z_DIR_PIN 13
#define Z_MIN_PIN 7
#define Z_MAX_PIN 6
#define Z_ENABLE_PIN 15
// our point structure to make things nice.
struct LongPoint {
long x;
long y;
long z;
};
struct FloatPoint {
float x;
float y;
float z;
};
FloatPoint current_units;
FloatPoint target_units;
FloatPoint delta_units;
FloatPoint current_steps;
FloatPoint target_steps;
FloatPoint delta_steps;
boolean abs_mode = false; //0 = incremental; 1 = absolute
//default to inches for units
float x_units = X_STEPS_PER_INCH;
float y_units = Y_STEPS_PER_INCH;
float z_units = Z_STEPS_PER_INCH;
float curve_section = CURVE_SECTION_INCHES;
//our direction vars
byte x_direction = 1;
byte y_direction = 1;
byte z_direction = 1;
//init our string processing
void init_process_string()
{
//init our command
for (byte i=0; i<COMMAND_SIZE; i++)
palabra = 0;
serial_count = 0;
}
//our feedrate variables.
float feedrate = 0.0;
long feedrate_micros = 0;
//Read the string and execute instructions
void process_string(char instruction[], int size)
{
//the character / means delete block... used for comments and stuff.
if (instruction[0] == '/')
{
Serial.println("ok");
return;
}
//init baby!
FloatPoint fp;
fp.x = 0.0;
fp.y = 0.0;
fp.z = 0.0;
byte code = 0;;
//did we get a gcode?
if (
has_command('G', instruction, size) ||
has_command('X', instruction, size) ||
has_command('Y', instruction, size) ||
has_command('Z', instruction, size)
)
{
//which one?
code = (int)search_string('G', instruction, size);
// Get co-ordinates if required by the code type given
switch (code)
{
case 0:
case 1:
case 2:
case 3:
if(abs_mode)
{
//we do it like this to save time. makes curves better.
//eg. if only x and y are specified, we dont have to waste time looking up z.
if (has_command('X', instruction, size))
fp.x = search_string('X', instruction, size);
else
fp.x = current_units.x;
if (has_command('Y', instruction, size))
fp.y = search_string('Y', instruction, size);
else
fp.y = current_units.y;
if (has_command('Z', instruction, size))
fp.z = search_string('Z', instruction, size);
else
fp.z = current_units.z;
}
else
{
fp.x = search_string('X', instruction, size) + current_units.x;
fp.y = search_string('Y', instruction, size) + current_units.y;
fp.z = search_string('Z', instruction, size) + current_units.z;
}
break;
}
//do something!
switch (code)
{
//Rapid Positioning
//Linear Interpolation
//these are basically the same thing.
case 0:
case 1:
//set our target.
set_target(fp.x, fp.y, fp.z);
//do we have a set speed?
if (has_command('G', instruction, size))
{
//adjust if we have a specific feedrate.
if (code == 1)
{
//how fast do we move?
feedrate = search_string('F', instruction, size);
if (feedrate > 0)
feedrate_micros = calculate_feedrate_delay(feedrate);
//nope, no feedrate
else
feedrate_micros = getMaxSpeed();
}
//use our max for normal moves.
else
feedrate_micros = getMaxSpeed();
}
//nope, just coordinates!
else
{
//do we have a feedrate yet?
if (feedrate > 0)
feedrate_micros = calculate_feedrate_delay(feedrate);
//nope, no feedrate
else
feedrate_micros = getMaxSpeed();
}
//finally move.
dda_move(feedrate_micros);
break;
//Clockwise arc
case 2:
//Counterclockwise arc
case 3:
FloatPoint cent;
// Centre coordinates are always relative
cent.x = search_string('I', instruction, size) + current_units.x;
cent.y = search_string('J', instruction, size) + current_units.y;
float angleA, angleB, angle, radius, length, aX, aY, bX, bY;
aX = (current_units.x - cent.x);
aY = (current_units.y - cent.y);
bX = (fp.x - cent.x);
bY = (fp.y - cent.y);
if (code == 2) { // Clockwise
angleA = atan2(bY, bX);
angleB = atan2(aY, aX);
} else { // Counterclockwise
angleA = atan2(aY, aX);
angleB = atan2(bY, bX);
}
// Make sure angleB is always greater than angleA
// and if not add 2PI so that it is (this also takes
// care of the special case of angleA == angleB,
// ie we want a complete circle)
if (angleB <= angleA) angleB += 2 * M_PI;
angle = angleB - angleA;
radius = sqrt(aX * aX + aY * aY);
length = radius * angle;
int steps, s, step;
steps = (int) ceil(length / curve_section);
FloatPoint newPoint;
for (s = 1; s <= steps; s++) {
step = (code == 3) ? s : steps - s; // Work backwards for CW
newPoint.x = cent.x + radius * cos(angleA + angle * ((float) step / steps));
newPoint.y = cent.y + radius * sin(angleA + angle * ((float) step / steps));
set_target(newPoint.x, newPoint.y, fp.z);
// Need to calculate rate for each section of curve
if (feedrate > 0)
feedrate_micros = calculate_feedrate_delay(feedrate);
else
feedrate_micros = getMaxSpeed();
// Make step
dda_move(feedrate_micros);
}
break;
//Dwell
case 4:
delay((int)search_string('P', instruction, size));
break;
//Inches for Units
case 20:
x_units = X_STEPS_PER_INCH;
y_units = Y_STEPS_PER_INCH;
z_units = Z_STEPS_PER_INCH;
curve_section = CURVE_SECTION_INCHES;
calculate_deltas();
break;
//mm for Units
case 21:
x_units = X_STEPS_PER_MM;
y_units = Y_STEPS_PER_MM;
z_units = Z_STEPS_PER_MM;
curve_section = CURVE_SECTION_MM;
calculate_deltas();
break;
//go home.
case 28:
set_target(0.0, 0.0, 0.0);
dda_move(getMaxSpeed());
break;
//go home via an intermediate point.
case 30:
fp.x = search_string('X', instruction, size);
fp.y = search_string('Y', instruction, size);
fp.z = search_string('Z', instruction, size);
//set our target.
if(abs_mode)
{
if (!has_command('X', instruction, size))
fp.x = current_units.x;
if (!has_command('Y', instruction, size))
fp.y = current_units.y;
if (!has_command('Z', instruction, size))
fp.z = current_units.z;
set_target(fp.x, fp.y, fp.z);
}
else
set_target(current_units.x + fp.x, current_units.y + fp.y, current_units.z + fp.z);
//go there.
dda_move(getMaxSpeed());
//go home.
set_target(0.0, 0.0, 0.0);
dda_move(getMaxSpeed());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -