I am making a C# User Interface for a project using MCU communicate with the PC using UART. The string sent from the MCU in this format(3 numbers per group, 3 groups):
<number>,<number>,<number>,.<number>,<number>,<number>,.<number>,<number>,<number>,.\n
With each number can change depend on the MCU sending. I have written a program which work fine for this configuration. In general, it take in the data from COM port as a string, filter out any characters that is not a number, then save them separately into a List.
However, when we expand the format to use 7 numbers per group (21 in total):
<number>,<number>,<number>,<number>,<number>,<number>,<number>,.<number>,<number>,<number>,<number>,<number>,<number>,<number>,.<number>,<number>,<number>,<number>,<number>,<number>,<number>,.\n
When I try the same approach, there is some sort of "stagger" in the data in. When the data is stable, it is fine. When there is any rapid change in the number coming in, the graph of the data look like this: The sharp drop in the middle of the graph is not how the data change; the UART port just "freeze up" and output 0 for all number in the receiving List, I have checked the data from Hercules myself. I think the problem come from overload since there is no differences in any other aspect between the 3 and 7 numbers datastream, but can StackOverflow users think of any other solution? EDIT: Should it helps, here is the code I used:
// 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;
}
Always the devil is in the details
In the writeConsole function of my code, I make a check for valid string by checking if they end in '\n' (since the data will be coming in real time) and if they are less than 64 characters long (21 value of maybe 2-3 digits each). Turn out, that is not a correct assumption at all when the data could easily reach twice as long when the data changed quickly enough (in my examples, the change could reach 100). So just delete the length check and the program work as usual.
PS: Come on guys, this is the second time I have to answer my own question already