Analog Clock
ericmedley
Posts: 4,177
On another thread there was discussion of an analog clock. I happened to be in the process of making one. So, here's all the ingredients for it. enjoy.
post:
post:
ericmedley wrote: »Okay, here it is.
I've included all the stuff you'd need to make it yourself to. I made pretty simple clock hands for this sample. It's much easier to create the different positions of the hands in a 3D amination program. But you can do it just fine with Photoshop.
To move the hand from one second/minute just select the layer of the hand and then rotate it by 6 degrees. You'll need to reposition the center of the hand with the spindle. Expoert, wash rinse repeeat...
Be careful not to move the guide layer.
The clock is made with 3 multi-state levels. In this example level 1 is hours. level 2 - minutes and level 3 seconds.
minutes and seconds are simple enough. just send the numberic value of the second and/or minute to the level and it'll work.
Hours is a little more complicated. Here's the formula to make that work. My version doesn't round. I honestly don't care that much. But you may want to round the calculation to get a more honest looking hour hand.send_level dev_AW_TP_01,3,SECOND_CURR // second hand send_level dev_AW_TP_01,2,MINUTE_CURR // minute Hand if(HOUR_CURR<13) { send_level dev_AW_TP_01,1,(((HOUR_CURR)*60)/12 )+ ((MINUTE_CURR*5)/60) // hour hand } else { send_level dev_AW_TP_01,1,(((HOUR_CURR-12)*60)/12 )+ ((MINUTE_CURR*5)/60) // hour hand }
Have fun.
e
PS: Okay, it appears that I cannot upload the file to the website. Must be too big or something. I'll put it on my website.
http://www.ericmedley.com/analog_clock.zip right-click and save as.
0
Comments
Eric,
Now that?s a cool clock!
Two thumbs way up.
I just had to make a minor adjustment to the TP file by changing the level ranges to 0-59 instead of 0-255.
Other than that the sample file does an excellent job showing all the pieces.
One suggestion for the hours calculation. Instead of doing the IF and ELSE, you can use the mod operator with one line of code and accomplish the same thing, like so:
OOPS!!! my bad on the levels. I made a new TP file with brand new faders. I forgot that one for sure. To all who use it. Make sure to check that one. Thanks for the math fix too. I have to admit that I'm pretty old-skool and don't spend much time tweaking my math for better performance. If I find a way that works, I just go with it. My poor little brain won't hold much nowadays...
e
(EDITED TO NOTE) I fixed the level problem in the sample TP file. It's now updated on the site. Sorry about that...
Here's the code I used to make it run.
Now all I need is the ticking sound to keep playing on the touchpanel. I'm sure that wouldn't cause any problems
More then one way to skin that cat...
I also changed the min max levels on the TP to 0-59 No ifs, no timelines... Just in DEFINE_PROGRAM
Remember SEND_LEVELS only get sent when the VALUE changes. So the second level only gets sent once a second, the min only once a min, and the hour only a few times an hour....
// Code I used...
DEFINE_PROGRAM
// oops made a typo...
SEND_LEVEL dvTP, 1, (((TIME_TO_HOUR(TIME) % 12) * 60) / 12) + ((TIME_TO_MINUTE(TIME) * 5) / 60)
SEND_LEVEL dvTP, 2, TIME_TO_MINUTE(TIME)
SEND_LEVEL dvTP, 3, TIME_TO_SECOND(TIME)
Actually that's just a snipet from the code just to illustrate the math. I figured y'all would program the thing the way you wanted.
I have mine in a trap that only comes on when someone is viewing the clock. In my program I try to minimize the network traffic as much as possible.
You say that as a joke but I did do that for fun. I put one of those obnoxious mechanical wind-up clock ticking samples.
When the fun was over I had to turn it off, of course...
Good Stuff! Minimize the traffic as much as possible. Yes there are many ways to tackle this task. It's good to see all of the ways we can dream up to make this work.
Here's a little function that I use that's either called by a timeline or as a quick fix in define_program behind a wait 2 or wait 5 depending on what else is runing in there. When its called it will only test for a change in the current second. If the second has changed it will then check to see if the minute has changed, so on and so forth. It's the most logical and efficient way I've found to update time vars.
How annoying was it - and how much network traffic did it generate. You would have had to keep calling it correct?
Ha!
It's a sample loop of about 5 ticks. I didn't really time it that well as it was meant to be a joke. But I was sending the 'SOU-' command every 3 seconds to make it sound continuous.
Food for thought:
All very good things to think about to minimize overhead. But keep in mind that just because you use IFs and Timelines and Conditions, all that has to be checked and takes time. The facts are that the interpreter handles math a lot faster than conditionals. Sometimes when doing NOT conditionals the interpreter has to do two to three checks before it decides the condition is true or false. Also Timelines add tons of overhead, so pick your poisons.
I am not saying that any of these methods are better than the other. But according to my testing the three send levels in mainline takes less than one millisecond to complete, I do not know how much overhead I added to just get the actual time, but very minimal of time. Plus the send levels do not create any traffic until the actual levels change.
I'm not sure how you are testing performance.
Moving this code to mainline slowed Mainline passes from 13760 passes to 1480 passes. Looks like a major slowdown to me.
OK - I have a question on this - and I am speaking from ignorance, not spite. So be nice y'all:)
Does it really matter that define_program runs only 1480 passes per second as opposed to 13760?
As I understand it (this may be the point of error on my part) mainline is the lowest on the priority and will only run if there are no other event in the stack. So is it a measure of system performance, or a measure of system spare time? (hey i'm board now - let's run mainline)
If I am parsing a bunch of data back from a device and going through a couple of thousand bytes with a while loop, isn't mainline also going to slow down even if i have nothing in mainline?
I fit is a measure of system performance, then are there hard numbers to maintain? ie your mainline must run between 5000 and 15000 times per second.
MIN = TIME_TO_MINUTE(TIME);
SEND_LEVEL dvTP, 1, (((TIME_TO_HOUR(TIME) % 12) * 60) / 12) + ((MIN * 5) / 60)
SEND_LEVEL dvTP, 2, MIN
SEND_LEVEL dvTP, 3, TIME_TO_SECOND(TIME)
You are correct... mainline only runs when needed and is not a measurement of performance... By actually having a counter in mainline forces it to run...
No I don't think so...
"Mainline is the section of the program that is executed continuously by the NetLinx Master Controller. DEFINE_PROGRAM contains the code known as mainline that is executed continuously as long as the Controller has power. Mainline is where all input (button events, level changes, command/string input, etc.) is processed. After each pass through mainline, NetLinx services the NetLinx bus and updates its internal structures." from AMX
If mainline slows down the interpretor slows down then you start getting Max Que threshold messages.
I'm very pragmatic when it comes to such considerations ... the bottom line is not if the processor is doing any extra work, but if my running program is affected. I'm not going to go out of my way to keep the DEFINE_PROGRAM section empty if it makes sense to have code there, though I do try, for the most part to keep my code event-driven. It's just not always the most graceful way to handle things, and if it costs me a few ticks, well, so be it. If it noticeably bogs the program down, that's another story. I've only once had a case where running code made any discernible difference; it's nearly always the message queue and device response that causes trouble.
Agreed. On the other hand, tracking passes through mainline can be an indicator of system health and stability. Code in DEFINE_EVENT and DEFINE_PROGRAM both affect the passes in mainline. 99% of projects I complete have no issue with the system getting bogged down. The problems occur when i'm working with a very large system and processing has to be distributed among masters. Checking the health of the master is important to having a stable system. Passes through mainline helps me understand where I am in processing load. (Of course the interpretor buffer must not be getting back logged.)
Just a thought.
Check out the discussion at the beginning of the thread.
I personally would use a time_line but only create it when "on page" and then kill it when all TPs are "off page" that way there is only overhead when there needs to be. So basically the clock code doesn't exist if you're not on the clock page. Typically I would do this for everything a module does form feedback to processing queues or sending queries. If on page fire the time_line ad let it control everything for that module and let it die when nobody's watching.
I still however have modules that runs code define_program and doesn't use time_lines but those are generally older code.
You should be a proud parent of your forked child.
Or am I missing something... :-)
Sorry,it was getting to me...
[php]
DEFINE_VARIABLE
INTEGER nThe_bird
INTEGER nThe_word
DEVCHAN dcEverybody_Heard[] = { {10001:1:0,1} }
DEFINE_EVENT
BUTTON_EVENT[dcEverybody_Heard]
{
PUSH:
{
the_word = GET_LAST (dcEverybody_Heard)
nThe_bird = nThe_word
}
RELEASE:
{
nThe_word = nThe_bird
IF(button.input.device<>(dcEverybody_Heard[nThe_word]))
{
SEND_STRING 0,"'PA PA PA OO MOW MOW PA PA PA OO MOW MOW MOW'"
}
}
}
[/php]
Ha! I have to do that too. My eyesight is getting so poor that I even have to put spaces between lots of things so I can read them. Like my_Functin ( var_1 , var_2 , var_3 ) instead of (var_1 ,var_2 ,var_3)
My for loops all look like
for ( nloop = length ; nloop > 0 ; nloop -- )
I'm real sure I won't be able to do this stuff much longer... I'll have to go back to full-time music production again. (or run my 22" monitor at 640 X 480 )
ROFLMAO!!
I'll nick that if you don't mind :-D