Timer2

when I run this bit of code, there are two things that baffle me.
Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?


[code]
PROGRAM Time;
USES Crt, Dos;
VAR hb, mb, sb, hsb: Word;
h, m, s, hs: Word;


BEGIN
ClrScr;
GetTime(hb, mb, sb, hsb);
Repeat
GotoXY(1, 1);
GetTime(h, m, s, hs);
write(m,':', s,':', hs);
UNTIL Keypressed;
GotoXY(10,10);
Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
Readln;
END.
[/code]

Comments

  • : when I run this bit of code, there are two things that baffle me.
    : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
    : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
    :
    :
    : [code]
    : PROGRAM Time;
    : USES Crt, Dos;
    : VAR hb, mb, sb, hsb: Word;
    : h, m, s, hs: Word;
    :
    :
    : BEGIN
    : ClrScr;
    : GetTime(hb, mb, sb, hsb);
    : Repeat
    : GotoXY(1, 1);
    : GetTime(h, m, s, hs);
    : write(m,':', s,':', hs);
    : UNTIL Keypressed;
    : GotoXY(10,10);
    : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : Readln;
    : END.
    : [/code]
    :
    1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.

    2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
  • : : when I run this bit of code, there are two things that baffle me.
    : : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
    : : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
    : :
    : :
    : : [code]
    : : PROGRAM Time;
    : : USES Crt, Dos;
    : : VAR hb, mb, sb, hsb: Word;
    : : h, m, s, hs: Word;
    : :
    : :
    : : BEGIN
    : : ClrScr;
    : : GetTime(hb, mb, sb, hsb);
    : : Repeat
    : : GotoXY(1, 1);
    : : GetTime(h, m, s, hs);
    : : write(m,':', s,':', hs);
    : : UNTIL Keypressed;
    : : GotoXY(10,10);
    : : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : : Readln;
    : : END.
    : : [/code]
    : :
    : 1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.
    :
    : 2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
    :

    So whats the best way around the first problem. How would one go about making an elegant timer in pascal that will know how long it took from the time a program displays an image to someone pressing a key on the keyboard?
  • : : : when I run this bit of code, there are two things that baffle me.
    : : : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
    : : : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
    : : :
    : : :
    : : : [code]
    : : : PROGRAM Time;
    : : : USES Crt, Dos;
    : : : VAR hb, mb, sb, hsb: Word;
    : : : h, m, s, hs: Word;
    : : :
    : : :
    : : : BEGIN
    : : : ClrScr;
    : : : GetTime(hb, mb, sb, hsb);
    : : : Repeat
    : : : GotoXY(1, 1);
    : : : GetTime(h, m, s, hs);
    : : : write(m,':', s,':', hs);
    : : : UNTIL Keypressed;
    : : : GotoXY(10,10);
    : : : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : : : Readln;
    : : : END.
    : : : [/code]
    : : :
    : : 1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.
    : :
    : : 2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
    : :
    :
    : So whats the best way around the first problem. How would one go about making an elegant timer in pascal that will know how long it took from the time a program displays an image to someone pressing a key on the keyboard?
    :
    You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
    [code]
    GetTime(hb, mb, sb, hsb);
    Repeat
    UNTIL Keypressed;
    GetTime(h, m, s, hs);
    GotoXY(10,10);
    Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    [/code]
    The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
  • : : : : when I run this bit of code, there are two things that baffle me.
    : : : : Firstly, why do the hundreth seconds seemingly randomly appear with extra digets such as '655'
    : : : : Secondly, why does pascal refuse to display the 'Writeln' outside of the 'Repeat Until ' Loop if I press 'enter'? It works fine if I press any other key on the keyboard...?
    : : : :
    : : : :
    : : : : [code]
    : : : : PROGRAM Time;
    : : : : USES Crt, Dos;
    : : : : VAR hb, mb, sb, hsb: Word;
    : : : : h, m, s, hs: Word;
    : : : :
    : : : :
    : : : : BEGIN
    : : : : ClrScr;
    : : : : GetTime(hb, mb, sb, hsb);
    : : : : Repeat
    : : : : GotoXY(1, 1);
    : : : : GetTime(h, m, s, hs);
    : : : : write(m,':', s,':', hs);
    : : : : UNTIL Keypressed;
    : : : : GotoXY(10,10);
    : : : : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : : : : Readln;
    : : : : END.
    : : : : [/code]
    : : : :
    : : : 1: The internal clock is updated only once around the 20 ms. Thus any timer based on GetTime() cannot go lower than that. Secondly there is also the 50-100 Hz refresh-rate of the monitor, which creates an interference pattern with the clock producing seemingly random milliseconds.
    : : :
    : : : 2: KeyPressed doesn't clear the keyboard buffer. This means that any keypresses inside the loop still exist after it. These are then handled by the readln(). Since ENTER ends the readln() statement, an ENTER will move the program to the next statement: "end.", ending the program and closing the window. If you run the program in a DOS window (Start > Run > cmd) then you will see the time, followed by the DOS prompt.
    : : :
    : :
    : : So whats the best way around the first problem. How would one go about making an elegant timer in pascal that will know how long it took from the time a program displays an image to someone pressing a key on the keyboard?
    : :
    : You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
    : [code]
    : GetTime(hb, mb, sb, hsb);
    : Repeat
    : UNTIL Keypressed;
    : GetTime(h, m, s, hs);
    : GotoXY(10,10);
    : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : [/code]
    : The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
    :

    1) If the clock increments ever 20milliseconds, then why does my timer display 2 seconds and 57milliseconds? (0:2:57)

    2)How does one clear the keyboard buffer?

    3) Is there any way around the monitor refreshments which create those annoying 655's or 654's?

  • : 2)How does one clear the keyboard buffer?
    :
    : 3) Is there any way around the monitor refreshments which create those annoying 655's or 654's?


    To clear the keyboard buffer, use READKEY. readkey is a function, so you can call it with or without a variable assignment. To just clear the buffer, call READKEY. To find out what key was pressed, use:
    [code]
    VAR
    key : Char;
    Begin
    Repeat
    If Keypressed Then
    Key := Readkey;
    GotoXY(1,1); Write(ORD(Key));
    Until Key = #13;
    End.
    [/code]
    This will repeat until you press ENTER.

    As for the flickering 655s, try using a [b]DELAY(1);[/b] after the Write procedure.

  • : You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
    : [code]
    : GetTime(hb, mb, sb, hsb);
    : Repeat
    : UNTIL Keypressed;
    : GetTime(h, m, s, hs);
    : GotoXY(10,10);
    : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : [/code]
    : The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
    :

    That's why I prefer to use the clock in memory. It is just a continuous counter, so you don't need to take into account minutes, hours, etc passing by. Just subtract the 2 numbers and you have a value. If you want actual time, divide the value by 18.2

    [code]
    VAR
    TimeStart,
    TimeEnd : LongInt;
    Begin
    Move(Mem[$0040:$006C],TimeStart,4);

    { BLAH BLAH BLAH, do some stuff here }

    Move(Mem[$0040:$006C],TimeEnd,4);
    WriteLn('Total Clock Ticks : ',TimeEnd-TimeStart);
    WriteLn('Total Time Taken : ',(TimeEnd-TimeStart)/18.2:3:2,' seconds');
    End.
    [/code]

    Phat Nat

  • : : You need to move the GetTime() outside the loop. First you get the starting time, and then the end time of the operation. By subtracting those, you can calculate the length of the operation. This won't work for operations which take less than 20 ms, but otherwise will perform the job quite nicely. Example:
    : : [code]
    : : GetTime(hb, mb, sb, hsb);
    : : Repeat
    : : UNTIL Keypressed;
    : : GetTime(h, m, s, hs);
    : : GotoXY(10,10);
    : : Writeln('Time:',m-mb,':',s-sb,':',hs-hsb);
    : : [/code]
    : : The calculation of this code doesn't take into account the overflow, when operations start at the end of a time unit and end at the beginning of that time unit, for example start at 12:44:55 and end at 12:45:04.
    : :
    :
    : That's why I prefer to use the clock in memory. It is just a continuous counter, so you don't need to take into account minutes, hours, etc passing by. Just subtract the 2 numbers and you have a value. If you want actual time, divide the value by 18.2
    :
    : [code]
    : VAR
    : TimeStart,
    : TimeEnd : LongInt;
    : Begin
    : Move(Mem[$0040:$006C],TimeStart,4);
    :
    : { BLAH BLAH BLAH, do some stuff here }
    :
    : Move(Mem[$0040:$006C],TimeEnd,4);
    : WriteLn('Total Clock Ticks : ',TimeEnd-TimeStart);
    : WriteLn('Total Time Taken : ',(TimeEnd-TimeStart)/18.2:3:2,' seconds');
    : End.
    : [/code]
    :
    : Phat Nat
    :
    :


    I tried your code and it works, but inconsistently... I dont understand why, sometimes, the time it takes is .99seconds, sometimes 1.10 seconds and sometimes .70 seconds etc, even though the delay is always consistent???

    [code]
    PROGRAM Time;
    USES Crt;
    VAR
    TimeStart,
    TimeEnd : LongInt;

    Begin
    Move(Mem[$0040:$006C],TimeStart,4);

    { BLAH BLAH BLAH, do some stuff here }
    ClrScr;
    Delay(1000);

    Move(Mem[$0040:$006C],TimeEnd,4);
    WriteLn('Total Clock Ticks : ',TimeEnd-TimeStart);
    WriteLn('Total Time Taken : ',(TimeEnd-TimeStart)/18.2:3:2,' seconds');
    Readln;
    End.
    [/code]
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories