串口通讯错误

发布于 2024-08-20 11:18:18 字数 1798 浏览 4 评论 0原文

我可能遇到了你今天听说过的最奇怪的错误。

我在线程中有一个(很长)方法,它将格式化数据发送到 RS232 Led 显示屏。

它应该很好地显示类似这样的内容

TITLE
SUBTITLE 1
ELEMENT 1
ELEMENT 2
SUBTITLE 2
ELEMENT 1
ELEMENT 2
ELEMENT 3

,每个内容都有自己的消息。

我在每条消息之后调用 Thread.Sleep(N) (因此每条消息都会显示 N 次)。

  • N 是秒数

好的,到目前为止一切都很好。问题是,如果 (10 <= N <= 20) 我得到以下输出:

TITLE
TITLE
TITLE
TITLE
TITLE
TITLE
TITLE
TITLE

发送消息时我可以听到嘟嘟声。我什至安装了一个串口监视器,以检查我发送的信息是否相同。

总结一下:

在线程睡眠 n <= 9 或 n >= 20 后,在串行端口上写入才有效。两者之间的任何内容都会产生错误的输出,例如输出是否被缓存或其他什么,

这可能是什么?

更新

  • 好的,我知道 System.Threading.Sleep 以毫秒为参数。只需将数字乘以 1000。
  • 每当 LED 显示屏收到新的格式正确的消息时,它就会发出蜂鸣声。我应该澄清这一点。

片段(这发送了第一个标题)

            using (var ld = new LedScreen(COM))
            {                    
                ld.AddEffect(LedScreen.Effects.Snow);
                ld.AddText(LedScreen.Colors.Red, titulos[ThreadControl.Fase]);
                ld.AddEffect(LedScreen.Effects.DSnow);
                ld.Write();
            }

            //Console.WriteLine(titulos[ThreadControl.Fase]);
            //esperamos N tiempo (titulo)
            Thread.Sleep(TiempoTitulo);

这是我编写的 LedScreen 类的 。写入方法是这样的:

    public void Write()
    {
        //caracteres de terminacion
        buffer.AddRange(new byte[] { 0xBF, 0xB1 });
        try
        {
            if (!sp.IsOpen) sp.Open();
            sp.Write(buffer.ToArray(), 0, buffer.Count);
        }
        finally
        {
            sp.Close();
        }
    }

更新 2

我终于让它工作了(丑陋的修复,但没什么。)

在每次写入串行端口之前,我都会立即发送一条“空白”消息。这会在发送实际消息之前清除屏幕。万岁!无论我使线程休眠多少秒,它都有效

I might just have the weirdest bug you've heard today.

I have this one (very long) method inside a thread, which sends formatted data to a RS232 Led Display.

It should display something like this

TITLE
SUBTITLE 1
ELEMENT 1
ELEMENT 2
SUBTITLE 2
ELEMENT 1
ELEMENT 2
ELEMENT 3

well, each one on it's own message.

I'm calling Thread.Sleep(N) after each one of the messages (so each message is displayed N time).

  • N being the number of seconds

Ok, everything is fine until now. The thing is that if (10 <= N <= 20) I get the following output:

TITLE
TITLE
TITLE
TITLE
TITLE
TITLE
TITLE
TITLE

I can hear the beep when I send the message. I even installed a serial port monitor, to check if the information I was sending was the same.

So just to summarize:

Writing on Serial Port works after sleeping the thread for n <= 9 or n >= 20. Anything in between will produce an erroneous output, like if the output was cached or something

What can this be?

Update

  • Ok, I know System.Threading.Sleep takes miliseconds as arguments. just multiply the number by 1000.
  • Whenever the led display receives a new well formatted message, it beeps. I should have clarified that.

Here is a snippet (this sends the first title)

            using (var ld = new LedScreen(COM))
            {                    
                ld.AddEffect(LedScreen.Effects.Snow);
                ld.AddText(LedScreen.Colors.Red, titulos[ThreadControl.Fase]);
                ld.AddEffect(LedScreen.Effects.DSnow);
                ld.Write();
            }

            //Console.WriteLine(titulos[ThreadControl.Fase]);
            //esperamos N tiempo (titulo)
            Thread.Sleep(TiempoTitulo);

I wrote the LedScreen class. The write method is this one:

    public void Write()
    {
        //caracteres de terminacion
        buffer.AddRange(new byte[] { 0xBF, 0xB1 });
        try
        {
            if (!sp.IsOpen) sp.Open();
            sp.Write(buffer.ToArray(), 0, buffer.Count);
        }
        finally
        {
            sp.Close();
        }
    }

Update 2

I finally got it to work (ugly fix, but meh.)

Before each write to the serial port, I send a "blank" message with no delay. That clears the screen, before sending the actual message. hooray! and it works for whatever amount of seconds I sleep the thread

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

相权↑美人 2024-08-27 11:18:18

您知道设备检测消息结束 (EOM) 的算法吗?设备可能使用字符内超时。这可以解释为什么它适用于 N > 。 20、如果在这段时间内缓冲区中没有出现新字符,则设备可能会确定消息已终止并显示缓冲区。如果将 ASCII 代码 10 放在消息的末尾,则可能会决定消息的其余部分滚动到单行显示的末尾而不显示它。

这并不能解释 N < 9 工作,不过。也许如果数据没有任何延迟地到达,设备会将其解释为串行显示的脚本?这种情况的指示是,如果消息显示的速度对于 N = 0 到 9 没有变化,但是对于所有 N > 1 时消息显示的速度确实变化。 20. 如果 N 的单位是毫秒,您可能无法确认这一点。

Do you know the device's algorithm for detecting end-of-message (EOM)? It could be that the device uses an intra-character timeout. That could explain why it works with N > 20, if no new characters showed up in the buffer in that time then the device might decide that the message was terminated and display the buffer. If you are putting ASCII code 10 at the end of the messages, it may be deciding that the rest of the message scrolls off the end of the one-line display and not show it.

That wouldn't explain the N < 9 working, though. Perhaps if data arrives without any delay at all the device interprets it as a script to display serially? The indication that that is the case is if the speed at which messages display doesn't vary for N = 0 to 9, but it does vary for all N's > 20. If N is in milliseconds you may not be able to confirm this.

找回味觉 2024-08-27 11:18:18

首先,您能澄清一下线程的睡眠时间吗? System.Threading.Thread.Sleep() 采用毫秒参数,而不是“秒”参数。

接下来,你知道串口write()成功了吗? (10-20 毫秒的硬编码延迟不一定总是足够长。)

为了防止溢出,我做了如下操作:

    public bool Send(byte[] bytes)
    {
        try
        {
            serialPort.Write(bytes, 0, bytes.Length);
            return true;
        }
        catch (Exception ex)
        {
            // log or note the error: can be TimeoutException or InvalidOperationException, etc
            return false;
        }
    }

First of all, can you please clarify the thread's sleep time? System.Threading.Thread.Sleep() takes a milliseconds argument, not a 'seconds' argument.

Next, do you know that the serial port write() succeeds? (A hard coded delay of 10-20 msecs is not necessarily always long enough.)

To prevent overrunning, I do something like:

    public bool Send(byte[] bytes)
    {
        try
        {
            serialPort.Write(bytes, 0, bytes.Length);
            return true;
        }
        catch (Exception ex)
        {
            // log or note the error: can be TimeoutException or InvalidOperationException, etc
            return false;
        }
    }
破晓 2024-08-27 11:18:18

有几件事可能会影响您的情况,其中最重要的是已经提到的“您正在谈论秒,但 Sleep() 需要毫秒参数,而不是秒”问题。

您还需要查看发送字符之间的时间长度。流量控制也行。串口参数(波特率等)。而且您需要知道您的设备的容差是多少。串行传输中丢失的数据通常意味着另一端的设备过载。

There are several things that might affect your situation, not the least of which is the already-mentioned "you're talking seconds, but Sleep() takes a milliseconds argument, not seconds" issue.

You also need to look at length of time between characters sent. Flow control too. Serial port parameters (baud rate, etc...). And you need to know what the tolerance of your device is. Lost data on a serial transmission usually means you are overloading the device on the other end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文