在 3D 打印过程中,G 代码控制着打印机的每一个动作,从移动喷头到控制温度。本文将介绍如何逐行读取 G 代码文件,并将这些指令转化为 X、Y、Z 三轴的运动控制,特别是 X 和 Y 轴的同步控制以及 Z 轴的独立控制。
1. 逐行读取 G 代码文件
G 代码文件是由一系列命令组成的文本文件,每一行指示打印机执行一个具体的操作。我们可以通过以下代码逐行读取这些命令:
void loop() {
if (printFile.available()) {
String line = printFile.readStringUntil('\n');
parse_line(line);
} else {
printFile.close();
while (1); // 停止执行
}
}
在这个代码中,readStringUntil('\n')
函数每次读取一行文本,并在遇到换行符时停止。下一次调用时,文件指针自动移到下一行,这样就能依次读取文件的每一行。
2. G 代码指令解析
G 代码文件中的每一行通常以不同的字母开头,如 G 或 M,这代表不同类型的指令。我们可以根据这些前缀解析出相应的指令并执行相应操作:
void parse_line(String line) {
line.trim(); // 去除行首尾的空格
if (line.startsWith("G")) {
parse_g_command(line); // 解析G代码指令
} else if (line.startsWith("M")) {
parse_m_command(line); // 解析M代码指令
} else if (line.startsWith(";")) {
// 这是注释行,忽略
} else {
// 处理其他类型的行
}
}
这里以 G 指令为例,解释具体的解析过程:
void parse_g_command(String line) {
int command = line.substring(1, line.indexOf(' ')).toInt(); // 获取G指令编号
switch (command) {
case 21:
set_units_to_metric(); // 设置单位为毫米
break;
case 90:
set_positioning_absolute(); // 设置为绝对定位模式
break;
case 28:
home_axes(line); // 执行归零操作
break;
case 1:
linear_move(line); // 线性移动
break;
// 可添加更多G指令的处理
}
}
command
是 G 指令的编号,例如 G21 设置单位为毫米,G90 设置为绝对定位模式。根据指令编号,我们可以调用相应的函数来执行相应的操作。
3. move_to
函数
move_to
函数是控制打印机头部在 X、Y、Z 三个轴上移动的核心。这个函数接收到目标位置的坐标后,将其转化为步进电机的指令。
void move_to(float x, float y, float z) {
if (z != current_z) {
long steps_z = calculate_steps(z, current_z, stepsPerRevZ, pitchZ);
move_axis_z(steps_z); // 移动Z轴到目标位置
current_z = z; // 更新当前Z轴位置
}
long steps_x = calculate_steps(x, current_x, stepsPerRevX, pitchX);
long steps_y = calculate_steps(y, current_y, stepsPerRevY, pitchY);
move_axes_xy(steps_x, steps_y); // 同步移动X和Y轴
current_x = x; // 更新当前X轴位置
current_y = y; // 更新当前Y轴位置
}
- Z 轴独立控制:函数首先检查 Z 轴目标位置是否与当前的位置不同。如果需要移动,则先计算步数并移动 Z 轴。
- 步数计算:通过
calculate_steps
函数计算从当前位置到目标位置的步数。 - 同步控制 X 和 Y 轴:在调整 Z 轴后,函数计算并同步移动 X 和 Y 轴,确保打印路径的准确性。
4. 步数计算与运动控制
在步进电机控制中,步数的计算非常重要。具体计算方法如下:
long calculate_steps(float target, float current, int stepsPerRev, float pitch) {
float distance = target - current;
return (distance / pitch) * stepsPerRev * microsteps;
}
- 距离计算:先计算目标位置与当前的位置差(
distance
)。 - 步数计算:将距离与螺距的比值乘以步进电机的每转步数(
stepsPerRev
)和微步数(microsteps
),得到实际需要的步数。
控制 X 和 Y 轴运动:
void move_axes_xy(long steps_x, long steps_y) {
long max_steps = max(steps_x, steps_y); // 找出两个轴中的最大步数
for (long i = 0; i < max_steps; i++) {
if (i < steps_x) {
digitalWrite(stepPinX, HIGH);
delayMicroseconds(stepDelay);
digitalWrite(stepPinX, LOW);
}
if (i < steps_y) {
digitalWrite(stepPinY, HIGH);
delayMicroseconds(stepDelay);
digitalWrite(stepPinY, LOW);
}
delayMicroseconds(stepDelay); // 控制运动速度
}
}
5. 斜率控制实现精确的同步
在某些情况下,X 和 Y 轴的步数差异较大,需要更加精确的同步控制。这时可以使用斜率(Slope)的方法:
if (steps_x > steps_y) {
float slope = (float)steps_y / steps_x;
float accumulated_y = 0;
for (long i = 0; i < steps_x; i++) {
digitalWrite(stepPinX, HIGH);
digitalWrite(stepPinX, LOW);
accumulated_y += slope;
if (accumulated_y >= 1.0) {
digitalWrite(stepPinY, HIGH);
digitalWrite(stepPinY, LOW);
accumulated_y -= 1.0; // 减去1,避免Y轴过度步进
}
delayMicroseconds(100); // 控制运动速度
}
}
- 斜率计算:
slope
是 Y 轴步数与 X 轴步数的比值,决定了 Y 轴步进的频率。 - 累加器:通过
accumulated_y
控制 Y 轴的步进时机,保证两轴同步运动。
总结
本文简单介绍了 3D 打印机解析 G 代码并将其转化为三轴运动控制的过程。通过步数计算和XY轴同步控制,确保打印头沿着指定的路径精确移动。而 Z 轴的独立控制则确保了每一层打印的高度准确。