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() 

Reply via email to