C# 从C中的串行端口读取数据

C# 从C中的串行端口读取数据,c#,compact-framework,serial-port,C#,Compact Framework,Serial Port,我尝试过使用Readline,数据被丢弃,我尝试过使用Read,但我不确定如何使用防错方法,因为我可能会一个接一个地收到多个数据包,我无法知道会有另一个数据包进来。在数据包之间,BytesToRead为0,因此我无法使用它。当将数据读取到缓冲区时,您是否有计时器或将线程置于睡眠状态以允许所有数据包到达 我迷路了。不知道下一步该做什么 我应该提到的是,我不能保证从串行端口输出的字符串将以\n或\r或\r\n结尾。我只需要一个简单的方法来读取所有的数据包,当用户按下打印时,将来自规模 有人在这里回答

我尝试过使用Readline,数据被丢弃,我尝试过使用Read,但我不确定如何使用防错方法,因为我可能会一个接一个地收到多个数据包,我无法知道会有另一个数据包进来。在数据包之间,BytesToRead为0,因此我无法使用它。当将数据读取到缓冲区时,您是否有计时器或将线程置于睡眠状态以允许所有数据包到达

我迷路了。不知道下一步该做什么

我应该提到的是,我不能保证从串行端口输出的字符串将以\n或\r或\r\n结尾。我只需要一个简单的方法来读取所有的数据包,当用户按下打印时,将来自规模


有人在这里回答我喜欢的想法-等待一定时间的所有数据包,但他们删除了他们的答案。你有没有可能再发一次?

你有没有试着听过这堂课的内容


我们不久前也经历了同样的过程

读取“数据包”的唯一方法是了解数据包的开始和结束在流中的位置

发件人:

因为SerialPort类缓冲数据,而BaseStream属性中包含的流不缓冲数据,所以这两个类可能会在可读取的字节数方面发生冲突。BytesToRead属性可以指示有字节要读取,但这些字节可能无法被BaseStream属性中包含的流访问,因为它们已缓冲到SerialPort类

我们使用了一个反向线程,您可以使用BackgroundWorker将数据读入缓冲区。 如果您不能使用SerialPort.Newline属性可靠地设置终止字符,例如,因为它会变化!然后,您将需要实现自己的数据包检测系统,因为您将无法使用阻塞SerialPort.Readline方法

您可以使用SerialPort.read或string,使用SerialPort.ReadExisting方法读入字节缓冲区,并在检测到数据中的有效数据包时生成事件。请注意,Read和我假设ReadExisting将清空SerialPort的缓冲区,因此您需要将数据保存在其他地方

如果设置SerialPort.ReadTimeout,则可以处理TimeoutException,并且可以轻松地处理设备不传输的情况。如果您使用的是固定字节数或其他非终止方案,这是重置数据包检测的一个好方法。如果不需要部分数据包,请在超时时使用SerialPort.DiscardInBuffer


祝你好运

因为字节可能随时进入,缓冲传入数据至关重要。所以你应该

缓冲传入的数据 扫描缓冲区以查找完整数据 从缓冲区中删除使用过的数据 我只是想知道你的串口是否还有问题。如果是这样的话,我用C语言开发了一种串口编程语言,我相信它几乎解决了所有人遇到的所有问题

请你看一看并试一试好吗?例如您可以像下面这样缓冲来自串行端口的传入数据,并轻松地执行字符串操作

state Init
  // define a global variable
  our $BUFFER = "";
  jump(Receive);
end state

state Receive
  recv();
  $len = length($DATA_PACKET);
  if("$len > 0") {
    $BUFFER += $DATA_PACKET;
    call(Parser);
  }
end state

state Parser
  // check if buffer matchs regular expression pattern
  if(match($BUFFER, "(?<WILLDELETE>.*?<STX>(?<DATA>.*?)<ETX>(?<CHECKSUM>[0-9A-F]{2}))")) {
    // Received complete data
    $lenData = length($WILLDELETE);
    $BUFFER = remove($BUFFER, 0, $lenData);

    // Do operations with the other parsed fields. $DATA and $CHECKSUM in this example.
  }
end state
该项目在sourceforge上免费提供,如果您有任何问题,请随时提问


据我所知,没有检测方案。我将尝试计时——在处理数据包之前等待几毫秒,以允许数据包到达。我看不到任何其他选择。我使用ReadLine已经6个月了,直到有人注意到数据丢失的错误。我们使用了很多工业规模,您通常可以在设备中设置终止字符。您是否可以控制输入设备,以便查看此信息?ReadLine更简单:我们有:\n ascii 13。我将尝试使用SerialPort.ReadByte逐字节读取数据,然后查找13。我还要将SerialPort.NewLine设置为\n我现在将它设置为\r\n…嗯,也许这就是问题所在。谢谢很抱歉出现这种混乱:最初我将SerialPort.NewLine设置为\n,但这不起作用,这就是我切换到\r\n的原因。到目前为止,我一直使用ReadLine。不能保证在串行端口上实际读取的数据是serialPort.BytesToRead。我建议检查serialPort.Read的返回值。
state Init
  // define a global variable
  our $BUFFER = "";
  jump(Receive);
end state

state Receive
  recv();
  $len = length($DATA_PACKET);
  if("$len > 0") {
    $BUFFER += $DATA_PACKET;
    call(Parser);
  }
end state

state Parser
  // check if buffer matchs regular expression pattern
  if(match($BUFFER, "(?<WILLDELETE>.*?<STX>(?<DATA>.*?)<ETX>(?<CHECKSUM>[0-9A-F]{2}))")) {
    // Received complete data
    $lenData = length($WILLDELETE);
    $BUFFER = remove($BUFFER, 0, $lenData);

    // Do operations with the other parsed fields. $DATA and $CHECKSUM in this example.
  }
end state