Binary Clock

mjk: Binary clock is a clock representing time in binary coded decimals. This means that each value of the current time (hours, minutes, seconds) are extracted as an independent ten-based values (hours between 0-23, minutes and seconds between 0-59). Each of these values are treated as two digit values (so, for example, three minutes past five would be represented as: 05 03). To get a binary representation out of these values, each pair is chopped to single digits (0 5 0 3). Now each of these digits can be treated as a single 4-bit value and the time can be represented by using LEDs or some other kind of methods to show the state of the bits inside of these values.

Here's a small application I made for my own amusement:

http://www.omanurkka.fi/files/binaryclock1.png

 # Title:       Binary Clock
 # Author:      Matti J. Kärki
 # Date:        30.8.2004
 # Description: A small Tcl/Tk application showing current time in
 #              Binary Coded Decimal (BCD) format. This application
 #              requires the Img package.
 
 
 package require Tk
 package require Img
 
 # Background color for the window. Note that the color
 # "#0000AC" is the background color used in the images
 # representing the LEDs.
 set BGCOLOR     {#0000AC}
 
 # Base64 encoded image data for a non-lit LED (in BMP format).
 set OFFIMGDATA  {
     Qk3mAQAAAAAAADYAAAAoAAAADAAAAAwAAAABABgAAAAAALABAAAAAAAAAAAA
     AAAAAAAAAAAArAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA
     rAAArAAAAAAAAAAA/wAA/wAA/wAA/wAAAAAAAAAArAAArAAArAAAAAAA/wAA
     /wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAArAAArAAAAAAA/wAA/wAA/wAA/wAA
     /wAA/wAA/wAA/wAAAAAArAAAAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA
     /wAA/wAAAAAAAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAA
     AAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAAAAAA/wAA/wAA
     /////wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAArAAAAAAA/wAA/////////wAA
     /wAA/wAA/wAA/wAAAAAArAAArAAAAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA
     /wAAAAAArAAArAAArAAAAAAAAAAA/wAA/wAA/wAA/wAAAAAAAAAArAAArAAA
     rAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA}
 
 # Base64 encoded image data for a lit LED (in BMP format).
 set ONIMGDATA   {
     Qk3mAQAAAAAAADYAAAAoAAAADAAAAAwAAAABABgAAAAAALABAAAAAAAAAAAA
     AAAAAAAAAAAArAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA
     rAAArAAAAAAAAAAAAAD/AAD/AAD/AAD/AAAAAAAArAAArAAArAAAAAAAAAD/
     AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAArAAArAAAAAAAAAD/AAD/AAD/AAD/
     AAD/AAD/AAD/AAD/AAAArAAAAAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
     AAD/AAD/AAAAAAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAA
     AAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAAAAAAD/AAD/
     ////AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAArAAAAAAAAAD/////////AAD/
     AAD/AAD/AAD/AAD/AAAArAAArAAAAAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/
     AAD/AAAArAAArAAArAAAAAAAAAAAAAD/AAD/AAD/AAD/AAAAAAAArAAArAAA
     rAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA}
 
 set ONIMG   [image create photo -data $ONIMGDATA -format bmp]
 set OFFIMG  [image create photo -data $OFFIMGDATA -format bmp]
 set BITS    [list 1 2 4 8]
 
 # Returns a current time in {H H M M S S} format. The format is
 # suitable for representing the time in decimal or binary format.
 proc getBCDtime {} {
     set bcdtime {}
     set tim [split [clock format [clock seconds] -format {%H %M %S}]]
 
     foreach t $tim {
         set bcdtime [concat $bcdtime [split $t {}]]
     }
 
     return $bcdtime
 }
 
 # Updates the clock display every second. This function
 # scans through the return value of the getBCDtime function
 # and makes a bit-vise comparsion with the elements of the
 # BITS table.
 proc clocktick {} {
     set t [getBCDtime]
 
     for {set x 0} {$x < 6} {incr x} {
         for {set y 0} {$y < 4} {incr y} {
             set y1 [expr 3 - $y]
             if {[expr [lindex $t $x] & [lindex $::BITS $y]] == 0} then {
                 .lbl$x$y1 configure -image $::OFFIMG
             } else {
                 .lbl$x$y1 configure -image $::ONIMG
             }
         }
     }
 
     after 1000 clocktick
 }
 
 # Creates a GUI. Constructs a clock display by placing a set
 # of label widgets in grid. Labels are named by using the
 # co-ordinates of the widget and the prefix ".lbl".
 proc gui {} {
     . configure -background $::BGCOLOR
     for {set x 0} {$x < 6} {incr x} {
         for {set y 0} {$y < 4} {incr y} {
             label .lbl$x$y -image $::OFFIMG -background $::BGCOLOR
             grid .lbl$x$y -column $x -row $y
         }
     }
 }
 
 # Start the show...
 gui
 clocktick

RHS A friend of mine has a binary clock on his desk, and I've wondered ever since I first saw it... why have two columns for each number, with the first column being the tens? When not just do the whole number in binary (1,2,4,8,16,32 instead of 1,2,4,8,10,20,40)?


mjk: Good guestion, RHS. It's because of readability. For humans, who are accustomed to reading ten-based numbers, showing tens in different column is easier to interpret than trying to see the time from single binary representation.

Here's a modification, which displays time in three columns:

http://www.omanurkka.fi/files/binaryclock2.png

 # Title:       Binary Clock 2
 # Author:      Matti J. Kärki
 # Date:        30.8.2004
 # Description: A small Tcl/Tk application showing current time in
 #              Binary Coded format. This application requires
 #              the Img package.
 
 package require Tk
 package require Img
 
 set BGCOLOR     {#0000AC}
 
 set OFFIMGDATA  {
     Qk3mAQAAAAAAADYAAAAoAAAADAAAAAwAAAABABgAAAAAALABAAAAAAAAAAAA
     AAAAAAAAAAAArAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA
     rAAArAAAAAAAAAAA/wAA/wAA/wAA/wAAAAAAAAAArAAArAAArAAAAAAA/wAA
     /wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAArAAArAAAAAAA/wAA/wAA/wAA/wAA
     /wAA/wAA/wAA/wAAAAAArAAAAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA
     /wAA/wAAAAAAAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAA
     AAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAAAAAA/wAA/wAA
     /////wAA/wAA/wAA/wAA/wAA/wAA/wAAAAAArAAAAAAA/wAA/////////wAA
     /wAA/wAA/wAA/wAAAAAArAAArAAAAAAA/wAA/wAA/wAA/wAA/wAA/wAA/wAA
     /wAAAAAArAAArAAArAAAAAAAAAAA/wAA/wAA/wAA/wAAAAAAAAAArAAArAAA
     rAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA}
 
 set ONIMGDATA   {
     Qk3mAQAAAAAAADYAAAAoAAAADAAAAAwAAAABABgAAAAAALABAAAAAAAAAAAA
     AAAAAAAAAAAArAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA
     rAAArAAAAAAAAAAAAAD/AAD/AAD/AAD/AAAAAAAArAAArAAArAAAAAAAAAD/
     AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAArAAArAAAAAAAAAD/AAD/AAD/AAD/
     AAD/AAD/AAD/AAD/AAAArAAAAAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
     AAD/AAD/AAAAAAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAA
     AAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAAAAAAAAD/AAD/
     ////AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAArAAAAAAAAAD/////////AAD/
     AAD/AAD/AAD/AAD/AAAArAAArAAAAAAAAAD/AAD/AAD/AAD/AAD/AAD/AAD/
     AAD/AAAArAAArAAArAAAAAAAAAAAAAD/AAD/AAD/AAD/AAAAAAAArAAArAAA
     rAAArAAArAAArAAAAAAAAAAAAAAAAAAArAAArAAArAAArAAA}
 
 set ONIMG   [image create photo -data $ONIMGDATA -format bmp]
 set OFFIMG  [image create photo -data $OFFIMGDATA -format bmp]
 set BITS    [list 1 2 4 8 16 32]
 
 proc strip0 {num} {
     if {[regexp {^0([0-9]+)} $num -> num2] > 0} then {
         return $num2
     }
     return $num
 }
 
 proc getBCDtime {} {
     set bcdtime [split [clock format [clock seconds] -format {%H %M %S}]]
 
     return $bcdtime
 }
 
 proc clocktick {} {
     set t [getBCDtime]
 
     for {set x 0} {$x < 3} {incr x} {
         for {set y 0} {$y < 6} {incr y} {
             set y1 [expr 5 - $y]
             if {[expr [strip0 [lindex $t $x]] & [lindex $::BITS $y]] == 0} then {
                 .lbl$x$y1 configure -image $::OFFIMG
             } else {
                 .lbl$x$y1 configure -image $::ONIMG
             }
         }
     }
 
     after 1000 clocktick
 }
 
 proc gui {} {
     . configure -background $::BGCOLOR
     for {set x 0} {$x < 3} {incr x} {
         for {set y 0} {$y < 6} {incr y} {
             label .lbl$x$y -image $::OFFIMG -background $::BGCOLOR
             grid .lbl$x$y -column $x -row $y
         }
     }
 }
 
 gui
 clocktick

one might want to add that there already was a binary clock in the analog clock section ALM


arezey, 8th January 2009: A simple binary clock in 42 lines of code.

 wm resizable . 0 0

 ttk::frame .fr
 grid .fr -row 0 -column 0

 set i 0
 foreach x {a b c d} {
         foreach y {1 2 3 4 5 6} {
                 canvas .fr.$x$y -background black -height 24 -width 24
                 grid .fr.$x$y -row $i -column [expr {$y-1}]
         }
         incr i
 }

 proc tick {} {
         foreach x {a b c d} {
                 foreach y {1 2 3 4 5 6} {
                         .fr.$x$y configure -background black
                 }
         }
         lassign [split [clock format [clock seconds] -format "%H:%M:%S"] ":"] h m s
         
         foreach e [list [list $h 1 2] [list $m 3 4] [list $s 5 6]] {
                 set c1 [lindex $e 1]
                 set c2 [lindex $e 2]
                 set v1 [string index [lindex $e 0] 0]
                 set v2 [string index [lindex $e 0] 1]
                 
                 if {$v1 >= 8} {.fr.a$c1 configure -background orange; incr v1 -8}
                 if {$v1 >= 4} {.fr.b$c1 configure -background orange; incr v1 -4}
                 if {$v1 >= 2} {.fr.c$c1 configure -background orange; incr v1 -2}
                 if {$v1 >= 1} {.fr.d$c1 configure -background orange}
                 if {$v2 >= 8} {.fr.a$c2 configure -background orange; incr v2 -8}
                 if {$v2 >= 4} {.fr.b$c2 configure -background orange; incr v2 -4}
                 if {$v2 >= 2} {.fr.c$c2 configure -background orange; incr v2 -2}
                 if {$v2 >= 1} {.fr.d$c2 configure -background orange}
         }
         
         after 1000 tick
 }

 tick