C#串口随机return重载时全0
C# Serial port randomly return all 0 when overloaded
我正在为一个使用 MCU 的项目制作一个 C# 用户界面,该项目使用 UART 与 PC 通信。 MCU发来的字符串格式为(每组3个数,3组):
<number>,<number>,<number>,.<number>,<number>,<number>,.<number>,<number>,<number>,.\n
每个数字都可以根据MCU发送而变化。我已经编写了一个程序,可以很好地适应这种配置。一般是把COM口的数据作为一个字符串,过滤掉所有非数字的字符,然后分别存入一个List中。
但是,当我们将格式扩展为每组使用 7 个数字(总共 21 个)时:
<number>,<number>,<number>,<number>,<number>,<number>,<number>,.<number>,<number>,<number>,<number>,<number>,<number>,<number>,.<number>,<number>,<number>,<number>,<number>,<number>,<number>,.\n
当我尝试同样的方法时,输入的数据中有某种"stagger"。当数据稳定时,就可以了。当传入的数字有任何快速变化时,数据图如下所示:
图表中间的急剧下降不是数据如何变化; UART端口只是"freeze up"并且接收列表中的所有数字都输出0,我自己检查了Hercules的数据。
我认为问题来自过载,因为 3 和 7 数字数据流之间在任何其他方面都没有差异,但是 Whosebug 用户可以想到任何其他解决方案吗?
编辑:如果有帮助,这是我使用的代码:
// Initialization
static SerialPort mySerialPort;
string receiveMessage = "";
public delegate void AddDataDelegate(string text);
public AddDataDelegate DELEGATE_WRITE;
DELEGATE_WRITE = new AddDataDelegate(writeConsole);
// com and baud are defined variables
mySerialPort = new SerialPort(com, baud);
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_datareceived);
mySerialPort.Open();
//Supporting functions
private void mySerialPort_datareceived(object sender, SerialDataReceivedEventArgs e)
{
string input = mySerialPort.ReadExisting();
textBox.BeginInvoke(method: DELEGATE_WRITE, args: new Object[] { input });
}
public void writeConsole(string text)
{
receiveMessage += text;
// check if the receiving data steam is valid: end with '\n' and not longer than 64 characters (21 value of maybe 2-3 digits each)
if (receiveMessage.Length > 64)
{
receiveMessage = "";
}
if (receiveMessage.Length > 0)
if (receiveMessage[receiveMessage.Length - 1] == '\n')
{
updateInterface(receiveMessage);
receiveMessage = "";
}
return;
}
void updateInterface(string input)
{
try
{
int[] result = calculate(input);
if (result == null)
{
MessageBox.Show("Error", caption: "Algorithm fail to extract data", buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Error);
return;
}
//Save the data to List
}
static int[] calculate(string input)
{
int[] outputs = new int[21];
int index = 0;
string s = "";
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (c == '.')
{
int output = int.Parse(s);
outputs[index] = output;
index++;
s = "";
}
else if (c >= '0' && c <= '9'|| c == '-')
{
s += c;
}
}
return outputs;
}
细节决定成败
在我的代码的 writeConsole 函数中,我通过检查它们是否以 '\n' 结尾(因为数据将实时传入)以及它们是否少于 64 个字符长(可能是 21 个值)来检查有效字符串每个 2-3 个数字)。事实证明,当数据变化足够快(在我的示例中,变化可能达到 100)时,数据很容易达到两倍长,这根本不是一个正确的假设。所以只要删除长度检查,程序就会照常工作。
PS: 来吧伙计们,这是我第二次必须回答我自己的问题了
我正在为一个使用 MCU 的项目制作一个 C# 用户界面,该项目使用 UART 与 PC 通信。 MCU发来的字符串格式为(每组3个数,3组):
<number>,<number>,<number>,.<number>,<number>,<number>,.<number>,<number>,<number>,.\n
每个数字都可以根据MCU发送而变化。我已经编写了一个程序,可以很好地适应这种配置。一般是把COM口的数据作为一个字符串,过滤掉所有非数字的字符,然后分别存入一个List中。
但是,当我们将格式扩展为每组使用 7 个数字(总共 21 个)时:
<number>,<number>,<number>,<number>,<number>,<number>,<number>,.<number>,<number>,<number>,<number>,<number>,<number>,<number>,.<number>,<number>,<number>,<number>,<number>,<number>,<number>,.\n
当我尝试同样的方法时,输入的数据中有某种"stagger"。当数据稳定时,就可以了。当传入的数字有任何快速变化时,数据图如下所示:
// Initialization
static SerialPort mySerialPort;
string receiveMessage = "";
public delegate void AddDataDelegate(string text);
public AddDataDelegate DELEGATE_WRITE;
DELEGATE_WRITE = new AddDataDelegate(writeConsole);
// com and baud are defined variables
mySerialPort = new SerialPort(com, baud);
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_datareceived);
mySerialPort.Open();
//Supporting functions
private void mySerialPort_datareceived(object sender, SerialDataReceivedEventArgs e)
{
string input = mySerialPort.ReadExisting();
textBox.BeginInvoke(method: DELEGATE_WRITE, args: new Object[] { input });
}
public void writeConsole(string text)
{
receiveMessage += text;
// check if the receiving data steam is valid: end with '\n' and not longer than 64 characters (21 value of maybe 2-3 digits each)
if (receiveMessage.Length > 64)
{
receiveMessage = "";
}
if (receiveMessage.Length > 0)
if (receiveMessage[receiveMessage.Length - 1] == '\n')
{
updateInterface(receiveMessage);
receiveMessage = "";
}
return;
}
void updateInterface(string input)
{
try
{
int[] result = calculate(input);
if (result == null)
{
MessageBox.Show("Error", caption: "Algorithm fail to extract data", buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Error);
return;
}
//Save the data to List
}
static int[] calculate(string input)
{
int[] outputs = new int[21];
int index = 0;
string s = "";
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (c == '.')
{
int output = int.Parse(s);
outputs[index] = output;
index++;
s = "";
}
else if (c >= '0' && c <= '9'|| c == '-')
{
s += c;
}
}
return outputs;
}
细节决定成败
在我的代码的 writeConsole 函数中,我通过检查它们是否以 '\n' 结尾(因为数据将实时传入)以及它们是否少于 64 个字符长(可能是 21 个值)来检查有效字符串每个 2-3 个数字)。事实证明,当数据变化足够快(在我的示例中,变化可能达到 100)时,数据很容易达到两倍长,这根本不是一个正确的假设。所以只要删除长度检查,程序就会照常工作。
PS: 来吧伙计们,这是我第二次必须回答我自己的问题了