注释
|
作为参考,这是重现问题的独立代码: Imports System.IO.Ports
Imports System.Threading
Public Class frmMain
Shared _serialPort As SerialPort
Shared _continue As Boolean
Dim readThread As Thread
Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click
_serialPort = New SerialPort()
_serialPort.PortName = "COM12"
_serialPort.BaudRate = 115200
_serialPort.Parity = Parity.None
_serialPort.DataBits = 8
_serialPort.StopBits = StopBits.One
_serialPort.Handshake = Handshake.None
_serialPort.ReadTimeout = 500
_serialPort.WriteTimeout = 500
_serialPort.Open()
_continue = True
readThread = New Thread(AddressOf Read)
readThread.Start()
GroupBox1.Enabled = True
btnOpen.Enabled = False
End Sub
Public Shared Sub Read()
While _continue
Try
Dim message As String = _serialPort.ReadLine()
Console.WriteLine(message.Trim())
Catch
End Try
End While
End Sub
Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
_continue = False
_serialPort.Close()
GroupBox1.Enabled = False
btnOpen.Enabled = True
End Sub
Private Sub btnReset_Click(sender As Object, e As EventArgs) Handles btnReset.Click
_serialPort.Write(Chr(24))
End Sub
Private Sub btnStatus_Click(sender As Object, e As EventArgs) Handles btnStatus.Click
_serialPort.Write("?")
End Sub
Private Sub btnUnlock_Click(sender As Object, e As EventArgs) Handles btnUnlock.Click
_serialPort.Write("$X" & vbLf)
End Sub
Private Sub btnTestA_Click(sender As Object, e As EventArgs) Handles btnTestA.Click
' works
_serialPort.Write("G90G10L20P0X0" & vbLf)
End Sub
Private Sub btnTestB_Click(sender As Object, e As EventArgs) Handles btnTestB.Click
' works
_serialPort.Write("G38.2X-1F25" & vbLf)
End Sub
Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
' works only every 2nd time and throws "Bad number format"
_serialPort.Write("G90G10L20P0X0" & vbLf & "G38.2X-1F25" & vbLf)
End Sub
End Class
|
|
@thoralt:不确定这里发生了什么,但这可能会破坏 Arduino 和您的计算机之间的通信。在 config.h 中,您可以取消注释 REPORT_ECHO_LINE_RECEIVED 选项(重新编译和闪存)让 Grbl 在执行之前报告它收到的字符串。它将被部分解析。没有空格,全部大写,没有评论。 |
|
回声是一个很好的起点@chamnit提及。 在我正在编写的 GUI 中,我也发现一个接一个地发送命令会导致 grbl 无法正确接收命令。我不确定为什么,但即使从 GUI 发送单独的 serialport.write 命令时也会发生这种情况。出于这个原因,我在发送另一个命令之前实现了等待 grbl 的 OK 响应。这已经解决了您在帖子中描述的所有实例。 |
|
当我以字符计数模式发送文件时,我还看到我正在编写的 GUI 有点奇怪。还没有弄清楚到底发生了什么,但作为一个额外的数据点,我发现如果 grbl 处于“检查”模式,我不会收到“错误的数字格式”错误。 |
|
我现在确实在启用的情况下重新编译了 grbl,
第一个命令解析得很好,而第二个命令在中间被截断了。显然,切割点与以前不同,现在 grbl 理所当然地抱怨未定义的进给率。我没有重新编译 我直接从 arduino 的 RX 输入端嗅到了信号,见下面的截图。它显示了有问题的传输过程中的解码字符。空字符不是空格,而是换行符(我通过放大验证)。显然,该消息已通过 USB 串行转换器正确传输。我尝试了另一个 arduino 来排除该特定硬件的任何问题,并使用了不同的品牌/不同的布局,但它显示了同样的问题。 正在接帖@AlexHolden和@109JB考虑到,目前 grbl 的缓冲区管理中的某些东西似乎很奇怪。我如何协助追踪此事?我可以提供电子硬件和 AVR 开发方面的技能。 |
|
@thoralt:确保您数到 127,而不是 Grbl 的 RX 缓冲区中的 128 个字符。这是一个常见的错误。(从技术上讲,我应该让 128 表示 128,但很长一段时间以来都是这样。) |
|
啊,我一直在使用 128。我想我可能是从 stream.py 示例中的“RX_BUFFER_SIZE=128”行得到的。 |
|
@chamnit我知道 127 字节的限制。我们在这里讨论的是一个 26 个字符的字符串,grbl 在第 22 个字符之后将其剪切。在我发送命令之前,我等待了几秒钟,然后重置/解锁,所以 grbl 的缓冲区肯定是空的。干扰 22 字节以上的命令不是缓冲区溢出问题,而是更棘手的问题。正如我所说,我愿意提供帮助,但还不了解 grbl 的内部工作原理。 |
|
@thoralt:如果这是 Grbl 方面的问题,那么当前的 GUI 也会出现这个问题。到目前为止,还没有报告任何问题,因为这样的事情将是一个严重的问题。因此,Grbl 不太可能是问题所在,而是流媒体或与您的设置有关的问题。 Grbl 的源代码直到提供回显为止都非常简单。串行读取 ISR 也非常简单。在过去的几个月里,这两者都没有发生重大变化。 请尝试不同的 GUI 或 Grbl 的流媒体脚本。验证是否通过其他方式正常发送相同的 g 代码。 |
|
为了进一步深入研究这个问题,我启动了我的 Mac(因为我不确定如何在 Windows 下快速获得一个带有串行端口的工作 Python)。我从 GitHub 复制了最新版本的 stream.py。 当只进行一个探测周期时,一切似乎都很好,即使在不久之后进行另一个探测周期也是如此。但是由于 stream.py 关闭了串行连接,Arduino 在此之后被重置,而在我的 VB.NET 测试设置中情况并非如此,我让连接保持打开状态。 所以我创建了一个包含多个探测周期的较长文件。由于我目前正在离线探测,没有连接步进器,grbl 进入警报状态(探测失败),所以我需要在每个探测周期后解锁。我不确定仅 $X 然后探测并重新开始是否合法,但没有找到任何反对它的信息。这是文件:
结果如下:
我不确定如何正确读取所有这些输出,但您可以在 grbl 的 PS:你有没有看我的示波器截图?在直接在 arduino 的 RX 引脚上物理测量有效 gcode 后告诉我“这是一个应用程序相关的问题”让我很难过。 |
|
@thoralt: 不必刻薄。这是第一次报告此类问题,这一事实仍然让我认为这是您的设置(也与硬件或连接相关)或流媒体相关。我提到这可能是与应用程序相关的问题,因为它几乎总是由应用程序引起的。如果您不相信我,请检查已关闭的问题线程。这通常是由于 streamer 发送了太多字符导致的,要么计数到 128 个字符,要么发送的字符比它认为的多,这会导致 Grbl 的 RX 缓冲区溢出。 现在您已经针对另一个流媒体进行了测试,这在很大程度上排除了流媒体。如果您可以再尝试一件事,请更改 Grbl 的串行波特率。这是在 config.h 中完成的。更改为 56700 波特或 250000 波特之类的值。由于 328p 和时钟的定时不准确性,这些被认为更准确(有关详细信息,请参阅 328p 数据表)。有一份报告称 115200 波特会导致一些与您的类似的奇怪问题,数据可能会丢失。即使您直接从 Arduino RX 引脚读取信号。 |
|
尝试只使用一个串行终端并粘贴尽可能多的缓冲区 |
|
@thoralt: 我想我看到了问题。这是您在探测之前调用的 EEPROM 写入。Interfacing wiki 中有一篇关于写入 EEPROM 的文章。无论何时发生这种情况,都会在写入期间禁用所有中断,包括串行 RX。AFAIK,在 Grbl 中没有办法避免这个问题,因为这是 328p AVR 的一个基本问题。 您的流媒体必须检测这些 EEPROM 写入命令,并在发送更多数据之前等待对特定行的 g 代码的确认。或者使用更简单的发送并等待响应协议。在这种情况下,写入 EEPROM 的是 G10L20 命令。 所以,是的,这是一个与应用程序相关的问题。不是咕噜咕噜。无论如何,我会更新 Wiki 使这个问题更清楚,以避免将来出现像这个问题一样的问题。 |
|
@chamnit对不起,如果你误会了我。英语不是我的母语,总是很难同时写得准确、礼貌和令人满意。我什至不得不查找“snarky”,绝对不想听起来像那样。我理解你的论点,grbl 的统计数据完全推翻了我的假设。再次抱歉。 也就是说,我用替代波特率测试了你的建议。我没有时间测试数百个探测周期(现在再次连接步进器),但错误似乎消失了。波特率设置中的舍入误差可能会导致问题(我在 USB 串行转换器上测量了 119.000 输出,也许 AVR 有点偏离另一个方向),但你的第二个建议,EEPROM 写入延迟,更多可能。 我将尝试实现类似在传输实际命令之前每当发生 EEPROM 写入时等待队列耗尽的操作。谢谢你的线索。 |
|
@thoralt: 没问题。我有一位德国教授作为研究生导师。我花了一段时间才理解他非常直接且通常简洁的陈述是建设性的批评,而不是贬低或侮辱性的言论。事实证明,他是我在校期间最喜欢的教授。 |



我目前正在努力进行探测。在 grbl-panel 中实现探测功能时,我遇到了以下奇怪的行为:
第一种情况(没有错误):发送命令之间有相当长的时间(单击单个按钮)
_serialPort.Write("G90G10L20P0X0" & vbLf)使用: OK将当前轴上的位置设置为 0_serialPort.Write("G38.2X-1F25" & vbLf):探测开始,OK第二种情况(有错误):立即发送命令
_serialPort.Write("G90G10L20P0X0" & vbLf & "G38.2X-1F25" & vbLf):错误的数字格式_serialPort.Write("G90G10L20P0X0" & vbLf & "G38.2X-1F25" & vbLf):探测开始,OK我不知道为什么第一次发送命令会导致“数字格式错误”,而稍后再次发送命令会导致预期的动作。
我使用的是 grbl 0.9j,但 0.9i 也有这个问题。我是不是以错误的方式使用了 gcode 命令,或者 grbl 没有按应有的方式运行?由于写入的数据远小于 127 字节,因此接收缓冲区中应该没有溢出。命令之间用\n隔开,所以应该分开执行。任何帮助是极大的赞赏。