c# - 写入串口后如何读取串口直到超时?
问题描述
我需要从串口向我的设备写入和读取数据。我已经测试了某些方法,起初我正在使用接收数据SerialDataReceivedEventArgs
,我觉得很难读取我需要定义发送命令的端口,因为命令几乎是 200 个命令。
我的第一种方法是使用:-
private void ObjCom_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (!ObjCom.IsOpen) return;
byte[] data = new byte[ObjCom.BytesToRead];
ObjCom.Read(data, 0, data.Length);
RaiseEventMsg("Buffer String: " + BitConverter.ToString(data).Replace("-", " "));
}
这RaiseEventMsg
是一个将当前信息传递给主 UI 的委托事件。第二种方法是:-
private long lngTickCount = Convert.ToInt64(1000L);
public void StartWriteToPort()
{
byte[] Cmd = null;
string strCmd = string.Empty;
string strMsg = null;
bool bCont = true;
long lngCurrent = 0;
long lngNow = 0;
try
{
RaiseEventMsg("Start Write To Port");
ObjCom.DiscardOutBuffer();
ObjCom.DiscardInBuffer();
GetFullCommandByte(ref Cmd, Convert.ToByte(123)); // Referencing Cmd with return and pass Command List(various set of command)
ObjCom.Write(Cmd, 0, Cmd.Length);
strCmd = ByteArrayToString(Cmd); // Convert byte array to Hex string
RaiseEventMsg("Send: " + strCmd);
bool bTimeout = false;
lngCurrent = DateTime.Now.Ticks;
while (!bTimeout)
{
lngNow = DateTime.Now.Ticks;
if (lngNow > (lngCurrent + (3 * lngTickCount)))
{
bTimeout = true;
break;
}
}
lngCurrent = DateTime.Now.Ticks;
while (ObjCom.BytesToRead <= 0)
{
lngNow = DateTime.Now.Ticks;
if (lngNow > (lngCurrent + (1000 * lngTickCount)))
{
bCont = false;
break;
}
}
if (!bCont)
{
strMsg = "Error - Timeout Hit";
RaiseEventMsg(strMsg);
return;
}
int Idx = 0;
string strASCIIFull = string.Empty;
if ((ObjCom.BytesToRead > 0) & (bCont == true))
{
while (ObjCom.BytesToRead > 0)
{
var strASCII = ObjCom.ReadByte();
var TmpHex = System.Convert.ToString(strASCII, 16).ToUpper();
if (TmpHex.Length == 1)
{
strASCIIFull += (" 0" + TmpHex);
}
else
{
strASCIIFull += (" " + TmpHex);
}
lngCurrent = DateTime.Now.Ticks;
while (ObjCom.BytesToRead <= 0)
{
lngNow = DateTime.Now.Ticks;
if (lngNow > (lngCurrent + (2 * lngTickCount)))
{
bCont = false;
break;
}
}
Idx += 1;
}
}
RaiseEventMsg("Recv: " + strASCIIFull);
}
catch (System.Exception ex)
{
string error = $"Exception on StartWriteToPort. Message: {ex.Message}. StackTrace: {ex.StackTrace}";
}
}
第二种方法的问题是,当我第二次调用此函数时,超时将命中。但是对于串行事件,它没有问题,超时协议设置为1秒。我的设备当前使用没有转换器的 USB 连接。设备的输入电缆是 B 型端口(如标准打印机端口)。
是否有任何其他方式可以直接从端口读取或对当前代码进行任何改进?
解决方案
您需要学习如何分层代码。目前你有一个很长的函数试图做所有的事情。
如果您有几个较小的函数来执行特定的操作,例如读取或写入大量信息,那么它将使您尝试做的事情变得更简单。
例如,串行通信通常有某种协议来封装信息包的存储方式。假设协议是“”,那么您知道每个数据包都以一个 STX 字节(0x01)开头,一个长度字节,它告诉您该部分中有多少字节,并且末尾必须有一个 ETX 字节(0x02)。您可以编写一个函数,该函数将返回一个字节数组,因为该函数将解释流并提取相关部分。
那么它可能很简单:
var packet1 = ReadPacket();
WritePacket(outputData);
var packet2 = ReadPacket();
推荐阅读
- mysql - Jackson @JsonIgnore 注释 - 不返回关系值
- swift - 使用变量将函数快速存储为 Obj-C 或 C++ 中的指针函数
- node-http-proxy - 正在修改代理的 HTTP 响应
- react-native - 外部范围 this 在 js 中丢失然后函数
- google-apps-script - 删除了通过应用脚本嵌入 gmail 的谷歌文档的格式
- c# - 有条件地拿走部分或全部物品
- cron - 未在 VestaCP (CentOs) 中运行的 Cron 作业
- react-native - Redux Native 如何使用 react-navigation-redux-helpers 导航
- r - 使用 multidplyr 进行矢量化不会呈现正确的输出
- php - 使用用户输入的 SQL 过滤器(如果提供)