Re: Re basic to vb
- From: "Mike Williams" <Mike@xxxxxxxxxxxxxxxxx>
- Date: Sat, 22 Aug 2009 10:31:47 +0100
"Viper900" <Viper900@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:9A2E296E-F7FC-4555-9E6F-D8F1003F7547@xxxxxxxxxxxxxxxx
Thank you to everyone that replied to my post. I have it
working now thanks to Steve for his delay mechanism.
With the delay set at .250 the motor steps really slow,
so i have decreased it to 0,005 but its not as fast as the
original. Can i change the 0,5 value in the delay .
If you're using the delay code that uses the VB Timer function (Do While Timer - sngStart < sngSeconds) then the smallest average delay you are going to get is about 0.015 seconds (or even greater on some early versions of Windows). In fact 0.015 seconds is approximately what you will get with the 0.005 delay value you are currently using. You won't actually get any delays of 0.015 seconds though because of the fact that the Timer function returns a value to the nearest one hundredth of a second, so if you attempt to use a time of 0.005 you will actually get a delay of either 0.010 or 0.020 seconds, with the average of a continuous stream of such delays being 0.015 seconds.
If you want a higher resolution then you can use the multimedia timer, either polling directly in a code loop as you are currently doing or alternatively using the events of a high resolution Timer based on the multimedia timer. For a code loop based solution such as the method you are currently using it is a simple case of changing your time variables from Singles to Longs and calling the timeGetTime function, which returns a value in milliseconds and which is capable of a resolution of one millisecond (0.001 seconds). The default resolution of timeGetTime is one millisecond only on early versions of Windows (Win 95 / 98 as far as I recall) but it can be set to one millisecond on all versions of Windows, including XP and Vista, using a simple call to timeBeginPeriod. This will give you a one millisecond resolution on virtually all systems except very early and very slow machines, in which case the resolution would still be about 2 milliseconds. Your delay Sub (without the DoEvents stuff for simplicity) would look something like this:
Private Sub Delay(tMilliseconds As Long)
Dim tStart As Long
tStart = timeGetTime
Do While timeGetTime - tStart < tMilliseconds
Loop
End Sub
You will of course still need to use DoEvents occasionally (perhaps about ten times per second or maybe more) if you want your program to be user responsive all the time but the most suitable place to do this depends on exactly what the rest of your code looks like so I haven't included it here.
The function declaration and the initialisation code to set up the resolution to one millisecond is as shown below. For simplicity the code sets the resolution in the Form Load event and does not reset it until the Form unloads. Doing it this way used to be frowned upon because changing the basic resolution used to have an effect on Windows thread switching frequency, thereby causing a slight but noticeable slowdown of the system on very slow machines. I'm not sure whether it still does, or whether it actually matters on today's machines, and whether it might therefore be better to set and reset the resolution only for the periods you are actually using the timer, but I can't detect any slowing down of the system at all on any of todays modern machines so I suppose it doesn't really matter a great deal. Ideally though you might be better off setting the resolution only while you are using the timer rather than in the Load etc events, or perhaps leaving it as it is (in the Load / Unload events) and changing it so that it sets the resolution to no less than you actually need. For example, if approximately 5 millisecond delays are the most you will ever require then you could change timeBeginPeriod 1 to timeBeginPeriod 5 (with an equivalent change to timeEndPeriod).
An alternative timing method would be to use a high resolution Timer based on the multimedia time (the timeGetTime stuff). These are a bit difficult to set up properly but there are a few of them "ready made" on various programming sites, although there is nothing intrinsically wrong with continuing to use your current "loop" method, especially if you are ever likely to need resolutions of much less than one millisecond, which you will be able to achieve in a loop using an alternative much higher resolution timing mechanism, such as QueryPerformanceCounter which can achieve reasonably accurate small period timings with a resolution of just a few microseconds on modern machines. You will never achieve totally accurate and totally reliable timings on a heavily multitasking system such as Windows of course no matter what you do, but you can get quite close for most practical purposes unless your timed periods are absolutely critical.
Having said all that, there may be some speed limitations with the IO system you are using to address the port. Others here will be able to help you with that if there is.
Anyway, here's the example "set resolution" code:
Mike
Option Explicit
Private Declare Function timeGetTime _
Lib "winmm.dll" () As Long
Private Declare Function timeBeginPeriod _
Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Declare Function timeEndPeriod _
Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Sub Form_Load()
timeBeginPeriod 1 ' set resolution
End Sub
Private Sub Form_Unload(Cancel As Integer)
timeEndPeriod 1 ' reset resolution
End Sub
.
- References:
- Re basic to vb
- From: Viper900
- Re: Re basic to vb
- From: Daryl Muellenberg
- Re: Re basic to vb
- From: Viper900
- Re basic to vb
- Prev by Date: Re: VB6 can't read registry on Windows 7?
- Next by Date: Re: VB6 can't read registry on Windows 7?
- Previous by thread: Re: Re basic to vb
- Next by thread: Re: Re basic to vb
- Index(es):
Relevant Pages
|