Contact me: hankecnc@gmail.com

速度的爆发 #1284

推推 grbl 3年前 (2023-01-23) 168次浏览
关闭
CliveMcCarthy 打开了这个问题 2017 年 9 月 9 日 · 52条评论
关闭

速度的爆发#1284

CliveMcCarthy 打开了这个问题 2017 年 9 月 9 日 · 52条评论

注释

速度的爆发 #1284
克莱夫·麦卡锡 评论了 2017 年 9 月 9 日  

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

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

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

这是串行接口的低级代码:

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

bool Grbl_is_connected = FALSE;
静态 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(“\t在输出上启用 XON/XOFF 流控制。\n”);
if(terminal_options->c_iflag & IXOFF) printf(“\t在输入上启用 XON/XOFF 流控制。\n”);
if(terminal_options->c_iflag & IXANY) printf(“\t键入任何字符将重新启动停止的输出。(The\n”);
if(terminal_options->c_iflag & IGNBRK) printf(“\t忽略输入中的 BREAK 条件。\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(“\t在输入时将 NL 转换为 CR。\n”);
if(terminal_options->c_iflag & IGNCR) printf(“\输入时忽略回车。\n”);

if(terminal_options->c_iflag & IUTF8) printf(“\tcharacter-erase 在 cooked 模式下正确执行。\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 结束时间;

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 terminal_options;
布尔确定=假;

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 必须快速执行大量非常短的行,它会变慢。这是因为规划器没有足够的距离来加速。查看存储库中的 stream.py 脚本,了解如何编写简单的流媒体。此外,针对 UGS 或 bCNC 等其他 GUI 进行测试以测试性能。

速度的爆发 #1284

在 $C 检查模式下一切正常。在那种模式下,我每秒可以处理 400 多行,没有错误或延迟。

速度的爆发 #1284
成员

@CliveMcCarthy:是的,因为检查模式不计划任何事情。只是解析。

速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 9 日 通过电子邮件
速度的爆发 #1284

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

速度的爆发 #1284

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

速度的爆发 #1284

速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 10 日 通过电子邮件
速度的爆发 #1284
成员
香奈儿 评论了 2017 年 9 月 10 日  

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

速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 11 日 通过电子邮件
速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 11 日 通过电子邮件
速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 11 日 通过电子邮件
速度的爆发 #1284
成员

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

速度的爆发 #1284
成员
香奈儿 评论了 2017 年 9 月 11 日  

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

速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 12 日 通过电子邮件
速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 12 日 通过电子邮件
速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 12 日 通过电子邮件
速度的爆发 #1284
成员

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

速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 12 日 通过电子邮件
速度的爆发 #1284
作者
克莱夫·麦卡锡 评论了 2017 年 9 月 12 日 通过电子邮件
喜欢 (0)