C#串行数据 - 格式化接收数据字符串后丢失数据

时间:2011-11-23 16:36:05

标签: c# formatting serial-port

我的项目是一个客户显示器,通过串行连接连接到餐厅POS(基于PC的收银机)。我正在使用C#,Visual Studio 2010.

当收银员接收客户的订单并将物品输入POS系统时,POS通过串口发送格式化文本字符串。我需要获取该文本并解析它以删除一些不需要的字符,格式化它并将其显示在屏幕上。

大多数情况下,一切都按照第一张图片中显示的那样工作(请注意,我在右边有原始的未格式化数据供参考)。每个它都被添加到列表框中,并在添加或删除每个新项目后进行税收和总更新(如果进行了订单更正)。

问题:当POS快速发送多个项目时,某些内容正在崩溃,并且所有文本都没有正确处理/格式化/放置在屏幕上。如第二张图片所示。

您可以看到几个项目“滑过”并显示项目代码的位置。

当我以任何方式(在测试中)格式化传入的字符串时,所有数据似乎都完全按照它进入屏幕。所以在我看来,字符串的处理导致问题,并且串行数据不断进入,一些被丢弃。我已经尝试过各种握手选项。

第一个代码是我现在使用的,第二个是我在构建单独的事件处理程序时使用的示例。两种方法都表现出相同的问

CODE:

private void OnDataReceived(object sender, System.EventArgs e)
    {
        RxString = (myPortController.Read());

        RxString = RxString.TrimStart(new char[] { (char)02 }); // trim the Char02 so I can test for the 'Clear Screen' signal
        if (RxString == "")
        {
        }
        else RxString = RxString.Remove(RxString.Length - 1, 1); // Trim the end of line ascii character (dont need it for list box)

        if (RxString.StartsWith("C"))  // this is the 'Clear Screen' signal.  ClearAll is a simple func. to remove text from all controls
        {                              // to clear the screen after each order.
            ClearAll();

        }
        else  // Next sections display the text on screen, testing for Tax, Total or if not, then its a regular Menu Item

            if (RxString.Contains("Tax"))
            {
                labelTax.Text = RxString.Remove(0, 5);
            }
            else
                if (RxString.Contains("Total"))
                {
                    labelTotal.Text = RxString.Remove(0, 5);
                }

                else

                    if (RxString == "")
                        RxString = "";  // just do nothing with an empty string (dont know better way of ignoring that)

                    else
                    {
                        listOrderItems.Items.Add((RxString.Remove(0, 5)));  // Add the main menu items to the Listbox
                    }

     }

使用单独事件处理的方法,但结果相同:

  private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        RxString = serialPort1.ReadExisting();
        this.Invoke(new EventHandler(DisplayText));
    }

1 个答案:

答案 0 :(得分:0)

那里有大量的信息可供参考,我不完全确定你已经给了我们足够的帮助来解决这个特殊的问题。因此,我将提出一种方法来自行解决这个问题(以及为SO社区提供更好问题的方法),而不是一个明确的解决方案。

探索测试驱动的开发,并使用已经过全面测试的组件构建您的OnDataReceived事件处理程序。处理程序的核心部分是文本处理,您可以轻松地使用另一个类。你似乎把一次工作的代码当作福音(可能还有一些巧合编码)。

获取一些简单的获取文本字符串并构建解析它们的类并返回适当的数据。从那里,构建更复杂的测试用例,包括更大的字符串,取消的项目等。一旦你对测试感到满意,那么用硬件做一些测试,看看它是如何工作的。如果失败,则需要添加更多测试用例。

然后......起泡,冲洗,重复。