Link to home
Start Free TrialLog in
Avatar of Roza
RozaFlag for Slovenia

asked on

Thread&time critical port processing

Hi!

I am developing application which controls DTR singnal on com port or set some values on LPT port.

I am using delphi6&7.

For com port handling I use CPortLib, for LPT SmallPort.

The problem I don't know how to make processing accurate as it can be.

My tehnique:

On Execute:

while not self.terminated do
begin
  - some non time critical processing.
  .
  .
  TimeCriticalProcedure(str);
end  
 

TimeCriticalProcedure:

start of loop which calculates times based on some values passed in string...
  - CalculateTimeDTR should be on
  SetDTR(true,stoptime,durationtime)
  calculate TimeDTR should be off
  SetDTR (false, stoptime, durationtime)
end of loop

procedure TMyThread.SetDTR(onoff: boolean;var StopTime: Cardinal;DurationTime: Cardinal);
begin
   while Windows.GetTickCount<StopTime do Sleep(1);
   if onoff then ComPort.SetDTR(true)
   else ComPort.SetDTR(false);
   StopTime:=StopTime+DurationTime;
end;

Priority of thread is set to tpTimeCritical.

What to do to maximum accurracy of port output.
ComPort&LPT components are created in thread.

Basicaly my thread does not need processor all the time, but only when the right time comes.

Some questions will be posted later. Thanks for any hints/ideas....
Avatar of mokule
mokule
Flag of Poland image


Are You aware that GetTickCount has resolution 10ms or 55ms depending on Win version
Is it enough for You?

mokule
ASKER CERTIFIED SOLUTION
Avatar of mokule
mokule
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Roza

ASKER

Hm. I did not know that about GetTickCount's resolution.

I know Win is not good for these tasks, but I know it should be ok for my task.
Avatar of Molando
Molando

GetTickCount is not your friend. A TTimer is painfull, as ends up being a windows message.

The best you could  use would be to go for the windowsAPI functions TimeSetEvent and TimeKillEvent. These functions work on callback events, rather than windows messages. Just a warning, the finer you set the timer, the more you will slow other things down.

Oh and in true microsoft stylie these sorts of timers are known multimedia timers, as multimedia programs need very accurate timers :)

Molando.

Hit f1 in delphi on TimerSetEvent, they are fairly straight forward.
@Molando
But TimeSetEvent still allows milliseconds resolution whilst QueryPerformanceCounter allows microseconds resolution.

mokule
don't use a tight loop like that in a TimeCritical thread !
instead calculate the time needed to wait and wait for it
like: WaitForSingleObject(Handle, StopTime - GetTickCount)
leave it at normal priority .. you really won't benefit much with using a timecritical thread
in the case of you current design you're only slowing everything else down and not gaining anything
Avatar of Roza

ASKER

Hi!

I have analyzed my problem and figured out that 1ms precision is not good enough since smallest time to have DTR unchanged is 40ms, could be even less.

Setting process priority to TimeCritical means a lot. If I set it to normal there is significant distortion (special when doing some other operation on system - like browsing&file copying) in signals going out if not there is qute an improvement, but not good enough.

Probably there is next step to try combine WaitForSingleObject(time*0.9) and then last few ms's doing
QueryPerformanceCounter(time2)
while (restoftime>time2) do QueryPerformanceCounter(time2)

Is that good way or not?

I will also have a look at TimeSetEvent...