开源改变世界

在 1 个完整的命令缓冲区后跳过行 #982

推推 grbl 3年前 (2023-01-23) 211次浏览

关闭
PieterjanDeconinck 打开了这个问题 2016 年 4 月 29 日 · 10 条评论
关闭

在 1 个完整的命令缓冲区后跳过行#982

PieterjanDeconinck 打开了这个问题 2016 年 4 月 29 日 · 10 条评论

注释

在 1 个完整的命令缓冲区后跳过行 #982

大家好。
我目前正在使用由 grbl 控制的 X-Carve 作为我正在进行的项目的一部分。它不用作数控机床。相反,主轴已被气缸取代。用于此的阀门由 M3/M5 主轴控制装置控制。

所以这一切都像魅力一样有效,至少在一段时间内是这样。固定数量的命令后,系统开始表现异常。看起来它跳过了很多行。我正在使用大动作,所以这对我的系统来说是个大问题。我用 C# 编写了自己的 GUI,它使用简单的发送 > 等待 ok/error 协议。奇怪的是所有命令都已发送并给出 ok 消息。所以看起来所有的命令都收到了,但是之后发生了一些奇怪的事情。

起初我认为问题出在使用 M 命令,但即使只使用 G 命令也会发生同样的事情。当我在 arduino 上将 RX 串行缓冲区设为正常大小的两倍(256 而不是 128)时,正确执行的命令数量也增加了一倍。所以当缓冲区被填充一次时似乎出了问题,但我还没有设法找到解决我的问题的方法……

这是我发送命令的代码,它在 for 循环中被重复调用:

     private void writeLineToSerial(string text)
        {
            if (_serialPort.IsOpen)
            {
                _serialPort.Write(text + "\r\n");
                string answer = _serialPort.ReadLine();
                if (!answer.Contains("ok"))
                {
                    // Try resending the command (USB data corruption possible)
                    _serialPort.Write(text + "\r\n");
                    answer = _serialPort.ReadLine();
                    if (!answer.Contains("ok"))
                    {
                        // Emergency break!
                        _serialPort.Write("!\n");
                    }
                }
            }
        }

也许我犯了一个明显的错误,但我似乎无法弄清楚……任何帮助将不胜感激!

在 1 个完整的命令缓冲区后跳过行 #982
成员

@PieterjanDeconinck: Grbl 使用 128 个字符的环形缓冲区。标准环形缓冲区有一个空缓冲区槽来跟踪其状态,因此缓冲区中有 127 个可用槽。所以对于 256 个字节,它是 255 个可用字节。这是一个常见的问题。FWIW,在 v1.0 中,我最终将其修复为 128/256 可用字节。

在 1 个完整的命令缓冲区后跳过行 #982

谢谢您的回答。但是因为我正在等待 OK,所以我认为这不是问题。我没有使用字符计数,所以我不明白为什么会出现这个问题。如果缓冲区已满,Grbl 会等待发送 OK,对吗?

似乎当缓冲区已满时,发送了下一行但被忽略了。有没有办法在仍然使用 wait for ok 协议的同时解决这个问题?还是我必须改为字符计数?

在 1 个完整的命令缓冲区后跳过行 #982
成员

@PieterjanDeconinck:如果您发送的字符太多,您将溢出串行 RX 缓冲区并损坏数据,这将导致 Grbl 的行为很像您描述的那样。尝试将字符数限制减少到 127 个字节,而不是 128 个。

在 1 个完整的命令缓冲区后跳过行 #982
成员

@PieterjanDeconinck: 该死的。对不起。我真的需要停止浏览这些消息。我误读了你的帖子。给我一点时间重新阅读它。

在 1 个完整的命令缓冲区后跳过行 #982
成员

@PieterjanDeconinck: 嗯,不太清楚是怎么回事。如果 Grbl 与 UGS 或 bCNC 等其他 GUI 一起工作,那么您的流媒体可能有问题。如果是这种情况,您可以让 Grbl 回显它收到的命令以帮助您诊断问题。取消#define REPORT_ECHO_LINE_RECEIVEDconfig.h 中的注释,重新编译并刷新。

在 1 个完整的命令缓冲区后跳过行 #982 chamnit 重新打开了这个 2016 年 4 月 29 日
在 1 个完整的命令缓冲区后跳过行 #982

您是否在发送后重置“answer”变量?如果是这样,我看不到它。

我的 VB 流媒体是这样做的:

For i As Integer = 0 To gcodearray.Length – 1
GRBLResponse = “”
SendToGRBL(gcodearray(i) & vbLf)
Do Until GRBLResponse = “ok”
Application.DoEvents()
If GRBLResponse.StartsWith(“error”) 然后退出子
循环
下一个

我的变量 GRBLResponse 将等同于您的答案变量

在 1 个完整的命令缓冲区后跳过行 #982

抱歉,帖子编辑器去掉了缩进。

在 1 个完整的命令缓冲区后跳过行 #982

ReadLine 的串行端口对象超时是多少?
您可以尝试在每个命令之间插入驻留 (G4 P0),或使用检查 gcode 模式 ($C) 查看是否有任何不同。
我自己编写了几个自定义 GUI,但没有发现这个问题。我的 GUI 通常是事件驱动的状态机,但我也在辅助 Arduino 上编写了与您的示例非常相似的代码,并且运行良好。由于我执行的操作类型,我通常偶尔会有停留。

在 1 个完整的命令缓冲区后跳过行 #982

谢谢你所有的快速回答!我终于找到了这个问题,正如预期的那样,它不是一个大问题:p
显然,在 Grbl 中,LF 和 CR 之间没有区别。由于我发送的是“\r\n”而不是“\n”,Grbl 响应了两次 ok。所以通信完全出错是合乎逻辑的,因为这样我的流就溢出了缓冲区。

@chamnit: 你的建议真的很有帮助,因为这意味着我不得不把 ReadLine 放两次。这显示了双重 ok 消息。谢谢!
@109JB:这不是问题,因为我将“answer”声明为局部变量。这会在函数执行后自动删除。

在 1 个完整的命令缓冲区后跳过行 #982

嘿!

我遇到了同样的问题。你能发布你的工作代码吗?

国王问候

喜欢 (0)