Reputation: 352
I need to read a message coming from a CAN
network every 20ms
. For this purpose I made a function which works defined below. It's kind of work around, but does the job.
public void Read_CAN_RC_Message()
{
bool a = true;
while (a)
{
Stopwatch t = Stopwatch.StartNew();
// My actual Function Starts Here
int rMulti = CANbus.CAN_Receive_multiple_nonblock(recieveMsg, 5);
if (0 < rMulti)
{
count++;
for (int k = 0; k < rMulti; k++)
{
if (recieveMsg[k].id == 0x400)
{
currentX = 0;
currentY = 0;
currentX = currentX | recieveMsg[k].data[3];
currentX = (currentX << 8) | recieveMsg[k].data[2];
currentX = (currentX << 8) | recieveMsg[k].data[1];
currentX = (currentX << 8) | recieveMsg[k].data[0];
currentY = currentY | recieveMsg[k].data[7];
currentY = (currentY << 8) | recieveMsg[k].data[6];
currentY = (currentY << 8) | recieveMsg[k].data[5];
currentY = (currentY << 8) | recieveMsg[k].data[4];
}
// Function Ends here
int timestep = t.Elapsed.Milliseconds; // To measure Time Needded to complete the Operation
timeCheck.Rows.Add(timestep,str);
}
while (t.Elapsed < timer20ms)
{
// Nothing
}
}
}
I soon realized that the operation takes 2ms
to complete and for remaining 18ms
my processor is stuck in an infinite loop. So this operation requires its own separate thread which always works (using the Processor). Is there a neater a more professional way to do this. Please suggest. I need to run this application in a separate thread as it has to run always as soon as the application starts till it shuts down.
Upvotes: 4
Views: 246
Reputation: 2603
I recommend Thread.Sleep
with a few additional tricks:
Request a high timer resolution: MSDN: Obtaining and Setting Timer Resolution. You can probably find the C# signatures on pinvoke.net
Use the Stopwatch
class to calculate the length of the wait period. Do not call Sleep if the period is less than 1ms.
Increase your thread priority using the Thread
class
Do expensive calculations on another thread if possible.
Optional: Use busy waiting after Thread.Sleep for up to 1 ms in order to get better pricision. Use Thread.SpinWait for this.
Combining 1. and 2. gave me enough precision to implement a frame brake for a game without causing stutter/lag.
Upvotes: 0
Reputation: 2880
In case of device that send data periodicaly you must use asynchronous way to get data.
To provide you complete solution or advice, show the full contract of CANbus dll.
Also it would be better if you explained the main task.
Upvotes: 0
Reputation: 352
I found a solution at other website. I am placing the Link, I have tested this and it works amazingly http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer Hope it will help people in future. Thanks for all your help. It is really appreciated. @idstam Thanks for sending me the MSDN Link. It taught me a thing or two.
Upvotes: 0
Reputation: 348
you can use the Timer with 20ms Timer_Elpased. Or you can put your thread in sleep mode for 15-20 milli secs. Thread.Sleep(20)
Upvotes: 1
Reputation: 2878
Use the Timer class. You can make it call your function every 20ms.
https://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.110).aspx
Upvotes: 2