1

i'd like to switch bit with time shorter than 1 ms. I'd prefer do this in C# Windows Forms, but it can be in for example console app in C++, C#. What i want to do is to switch bit and send it via LPT port.

Switching bit in this code is to slow..

PortAccess.Output(888,1);
Thread.Sleep(1);
PortAccess.Output(888,0);
Thread.Sleep(1);

I've read this post: How to use QueryPerformanceCounter? , but it's only timer..

Please help :)

Community
  • 1
  • 1
Elfoc
  • 3,649
  • 15
  • 46
  • 57

3 Answers3

3

There is no easy or obvious way to do this kind of fine-grained timing control in the C#/.NET environment. You can use the Stopwatch class to get close, but the resolution isn't great for real-time work. To use a timer to do something like this - nonsense code but you loop until the time elapsed is your desired interval:

Stopwatch swatch = new Stopwatch();

while(true)
{
    swatch.Reset();
    swatch.Start();
    PortAccess.Output(888, 1);
    while (swatch.ElapsedMilliseconds < 1) { }

    swatch.Stop();
    swatch.Reset();
    swatch.Start();
    PortAccess.Output(888, 0);
    while (swatch.ElapsedMilliseconds < 1) { }
    swatch.Stop();
}

Sleep should not be used for timing anywhere. Sleep only basically says, "sleep for at least X milliseconds". So Sleep(1) might sleep for 25ms.

And a by-the-way: next to no PCs have parallel ports anymore. This is an ancient - no, the most ancient way to write bits or flip outputs external to a PC. Doing it by directly outputting to a PC IO port is really rubbish too. You could look for an external digital IO device/board/interface with a decent driver - much better idea.

Kieren Johnstone
  • 41,277
  • 16
  • 94
  • 144
  • I'm using LPT to communicate with external CNC driver. For that i was using MACH3 Software, which is working in driver level. My app doesn't need to be very precise in timing, and after adding your code speed of stepper motor is OK :) – Elfoc Jul 14 '11 at 08:37
1

First, you have to be aware that Sleep() does not have such a fine resolution. Usually it's about 20ms resolution, so that your calls will wait much longer than what you want.

Second, in a system like Windows which is not providing realtime warranties you cannot rely on being able to actually perform something each millisecond, even if you keep the thread alive (using Spinwait() for instance). The thread may and will still be interrupted by the OS in the normal task switching process and therefore you'll have periods of no activity for up to several milliseconds.

In short, don't try that. It will not work.

Lucero
  • 59,176
  • 9
  • 122
  • 152
1

Keeping in mind that what Lucero and Kieren, I'll still answer your question.

You can use the Stopwatch to get sub-millisecond precision using Ticks where 1 Tick== 1/10,000 millisecond. For example here wait 1/10 millisecond:

    Stopwatch sw = Stopwatch.StartNew();
    while (sw.ElapsedTicks <1000);
    Debug.Print(sw.ElapsedTicks.ToString());

You should make sure that Stopwatch has a high enough frequency for your needs on the system you'll be using it. Also, please remember that you are not at the driver level here, so there is nothing approaching real-time guarantees with this.