PowerMeter 类:串口通信数据获取优化
public class PowerMeter { private SerialPort port; private int handshakeAttempts = 0; private int dataRetrievalAttempts = 0;
// 打开串口并发送握手命令
public void OpenPort(PowerMeterInfo powerMeterInfo)
{
port = new SerialPort(powerMeterInfo.Port, powerMeterInfo.BaudRate);
port.Open(); // 打开串口
string result = SendCommand('?'); // 发送握手命令
while (result != '.' && handshakeAttempts < 500) // 循环发送握手命令直到握手成功或达到最大重试次数
{
result = SendCommand('?');
handshakeAttempts++;
}
if (handshakeAttempts >= 500) // 如果握手失败次数达到500次,则关闭端口并抛出异常
{
port.Close();
throw new Exception('握手未成功');
}
else // 如果握手成功,则用多线程或者异步线程调用GetCompleteData()方法
{
Task.Run(() => GetCompleteData());
}
}
// 关闭串口
public void ClosePort()
{
port.Close(); // 关闭串口
}
// 发送命令并读取返回数据
private string SendCommand(string cmd)
{
port.Write(cmd); // 发送命令
System.Threading.Thread.Sleep(2); // 等待2毫秒
return port.ReadExisting(); // 读取返回数据
}
// 发送命令并读取返回数据,直到获取完整的数据字符串
private string GetCompleteData()
{
string cmd = 'T'; // 获取数据命令
string data = '';
string result = '';
int dataRetrievalAttempts = 0;
while (!data.StartsWith('A') && !data.StartsWith('B') && !data.StartsWith('C') && !data.StartsWith('D') && !data.StartsWith('E') && !data.StartsWith('F') && !data.StartsWith('G') && dataRetrievalAttempts < 20)
{
result = SendCommand(cmd); // 发送命令
if (result != '') // 如果返回数据不为空,则拼接数据
{
data += result;
}
else // 如果返回数据为空,则增加重试次数
{
dataRetrievalAttempts++;
}
}
if (dataRetrievalAttempts >= 20) // 如果连续20次没有数据返回,则关闭串口并抛出异常
{
port.Close();
throw new Exception('获取数据错误');
}
else // 如果数据获取成功,则处理数据
{
while (!data.EndsWith('V'))
{
result = SendCommand(cmd); // 发送命令
if (result != '') // 如果返回数据不为空,则拼接数据
{
data += result;
}
}
// 处理数据
}
}
}
原文地址: https://www.cveoy.top/t/topic/mFfo 著作权归作者所有。请勿转载和采集!