
Search

As of October, 2016, Embarcadero is offering a free release
of Delphi (Delphi
10.1 Berlin Starter Edition ). There
are a few restrictions, but it is a welcome step toward making
more programmers aware of the joys of Delphi. They do say
"Offer may be withdrawn at any time", so don't delay if you want
to check it out. Please use the
feedback link to let
me know if the link stops working.

Support DFF - Shop
If you shop at Amazon anyway, consider
using this link.
We receive a few cents from each
purchase. Thanks

Support DFF - Donate
If you benefit from the website, in terms of
knowledge, entertainment value, or something otherwise useful,
consider making a donation via PayPal to help defray the
costs. (No PayPal account necessary to donate via credit
card.) Transaction is secure.

Mensa®
Daily Puzzlers
For over 15 years
Mensa Page-A-Day calendars have provided several puzzles a year
for my programming pleasure. Coding "solvers" is most fun,
but many programs also allow user solving, convenient for "fill
in the blanks" type. Below are Amazon links to the
two most recent years.
Mensa®
365 Puzzlers Calendar 2017
Mensa®
365 Puzzlers Calendar 2018

(Hint: If you can
wait, current year calendars are usually on sale in January.)

Contact
Feedback:
Send an
e-mail with your comments about this program (or anything else).

|
| |
Problem Description
Here's a binary clock that may be useful when learning the
binary number system.
Background & Techniques
I received a hardware version of this clock as a Christmas gift this
year. It occurred to me that a software version might be
helpful in an educational environment. I.e., for someone
teaching or learning the binary number system.
In the familiar decimal number system, we use 10 symbols (0
through 9) and positions from the left side of the number represent
increasing powers of 10. So 289 in decimal means 2
"hundreds" + 8 "tens" + 9
"ones". In the binary system, we use two symbols (0
and 1) and positions from the left represent increasing powers of
2. So 1101 in binary represents 1 "eight" + 1
"four" + 0 "twos" + 1 "one" (or
13 in decimal).
In our clock we are going to represent each of the six digits used for hours, minutes and seconds as a binary number. Since each
number represents a single decimal digit, we will need 4 binary digits for
each. The maximum number we can represent with three binary digits
(bits) is 111 which is 4+2+1=7 and we will also need to show bit
representation of 8 and 9, thus the need for four.
To match the hardware version of the clock, I represent the
numbers vertically with the top LED representing
"8" . So, using "light off" for 0 and
"light on" for 1, the clock above represents 09:50:34.
Binary Values |
Decimal value of row |
0 |
1 |
0 |
0 |
0 |
0 |
"8" |
0 |
0 |
1 |
0 |
0 |
1 |
"4" |
0 |
0 |
0 |
0 |
1 |
0 |
"2" |
0 |
1 |
1 |
0 |
1 |
0 |
"1" |
H |
H |
M |
M |
S |
S |
|
0 |
9 |
5 |
0 |
3 |
4 |
Decimal «-- time |
The clock starts with the current system clock time and is updated
every second. You may left click anywhere on the clock
to start and stop it. Right mouse clicks will bring up a
configuration panel with a number of options. You can change the
background, LED, and label colors, set 12 or 24 hr. time
formats, hide or display labels, etc.
I added way to enter an arbitrary time value to be displayed, even
hiding it as entered if appropriate, so that students could be tested on
their ability to convert fixed binary values to decimal. By
default clocks with manually entered times will be in stopped mode -
clicking can start such clocks running from the entered time.
Non-programmers are welcome to read on, but may
want to skip to the bottom of this page to
download executable version of the program.
This was a fun little program providing a chance
to practice with several Delphi features.
 | The timer's OnTimer timer exit, Timer1Timer,
updates the clock (if the clock is running). It actually calls the UpdateTime
procedure to put the current time value in binary format, ready to
display. I'm checking for seconds change every 1/10 second, just to
ensure that clock updates stay accurate. |
 | The form's OnPaint exit , FormPaint,
does the actual drawing on the form's canvas. |
 | The form's OnResize exit, FormResize,
is called by windows initially and every time that the form is
resized. This exit calculates the "cell size" for each
binary digit or label character, and the size of the LED image and the
size of the label font (HHMMSS or 8421 labels). |
 | In the configuration dialog, ConfigDlg,
I used the PasswordChar property of the edit box to optionally
hide or display times being manually entered. |
There is some confusion over the best way to update
a form's canvas. We can choose from calling FormPaint
procedure directly, Invalidate, Update, Repaint.
Here's the way I understand it:
 | Our OnPaint exit
procedure, FormPaint, issues commands
(windows messages really) which write to the form's canvas. It is
called automatically by Windows when, for example, the window is resized,
moved, restored after being minimized, is redrawn when some popup window
that covered the clock is removed, etc. We can also call it
directly when we know that the display needs to be redrawn.
These paint messages are normally considered low priority and will be
processed by windows the next time it is idle. |
 | Invalidate marks the entire window as
invalid so that it will be erased and entirely redrawn the next time that
paint messages are processed. |
 | Update forces window to immediately
processes any outstanding paint messages for this window. |
 | Repaint calls Invalidate followed
by Update. |
In this case, it is adequate just to call FormPaint
from UpdateTime. We will be waiting for the next timer pop
most of the time anyway, so there is plenty of time for windows to update
the screen. Just for fun, I tried several other techniques and
left them as comments in the code. The only noticeable
difference is a slight flicker when Invalidate is used. I
suppose because it erases the background before repainting the
screen.
Why can't we just embed the drawing code in
the UpdateTime procedure? If the clock is running, we could
since it will be redrawn every second anyway. Try stopping the
clock though and then minimize and restore it, and you'll see the
problem.
Running/Exploring the Program
Suggestions for Further Explorations
 |
How
about an "advanced" configuration option that switches
to 3 columns (one each for hours, minutes, and seconds) with 6 bits
each - we would need 6 bits to represent 59 minutes or
seconds. |
 |
Add
an option to the configuration panel to switch display from vertical to
horizontal layout. |
Original Date: February 14, 2003 |
Modified:
May 15, 2018
|
|
|