-
Jun 3rd, 2019, 06:03 AM
#1
Thread Starter
New Member
Using timers to action next set of code
Evening All,
Just need some advice on using a timer to automatically action the next set of code, once the time reaches a particular time. I was considering using a DO WHILE or DO UNTIL but just can't get it to work
textbox4 allows to see the steps counting up which is great. As soon as I add the DO WHILE/UNTIL it stops counting. Below is my code, which is used to move stepper motors.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
TextBox4.Text = TextBox4.Text + 1
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim BoardNumber As Integer
Dim Steps As Integer
Dim Interval As Integer
Dim Direction As Integer
Dim Inputs As Integer
Dim Outputs As Integer
Dim Err As Integer
Dim Result As Integer
Dim M1Mode As Integer
Dim M2Mode As Integer
Dim M1StepsLeft As Integer
Dim M2Stepsleft As Integer
Static count As Integer
Dim skip As Integer
skip = TextBox3.Text
count = count + 1
Result = count + skip
TextBox2.Text = Result
If Result = 3 Then
Timer1.Interval = 100
Timer1.Start()
BoardNumber = 1
Steps = 200
Interval = 100
Direction = 0
Err = CM_Stepper_RunMotor2(BoardNumber, Steps, Interval, Direction, Outputs)
Do Until TextBox4.Text >= 100
Loop
TextBox1.Text = "it worked"
End If
End Sub
End If
-
Jun 3rd, 2019, 07:52 AM
#2
Re: Using timers to action next set of code
TextBox4.Text = TextBox4.Text + 1
The TextBox Text Property is a String, even though it probably holds a number, that's a bad programming technique.
It would be better to declare a Form-level Integer variable
Code:
Dim counter as Integer = 0
Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
counter += 1
TextBox4.Text = counter.ToString
End Sub
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Jun 3rd, 2019, 07:56 AM
#3
Re: Using timers to action next set of code
You shouldn't use a busy loop to wait for a Timer to finish.
Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
counter += 1
if counter = 101 then
TextBox1.Text = "it worked"
Timer1.Enabled = False
Return
End If
TextBox4.Text = counter.ToString
End Sub
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Jun 3rd, 2019, 12:48 PM
#4
Re: Using timers to action next set of code
Also, I haven't verified this with .Net, but if the Timer component works as it has in the past, it won't be very accurate, so you need to verify your timing another way if you need to be accurate.
Example, you've chosen an interval of 100, which you would expect to get a tick event every 100 milliseconds.
But, since the base clock that the timer is using is based on a 64hz clock, i.e. 15.625 ms per tick, your tick will likely happen at the nearest tick of the clock that is equal to or greater than 100 ms. In this case, it is likely that each tick is happening at around 109 ms.
Explaination: You want 100 ms. The clock ticks at 15.625 ms intervals, 100 / 15.625 = 6.4. Since you can't get a tick at 6.4, it has to be either 6 or 7, and by design you are guaranteed the interval will not be less than what you selected, then event will be generated every 7th clock tick.
7 * 15.625 = 109.375
Therefore you chose 100 ms interval and 100 ticks, so the motor should step for 10 seconds, but in this case will likely step for 10.9375 seconds which is almost a 10% error.
With .Net, I would set the timer to much smaller interval, usually 1 for reasons I won't go into at the moment. In most cases, this will result in a 64hz event tick. At the beginning of the timing, I would start a stopwatch object and then in the tick event, check its elapsed time to see how much time has really passed. You could then stop at your desired time, i.e. 10 seconds, within .015625 seconds of the time you want, rather than .9375 of the time you want.
You would likely take the number of steps you want, or at most 1 more compared to taking an extra 9 or 10 steps using the timer alone.
If you needed higher precision, then using a stopwatch in conjunction with a background thread to monitor timing would allow finer control.
I guess, perhaps in your case, you specify the number of steps to the controller, so it won't do extra steps, but the timer will finished up a bit late. Perhaps in your case, that isn't a bad thing, since the actions should be completed before the timer says they should be completed.
Last edited by passel; Jun 3rd, 2019 at 12:56 PM.
-
Jun 3rd, 2019, 05:28 PM
#5
Re: Using timers to action next set of code
And since nobody mentioned it, here's the reason why the do loop wrecks your code:
The timer tick is an event, which means that the UI has to be free to handle the event, or you'll never get it. Your loop is occupying the loop completely. The tick event won't interrupt that loop. Instead, the tick will not be handled until the loop has completed. Of course, since the ticks aren't being handled, the loop will never complete, and since it will never complete, the ticks will never be handled. Therefore, you have created a deadlock where the loop needs the tick and the tick needs the loop. Neither ends because it needs the other.
As .Paul said, don't use a loop to wait for a timer like that. There IS a way to make that code work, it's just such a terrible idea that it isn't worth showing. For one thing, a busy wait is going to force the CPU to run as fast as it possibly can. Right now, it isn't getting anywhere. A bad solution would be to allow it to get somewhere, while still running as fast as it possibly can.
Anyways, the others have covered correct solutions.
My usual boring signature: Nothing
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|