This live screen grab is from one of my HamClocks. It updates automatically every minute after making a random tap.

Ham Clock

This page refers to my QST article in the October 2017 issue. All updates will be posted here.

I would like to give Shoutouts to Adafruit and the Raspberry Pi Foundation for their great products, software and documentation.

News highlights: See the complete version history in the Download tab and details in the User Guide.
  • Web interface now uses port 8080; see FAQ for details.
  • Set any desired color for satellite track and foot print.
  • New option to show maidenhead grid key.
  • Real-time Moon view available in all panes
  • Set background to Terrain or Countries map in Setup or show real-time global propagation reliability map by tapping desired band on VOACAP pane.
  • Now manufactured by Veritium Research and marketed by Gigaparts rebranded as HFClock.

73, Elwood Downey, WBØOEW

Original QST Article proof


Download current stable HamClock release source code here.

Revision history:

Version 2.56: 2021-01-09 Version 2.55: 2020-12-13 Version 2.54: 2020-12-05 Version 2.53: 2020-10-28 Version 2.52: 2020-10-10 Version 2.51: 2020-08-08 Version 2.50: 2020-07-26 Version 2.49: 2020-07-10 Version 2.48: 2020-07-03 Version 2.47: 2020-06-19 Version 2.46: 2020-05-29 Version 2.45: 2020-05-13 Version 2.44: 2020-05-07 Version 2.43: 2020-04-16 Version 2.42: 2020-04-02 Version 2.41: 2020-03-04 Version 2.40: 2020-01-19 Version 2.39: 2020-01-18 Version 2.38: 2020-01-01 Version 2.37: 2019-12-27 Version 2.36: 2019-12-21 Version 2.35: 2019-12-15 Version 2.34: 2019-12-02 Version 2.33: 2019-11-28 Version 2.32: 2019-11-26 Version 2.31: 2019-11-11 Version 2.30: 2019-10-25 Version 2.29: 2019-10-11 Version 2.28: 2019-10-11 Version 2.27: 2019-10-10 Version 2.26: 2019-10-09 Version 2.25: 2019-10-07 Version 2.24: 2019-10-02 Version 2.23: 2019-09-28 Version 2.22: 2019-09-23 Version 2.21: 2019-09-20 Version 2.20: 2019-09-14 Version 2.19: 2019-09-10 Version 2.18: 2019-08-18 Version 2.17: 2019-08-16 Version 2.16: 2019-08-10 Version 2.15: 2019-08-07 Version 2.14: 2019-08-05 Version 2.13: 2019-08-05 Version 2.12: 2019-08-05 Version 2.11: 2019-08-04 Version 2.10: 2019-08-03 Version 2.09: 2019-07-27 Version 2.08: 2019-07-19 Version 2.07: 2019-07-14 Version 2.06: 2019-07-11 Version 2.05: 2019-07-10 Version 2.04: 2019-07-06 Version 2.03: 2019-07-03 Version 2.02: 2019-06-20 Version 2.01: 2019-06-10 Version 2.00: 2019-05-27 Version 1.94: 2019-05-13 Version 1.93: 2019-05-10 Version 1.92: 2019-05-09 Version 1.91: 2019-04-24 Version 1.90: 2019-03-31 Version 1.89: 2019-03-15 Version 1.88: 2019-01-20 Version 1.87: 2018-12-25 Version 1.86: 2018-12-23 Version 1.85: 2018-12-17 Version 1.84: 2018-12-11 Version 1.83: 2018-12-10 Version 1.82: 2018-12-03 Version 1.81: 2018-12-01 Version 1.80: 2018-11-24 Version 1.79: 2018-11-23 Version 1.78: 2018-11-21 Version 1.77: 2018-11-04 Version 1.76: 2018-10-08 Version 1.75: 2018-10-05 Version 1.74: 2018-09-29 Version 1.73: 2018-09-28 Version 1.72: 2018-09-25 Version 1.71: 2018-09-23 Version 1.70: 2018-09-22 Version 1.69: 2018-09-19 Version 1.68: 2018-09-17 Version 1.67: 2018-09-15 Version 1.66: 2018-09-12 Version 1.65: 2018-09-09 Version 1.64: 2018-09-06 Version 1.63: 2018-09-04 Version 1.62: 2018-09-02 Version 1.61: 2018-09-01 Version 1.60: 2018-08-25 Version 1.59: 2018-08-22 Version 1.58: 2018-08-19 Version 1.57: 2018-08-19 Version 1.56: 2018-08-19 Version 1.55: 2018-08-16 Version 1.54: 2018-06-30 Version 1.53: 2018-06-19 Version 1.52: 2018-06-03 Version 1.51: 2018-06-01 Version 1.50: 2018-05-29 Version 1.49: 2018-05-13 Version 1.48: 2018-05-12 Version 1.47: 2018-05-05 Version 1.46: 2018-05-01 Version 1.45: 2018-04-29 Version 1.44: 2018-04-27 Version 1.43: 2018-04-20 Version 1.42: 2018-04-10 Version 1.41: 2018-03-25 Version 1.40: 2018-03-18 Version 1.39: 2018-02-17 Version 1.38: 2018-02-10 Version 1.37: 2018-02-04 Version 1.36: 2018-01-24 Version 1.35: 2018-01-19 Version 1.34: 2018-01-10 Version 1.33: 2017-12-30 Version 1.32: 2017-12-08 Version 1.31: 2017-11-26 Version 1.30: 2017-11-25 Version 1.29: 2017-11-17 Version 1.28: 2017-11-10 Version 1.27: 2017-10-19 Version 1.26: 2017-10-05 Version 1.25: 2017-10-04 Version 1.24: 2017-10-02 Version 1.23: 2017-09-30 Version 1.22: 2017-09-30 Version 1.21: 2017-09-23 Version 1.20: 2017-09-21 Version 1.19: 2017-09-20 Version 1.18: 2017-09-19 Version 1.17: 2017-09-17 Version 1.16: 2017-08-20

How do I build the ESP8266 software?

See the ESP8266 Notes tab.

How do I build the Raspberry Pi Desktop or fb0 software?

See the Desktop tab.

Can HamClock run on Windows?

No, it can not run natively on Windows but it can display on Windows by using an X Server. The idea is to run the HamClock program on a UNIX-like system, such as RPi or WSL (Windows Subsystem for Linux) or Cygwin, then run HamClock in such a way that it displays on the X Server running on Windows.

For example:

  • I downloaded and installed VcXsrv on an old XP system I have here.
  • I ran the installer which places a shortcut on the desktop named XLaunch
  • I double clicked XLaunch and I accepted all defaults except I set Display Number 1 and I disabled access control for now.
  • Then on a RPi on the same network, I built HamClock and ran it as follows:
        make -j 4 hamclock-800x480
        export DISPLAY=""
  • whence HamClock immediately appeared on the Windows machine and worked fine

Note in the example above, is the IP of the Windows machine, so change that to match your system configuration. Also note the ":1" of the DISPLAY environment variable says to use X Server display 1, which corresponds to the selection I made while running XLaunch. If you find it won't connect, it might be due to your Windows firewall. X Window servers listen on port 6000 + display_number, so in this case be sure Windows is allowing incoming connections on port 6001.

Can HamClock run on iPhone or iPad?

Similar answer as previous FAQ but you'll need an X server app for iPad. I find Mocha X11 works well.

How does HamClock compare to Geochron 4k?

I do not have a Geochron 4K but from its literature I can think of the following display functions related to ham radio that HamClock offers but Geochron does not:

  1. VOACAP propagation predictions for any HF band or path at several power levels
  2. trend plots and predictions for solar flux, sunspot, XRay and Kp index
  3. short and long path antenna beam heading and distance to any DX location
  4. display next satellite rise/set times and overhead pass (not just global track)
  5. display local time in HH:MM digital, analog or calendar formats
  6. azimuthal world maps centered on any location
  7. local weather, time, grid square, prefix and sun rise/set times at any DX location
  8. live scrolling DX cluster display
  9. live display of WSJT-X and JTDX FT8 contacts
  10. live solar images from Solar Dynamics Observatory
  11. live Moon rendering with DE information
  12. live NCDXF beacon location, time and frequency schedule
  13. live RSS feeds from popular ham web sites
  14. stopwatch and station ID count down timer with optional color LED and switch control
  15. show Moon rise/set and overhead passes for EME
  16. adjust time forward or back to explore gray line location, satellite orbits etc
  17. optional Elecraft KX3 transceiver frequency control from DX Cluster spot
  18. optional local temperature, pressure and humidity sensor for real-time and 25 hour trend plots
  19. optional photosensor to adjust display brightness with changes in room lighting
  20. adjustable scheduled display On and Off times, and idle time dimming
  21. remote control functions from any browser or curl command line

Conversely, Geochron can do things HamClock can not. These items are certainly interesting but to me they do not seem specifically useful to the typical amateur radio operator:

  1. air and sea traffic
  2. pollution and population maps

If I have misrepresented Geochron in any way, please tell me how and I will correct immediately.

How does the DX Cluster feature work?

  1. In the Setup page, tap the Cluster? button then set the internet host name and port for your desired DX Spider node. A good list is here. Be sure to choose a Spider node, AR and CC clusters are not supported. Turn off the Cluster? button if you don't want to use a cluster.
  2. Once HamClock is up and running, tap the center plot pane until the DX Cluster page appears. The name of the host will be shown in yellow, and it will turn green when a connection is established. If the connection fails, it will show an error in red.
  3. Once connected, just leave it run, new spots will be listed, scrolling when full. Tap on a spot to set DX to that location. The tap can also set the frequency of an Elecraft KX3, see the User Guide for details.
  4. Beware: HamClock stays logged into the cluster node with your call sign as long as the DX Cluster pane is active. So do not use this feature if you want to use the unassisted category in a contest -- some judges do check!
  5. Spider nodes support a lot of options and settings and HamClock makes no attempt to control any of them. But you may still be able to set them by logging in to the same cluster a second time simultaneously from a different application or telnet session. You should use the same call but add an SSID suffix like "-1" so the spider software won't detect a duplicate and disconnect HamClock. Now from this second connection, make the desired settings and most nodes will carry them over to all login sessions, including the HamClock session. Here is just one example of a set of filters that will show only CW spots from operators in US or southern Canada:
        filter1 reject not by_zone 3,4,5
        filter2 reject not on hf/cw
        filter3 reject on hf/rtty
        filter4 reject on hf/ssb
        filter5 reject info ft8
  6. The same mechanism can communicate with WSJT-X or JTDX. Instead of showing cluster spots, it shows each FT8 station you attempt to work and also immediately loads DX with its location. Details for doing this are in the User Guide.

Can I make different sizes beyond those in the Makefile?

No. Each size requires its own custom fonts, symbols, maps and solar images in order to take full advantage of the higher resolutions. Otherwise, these would be very pixelated if they were just multiples of the base images. Plus, if the aspect ratio changes, the layout would need to be rebalanced. This is why all sizes are multiples of 2 of the base size in order to maintain the same layout proportions.

Why can I click on the DE or DX grid square and sometimes get a second value?

Because displaying location only to a whole degree, or any finite precision, can be ambiguous. Suppose you use the Setup screen to enter location 40N and 100.1W. This is in grid square DN90. But this location will be rounded to 40N 100W for display and this location is in grid square EN00. Just looking at the rounded HamClock display values you can't tell what the original location is, so HamClock gives you the choice of selecting the grid according to your intended usage.

The reason this happens is because grid squares increase from west to east, starting at 180W, and the major longitude grid boundaries are on even integral values. Thus 100W is in one grid and 100.1W is in a different grid. This becomes easier to see when using signed notation. You might expect moving from -100 to -100.1 would stay in the same grid but it doesn't because it is more westward and crosses the boundary at -100. But there is no ambiguity going from -101 to -101.1 because these are both near the center of the same grid, DN90. There is also no grid change going from the eastern longitude of positive 100 to 100.1 because the numeric increase is eastward and both locations are in the same grid, ON00.

The exact same thing happens with latitudes except they grow northwards from 90S and grid boundaries are on every integral line.

In addition to being set from the Setup screen, fractional coordinates can also result when setting location with other methods as well, such as IP Geolocation, gpsd or the remote web socket interface -- in all cases the full precision is maintained internally but only displayed to whole degrees. However, if you set a location by tapping the map or tapping the coordinate values to increment or decrement them then HamClock discards any fractional coordinate values so these methods never lead to a grid square ambiguity.

Occasionally you mention web interface to the HamClock, what is this?

Among its other features, the HamClock is also a web server on port 8080. This allows you to remotely control your HamClock over a network using a browser or command line tool such as curl or wget.

To try the following examples, you will need a computer on the same network as your HamClock. Here we will use curl but the same URLs will work in your browser as well (although some browsers are getting more paranoid about accessing a web site with http and you may be asked to trust the site).

Start by querying HamClock for a list of all its commands as follows: (actually any unrecognized command will produce this help text)

        curl ''
  • You must change the example address to the IP your HamClock displays periodically just below your call sign.
  • Note the good practice of surrounding the URL with apostrophes to insure it is not interpreted with shell metacharacters. Do not include these when using a browser.

The output will be a list of all supported commands as follows:

Syntax Summary
get_capture.bmp Save screen as bmp file
get_config.txt Report current HamClock configuration settings
get_de.txt Report DE info
get_dx.txt Report DX info
get_dxspots.txt Report current list of DX cluster spots
get_satellite.txt Report current satellite position, if one is defined
get_sensors.txt Generate list of sensor values, if one is attached
get_stopwatch.txt Report stopwatch state and timer value
get_sys.txt Report some basic HamClock system information
get_time.txt Report HamClock's idea of UTC
set_displayOnOff?on|off Turn display on or off
set_displayTimes?on=HR:MN&off=HR:MN&idle=mins Set DE display on and off times and idle duration
set_newde?lat=X&lng=Y Define a new DE location using latitude/longitude
set_newdegrid?AB12 Define a new DE location using its maidenhead grid square
set_newdx?lat=X&lng=Y Define a new DX location using latitude/longitude
set_newdxgrid?AB12 Define a new DX location using its maidenhead grid square
set_pane?Pane[123]=one from below


Set what is displayed in a given plot pane
set_satname?abc|none Select satellite from built-in list, or none
set_sattle?name=abc&t1=line1&t2=line2 Define a satellite using TLE values
set_stopwatch?countdown=mins Set count down timer and start
set_time?ISO=YYYY-MM-DDTHH:MM:SS Set UTC to the given time
set_time?Now Set UTC to current time from network
set_time?unix=secs_since_1970 Set UTC to the given UNIX time
set_touch?x=X&y=Y&hold=[0,1] Virtually touch, or hold, screen coordinate X, Y; scaled to 800 x 480
set_voacap?band=[80-10,off] Set VOACAP map band, or turn off
restart Restart HamClock
updateVersion Check for new version and update if found
any command not recognized Show this help


Get the current clock UTC time:

        curl ''

Set display to shut off at 10 PM and back on at 8 AM, DE time, with 10 minutes idle time:

        curl ''

Set a new DE location from latitude and longitude:

        curl ''

Save the current display to a file named hcscreen.bmp:

        curl '' > hcscreen.bmp

Set satellite to ISS and report current ephemeris with respect to DE:

        curl ''

Set Pane 3 to show NOAA Space weather:

        curl '

Toggle the screen lock padlock

        curl ''

What is the HamClock diagnostic output?

It is additional status and diagnostic information HamClock writes to the process stdout. You will see this when you start the program from the terminal command line. But, using normal shell syntax, you can save it to a file like this:

        hamclock-800x480 > log.txt

or throw it away like this:

        hamclock-800x480 > /dev/null

Then in either case, just to get even more geeky, since you have avoided displaying the diagnostics on the terminal you might as well run the program in the background to get a shell prompt immediately again to do something else by appending an & like this:

        hamclock-800x480 > /dev/null &

If you run hamclock on RPi using a desktop shortcut, the diagnostic output goes to


What is sudo and why should I use it with HamClock?

Sudo stands for "super-user do". In UNIX, the super user refers to extra privileges bestowed on the root user. Rather than actually logging out and logging back in as user root to gain these privileges, this command arranges for you to have these greater privileges just long enough to run the command that follows on the same line. After that command completes, you are again restricted back to the normal privileges of your current user login.

Another effect of the sudo command is to temporarily change the HOME directory to /root. HamClock creates and uses a working directory named .hamclock (note the leading dot) and places this in the HOME directory. HOME for the normal pi user is /home/pi. Thus, if you run hamclock without sudo it uses /home/pi/.hamclock but if you run it with sudo it uses /root/.hamclock and files therein are not accessible to the normal pi user. This duality can cause much confusion so beware.

The reason for using sudo in the first place is that HamClock requires super-user privileges to perform certain external IO and networking functions. Those with sufficient UNIX/linux administrative experience can make adjustments so hamclock could run without root privileges. But in the interest of providing the simplest and most enjoyable experience possible for the majority of users, the instructions for HamClock just use sudo throughout.

Now you know the rest of the story.

Is it possible to change the RSS feeds?

No. RSS feed formats are surprisingly inconsistent so I perform all the heavy lifting on my server and only send the plain titles to the HamClock. Plus, most now use https which uses too much memory for the little ESP processor.

That said, if you have a feed in mind that is of general interest to the global ham community, send me your suggestion and I will consider adding it to the server processing.

Is it possible to change the set of satellites?

No. The list is maintained on my server which performs all the heavy lifting of discovery and updating, sending only the TLEs to the HamClock.

That said, if you have a satellite in mind that is of general interest to the global ham community, send me your suggestion and I will consider adding it to the server list.

How are the background maps managed?

As of Version 2.52, the background map images are downloaded and stored as local files as needed. In previous versions they were embedded within the executable image and were thus immutable and limited by size of non-volatile memory.

This meant the ESP HamClocks could only ever support one map style, and even that was only at half the available screen resolution. ESP HamClocks now use the extended FLASH file system to store the map images at full resolution. The improved resolution is especially apparent in the night portion of the Terrain style map. Unfortunately, more pixels and slower FLASH access means the display update rate on the ESP is about 30% slower but the added flexibility and visual results seem worth it.

The UNIX versions of HamClock store their map files in ~/.hamclock. There is essentially no limit to the number of files that can be stored. Note if you run with sudo, this refers to root's home directory, not your login home.

If you run HamClock without a network connection, you will be limited to map styles already downloaded.

The maps are stored in .bmp format, version 4, using 16 bit RG565 pixels. There are separate files for day and night for each map style. HamClock uses these to render the two sunlit regions and blends them in a 12° band to match civil twilight.

As of version 2.54, this same mechanism is also used to provide the VOACAP global propagation reliability maps. Again, limited storage on the ESP means only one set of the standard background images can be stored when the reliability maps are in use.

How does the self-update facility work?

To update itself, HamClock asks the support server if there is a newer version available. If so, for the ESP systems, this is a binary file that is downloaded directly into FLASH and that's all there is to it.

For the Desktop UNIX systems, this is a zip file containing the source code. The zip is downloaded into /tmp; exploded; make is run with the same target as the basename of the currently running hamclock program; and the resulting program file effectively overwrites the currently running program file. This creates two challenges: how to find the full path of the program file to a running program and how to update its program file while it is still running.

To find the program file full path, hamclock first checks the argv[0] path given when it was executed. If this is already a full path, indicated by beginning with a slash (/), we are done. If not, then a test is made whether a file with that name exists with respect to the current working directory of hamclock. If so, we are done. If it still is not found, then the argv[0] name is checked for in each of the directories named in the PATH environment variable. If still not found, the update fails.

It is not possible on UNIX to modify the program file of a running program (even as root). So instead, hamclock does it indirectly by first removing the program file then copying in the new one created by make with the same name. To remove the current program file, hamclock needs write permission on its containing directory because removing a file actually just edits its out of its containing directory. If hamclock does not have this permission, the update fails. Copying in the new file then edits the same name back into the same directory, so it looks like it was overwritten when actually it was deleted and added again. Meanwhile, hamclock can continue to run because a deleted file still actually exists until the last process with it open closes it or exits, even if it is not named by any directory.

Holding the padlock does not restart ESP, what's going on?

For some unknown reason, this feature does not work the first time you try it after flashing the ESP Huzzah via USB from your computer. Use the reset button on Huzzah once then the padlock will work from then on. This issue does not occur if the Huzzah was reflashed remotely.

How do I use the Bosch BME280 environment sensor on RPi?

  1. connect the sensor to the RPi using the 40 pin connector as follows:

    RPi Header pin BME label
    1 Vin
    3 SDI
    5 SCK
    9 GND

  2. install i2c-tools:
        sudo apt-get install i2c-tools
  3. run sudo raspi-config and set the following options:
        Interface Options: I2C: enabled
  4. Check the Bosch is connected correctly with these tests:
        sudo i2cdetect -y 1
    you should see 77 in lower right corner of matrix; then
        sudo i2cdump -y 1 0x77 b
    you should see a matrix of different numbers, not just all XX
  5. Start HamClock. Enter Setup, go to Page 2, tap GPIO so it says Active, then tap Done.
  6. After HamClock is up and running again, tap near the top of pane 3 until one of the environmental plots appear; tap in the lower half to cycle through them all.

How do I shut off HamClock on the RPi fb0?

Click and hold the padlock for 3 seconds, then select Exit.

How do I safely power off my RPi?

  1. First tell linux to shut down gracefully in either one of these two ways:
    1. If running fb0 HamClock: Click and hold the padlock for 3 seconds, then select Shutdown
    2. otherwise in general: Log in and type the following command:
          sudo halt
  2. Then either way, watch the green LED; when it stops blinking it is safe to remove power.
  3. Note you do not need to bother shutting off HamClock before powering off RPi, it won't hurt the Clock in any way.

My question is not here and I can not find the answer after studying everything on this site, where can I get help?

Send a polite note to me at

Executing and Displaying on Windows 10

Contributed by Joeri van Dooren,

  1. In windows download
  2. Install; choose single windows
  3. In Windows install WSL2 with ubuntu.
  4. Start wsl.exe
  5. sudo apt -y install g++ libx11-dev wget
  6. wget
  7. unzip
  8. cd ESPHamClock
  9. make hamclock-800x400
  10. export DISPLAY=:0
  11. ./hamclock-800x480

Automating qrz page from spots

Contributed by Hans Klausmann,

        # This little python script reads live dx cluster messages from a running hamclock
        # and shows the QRZ page for each station. It can run on any pc at the local network
        # Requirements:
        # 1. a running hamclock with internet connection
        # 2. a configured DX Cluster
        # 3. adjust the ip-nr below: ...wget  to ip-nr of hamclock
        # 4. adjust the time.sleep(15) to your needs
        # 5. chmod +x
        # usage: python ./

        import webbrowser
        import os
        import time
        #os.system('wget  ajust below !
        os.system('wget -O dxspots.txt -q')

        my_file = open("./dxspots.txt","r")
        lines =
        for line in lines:
            call = line[9:17]
            if i > 1:
              url = ""+call
            elif i == 1:


Script to simplify sending web commands from command line

Seed planted by Barry, N0NZ,

        # handy wrapper to send commands to HamClock

        # set to your HamClock host or IP

        # changed from 80 to 8080 as of HamClock version 2.56

        # show error msg and usage summary then exit.
        # arg1 = name of erroneous command, if any
        # arg2 = number of expected arguments, if any
        function usage {
            (( $# == 1 )) && echo "Error: unknown command: $1"
            (( $# >  1 )) && echo "Error: $1 requires $2 argument(s)"
            echo "Usage:" $(basename $0) "cmd [_arg1_ _arg2_ ... ]"
            echo "  voacap _band_"
            echo "  dxgrid _GRID_"
            echo "  setpane _number_ _contents_"
            exit 1

        case $1 in

                [ $# -eq 2 ] || usage $1 1
                curl "http://$HOST:$PORT/set_voacap?band=$2"

                [ $# -eq 2 ] || usage $1 1
                curl "http://$HOST:$PORT/set_newdxgrid?$2"

                [ $# -eq 3 ] || usage $1 2
                curl "http://$HOST:$PORT/set_pane?Pane$2=$3"

                usage $1


Script to read and write the eeprom config file

There is no reason whatsoever you would ever need to do this, but someone asked if they could edit the eeprom config file. So, since I enjoy writing perl, I couldn't resist writing to do exactly that. You can download it contained within this zip file

Save the script in the ESPHamClock source code directory and make it executable as usual. This location is required because the script uses the HamClock.h and nvram.cpp source files to find the symbolic names and lengths of the various parameters saved in eeprom. It also, of course, needs to know the location of the eeprom file itself, which it looks for in ~/.hamclock/eeprom. The type of the parameter is not saved in the eeprom file, so the script also needs to know the data type, denoted with d for decimal (or hex), f for float or s for string.

Run the script with no args or -help for a usage summary:

        Purpose: read or modify HamClock's config file at /Users/ecdowney/.hamclock/eeprom
        Usage: NV_XXX {dfs} [value]
            NV_XXX is one of the names in the NV_Name enum in HamClock.h
            one of d, f or s to indicate value is type decimal, float or string
            optional value to write, or read if absent

Remember, you are hacking a file not intended for human consumption, so you can very easily mess things up. There's no error checking, no explanation for what the parameters mean, no checking for consistency among related parameters (such as lat/lng and grid square), etc etc; you are literally just modifying raw byte storage. At the very least, I suggest you save a copy before making changes, just in case or, if you really mess up, just delete it altogether and HamClock will create a new one containing all default values. And surely it goes without saying, you should never edit the file while HamClock is running.

Alright, let's try it! Here are a few examples:

Read the call sign:

        ./ NV_CALLSIGN s

Set a new call sign:

        ./ NV_CALLSIGN s AB1XYZ

Set DX latitude to 23.4 degrees south:

        ./ NV_DX_LAT f -23.4 
        NV_DX_LAT = -23.4

Building the ESP8266 software

  1. Install the Arduino IDE from here. I am currently using version 1.8.13.
  2. Open Preferences. In the field labeled Additional Boards Manager URLs copy/paste the following line then click Ok:
  3. Open Tools → Boards → Boards Manager
  4. Search for "esp8266"
  5. Select version 2.7.4 then click Install.
  6. Open Tools → Manage Libraries, set Type and Topic to All, then search for and install the following libraries:
    • Adafruit GFX (all), version 1.10.2
    • Adafruit Unified Sensor, version 1.1.4
    • Adafruit BME280, version 2.1.1
    • Adafruit RA8875 (only), version 1.4.0
    • Time, version 1.6.0

    Other versions might work but these are the versions I am using now.

  7. Quit and reopen the Arduino IDE
  8. Connect your computer to the Huzzah with a USB port
  9. Open Tools → Board → ESP8266 Boards and select Adafruit Feather Huzzah ESP8266
  10. Download current stable HamClock release here. Unzip it anywhere you wish, but probably best to use the default sketch folder.
  11. Use File → Open and find the ESPHamClock.ino file you just unzipped. This will create a new project.
  12. In the IDE Tools menu make the following selections (click for larger view):


    Set the port to match the USB connection of your Huzzah.

  13. Run Sketch → Verify/Compile then Sketch → Upload
  14. Your HamClock should start running. Read the User Guide and have fun.

Using the 9" display

To use a 9" ER-TFTM090-2 from

Select these options during purchase:

  • Pin header 4 wire SPI
  • VDD 5 V
  • Touch panel 9" resistive
  • Micro SD - none
  • Font chip - none

This is the wiring list:

	    EP = ESP Huzzah
	    BM = BME280 sensor
	    PC = photo cell
	    DP = display

	    EP_SCL    BM_SCK
	    EP_SDA    BM_SDI
	    EP_3V     BM_VIN
	    EP_GND    BM_GND

	    EP_ADC    PC_1, 330k
	    EP_GND    PC_2
	    EP_3V     330k

	    EP_SCK    DP_8
	    EP_MO     DP_7
	    EP_MI     DP_6
	    EP_2      DP_5
	    EP_16     DP_11
	    EP_USB    DP_3, 4, 37, 38
	    EP_GND    DP_1, 2, 13, 31, 39, 40


  • Larger, brighter, richer colors
  • Simpler wiring because you do not need the RA8875 or flat cable


  • Requires a very good USB supply, at least 2 A. This one from Adafruit is known to work well.

Stand ideas

The display stand from Adafruit can be made to work with a little ingenuity but is not perfect for the LCD. Send suggestions for better ideas and I will post here.

  • One alternative I found is this video that suggests normal picture framing components could be used.
  • The stand from Adafruit is actually made by Pimoroni so I asked them for better suggestions. They said they know of no stand suitable for the Adafruit LCD but thought this one might be pressed into service with less effort.
  • G3XOU used this RPi screen support with some assembly details here .
  • KF5LW suggests adopting this RPi screen support. He said he 3D-printed a piece to the RPi dimensions then it worked well.
  • W3TMC sent a photo of the nice looking oak stand he built.
  • N2YTF did a nice job with some simple wood and a breadboard. He sent photos here and here.
  • N6ROB attached the components and display to the stand with hot glue after sanding and wiping down with alcohol. The result looks clean and efficient.
  • N7EEK has taken a minimalist approach that works well using a $9 stand from Amazon. See his photos here.
  • ON4AEY made a nice clock and sent me this link to share.
  • N7LVS made this YouTube video showing his construction technique.
  • HB9AJG shared his very nice arrangement from the front, back and in his shack.
  • WA1TOV put his in a clear frame he found here. He comments: The back of the display is glued to the face of the frame. You might be able to see round glue dots in the rear view photos. I used E6000 glue. To do this I had to cut a 1.5" slot in the frame to feed the ribbon through. This was done with a Dremel and cut off wheel, just working very carefully and then cleaning it up with a jeweler's file. Photos: front, side and rear.

If you find your display idea works better when the cable exits from the top, there is an option in the Setup screen that allows you to flip the display upside down.

Here is how I built my first two prototypes:

Shack photo showing 7" version.

Rear of 7" version

Both the 7" and 9" versions.

Rear of 9" version

This is a guide to the touch controls and map symbols of HamClock. A printable view is also available.

HamClock was originally developed for the ESP8266 such as the Adafruit Huzzah. But after we created a porting layer, it may now also be built for Raspberry Pi, macOS, linux, Ubuntu, FreeBSD or most any other UNIX-like system. There are two basic configurations:

Instructions for each configuration are below, but first a few preliminaries:

To give HamClock a try as an application on your GUI desktop, follow these steps:

  1. open a terminal on the target system desktop to get a command line prompt
  2. run these commands (use copy/paste):
    curl -o
    cd ESPHamClock
    make -j 4 hamclock-800x480
    sudo ./hamclock-800x480
  3. If you get errors during make:
    • on RPi try updating and loading more packages such as
      sudo apt-get update
      sudo apt-get -y install make g++ libx11-dev
    • on Ubuntu try loading more packages such as
      sudo apt install curl make g++ xorg-dev
    • on macOS try installing XQuartz and Xcode. Then run
      xcode-select --install
  4. The example make command above will build HamClock at 800x480 pixels for X11. Type make help for a list of other sizes available. Then redo the make and sudo commands again substituting the preferred size.
  5. If you would rather not see the diagnostic output, then save it to a file by changing the invocation to something like this:
    sudo ./hamclock-800x480 > hamclock.log 2>&1 &
  6. If you would like a Desktop icon with which to start HamClock on RPi, copy hamclock.desktop to your Desktop folder with this command:
    cp hamclock.desktop ~/Desktop
  7. If you would like HamClock to start automatically when you log in, make sure you have an autostart directory then copy hamclock.desktop into there with these commands:

    mkdir -p ~/.config/autostart
    cp hamclock.desktop ~/.config/autostart

    The sample hamclock.desktop file assumes you made hamclock-800x480 so edit the Exec line if you have chosen a different size program name.

  8. If you want HamClock to completely fill the display but can't find a good match between your screen size and a HamClock size, try running xrandr. This command can resize your display resolution to more closely match HamClock. For example, my display is 1920x1280 so I build hamclock-1600x960 and run the following command:
    xrandr --output HDMI-1 --scale 0.833x0.92
    I computed 0.833 from 1600/1920 but 0.92 was found experimentally to account for the extra menu bar height. With care, this technique can come quite close but don't expect perfection.

    I know this works fine with a mouse pointer, but may have coordinate issues with a touch screen.

  9. On macOS, you can turn the bare executable into a clickable App on your Desktop as follows:
    make -j 4 hamclock-800x480
    mkdir -p ~/Desktop/
    cp hamclock-800x480 ~/Desktop/
    cp hamclock.plist ~/Desktop/
    To give it a proper icon:
    1. open hamclock.png with Preview
    2. type Commmand-A to select the image
    3. type Commmand-C to copy the image to the clipboard
    4. right-click the new Desktop item and select Get Info
    5. click the existing default icon in the upper left corner
    6. type Command-V to paste a new icon
    7. close Get Info
    8. close Preview

    If anyone knows how to stop the dock icon from bouncing forever, other than disabling dock opening animation for all apps, please let me know.

To try HamClock on an RPi using a dedicated HDMI or DSI display, follow these steps:

This is also referred to as the fb0 configuration.

Note: This configuration is intended for applications where the entire RPi display is dedicated to HamClock. There is no GUI infrastructure and thus no VNC, screen saver or other nice GUI controls. You must use ssh as instructed to perform everything from the command line. Do not try to use the RPi display for these commands.

  1. log in via ssh (or putty, etc)
  2. run sudo raspi-config one time and set the following options:
    1. System Options → Boot/Auto Login → Console (not AutoLogin)
    2. For HDMI only (not for DSI): Advanced options → Resolution → choose one the same or a little larger than a HamClock size
  3. reboot
  4. connect to your RPi again with ssh and run the following commands:
    curl -o
    cd ESPHamClock
    make -j 3 hamclock-fb0-1600x960
    sudo ./hamclock-fb0-1600x960
  5. If you get errors during make:
    • on RPi try updating and loading more packages such as
      sudo apt-get update
      sudo apt-get -y install make g++ libx11-dev
    • on Ubuntu try loading more packages such as
      sudo apt install curl make g++ xorg-dev
  6. The example make command above will build HamClock at 1600x960 pixels for fb0. If you want the smaller size 800x480 for the 7" display, redo the make and sudo commands with hamclock-fb0-800x480. Type make help for a list of other fb0 sizes available.
  7. If HamClock is printing a message about incorrect frame buffer depth, try this:
    • sudo nano /boot/config.txt
      • move the cursor around in the file using your arrow keys
      • find any/all lines that contain dtoverlay=vc4-fkms-v3d and put a # sign at the front of each such line
      • exit with Ctrl-X, answer Y to save
    • sudo reboot
    • after linux comes back up, log in again using ssh and type
      • sudo fbset -depth 32
    • now try hamclock again:
      • cd ESPHamClock
      • sudo ./hamclock-fb0-1600x960
  8. If you would rather not see the diagnostic output, then save it to a file by changing the invocation to something like this:
        sudo  ./hamclock-fb0-1600x960 > hamclock.log 2>&1 &
  9. If you see a little blinking line near the left edge, try running this command:
        sudo bash -c "echo 0 > /sys/class/graphics/fbcon/cursor_blink"
  10. To start fb0 HamClock automatically when the system boots, consider using crontab. For example:
    1. Start crontab with the edit option:
          crontab -e
    2. Add this one line:
          @reboot cd ESPHamClock; sudo ./hamclock-fb0-800x480 > hamclock.log 2>&1
    3. Save and exit the editor. Test by rebooting. This example assumes ESPHamClock is in your home directory and you want to run hamclock-fb0-800x480 therein. Adjust as necessary to match the configuration you specified in your make command. This example also saves the diagnostic output but if you would rather just discard it, change the log file name to /dev/null like so:
          @reboot cd ESPHamClock; sudo ./hamclock-fb0-800x480 > /dev/null 2>&1
    4. To learn more about crontab type:
          man 5 crontab
This site does not use cookies.