View Full Version : Countdown clock
E.C.Ante
10-09-2007, 03:05 AM
I hope someone can help me with the following problem:
Letīs say you have a baby who needs to take his milk at the most in one hour. If he doesnīt get it after that time, well then he cries loud! :mad:
At the same time the best NBA game is on TV now and you donīt want to miss it! So you need to go back and forth from where the tv room is to the babyīs room.
To help you accomplish your task you have a countdown clock that runs backwards in cycles of 1 hour. It starts the cycle exactly after the baby has taken his milk, then you have one hour again to enjoy the game! Normally you wait until the commercials to give the milk, not until the last second of the clock before it fires the alarm! (5 mins or so before the times up, use a random fashion)
So guys, give me your best shot to model this countdown clock. Thanks for your interest.
Tom David
10-09-2007, 07:15 AM
Eduardo,
Nice description of the problem :)
I build a model with a Soure and a Sink and connected them (so I have events and the model is running).
I put the following code on the reset trigger of the Source:
/**TD*/
treenode current = ownerobject(c);
// DEFINE LOCAL VARIABLES
double dTimeCommercials = normal(300,20);
double dTimeForMilk = 3600 - dTimeCommercials;
// SEND DELAYED MESSAGE
senddelayedmessage(current,dTimeForMilk,current,dT imeCommercials);
// SCREEN MESSAGE
stop(); if(msg(getname(current),
concat("Actual Time: ",numtostring(time(),0,4)," seconds.",strascii(13),"Next Time Commercials: ",numtostring(dTimeCommercials,0,4)," seconds.",strascii(13),"Next Time For Milk: ",numtostring(dTimeForMilk,0,4)," seconds." )) == 1) {go();} else {stop();}
This code is on the on message trigger of the Source:
/**TD*/
treenode current = ownerobject(c);
// SCREEN MESSAGE
stop(); if(msg(getname(current),concat("Not It Is Time For Milk: ",numtostring(time(),0,4) )) == 1) {go();} else {stop();}
// DEFINE LOCAL VARIABLES
double dTimeWhenCycleStartsAgain = msgparam(1);
double dTimeCommercials = normal(300,20);
double dTimeForMilk = 3600 - dTimeCommercials + msgparam(1);
// SEND DELAYED MESSAGE
senddelayedmessage(current,dTimeForMilk,current,dT imeCommercials);
// SCREEN MESSAGE
stop(); if(msg(getname(current),
concat("Actual Time: ",numtostring(time(),0,4)," seconds.",strascii(13),"Start Cycle in: ",numtostring(dTimeWhenCycleStartsAgain,0,4)," seconds.",strascii(13),"Next Time Commercials: ",numtostring(dTimeCommercials,0,4)," seconds.",strascii(13),"Next Time For Milk: ",numtostring(dTimeForMilk,0,4)," seconds." )) == 1) {go();} else {stop();}
Messages appear and show when is milk time, when is the commercial time and when is the next milk time.
I assumed, that the next milk time will start in a time windows like every 3600 seconds. So the next milk time cycle will start at 3600, 7200, etc.
If the next milk cycle starts, if the milk is given, that it is even simpler.
I am sure you are able to figure this out by yourself. ;)
So my solution is just to use delayed messages and calculate the time for the next event. :eek:
I hope I understood you problem right and this gives you a hint for a solution.
Good success
tom the (A)tom
Tom David
10-09-2007, 11:31 PM
Eduardo,
Last night I was all the time thinking about the milk problem and how glad I am that I do not have this problem in real life :).
It came to my mind that you like to see a timer (countdown clock), as you wrote in the header of your thread.
So I implemented this and I had a look over my yesterday code and there were a few things I do not like at a second look.
I changed the code to the code below. Now you do not get the first message if you press Return, but if you press Run. I think that a better way to do it. The second reason is that you have the main code only on one place, which is much better programming.
Anyway, her is the code.
On Reset:
/**TD*/
treenode current = ownerobject(c);
// INIT LABEL
setlabelnum(current,"TimerTimepoint",0);
// SEND DELAYED MESSAGE
senddelayedmessage(current,0,current);
On Message:
/**TD*/
treenode current = ownerobject(c);
// SCREEN REFRESH
repaintall();
// SCREEN MESSAGE
if(time() !=0) {stop(); if(msg(getname(current),concat("Not It Is Time For Milk: ",numtostring(time(),0,4) )) == 1) {go();} else {stop();}}
// DEFINE LOCAL VARIABLES
double dTimeWhenCycleStartsAgain = msgparam(1);
double dTimeCommercials = normal(300,20);
double dTimeForMilk = 3600 - dTimeCommercials + msgparam(1);
// SET LABEL
setlabelnum(current, "TimerTimepoint", time() + dTimeForMilk);
// SCREEN MESSAGE
stop(); if(msg(getname(current), concat("Actual Time: ",numtostring(time(),0,4)," seconds.",strascii(13),"Start Cycle in: ",numtostring(dTimeWhenCycleStartsAgain,0,4)," seconds.",strascii(13),"Next Time Commercials: ",numtostring(dTimeCommercials,0,4)," seconds.",strascii(13),"Next Time For Milk: ",numtostring(dTimeForMilk,0,4)," seconds." )) == 1) {go();} else {stop();}
// SEND DELAYED MESSAGE
senddelayedmessage(current,dTimeForMilk,current,dT imeCommercials);
// SCREEN REFRESH
repaintall();
Custom Draw Code:
/**TD*/
treenode current = ownerobject(c);
treenode view = parnode(1);
// SHOW TIMER
double dTimerTime = getlabelnum(current, "TimerTimepoint") - time();
drawtext(view, concat("NextMilkTime: ",numtostring(dTimerTime,0,4)), 0, 0.1, 0, 0.25, 0.25, 0, 0, 0, 0, 0, 0, 0);
// RETURN ZERO
return 0;
You need to create a label called TimerTimepoint on the object (Source).
I hope, now I can forget about the milk problem :D.
Good success!
tom the (A)tom
E.C.Ante
10-10-2007, 03:21 AM
Tom,
thatīs a great aproach! you really got the bird in the air man. :D
For my specific solution, I made some other changes. I definitely just didnīt get it why you use the variable:
dTimeWhenCycleStartsAgain = msgparam(1);
For my case, I just put it away, otherwise my baby getīs his milk sometimes after the timeframe! :o
Thanks cowboy!
Tom David
10-10-2007, 04:27 AM
Eduardo,
You will get a sumo baby :eek: if you leave
dTimeWhenCycleStartsAgain = msgparam(1);
out, because over the time you shorten the time between giving milk:
1. dTimeForMilk1 = 3600 - dTimeCommercials
2. dTimeForMilk2 = dTimeForMilk1 + 3600 - dTimeCommercials
3. dTimeForMilk3 = dTimeForMilk1 + dTimeForMilk2 + 3600 - dTimeCommercials
So your times might be:
1. dTimeForMilk1 = 3600 - 200 => 3400 == 3400
2. dTimeForMilk2 = 3400 + 3600 - 100 => 6900 and not 7100
3. dTimeForMilk3 = 3400+ 3500 + 3600 - 300 => 10200 and not 10500
Do this a while an you will feed you baby a lot and you will not see a lot of the NBA game.
But as I wrote in my first post, that this could be what you want to do, that the next hour starts after the feeding and not after the timeframe of an hour.
I hope I was able to make my point understandable :confused:.
Anyway, if it is working for your case, I am glad and happy :cool:.
tom the (A)tom
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.