Forum Index > Projects > Clock Kits
 Seconds hand display and code refactoring
 |  Printable Version
By: Anonymous: hudson () on Saturday, February 04 2012 @ 07:28 PM PST (Read 6104 times)  
Anonymous: hudson



I wanted the clock to display a seconds hand in the fifth digit, and while I was hacking on the code I refactored a bunch of it. The major change is to compress the font into 16-bits per character (since there are sixteen non-dot LEDs per digit) and to store the bitmap in program memory so that it doesn't take up SRAM. The PWM parameters were extracted from code and moved into a static table as well. The drawing routine now draws direct from an ASCII buffer, rather than having a separate "convert to SPI" step.

Overall these changes reduced the size of the program by about 2 KB, even with the new features, and reduced the SRAM footprint significantly.

The updated source code is posted here: https://bitbucket.org/hudson/alphaclock/src/tip/alphaclock_18_Rev1_0/alphaclock_18_Rev1_0.pde





       
   
By: bastard (offline) on Tuesday, February 07 2012 @ 01:50 PM PST  
bastard

Hi!

Nice seconds hand! I like it.

I improved your code:

  • No more 'H' in 24 hour mode.
  • Show alarm off by switching the LED off.
  • Use the font suggestion from Robert.



Would you like to commit my changes into your repository?

[ URL DELETED UPON REQUEST ]


Bye

Stefan


Forum Apprentice
Apprentice

Status: offline

Registered: 12/20/08
Posts: 13
Bavaria, Germany

Profile Email Website  
   
By: bastard (offline) on Wednesday, February 08 2012 @ 02:07 AM PST  
bastard

Sorry Guys,

new download URL: [ URL DELETED UPON REQUEST ]

Bye

Stefan


Forum Apprentice
Apprentice

Status: offline

Registered: 12/20/08
Posts: 13
Bavaria, Germany

Profile Email Website  
   
By: Anonymous: Robert () on Thursday, February 09 2012 @ 01:51 PM PST  
Anonymous: Robert

Thanks, bastard! I love it!!

Now to add in some real functionality... like the date...






       
   
By: Anonymous: Robert () on Thursday, February 09 2012 @ 01:53 PM PST  
Anonymous: Robert

Oh yes, I meant to thank hudson too... he did so much work...





       
   
By: Anonymous: Robert () on Thursday, February 09 2012 @ 08:06 PM PST  
Anonymous: Robert

As for refactoring code, I was thinking:

  • Directly comparing millisecond timestamps leads to issues when millis() rolls over. Instead of using:

    PHP Formatted Code

    if (millis() > specialTime) {
      // do something here
    }
     


    try this:

    PHP Formatted Code

    if ( ((long)(millis() - specialTime)) > 0 ) {
      // do something here
    }
     


  • The colon should not blink when alarm time is being shown.






       
   
By: Anonymous: hudson () on Monday, February 13 2012 @ 04:04 PM PST  
Anonymous: hudson

Quote by: bastard
Would you like to commit my changes into your repository?


I've merged some of them in. Thanks for the catch on the alarm indicator. I liked some of the font changes, although the 8 was a bit too much for me. The 0, 1, 3, 5 and 7 are definitely improved.

The next major change that I'd like to make is to track the date and ms since midnight so that the pwm is cleaner for display. Doing the mod operation to translate ms into HH:MM:SS isn't insanely expensive, especially compared to the time the system spends busy waiting right now.





       
   
By: Anonymous: Robert () on Tuesday, February 14 2012 @ 02:57 PM PST  
Anonymous: Robert

I was thinking of how to get the date from a simple count of days.

Starting from March:

PHP Formatted Code

Month: MR AP MY JE JL  AU SE OC NO DE  JA  FE
 Days: 31 30 31 30 31  31 30 31 30 31  31 <30
       ^--153 days--^  ^--153 days--^
 



You will need to special case the leap-day (Feb. 29), but the algorithm goes like this:

Day 0 = March 1 of some leap year

Take every 1461 days as 4 years.
If remainder is 1460, then STOP: it is leap-day, about 4 years later.
Otherwise, with the remainder:
Take every 365 days as 1 year.
With the remainder from that:
Take every 153 days as 5 months. (Clean up for Dec. - Jan. year change.)
With the remainder from that:
Take every 61 days as 2 months.
With the remainder from that:
Take 31 days as 1 month.
We now have the correct year and month. We also have a remainder.
To this final remainder:
Add 1 to get the day of the month.

I am typing this on a public computer, and cannot compile code here.
Please check for accuracy.






       
   
By: Anonymous: Robert () on Tuesday, February 14 2012 @ 03:05 PM PST  
Anonymous: Robert

Date adjust probably belongs in the main settings menu.
Time adjust could also go in the main settings menu.

I do not believe that the clock has too few buttons for all of this. My wristwatch has only four buttons, and one of them is for the light.





       
   
By: bastard (offline) on Tuesday, February 14 2012 @ 11:51 PM PST  
bastard

Hi,

I wonder, why you want to do calendar-math? The cronodot has already all built in.

From the datasheet:

The clock/calendar provides seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year.



Bye

Stefan


Forum Apprentice
Apprentice

Status: offline

Registered: 12/20/08
Posts: 13
Bavaria, Germany

Profile Email Website  
   
By: Anonymous: Robert () on Thursday, February 16 2012 @ 12:32 PM PST  
Anonymous: Robert

Quote by: bastard

Hi,

I wonder, why you want to do calendar-math? The cronodot has already all built in.

From the datasheet:

The clock/calendar provides seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year.



Bye

Stefan



In that case, why put in time math? After all, our clock doesn't need to know that 60 seconds make a minute, and 60 minutes make an hour, or even that 1000 milliseconds make 1 second... that is the Chronodot's job.

Maybe we're not using the Chronodot. Maybe we're using the TTL-serial connector to get the time.

Anyway... the Chronodot is a bit lame when it comes to the calendar. It does not detect invalid dates. It also does not calculate the day of the week. I do not see why, if I set the year, month, and day of the month, I should not have the day of the week set for me, as well.

Also, bastard, I see you are from Germany. Don't they use week numbers over there? If you want those, you will need calendar math.





       
   
By: Anonymous: hudson () on Friday, February 17 2012 @ 09:30 PM PST  
Anonymous: hudson

Two new features were committed tonight: a pulsing nightlght and thin font support for 0-19, based on the one constructive idea posted to the adafruit forum and now have H:MM:SS display: image

Next up for this weekend: YYMMDD display that alternates with the time.





       
   
By: Anonymous: Robert () on Sunday, February 19 2012 @ 09:56 PM PST  
Anonymous: Robert

Here is a useful Web page with calendars. Very helpful to help debug.

http://www.timeanddate.com/calendar/





       
   
By: Anonymous: Robert () on Monday, February 20 2012 @ 01:05 AM PST  
Anonymous: Robert

The above comment is SPAM.

[Thank you-- the spam comment has been deleted, - WHO]





       
   
By: Anonymous: Robert () on Thursday, February 23 2012 @ 01:48 PM PST  
Anonymous: Robert

Hudson:
Please keep in mind that the Chronodot's "day" register (for day of the week) is distinct from the "date" register (for day of the month). Also please keep in mind the locations of these registers relative to each other and to the time-of-day registers.

Also, the Chronodot is (intentionally?) too stupid to figure out what day of the week it is once you've told it the year, month, and date. So you have to have the Arduino calculate it.

Reference:
http://datasheets.maxim-ic.com/en/ds/DS3231.pdf


How to get the serial day number in a system in which Friday, March 1, 1996 is day 0:
(assuming you have year, month, and day of the month, and that you are using conventional human month numbers)
First calculate:
((year &#8722; 2000) * 12) + (month) + 45
Now we have a sort of serial month number, in a system which counts March 1996 as month 0.
Using this serial month number:
Count every 48 months as 1461 days.
With the remainder from that:
Count every 12 months as 365 days.
With the remainder from that:
Count every 5 months as 153 days.
With the remainder from that:
Count every 2 months as 61 days.
If there is still a month left, count it as 31 days.
To all these days, we then add the day of the month, and then subtract 1.

Calculation of the day of the week given this serial day number is left as an exercise for the reader.






       
   



 All times are PDT. The time is now 03:23 AM.
Normal Topic Normal Topic
Locked Topic Locked Topic
Sticky Topic Sticky Topic
New Post New Post
Sticky Topic W/ New Post Sticky Topic W/ New Post
Locked Topic W/ New Post Locked Topic W/ New Post
View Anonymous Posts 
Able to Post 
Filtered HTML Allowed 
Censored Content 

Evil Mad Scientist Forum Archives — Read only!

Please visit our new forums for new discussions.


DIY Hardware for Electronic Art


The Original Egg-Bot Kit


Octolively
Interactive LED kits


Meggy Jr RGB
LED matrix game
development kit.


Business-card sized
AVR target boards


Peggy 2
LED Pegboard kits

My Account






Lost your password?