BBC BASIC for Windows
« Setting Windows tick »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 9:55pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Setting Windows tick  (Read 730 times)
manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Setting Windows tick
« Thread started on: Oct 31st, 2012, 11:24am »

BBC Basic's Help system describes how to use SYS "GetTickCount" to obtain the number of milliseconds since Windows was started. Is it possible to set this value to an arbitrary value or even zero? My aim is to combine the SYS command with external GPS clock data to obtain millisecond real-time resolution within a BBC Basic program.
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: Setting Windows tick
« Reply #1 on: Oct 31st, 2012, 12:56pm »

on Oct 31st, 2012, 11:24am, manxman wrote:
Is it possible to set this value to an arbitrary value or even zero?

No, there's no 'SetTickCount' or equivalent API function. You would have to set a variable equal to the current value and subtract it from subsequent values to achieve a similar effect. Also, bear in mind that the value returned from GetTickCount, whilst guaranteed to be monotonic, is only approximate. Here are a few consecutive values returned on my PC:

Code:
  14127265
  14127281
  14127296
  14127312
  14127328
  14127343
  14127359
  14127375
  14127390
  14127406 

SYS "timeGetTime" may be more reliable in this respect:

Code:
      SYS "timeBeginPeriod", 1
      FOR I% = 1 TO 10
        REPEAT
          O% = C%
          SYS "timeGetTime" TO C%
        UNTIL C% <> O%
        PRINT C%
      NEXT 


Quote:
My aim is to combine the SYS command with external GPS clock data to obtain millisecond real-time resolution within a BBC Basic program.

Remember that Windows is not a Real-Time Operating System. It doesn't matter what software tricks you employ, you can never achieve (reliable) millisecond resolution in a program running under Windows.

Richard.
User IP Logged

manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Re: Setting Windows tick
« Reply #2 on: Oct 31st, 2012, 5:41pm »

laugh Richard,

Thanks for your speedy reply and the tip for an alternative Windows function. I did think about subtracting an offset, as you suggest, but thought there might be a better way. My requirement is to precisely time each reading in a stream of data sent at 20/s from a geophysical instrument.

What I plan to do now is to use a GPS module and a commercial utility (NMEA Time) to periodically reset the PC clock, which will still have a jitter due to latency in the OS and small steps each time there is a clock reset. These effects will be smoothed out by applying piecewise interpolation to successive segments of, say 1 hour, to give monotonic smooth times for my data stream. I guess this the best that can be done!
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: Setting Windows tick
« Reply #3 on: Oct 31st, 2012, 10:49pm »

on Oct 31st, 2012, 5:41pm, manxman wrote:
My requirement is to precisely time each reading in a stream of data sent at 20/s from a geophysical instrument.

Define "precisely"! As I said before, Windows is not a Real Time OS, and millisecond timing accuracy is impossible. Threads and processes are scheduled to a CPU core on a time-sharing basis, and each timeslice will occupy at least several milliseconds, possibly tens of milliseconds. So you must make allowances for your program to 'freeze' for that sort of period.

For your kind of application it is normal for the data to be received in a dedicated piece of equipment which attaches precise time-stamps, before passing the data with its time-stamps onto the PC for processing. That way it doesn't matter that the software is not real-time.

If a resolution in the order of 20 milliseconds is acceptable then you may be able to get away with a purely software solution (on a statistical basis - it cannot be guaranteed). In that case you may be able to use timeGetTime with a correction to make it agree with 'clock time' (e.g. from GPS or an internet time server).

Richard.
User IP Logged

manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Re: Setting Windows tick
« Reply #4 on: Nov 4th, 2012, 7:20pm »

Richard,

Thanks for your comments. To avoid composing a very long start to this thread I avoided describing all my thoughts for a 'precise' timing solution, but to tidy things up, here is a more thorough exposition:

There will be six instruments distributed in an array spaced apart 10 - 20km, each logging on a single PC. To be more precise (!) each item in the instruments' data stream needs to be timestamped, either to some arbitrary common time or UTC, to an accuracy of 20mS across the array. Note that each instrument's data stream is only approximately 20Hz, being maintained by a stock quartz crystal. As you say, the PC clock is a very poor standard on which to base 'precise' timing of external events, so there are several solutions to this problem:

1 Have each instrument timestamp the data independently of the PC, e.g. by an integrated GPS, MSF or DCF clock module. This solution avoids the jitter, drift and latency inherent in the PC clock but involves more hardware design for me. Another problem is that radio atomic clock transmitters are sometimes switched off for maintenance.

2 Use a GPS or radio module, combined with a program such as NMEA TIME or TARDIS to continuously correct the PC clock to follow UTC. My logging program will assign timestamps using this 'corrected' PC clock which will have small correction steps due to this process. These would be smoothed with another custom program that corrects the timestamps.

3 Build and integrate a 50Hz mains frequency clock for each instrument. Once all are synchronised on the same cycle, they will keep lock to within 20mS. Exact synchronisation within the array is more important than the actual times being exact UTC. Synchronisation can be achieved by incorporating an TCXO or OCXO in each clock unit, designed to start the 50Hz clocks at the same time after leaving the lab.

Solution 3 is very attractive since each instrument does not need clear RF reception: each would be powered from the mains, which provides the secure timebase. I'll start by experimenting with option 2 though and see how things progress.

Sorry for the imprecise delay in my reply!

Manxman

User IP Logged

manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Re: Setting Windows tick
« Reply #5 on: Nov 8th, 2012, 8:19pm »

Richard,

Referring to your reply, thank you for pointing me to a more effective Windows call which does indeed resolve 1mS. However, I am curious to know what is the purpose of the call at the start of your sample code:

SYS "timeBeginPeriod", 1

Removing this line has no effect on the result, nor does changing the parameter from 1 to 2, 3, 4, etc.

Regards,

Manxman

User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: Setting Windows tick
« Reply #6 on: Nov 8th, 2012, 9:28pm »

on Nov 8th, 2012, 8:19pm, manxman wrote:
Removing this line has no effect on the result, nor does changing the parameter from 1 to 2, 3, 4, etc.

Ah, you need to learn a very important lesson: not all Windows PCs are the same! On my PC (a perfectly ordinary Dell desktop) calling timeBeginPeriod makes a dramatic difference: without it the resolution of timeGetTime is worse than 15ms (the value changes at 64 Hz, the same as GetTickCount). Having called timeBeginPeriod the resolution improves to 1 ms (1000 Hz).

You cannot determine the validity of software by testing alone (not that testing is unimportant of course, but it is not sufficient). You must always abide by what Microsoft state on MSDN which in this case is the following: "The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine. You can use the timeBeginPeriod and timeEndPeriod functions to increase the precision of timeGetTime":

http://msdn.microsoft.com/en-gb/library/windows/desktop/dd757629.aspx

I expect that on your PC some other application, which happens to have been loaded and run before BBC BASIC, has already set the resolution of the timer. But you certainly can't rely on that being the case on a different PC, or even on the same PC if its configuration changes.

Richard.
« Last Edit: Nov 8th, 2012, 9:31pm by admin » User IP Logged

manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Re: Setting Windows tick
« Reply #7 on: Nov 8th, 2012, 9:38pm »

Richard,

Thanks for that detailed explanation. Now all is clear!

Regards,

Manxman
User IP Logged

manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Re: Setting Windows tick
« Reply #8 on: Nov 20th, 2012, 4:52pm »

Richard,

At the risk of becoming a bore, may I ask whether the centiseconds value returned by BBC4W's TIME (after setting to zero) also rolls over in 49 days in the same way as the value returned from SYS "timeGetTime"?

Regards,

Manxman
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: Setting Windows tick
« Reply #9 on: Nov 20th, 2012, 6:05pm »

on Nov 20th, 2012, 4:52pm, manxman wrote:
may I ask whether the centiseconds value returned by BBC4W's TIME (after setting to zero) also rolls over in 49 days

It doesn't if BB4W is running continuously for that time (and assuming you access TIME periodically). In those circumstances you get a true 32-bit count of centiseconds, which will therefore run for about 248 days before overflowing to a negative number (or 496 days before it rolls over fully).

But if you have to restart the PC, or even restart BB4W, (which is pretty likely in a period of 49 days!) then the internal offset gets reset and you lose that extended roll-over capability. You could attempt to work around that limitation by periodically saving the offset to a disk file and then re-loading it when BB4W is restarted, but then the 496-day roll-over would need to be taken account of (and you would still have a problem if the PC was restarted of course).

If you want to experiment with that approach, the offset is stored at !544 (ironically the very next memory location after those documented on the Wiki; I should perhaps add it to the list). Whatever is stored in that location gets added to the returned value of TIME (you can try it yourself).

Richard.
User IP Logged

manxman
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 21
xx Re: Setting Windows tick
« Reply #10 on: Nov 28th, 2012, 5:15pm »

Thank you for another comprehensive reply.

Perhaps I will sit by my PC for 248 days simply to check what you say!

Regards,

Manxman grin
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls