2

让我解释一下场景:为我带来数据(字符串)的串行端口,如下例所示:

02051014 0009 M 0 741 30041105 2632 0 30041105

我尝试过各种读取(读取、读取字节、读取字符、读取行、读取现有)。我试图更改新行,但数据一直重复。看看上面的例子,现在看看数据是怎么来的:

0220510114 00009 M 0 741 300441105 2632 0 300411055

任何人都知道我该如何解决这个问题?

编码:

[...]
try
{
    this.serialPort = new SerialPort("COM1", 2400, Parity.None, 7, StopBits.One);
    this.serialPort.DataReceived += new SerialDataReceivedEventHandler(portaSerial_DataReceived);
    this.serialPort.Handshake = Handshake.XOnXOff;
    this.serialPort.Encoding = Encoding.ASCII;
    this.serialPort.Open();
}
[...]
private void portaSerial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        var invalidValuesToBreakLine = new int[] { 13, 10, 0 };
        int data;

        while (this.serialPort.BytesToRead > 0)
        {
            data = this.serialPort.ReadChar();

            if (invalidValuesToBreakLine.Contains(data))
            {
                if (!this.breakLineWasPerformed)
                {
                    this.breakLineWasPerformed = true;

                    this.dataList.Add(this.temporaryString);

                    this.temporaryString = string.Empty;
                }
            }
            else
            {
                if (this.breakLineWasPerformed)
                {
                    this.breakLineWasPerformed = false;
                }

                this.temporaryString += (char)data;
            }
        }
[...]
4

2 回答 2

0

我会尝试的第一件事是data在每次调用该方法后重置为空字符串ReadChar(),或者刷新输入缓冲区。

我怀疑调用BytesToRead()返回大于零,但 ReadChar() 调用返回串行端口缓冲区上的原始字符。这是由于串行端口的内部时序,以及您的代码对于硬件设备可能“运行得太快”这一事实。

我可能会重新考虑该方法中的整个 while 循环。您可能会简化很多,只需尝试以下(使用您的自定义代码)

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    Console.WriteLine("Data Received:");
    Console.Write(indata);
}

要更改换行符,只需检查indata字符串并中断字符,将结果存储在全局变量中,然后重用剩余的数据。

于 2013-02-05T14:17:15.397 回答
0

经过挖掘,我发现这个StackOverflow 问题/答案表明该DataReceived事件可能会在意外时间触发。所以,如果可能的话,你应该设置一个NewLine并触发它。

作为对这个想法的测试,您可以尝试添加一个按钮并等到您知道您有一些数据,然后单击它以向您显示流。如果没有重复,则表明该DataReceived事件过于急切且触发不正确。然后,您可能想要检查您的NewLine,DtrEnable等等DsrHolding

private void TestButton_Click(object sender, EventArgs e)
{
    string indata = this.serialPort.ReadExisting();
    MessageBox.Show(indata);
}
于 2013-02-05T13:38:56.443 回答