Hi Rod,
You are setting to go off every minute is the reason why you are getting
that.
You have to set it to 1000 * 60 * 15 or
timerVal = 1000 * 60 * Interval
because The Timer Is Counting In Milliseconds.
You also have to shut it off after speaking before setting the timer
again...
so when it finally speaks do this:
If globalTimer > 0 Then
StopTimer globalTimer
globalTimer = 0
' this is 0 if not running, so you always have to check it and make sure it is
off before starting or setting the timer again.
When you first start the timer you also have to save it's ID so it knows what
to shut off
(see above)
globalTimer = StartTimer( timerVal, "MyTimer")
I use globaltimer as the ID for the timer action, you can choose any name.
Also use timerVal for the interval you wish to set it to.
Bruce
Sent: Saturday, April 06, 2013 11:43 PM
Subject: Re: Timer in apps stop working
Hi Bruce,
I spent the evening trying to attempt to re-write my routine to conform with
your suggestions, and I did achieve some success. See what you think:
'Begin code
Option Explicit
Dim MyHour, MyMin, MySec
Dim Interval : Interval = 15
Dim SpokenYet : SpokenYet = False
StartTimer 1000, "MyTimer"
Sub MyTimer()
MyHour = Hour(Now)
MyMin = Minute(Now)
MySec = Second(Now)
If MyMin Mod Interval = 0 Then 'on the announcement interval
Queue "SpeakTime"
End If 'on the announcement interval
StartTimer 1000, "MyTimer"
End Sub 'MyTimer
Sub SpeakTime()
If MySec > 5 Then SpokenYet = False : Exit Sub
If MySec < 5 And SpokenYet = True Then Exit Sub
If MyHour = 0 Then MyHour = 12
If MyHour > 12 Then MyHour = MyHour - 12
Speak "The time is " & MyHour
If MyMin < 10 Then Speak "o"
If MyMin = 0 Then Speak "clock" Else Speak MyMin
SpokenYet = True
End Sub 'SpeakTime()
'End code
Bruce, I think that this should speak the time twice, every 15 minutes, and
be quite reliable. I'm not quite sure, however. I do know that it speaks
the time twice, at the top of the minute, when I set the Interval value
equal to 1, and it does work when Interval is equal to 2. Smile. Is this
what you had in mind when you said I should set a flag after speaking the
time?
Take care,
Rod :)
-----Original Message-----
From: BX
Sent: Saturday, April 06, 2013 8:20 PM
To: [email protected]
Subject: Re: Timer in apps stop working
Hi Rod,
This is the guts of the Cuckoo Clock program. Note the Timer is in
milliseconds.
Also, I did have the same problem you spoke of and Chip had mentioned.
The Timer is counting and the value coming back is the remaining count, so I
saved that count inside the .ini file just in case there was a failure such
as yours.
It is called Globaltimer.
Now when it fires it is supposed to be in milliseconds and a single
second seems huge, but it is not and should not rely on it. But, you are
certainly going to be within a few seconds, and a minute counter needs not
to check seconds.
so, do as I had mentioned, do the integer division, (mod) and when the
minutes gets to 0 you are ready to go and the timer when tripped you are
within at least a minute, far more than you need.
' This function sets our timer and calls appropriate functions based on
settings.
' This is the guts of the Cuckoo Clock program.
Function SetCuckooClockTimer()
' We need a timer to fire every hour/half/quarter, based on the present
time.
' The StartTimer fires events in milliseconds, so we take our final result
and multiple it by 1000, and pass the result as the first parameter.
' The second parameter of StartTimer is the routine that we want called when
the timer fires. That routine is called CheckToSpeak
' The return value from the StartTimer method call will be returned as the
value for the SetCuckooClockTimer function.
Dim timerVal, thisMinute: thisMinute = DatePart("n",Now)
Dim totalSeconds, thisSecond: thisSecond = DatePart("s",Now)
' We may be cuckooing every quarter hour so check for it:
If announceHour = announceQuarterHourTrue and thisMinute < 15 Then
' We are in the first quarter hour of seconds.
totalSeconds = 900
ElseIf announceHour <> announceHourTrue and thisMinute < 30 Then
' We are in the second quarter hour of seconds.
totalSeconds = 1800
ElseIf announceHour = announceQuarterHourTrue and thisMinute < 45 Then
' We are in the third quarter hour of seconds.
totalSeconds = 2700
Else
' We are in hourly chime only and need one hour of seconds.
totalSeconds = 3600
End If
' Calculate the actual seconds remaining in the part of the hour you are in:
timerVal = (totalSeconds - (thisMinute * 60 + thisSecond))
' Now we need to figure out if our timer is less than two minutes, and
this isn't the first time we've set the timer.
'If that case is true then we need to add an hour/half/quarter hour to
the timer.
' This will keep the timer from firing and then immediately (or within
two minutes) firing again.
' We do this because timers are not precise, and fluctuations can cause
multiple firings too close together.
If Not scriptInit Then
If timerVal <= 120 Then
' Place a calculation based on actual time and announceHour setting.
If announceHour > 0 Then
timerVal = timerVal + 3600 / announceHour
Else
timerVal = timerVal + 3600
' End of if announce hour > 0
End If
' end of less than 2 minutes.
End If
' End of not script init.
End If
If globalTimer > 0 Then
StopTimer globalTimer
globalTimer = 0
INIFile(myINIFile).Number( "Configuration", "Global_Timer") = globalTimer
' End of global timer.
End If
' Now lets check-set the sleep flag and the timerVal.
SetSleepFlag timerVal
' Speak Round( timerVal/60), speakerVoice
' Now lets set the alarm timer if on.
Queue "SetAlarmTimer"
' Convert time to milliseconds.
timerVal = timerVal * 1000
' Now set the timer and send its val back to the function!
If sleepFlag Then
' Speak " minutes before Queue Announce wakeup set ", speakerVoice
SetCuckooClockTimer = StartTimer( timerVal, "QueueAnnounceWakeup")
Else
' Speak " minutes before Queue check to speak set ", speakerVoice
SetCuckooClockTimer = StartTimer( timerVal, "QueueCheckToSpeak")
End If
scriptInit = False
' End of function SetCuckooClockTimer
End Function
' GetCuckooClockTimer is the function that gets called when the time
remaining
' until the next Cuckoo clock time needs to be retrieved.
Function GetCuckooClockTimer()
' This procedure is used when the present time hotkey is pressed Insert-T
and you also
' want to know when the next alarm will sound, in minutes; enhanced Insert-T
key mode.
' The value returned will be determined using a similar method as
' the SetCuckooClockTimer function. The differences are that we don't need
' to multiply the result by 1000, because we're not interested in
' milliseconds. We will, however, divide the result by 60 because we
' want to return the number of seconds remaining until the next hour
segment.
Dim sleepSeconds: sleepSeconds = ((sleepTime \ 100) * 3600) + ((sleepTime
mod 100) * 60)
Dim wakeupSeconds: wakeupSeconds = ((wakeupTime \ 100) * 3600) +
((wakeupTime mod 100) * 60)
Dim thisHour: thisHour = Hour(Now)
Dim thisMinute: thisMinute = DatePart("n",Now)
Dim thisSecond: thisSecond = DatePart("s",Now)
Dim totalSeconds, theTotalSeconds: totalSeconds = 3600
theTotalSeconds = thisHour * 3600 + thisMinute * 60 + thisSecond
If thisMinute <30 and announceHour = announceHalfHourTrue Then
totalSeconds = 1800
End If
If announceHour = announceQuarterHourTrue Then
If thisMinute < 45 Then
totalSeconds = 2700
End If
If thisMinute < 30 Then
totalSeconds = 1800
End If
If thisMinute < 15 Then
totalSeconds = 900
End If
End If
If sleepEnabled and wakeupSeconds > theTotalSeconds and (sleepSeconds <
theTotalSeconds or sleepSeconds > wakeupSeconds) Then
totalSeconds = wakeupSeconds
sleepFlag = True
ElseIf sleepEnabled and wakeupSeconds < theTotalSeconds and sleepSeconds <=
theTotalSeconds and sleepSeconds > wakeupSeconds Then
totalSeconds = 3600 * 24 + wakeupSeconds
sleepFlag = True
ElseIf sleepEnabled and wakeupSeconds > theTotalSeconds and sleepSeconds >
theTotalSeconds and sleepSeconds < wakeupSeconds and (sleepSeconds \
(3600/PreviousAnnounceHour)) = (theTotalSeconds \
(3600/PreviousAnnounceHour)) and (sleepSeconds \
(3600/PreviousAnnounceHour)) = (wakeupSeconds \ (3600/PreviousAnnounceHour))
Then
totalSeconds = wakeupSeconds
sleepFlag = True
Else
thisHour = 0
sleepFlag = False
End If
GetCuckooClockTimer = Round(((totalSeconds - (thisHour * 3600 + thisMinute *
60 + thisSecond))) / 60)
End Function
Sent: Saturday, April 06, 2013 4:56 PM
Subject: Re: Timer in apps stop working
Hi everyone,
Good news! :)
First, thanks for all the concern, advice, and willingness to help. Second,
I think, Bruce, your cuckoo clock is a monument to beauty and app
competence. Cheers to you. Third, Chip, I remembered a comment you made in
your class on event handlers, about the fact that you have to queue speech
and disk access or else you'll run into problems. Well, my clock sub had
this problem, and this is why it was failing to reset. Being fairly new to
writing apps, it's pretty clear that I have a lot to learn. Hey, I was even
thinking, as you see on many e-lists, perhaps we should be given a ranking
when we post to this list. Smile. Well, I'm just teasing a bit, but it is an
idea, although I guess people get to know who the MVP's are, eh? Smile.
I tend to be a bit more hands on then perhaps is good for me, such that I
don't take the time to read good code like yours, Bruce and Chip, but I've
had my chastisement, and I promise I'll do more research before being so
ambitious in the future. Being that as it may, I can't help but enclose my
simple little app for announcing the time, fixed so that it doesn't hang,
and please feel free to comment.
Thanks for everything, good friends,
Rod :)
Here's my code for announcing the time every 15 minutes using the default
synthesizer:
Option Explicit
Dim MyHour, MyMin, MySec
Dim Interval : Interval = 15
StartTimer 1000, "MyTimer"
Sub MyTimer()
MyHour = Hour(Now)
MyMin = Minute(Now)
MySec = Second(Now)
If MySec = 0 Then
If MyMin / Interval = Int(MyMin / Interval) Then 'on the announcement
interval
Queue "SpeakTime"
End If 'on the announcement interval
End If 'MySec = 0
StartTimer 1000, "MyTimer"
End Sub 'MyTimer
Sub SpeakTime()
If MyHour = 0 Then MyHour = 12
If MyHour > 12 Then MyHour = MyHour - 12
If MyMin = 0 Then MyMin = "o'clock"
Speak MyHour & " " & MyMin
End Sub 'SpeakTime()