关于GCode_interpreter
下学期要做课设,要徒手画a0的图,准备做个A0的绘图仪@_@
本来想用grbl来驱动,但了解之后发现它是用avr的c写的,而且代码量也挺大的,考虑到后面可能要加一些功能(换笔什么的),怕修改不来,就放弃了。后来又找了很多g代码解释器,最后发现了GCode_interpreter。GCode_interpreter是用Arduino语言写的,理论上支持所有的arduino,虽然性能和功能上不及grbl,但是结构简单,代码量少。唯一比较不好的就是没有加减速功能,容易导致步进电机过冲或者丢步。
程序说明
GCode_interpreter主要由_init、GCode_interpreter、process_string、stepper_contorl四个文件组成(当然还有extruder,但是这里就不做解释了)_init文件是对一些基础参数的预定义,比如步进电机分辨率、针脚等;GCode_interpreter是主程序;process_string存放一些和指令处理有关的函数;stepper_contorl存放和步进电机运动有关的函数。
process_string中的函数说明
函数 | 说明 |
---|---|
init_process_string() | 初始化串口数据 |
process_string() | 处理指令 |
search_string() | 提取指令中某个字符后空格前的浮点数 |
has_command() | 判断指令中是否有某个字符 |
stepper_control中的函数说明
函数 | 说明 |
---|---|
init_steppers() | 初始化步进电机 |
dda_move() | 执行指定运动 |
can_step() | 判断步进电机是否可以运动 |
do_step | 步进电机走一步 |
read_switch() | 读取限位开关状态 |
to_step() | 计算需要的脉冲数 |
set_target() | 设定目标坐标 |
set_position() | 设定当前坐标 |
caculate_deltas() | 坐标计算(当前和目标的差值、当前已行走的步数、步数的差值、运动方向) |
calculate_feedrate_delay() | 计算两个脉冲之间的延迟 |
getMaxSpeed() | 以最大速度运行(实为默认速度) |
主要变量说明
变量 | 说明 |
---|---|
worda[] | 储存指令的数组 |
serial_count | 指令长度 |
current_units.x(/y/z) | 当前坐标 |
target_units.x(/y/z) | 目标坐标 |
deltas_units.x(/y/z) | 当前和目标坐标的差值 |
current_step.x(/y/z) | 当前步数坐标 |
target_step.x(/y/z) | 目标步数坐标 |
deltas_step.x(/y/z) | 到达目标位置还需要行走的步数 |
abs_mode | true为绝对坐标模式 |
x_units/y_units/z_units | 步进电机运动1mm需要的脉冲数 |
x_direction/y_direction/z_direction | 运动方向 |
feedrate | 速度 |
feedrate_micros | 脉冲间的延迟 |
x_can_step/y_can_step/z_can_step | true允许运动 |
程序大致的流程图:
代码注释
以下代码和原固件有些地方不太一样(比如:原固件有些变量名在我的ide中和关键字冲突了,被我改了)
GCode_interpreter
// Arduino G-code Interpreter
// v1.0 by Mike Ellery - initial software (mellery@gmail.com)
// v1.1 by Zach Hoeken - cleaned up and did lots of tweaks (hoeken@gmail.com)
// v1.2 by Chris Meighan - cleanup / G2&G3 support (cmeighan@gmail.com)
// v1.3 by Zach Hoeken - added thermocouple support and multi-sample temp readings. (hoeken@gmail.com)
#include <HardwareSerial.h>
#include <Servo.h>//我在原固件基础上加入了m03和m05来控制舵机
//our command string
#define COMMAND_SIZE 128 //单个指令的最大长度
char worda[COMMAND_SIZE];//储存指令的数组
byte serial_count;//指令长度
int no_data = 0;//0为串口有数据,>0为无数据
Servo a;
void setup()
{
//Do startup stuff here
Serial.begin(115200);//波特率
Serial.println("start");
a.attach(12);//舵机
//other initialization.
init_process_string();//初始化
init_steppers();
init_extruder();
}
void loop()
{
char c;
//keep it hot!
extruder_manage_temperature();//有关extruder的将不作注释
//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')
{
worda[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))//如果指令长度不为0,且接收到换行或短时间内串口无数据
{
//process our command!
process_string(worda, serial_count);//执行指令
//clear command.
init_process_string();//初始化
}
//no data? turn off steppers
if (no_data > 1000)//长时间无数据
disable_steppers();//关闭步进电机
}
_init
//这个文件包含一些预定义
// define the parameters of our machine.
#define X_STEPS_PER_INCH 2540//走1英寸需要的脉冲数,以英寸为单位的时候使用,根据传动