Reputation: 101
Iam currently working on a project where i have to read serial port continuously. The data is coming continuously for a max of 45 min. I have to validate the data via checksum and create a packet of 79 bytes. After this i have to plot the data(Trajectory) on a real time basis. The problem with the code is that at start it uses 20% of the CPU usage(Pentium 4, 3.0 GHz, Hyper threading)(which i think is still high) but with time the CPU usage increases and at end it reaches to 60%.
The data is coming in with a baud rate of 115200 and is sent continuously at the rate 100 msec.
My code for reading, validating and plotting is as follows: The following function receive the data and validate it...
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
header1 = serialPort1.ReadByte();
if (header1 == 0)
header2 = serialPort1.ReadByte();
if ((header1 == 0) && (header2 == 1))//Store the data in an array.
{
for (int i = 0; i < 77; i++)
abudata[i] = serialPort1.ReadByte();
tail = abudata[76];
}
else
{
serialPort1.DiscardInBuffer();
}
checksum = 1;// Calculate the checksum.
for (i = 0; i < 74; i++)
checksum = checksum + (abudata[i]);
checksum1 = (abudata[75] << 8);
checksum1 = checksum1 + (abudata[74]);
if ((checksum == checksum1) && (tail == 4))
this.Invoke(new EventHandler(Display_Results));// Function to display
}
catch (Exception ode)
{
l4[4].BackColor = Color.Red;
}
}
The following function display the data on labels and draw the trajectory on a picture box
private void Display_Results(object s, EventArgs e)
{
head1[0] = header1;
head1[1] = header2;
for (k = 0; k < 77; ++k)
head1[k + 2] = (((int)abudata[k]) & 0x000000ff);
jk = 0;
for (k = 0; k < 36; ++k) //Data packing into 36 bytes
{
num_1[k] = (ulong)((head1[jk + 1]) + (head1[jk] << 8)) & 0x0000ffff;
num_1[k] = (double)num_1[k];
num_2[k] = (double)num_1[k];
jk = jk + 2;
signbit = (int)num_1[k] >> 15;
if (signbit == 1)
{
sgnval = -1;
num_1[k] = num_1[k] - 65535;
num_1[k] = num_1[k] * (-1.0);
}
else
sgnval = 1;
//Converting the data into engineering values
engval[k] = Math.Round(num_1[k] * parammaxval[k] * sgnval / 32767.0, 3);
if (k == 14)
{
try
{
curr_x = (pictureBox2.Width / 2) + (int)((engval[13] * (pictureBox2.Width)) / map_width);
curr_y = (pictureBox2.Height / 2) - (int)((engval[14] * (pictureBox2.Height)) / map_height);
PointF p1 = new Point(curr_x, curr_y);
if (_gPath != null && _gPath.PointCount > 0)
p1 = _gPath.PathPoints[_gPath.PathPoints.Length - 1];
PointF p2 = new Point(curr_x, curr_y);
_gPath.AddLine(p1, p2);
pictureBox2.Invalidate();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
Upvotes: 2
Views: 3111
Reputation: 101
i got what was the problem with the above code..
I am using Graph path for plotting the trajectory
if (k == 14)
{
try
{
curr_x = (pictureBox2.Width / 2) + (int)((engval[13] * (pictureBox2.Width)) / map_width);
curr_y = (pictureBox2.Height / 2) - (int)((engval[14] * (pictureBox2.Height)) / map_height);
PointF p1 = new Point(curr_x, curr_y);
if (_gPath != null && _gPath.PointCount > 0)
p1 = _gPath.PathPoints[_gPath.PathPoints.Length - 1];
PointF p2 = new Point(curr_x, curr_y);
_gPath.AddLine(p1, p2);
pictureBox2.Invalidate();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Now as the application continues to run, it gathers lots of graph points and hence plotting this huge number of point is consuming the resources.
Can anybody suggest me solution to this problem that how to plot the trajectory without slowing the system...
Upvotes: 1
Reputation: 14090
I extensively work with serial port connected devices and may assure you, that regular using of SerialPort class by itself doesn't produce high CPU load.
FIRST I would suggest you to PROFILE your application. There are a bunch of profilers for .NET
Only after profiling I would suggest to decouple SerialPort reading and data processing. Use Producer Consumer pattern. Put data from SerialPort to queue and consume it from other thread.
That what I have in SerialPortDataReceived function in one of my projects
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
lock (SyncObject)
{
if (!_serialPort.IsOpen) return;
try
{
int toread = _serialPort.BytesToRead;
byte[] bytes = new byte[toread];
_serialPort.Read(bytes, 0, toread);
ProducerAddBytes(bytes);
}
catch (TimeOutException)
{
//logic
}
}
}
P.S. But PROFILE FIRST!
Upvotes: 4