开源改变世界!!

速度爆发 #1284

推推 grbl 2年前 (2022-10-30) 151次浏览 0个评论
关闭
CliveMcCarthy 打开了这个问题 on 9 Sep 2017 · 52 条评论
关闭

速度爆发#1284

CliveMcCarthy 打开了这个问题 on 9 Sep 2017 · 52 条评论

注释

速度爆发 #1284

克莱夫麦卡锡 评论 on 9 Sep 2017  

我正在用 Linux 上的 GTK+3.0 在 C 中为 Grbl 编写一个 GUI。它是一个比其他 GUI 更简单的界面,因为我们的工作是 2D 的,具有适度的 Z 要求(绘图仪上的大型艺术图纸)。我正在使用带有规范协议的串行端口和 Grbl 0.9j 的简单发送和确认接口

大多数 G 代码指令的距离都很短~1mm,而且有很多。我发现大多数 G 代码行执行速度非常快(不到 100 毫秒),但有些,特别是在启动时,需要几秒钟。有时可能需要 Grbl 12 秒才能响应 G 代码行。

这是可以预料的还是我有错误?测量,运行 10,000 行 G 代码,我每秒处理大约 13 行。G 代码的进给速度设置为 6,000 毫米/分钟。

以下是串行接口的低级代码:

`
#include “common_header.h”
#include “Arduino_serial_interface.h”

布尔 Grbl_is_connected = 假;
静态int fd;

void show_terminal_options(struct termios *terminal_options)
{
printf(“————————————– ————————\n”);
// — 控制终端输入的选项 — c_iflag
if(terminal_options->c_iflag & ICRNL) printf(“\ttranslate CR to NL on input\n”);
if(terminal_options->c_iflag & IXON) printf(“\tEnable XON/XOFF flow control on output.\n”);
if(terminal_options->c_iflag & IXOFF) printf(“\tEnable XON/XOFF flow control on input.\n”);
if(terminal_options->c_iflag & IXANY) printf(“\t键入任何字符将重新启动停止的输出。(\n”);
if(terminal_options->c_iflag & IGNBRK) printf(“\t忽略输入的中断条件。\n” );
if(terminal_options->c_iflag & BRKINT) printf(“\t如果设置了 IGNBRK,则忽略 BREAK。如果未设置但\n”);
if(terminal_options->c_iflag & IGNPAR) printf(“\tignore 成帧错误和奇偶校验错误。\n”);
if(terminal_options->c_iflag & PARMRK) printf(“\t如果该位被设置,输入字节有奇偶校验或帧错误\n”);
if(terminal_options->c_iflag & INPCK) printf(“\t启用输入奇偶校验。\n”);
if(terminal_options->c_iflag & ISTRIP) printf(“\t去掉第八位。\n”);
if(terminal_options->c_iflag & INLCR) printf(“\ttranslate NL to CR on input.\n”);
if(terminal_options->c_iflag & IGNCR) printf(“\tignore 输入时回车。\n”);

if(terminal_options->c_iflag & IUTF8) printf(“\tcharacter-erase 在熟模式下正确执行。\n”);

// --- options to control terminal output --- c_oflag
if(terminal_options->c_oflag & OLCUC)	printf("\tmap lowercase characters to uppercase on output\n");
if(terminal_options->c_oflag & ONLCR)	printf("\tmap NL to CR+NL on output.\n");
if(terminal_options->c_oflag & OCRNL)	printf("\tmap CR to NL on output.\n");
if(terminal_options->c_oflag & OPOST)	printf("\tEnable implementation-defined output processing.\n");
if(terminal_options->c_oflag & ONOCR)	printf("\tDon't output CR at column 0.\n");
if(terminal_options->c_oflag & ONLRET)	printf("\tDon't output CR.\n");
if(terminal_options->c_oflag & OFILL)	printf("\tSend fill characters for a delay, rather than using a timed\n");
if(terminal_options->c_oflag & OFDEL)	printf("\tFill character is ASCII DEL (0177).  If unset, fill character\n");
if(terminal_options->c_oflag & NLDLY)	printf("\tNL delay mask.  Values are NL0 and NL1.  [requires\n");
if(terminal_options->c_oflag & CRDLY)	printf("\tCR return delay mask.  Values are CR0, CR1, CR2, or CR3.\n");
if(terminal_options->c_oflag & TABDLY)	printf("\tHorizontal tab delay mask.  Values are TAB0, TAB1, TAB2, TAB3\n");
if(terminal_options->c_oflag & BSDLY)	printf("\tBackspace delay mask.  Values are BS0 or BS1.  (Has never been\n");
if(terminal_options->c_oflag & VTDLY)	printf("\tVertical tab delay mask.  Values are VT0 or VT1.\n");
if(terminal_options->c_oflag & FFDLY)	printf("\tForm feed delay mask.  Values are FF0 or FF1.  [requires\n");


// --- options to control terminal hardware --- c_cflag
if(terminal_options->c_cflag & CLOCAL)	printf("\tignore modem control lines.\n");
if(terminal_options->c_cflag & CREAD)	printf("\tenable read\n");
if(terminal_options->c_cflag & CSIZE)	printf("\tcharacter size mask.  Values are CS5, CS6, CS7, or CS8.\n");
if(terminal_options->c_cflag & CSTOPB)	printf("\tSet two stop bits, rather than one.\n");
if(terminal_options->c_cflag & PARENB)	printf("\tenable parity generation on output and parity checking for\n");
if(terminal_options->c_cflag & CRTSCTS)	printf("\tEnable RTS/CTS (hardware) flow control\n");

if(terminal_options->c_cflag & CBAUD)	printf("\tBaud speed mask (4+1 bits).  [requires\n");
if(terminal_options->c_cflag & CBAUDEX)	printf("\tExtra baud speed mask (1 bit)\n");
if(terminal_options->c_cflag & PARODD)	printf("\tIf set, then parity for input and output is odd; otherwise\n");
if(terminal_options->c_cflag & HUPCL)	printf("\tlower modem control lines after last process closes the device\n");
if(terminal_options->c_cflag & CIBAUD)	printf("\tMask for input speeds.  The values for the\n");
if(terminal_options->c_cflag & CMSPAR)	printf("\tUse 'stick' (mark/space) parity (supported on\n");


// --- options to control terminal user interface --- c_lflag
if(terminal_options->c_lflag & ISIG)	printf("\tWhen any of the characters INTR, QUIT, SUSP, or DSUSP are\n");
if(terminal_options->c_lflag & ECHO)	printf("\tEcho input characters.\n");
if(terminal_options->c_lflag & ICANON)	printf("\tcanonical mode enabled\n");
if(terminal_options->c_lflag & ECHOCTL)	printf("\tECHOCTL\n");
if(terminal_options->c_lflag & ECHOPRT)	printf("\tECHOPRT\n");
if(terminal_options->c_lflag & NOFLSH)	printf("\tDisable flushing the input and output queues when generating\n");
if(terminal_options->c_lflag & TOSTOP)	printf("\tSend the SIGTTOU signal to the process group of a background\n");
if(terminal_options->c_lflag & IEXTEN)	printf("\tEnable implementation-defined input processing.  This flag, as\n");
if(terminal_options->c_lflag & ECHOE)	printf("\tIf ICANON is also set, the ERASE character erases the\n");
if(terminal_options->c_lflag & ECHOK)	printf("\tIf ICANON is also set, the KILL character erases the current\n");
if(terminal_options->c_lflag & ECHONL)	printf("\tIf ICANON is also set, echo the NL character even if ECHO is\n");
if(terminal_options->c_lflag & ECHOKE)	printf("\tIf ICANON is also set, KILL is echoed by\n");
printf("--------------------------------------------------------------\n");

}
double compute_task_milli_seconds(struct timeval *start_time)
{
double elapsed_time;
结构 timeval end_time;

gettimeofday(&end_time, NULL);

elapsed_time	= (end_time.tv_usec / 1000.0 + end_time.tv_sec * 1000)
				- (start_time->tv_usec / 1000.0 + start_time->tv_sec * 1000);

return elapsed_time;

}
int write_arduino(char *g_code)
{
int n;

n = write(fd, g_code, strlen(g_code));

if(n < 0)
{
	printf("Error writing: %s\n", strerror(errno));
}

printf("Write : %2d bytes "ANSI_COLOR_YELLOW"%s"ANSI_COLOR_RESET,
	strlen(g_code), g_code);
return n;

}
int read_arduino(char *response)
{
struct timeval start_time;
双毫秒;
诠释 n = 0;

memset(response, '\0', G_CODE_LINE_LENGTH);

gettimeofday(&start_time, NULL);
n = read(fd, response, G_CODE_LINE_LENGTH);

if(n < 0)
{
	printf("Error reading: %s\n", strerror(errno));
}
else
if(strlen(response) == 0)
{
	printf("Read : %s zero length\n", response);
	n = 0;
}
else
{
	milliseconds = compute_task_milli_seconds(&start_time);
	printf("Read  : %2d bytes "ANSI_COLOR_GREEN"%s"ANSI_COLOR_RESET,
		strlen(response), response);
	if(milliseconds > 100.0)
		printf(ANSI_COLOR_RED"\t%6.2lf seconds\n"ANSI_COLOR_RESET,
			milliseconds / 1000.0);
}

return n;

}
int initialize_serial_port(const char *serial_port)
{
char Ctrl_X_Reset_Grbl[] = {CTRL_X, ‘\n’, ‘\0’};
结构 termios 终端选项;
布尔确定 = 假;

fd = open(serial_port, O_RDWR | O_NOCTTY);
sleep(3); // wait for connection
memset(&terminal_options, 0, sizeof(struct termios));

printf("Connecting to Arduino via %s\n", serial_port);

if(tcgetattr(fd, &terminal_options) != 0)
{
	printf("error from tcgetattr: %s\n", strerror(errno));
	ok = FALSE;
	return ok;
}

show_terminal_options(&terminal_options);

// set Baud rates
cfsetospeed(&terminal_options, (speed_t)B115200);
cfsetispeed(&terminal_options, (speed_t)B115200);

// --- options to control terminal input
terminal_options.c_iflag	|= IGNCR;		// ignore CR on input
terminal_options.c_iflag	&= ~ICRNL;		// translate CR to NL on input
terminal_options.c_iflag	&= ~INLCR;		// translate NL to CR on input

// --- options to control terminal output
terminal_options.c_oflag	|= OLCUC;		// map lowercase to uppercase on output

// --- options to control terminal hardware
terminal_options.c_cflag	&= ~PARENB;		// no parity
terminal_options.c_cflag	&= ~CSTOPB;		// one stop bit
terminal_options.c_cflag	&= ~CSIZE;		// character size mask
terminal_options.c_cflag	|= CS8;			// make 8N1
terminal_options.c_cflag	&= ~CRTSCTS;	// no flow control
terminal_options.c_cflag	|= CREAD;		// turn on read
terminal_options.c_cflag	|= CLOCAL;		// ignore modem ctrl lines

// --- options to control terminal user interface
terminal_options.c_lflag	|= ICANON;		// enable canonical mode

show_terminal_options(&terminal_options);

// flush port, then apply attributes
tcflush(fd, TCIFLUSH);
if(tcsetattr(fd, TCSANOW, &terminal_options) != 0)
{
	printf("error from tcsetattr %s\n", strerror(errno));
	ok = FALSE;
	return ok;
}

write_arduino(Ctrl_X_Reset_Grbl);
sleep(3); // wait for reset

Grbl_is_connected = TRUE;
ok = TRUE;
return ok;

}
`

速度爆发 #1284

你可能有一个错误。Grbl 应该几乎立即执行它收到的任何命令。如果 Grbl 必须快速执行许多非常短的行,它会变慢。这是因为规划器没有足够的距离来加速。查看 repo 中的 stream.py 脚本,了解如何编写一个简单的流媒体。此外,针对 UGS 或 bCNC 等其他 GUI 进行测试以测试性能。

速度爆发 #1284

在 $C 检查模式下一切正常。在这种模式下,我每秒可以收到超过 400 行,没有错误或延迟。

速度爆发 #1284

@CliveMcCarthy: 是的,因为检查模式没有任何计划。解析一下。

速度爆发 #1284
速度爆发 #1284

经过更多测试后,我似乎可以平均每秒发送 40 条 G 代码行,每行 1 毫米,即 2,400 毫米/分钟。有长达 12 秒的重复周期性延迟。

速度爆发 #1284

当 Grbl 处于检查模式时,数据以每秒 400 行的速度传输,所以我知道串行链路是好的。你对我有什么想法,加快 Arduino 上的计划/执行过程吗?

速度爆发 #1284

速度爆发 #1284
速度爆发 #1284
成员

尚尼特 评论 2017 年 9 月 10 日  

您是否按照我的要求进行了测试并针对信誉良好的 GUI 进行了测试?Grbl 每秒可以处理高达 250 行。就像 wiki 页面状态一样,发送和响应协议并不是最快的。如果您需要更快,请使用字符计数协议。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

将您的 $1 设置为 $1=255。Grbl 每秒可以处理多达 400 行。这是每行 2.5 毫秒。不是 25. 机器可能会停止,强制执行步骤延迟,然后恢复。默认值约为 25 毫秒,这可以解释您的问题

速度爆发 #1284
成员

尚尼特 评论 2017 年 9 月 11 日  

您看到的较长延迟来自您的 g 代码。Grbl 必须在执行需要与运动同步的行之前执行所有缓冲的运动。M8 M9 M30 等都可以作为同步命令。延迟来自等待完成排队的运动。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

你还在使用发送响应协议吗?如果是这样,请使用 UGS 或 GRBL stream.py 脚本再次测试。他们使用字符计数协议。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

我的代码以非常大的 G 代码文件在稳定的条件下驱动 Grbl。它已经持续运行了八个多小时,还有六个小时的时间。

似乎 Grbl 每隔 100~120 行左右就停止一次。我的代码发送一个“?” 每 20 行请求一次状态,并且计划缓冲区(除少数例外)报告 17 次——它总是满的——甚至在停顿之前也是如此。

停顿的特点是读取响应时间超过一秒。正常响应时间不到 20 毫秒。

速度爆发 #1284

我今天早上的第一个实验是将结偏差从 0.02mm 增加到 1mm,这似乎减少了失速的数量。我现在将任何 100 毫秒或更长的响应视为停顿。绝大多数都在 20 毫秒以下。

速度爆发 #1284
成员

尚尼特 评论 on 12 Sep 2017

编译后的 C 可执行文件比 Python 或 Java 快已经不是什么秘密了。您的 GUI 的延迟很低,我并不感到惊讶。

我开始觉得我在一遍又一遍地重复自己。这是浪费时间和精力。请考虑字符计数协议。正如 wiki 界面页面所述,它效率更高,可以加快工作速度,建议用于要求更高的工作。主要原因是您没有考虑将串行消息传输到 Grbl 所需的时间。对于 115200 波特的 25 个字符,大约是 2.2 毫秒。Grbl 必须等到它收到完整的消息后才能解析并执行它。另外,请考虑 Grbl 将“ok”传输回您的 GUI 所需的时间。尽管时间更短,Grbl 可以立即开始执行下一行,然后再传输“ok”和 USB 协议 + 主机的延迟时间。

请尝试了解 Grbl 的工作原理,然后再对其进行“表演”时间。Grbl 有一个 15 块左右的规划器。它在规划器内的总距离内规划最佳加速和执行时间。如果这些块都是很短的线,那么它里面没有那么多的距离或时间。如果您的加速度很低,那么它在必须减速到缓冲区末端停止之前无法加速到高速,以始终确保始终管理运动。这些因素,包括路口偏差(改变它通过路口的速度),都会影响 Grbl 的性能,但与沟通没有太大关系。这是您的设置、规划器大小和规划器假设的限制。

至于您的 1 秒读取响应问题,很难说出您定义为 1 秒的内容。我认为您需要分享您的 $$ 设置、您的 $I 构建信息字符串和您的测试程序。因此,我可以看到您正在尝试做什么,并帮助确定主要问题是什么。

速度爆发 #1284
速度爆发 #1284
$1=255 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=0 (dir port invert mask:00000000)
$4=0 (step enable invert, bool)
$5=0 (limit pins invert, bool)
$6=0 (probe pin invert, bool)
$10=12 (status report mask:00001100)
$11=1.000 (junction deviation, mm)
$12=1.000 (arc tolerance, mm)
$13=0 (report inches, bool)
$20=0 (soft limits, bool)
$21=0 (hard limits, bool)
$22=0 (homing cycle, bool)
$23=0 (homing dir invert mask:00000000)
$24=25.000 (homing feed, mm/min)
$25=500.000 (homing seek, mm/min)
$26=250 (homing debounce, msec)
$27=1.000 (homing pull-off, mm)
$100=250.000 (x, step/mm)
$101=250.000 (y, step/mm)
$102=250.000 (z, step/mm)
$110=15000.000 (x max rate, mm/min)
$111=15000.000 (y max rate, mm/min)
$112=4000.000 (z max rate, mm/min)
$120=10000.000 (x accel, mm/sec^2)
$121=10000.000 (y accel, mm/sec^2)
$122=10.000 (z accel, mm/sec^2)
$130=1200.000 (x max travel, mm)
$131=1000.000 (y max travel, mm)
$132=200.000 (z max travel, mm)
ok
速度爆发 #1284

您超过了 Grbl 支持的最大 30kHz 步进速率。(15,000 毫米/分钟 *250 步/毫米)/60 秒/分钟 -> 62.5 kHz。Grbl 不会主动对此进行检查,因为 v1.1 中没有任何闪存空间。所有剩余的字节都保留用于错误修复。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

这就是我和我的合作者正在做的事情。您在墙上看到的作品是由四张 1200 毫米 x 800 毫米的纸上墨水画制成的。

速度爆发 #1284

速度爆发 #1284

不确定您是否收到我的回复,但问题是您超过了 Grbl 支持的 30kHz 最大步进速率。这会导致您的 Arduino 冻结并可能崩溃。Arduino 的所有时间都花在维修步进脉冲而不是计划上。将您的步长/毫米减少到更真实的值,例如 40 步/毫米到 80 步/毫米。

速度爆发 #1284
$1=255 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=0 (dir port invert mask:00000000)
$4=0 (step enable invert, bool)
$5=0 (limit pins invert, bool)
$6=0 (probe pin invert, bool)
$10=12 (status report mask:00001100)
$11=1.000 (junction deviation, mm)
$12=1.000 (arc tolerance, mm)
$13=0 (report inches, bool)
$20=0 (soft limits, bool)
$21=0 (hard limits, bool)
$22=0 (homing cycle, bool)
$23=0 (homing dir invert mask:00000000)
$24=25.000 (homing feed, mm/min)
$25=500.000 (homing seek, mm/min)
$26=250 (homing debounce, msec)
$27=1.000 (homing pull-off, mm)
$100=50.000 (x, step/mm)
$101=50.000 (y, step/mm)
$102=250.000 (z, step/mm)
$110=5000.000 (x max rate, mm/min)
$111=5000.000 (y max rate, mm/min)
$112=4000.000 (z max rate, mm/min)
$120=500.000 (x accel, mm/sec^2)
$121=500.000 (y accel, mm/sec^2)
$122=10.000 (z accel, mm/sec^2)
$130=1200.000 (x max travel, mm)
$131=1000.000 (y max travel, mm)
$132=200.000 (z max travel, mm)
ok
速度爆发 #1284
速度爆发 #1284

重新测试UGS。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

@CliveMcCarthy看你的画很有趣。你介意把你的文件发给我吗?我可以在 STM32 端口以及我的 Windows 模拟上尝试它,看看我是否能找到一些东西。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

@CliveMcCarthy你不能压缩文件?STM32端口在ARM上,可以轻松获得180KHz步进时钟。https://www.youtube.com/watch?v=5DBtbAYmfEE&t=2s

速度爆发 #1284

我没有收到任何文件。重命名为 .txt 并拖放到您的 github 响应中。

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

如果你不想公开分享任何东西,你可以给我发电子邮件。

速度爆发 #1284

这有我对 Grbl 的低级接口。没有什么特别的,只是它确实试图测量传输速度。它可能需要一些工作才能在 Windows 上运行,但对于 Linux 来说会很好。

Arduino_serial_interface.txt

速度爆发 #1284

不,我的意思是分享您正在测试的 g 代码文件。这就是我需要查看问题与 Grbl 相关的全部内容。

速度爆发 #1284

行,可以。这是在 14 分钟内运行的文件。
hello_image_small.txt

速度爆发 #1284

这是USBCNC可以尝试的大图。天使.cnc.gz

速度爆发 #1284
速度爆发 #1284

@CliveMcCarthy:在您的 g 代码程序中的任何地方都没有性能问题。我只是用 stream.py 脚本和 Grbl v1.1(在性能方面与 v0.9 基本相同)对其进行了测试。Grbl 完全按照它应该运行的方式运行它。去ARM不会有什么不同。让我来告诉你为什么。

您已经在整个程序中组合了编程的 3 轴运动。与 10000mm/s^2 和 500mm/s^2 的 x 和 y 轴相比(在您的缩减设置中),您的 Z 轴加速度非常小,为 $122=10.00。你认为是停滞的,不是停滞的。它是 Grbl 故意放慢速度并确保不超过 z 轴加速度限制。

UGS 和你的 GUI 程序导致同时出现的原因是这个程序要求不高。当我说要求时,是指每秒有 400 条线,每条线长约 0.1 毫米。这是激光雕刻的常见问题(请注意,Grbl LPC 端口每秒可以处理约 1300 行)。

如果您希望我以更快的进给速度对您的第一个测试进行测试,您需要上传该文件或至少一个类似的文件,以便我可以比较执行时间(使用您的旧设置,除了您的步长/毫米全部为 50.0) .

速度爆发 #1284
速度爆发 #1284
速度爆发 #1284

usbcnc 评论 2017 年 9 月 13 日  

@CliveMcCarthy
在以下设置。
$100 = 250.000(X 轴移动分辨率,步长/mm)
$101 = 250.000(Y 轴移动分辨率,步长/mm)
$102 = 250.000(Z 轴移动分辨率,步长/mm)
$110 = 15000.000(X 轴最大值速度,毫米/分钟)
$111 = 15000.000(Y 轴最大速度,毫米/分钟)
$112 = 4000.000(Z 轴最大速度,毫米/分钟)
$120 = 10000.000(X 轴加速度,毫米/秒^2)
$121 = 10000.000(Y 轴加速度,mm/sec^2)
$122 = 10.000(Z 轴加速度,mm/sec^2)

我在 STM32F103 GRBL 上运行 angel.cnc 3:19,完全没有问题。(18xxxx 行)。
在 Win32 模拟上运行 2:30(Win32 速度不准确)。我可以确认 GRBL 逻辑没有问题,很可能与您的文件有关,已达到 Arduino 的最大时钟速率。
速度爆发 #1284

速度爆发 #1284
喜欢 (0)

您必须 登录 才能发表评论!