In our house, the concept of time is somewhat fuzzy. This is especially true in the morning as we get ready for school and work. The number of days dropping off the kids late to school is a little embarrassing. Additionally, the expenses taking the toll road so I can shave ten minutes from my commute to make the morning meetings is way out of budget. While in the car, the direction application on the smartphones can conveniently give the estimated time of arrival (ETA) to the destination, but doesn’t warn us when we should leave the house. So this hack is all about helping fix this problem and making the Nixie tube clock a little more useful than just looking cool.
This DIY project will combine the estimated time of arrival function with a Nixie tube display to create an estimated time of arrival (ETA) Nixie tube clock. It is all easily controlled by a Raspberry Pi Zero W that is connected to the internet through WiFi to provide the latest time and gets the ETA for any number of destinations. The travel time is provided by the free Google Directions API interface that includes traffic to give the best estimates on any particular day. The goal is that with an ETA Nixie tube clock, no math is needed to add a rough, often optimistic travel time, to the actual time to determine if we are running late. The clock does that for you and with the power of IOT, is much more accurate! A motion sensor is also added to the clock to turn off the Nixie Tube Display when no one is around, saving power and increasing the Nixie tube lifetime. The complete project, including the six IN-4 Nixie tubes, are powered from a 1 amp iPhone charger using the 5v to 170v Nixie Tube Power supply described in an earlier blog. Now that it is built, we will see if it brings our family’s concept of time a little more into focus.
This is a full open source hardware and software project. The schematics, PCB layout, and BOM were done in KiCad (TM). The Raspberry Pi software was written in python is also open source and the hardware and software project files are available for download at Github. This blog will describe the design and how to build and set up the ETA Nixie tube clock. Additional blogs will describe how to build a wooden Nixie clock mount and how the software can be customized to add your own display flare. Comment are welcome and encouraged. Do you need an ETA Nixie Tube Clock so you aren’t late in the morning?


The Clock in Action
The ETA Nixie clock is programmed to display the normal time and up to ten different ETA times that are easy to identify and visually stimulating. The current time is displayed for 5 seconds (i.e. 8:41:38 AM), then up to ten different ETA destinations are displayed for three seconds each before the cycle is repeated. The current time displays all six digits including seconds. The ETA locations are numbered and display hours and minutes without seconds helping to distinguish between them. In our house, the ETA to work is ETA number 1 (i.e. 9:07 AM) and the ETA to school is ETA number 2 (i.e. 8:58 AM). Lots of other options are possible with custom programming of the Raspberry Pi to meet your ETA requirements.
Circuit Design

This project uses six IN-4 Nixie tubes as the display and controls them using a retro method used by some original computers. For these tubes the ignite voltage is near 165v with a nominal rated current of 2.5mA. While many tubes have one anode pin to drive each of the ten digits, the IN-4 also has two additional anode pins to drive the even and odd digits respectively and were used in this schematic. This two anode method controls the Nixie tubes as a bi-quinary system. The advantage with this control is that 6 serial bit registers can display all ten possible numbers for each digit. A six digit display needs to use just 36 bits (i.e. 6×6) versus 60 without this coding. One bit represents if the digit is even or odd and the additional 5 represent the digit.
The odd/even bit will control which anode will be driven by 165v by the transistor network attached to each Nixie. For example, For example, When D0 is pulled low (i.e. the register value is 1), Transistors Q2 and Q3 are turned on, applying the drive voltage to the even anode (pin 10). When this voltage is floating (i.e. the register value is 0), transistors Q4 and Q5 are turned on, applying a voltage to the odd anode (pin 13).
The Nixie Tube off voltage and current characteristic enable the use of a 50v avalanche rated output serially to parallel converter. At first glance, the 50v rating of the TPIC6B585 output stage does not appear to be enough to power a 170v Nixie tube. The current rating and on resistance of the open drain outputs can easily drive the Nixie display’s 3mA on-current rating. However, during the off state, this current will drop to below 100uA when the Nixie tube display extinguishes near 130v. This is the why a 50v avalanche rated device will work in this application. When the output of theTPIC6B585 stage turns off by the appropriate serial stream, The voltage will rise to its avalanche voltage around 50v and absorb the small 100uA Nixie tube off current just fine. The power dispassion is just 5mW, super small for the TPIC6B595.
The plethora of Raspberry Pi GPIO pins facilitates easy and flexible data transfer transfers data to the Nixie Display. The RPi GPIO pins are connected to the full complement of a clock (SRCLK), data (SER_IN), output enable (/G), load (RCLK), and clear (/SRCLR) control pins on the TPIC6B585. The data and clock lines transfer the serial data into the shift registers. The load will latch this data into the output registers. The output enable will turn on the output stage to the data present in the output registers. And the clear is a fast clear of the register data. All the control pins from the Raspberry Pi are translated to appropriate IO voltage by the 74HCT04 inverter IC. This “HCT” logic variant converts the Raspberry Pi’s 3.3v GPIO logic into the 5v logic of the TPIC6B595.
Software Design
The code for the clock was written in Python mostly because I know the language. 🙂 Python also has a large established code base for the Raspberry pi and the object-oriented features simplify the software structure. The goal was to put a code structure together that would allow for easy future enhancements to the code. However, as a minimum, the software has the following features:
1. A timer to preciously update the time each second.
2. An object Nixie Display Class customized to the serial encoding system and different types of Nixie tubes. IN-4 bi-quinary method was used in this project. I will expand this to IN-14 Nixie types in the future and hope others can propose additional types on the GitHub repository.
3. A timer to turn off the Nixie Display when no motion is sensed on the motion sensor for 15 minutes.
4. A timer that will query Google Maps Traffic information every four minutes. Faster times are possible of course, but this value allows for a decent number of ETA queries while staying under Google’s free API requests limit.
With multiple timers and one that needs to be precise, the code used the python threading module to avoid timing issues with a single control loop. One timer thread is used for each timer above and global parameters are used to keep data synchronized. The resulting code structure was quite simple compared to other single control loop embedded codes I’ve implemented. I really like this Python on a Raspberry Pi stuff.
Building Your Own
Below are the steps to build your own ETA Nixie Tube Display. All the design and PCB files are located at Github.
Recommended Equipment and tools
- Temperature controlled soldering iron with surface mount and larger high heat tips.
- Oscilloscope
- Two Multi-meters
- Wire cutters and strippers
You can see the lab equipment I used to bring up and develop these displays. While ideally, you don’t need these for the project, mistakes do happen on the component soldering and placement and these will help to pinpoint the issue.
Step 1 : Order the power supply PCB
Order 5v to 170v Nixie Supply Boards from your favorite PCB manufacturer. The gerber files are on GitHub or you can order them directly from oshpark.
Step 2: Order the Nixie display PCB
Order the ETA Nixie Clock PCB from your favorite PCB manufacturer. The gerber files are on GitHub or you can order them directly from oshpark.
Step 3: Order the parts
The Parts are available from Digi-Key (TM). The Github repository clock and power supply have *.ods spreadsheet files with the Bill of material and Digi-Key (TM) part numbers for the major components. Also order the following items:
- m2 plastic standoffs and Screws to place them together. (this kit is more than you need, but good to have in kit)
- 6 x IN-4 Nixie Tubes
- PIR Motion Sensor (optional)
- Raspberry Pi Zero W (this has Wi-Fi built in)
- 0.1″ header kit (optional)
- Solderless connector kit (optional)
- 1A iPhone / USB Charger
Step 4: Assemble the power supply PCBA
Assemble the Nixie Tube power supply boards using the supplies BOM and schematic. Experience at soldering is required here as this has really tight spacing to keep it small.

Step 5: Assemble the Nixie display PCBA
Assemble the Nixie Tube Boards without the IN-4 Nixie Tubes and Resistors R24, R32, R40, R48, R56, R64. During bring up we will test the Nixie tubes one by one.

Step 6: Install Just One Nixie Tube
During this step, the IN-4 Nixie tubes will be adjusted to be installed, but only one will be installed now and tested. Then the rest will be installed one at a time. For now, place the IN-4 Nixie tubes into the board, WITHOUT SOLDER, and ensure that the two white Dots are vertically aligned.

If they are not all aligned, then you will need to mount the Nixie tubes off the board with standoffs and bend the leads of the misaligned boards so they line up appropriately.


Once all the Nixies are adjusted, remove five of them and solder just Nixie U3.
Step 7: Attach header to Raspberry Pi
Solder a header to the Raspberry Pi Zero W with CD memory.

Step 8: Testing the power supply
Test the Nixie Tube Power Supply with a bench supply and a multimeter on the input and output of the power supply. Short the enable input to ground. Rise the voltage on the power supply slowly looking at the output voltage. With no load, you should see 166v when the input is at 4v. If you hear or see anything usually, you will need to stop and debug. Send me a comment below and I can help.
Repeat the same test by powering the supply from the iPhone charger. Ensure you get 166v on the output.
IMPORTANT: NOW Remove the short on the enable pin. It will be driven by the Raspberry Pi during operation
Step 9: Solder the power wires to display
Make the wires one inch long and attach them to the Nixie tube display.

It is now time to check the assembly by powering up the Nixie power supply. With a multimeter attached to the 5v connection and the 170v output connection, Plug in the USB cable into the iPhone charger. You should immediately see 5v on the 5v Net. The voltage should be above 4.5v. Otherwise, there may be a misconnection on the board. The 170v net should be less than the 5v net by a diode drop. The power supply should be off at this stage.

To turn on and test the power supply, Again connect the enable pin to ground. You should see 165v as you measured earlier. If not, then there is a misconnection.

Step 10: Getting a Google Maps API Client Key
Google Directions API was called to get the ETA times for each of the locations. For you to use the software you will need to click the “Get a key” on this linked page. With this API key, you can test the directions of each of your desired distances using the URL example shown on the Google page. If these test ok, then replace both the current address and the ETA addresses in the locations.py file as will be described below.
Step 11: Setting up the Rasberry pi Zero W
This step assumes you have set up the Raspberry Pi Zero with the latest Raspian software and connected it to your local WiFi network. Here is a great blog on how to set up the Raspberry Pi Zero W as a headless system over wi-fi. Change the password and setup it so it will log onto the local Wi-Fi system at boot up. You can do this within the raspi-config program:
[code language=”text ” light=”true”] sudo raspi-config [/code]
After you install the configure the following steps will be followed:
Step 11.1 Create an ETANixieClock directory from the /home/pi directory.
[code language=”text ” light=”true”] mkdir ETANixieClock [/code]
Step 11.2 Copy all the code files from the GitHub repository into the new ETANixieClock Directory.
These files are located in the ETANixieCode directory
Step 11.3: Create a googlemapsclientkey.py file with the key you acquired in step 10.
Add your google api key you got above to the following code line:
[code language=”bash” light=”true”]
#!/usr/bin/python
# gmaps client key
clientkey = ‘KEY’
[/code]
Step 11.4: Create a locations.py file with your Nixie clock location and the addresses of each of your desired ETA locations.
[code language=”bash” light=”true”]
#!/usr/bin/python
# this file contains the ETA locations at startup and the clock location
#address list for home and work. Initialize dest array with the number of ETA locations
dest = [0,0]
dest[0] = {‘toplace’:’work’,’toaddress’:’24200 Dana Point Harbor Dr, Dana Point, CA 92629′}
dest[1] = {‘toplace’:’school’,’toaddress’:’33333 Pacific Coast Hwy, Dana Point, CA 92629′}
#dest[2] = {‘toplace’:’work2′,’toaddress’:’15822 Bernardo Center Dr, San Diego, CA 92127′}
# clock location
orig = “Dana Point, CA 92629”
[/code]
Step 11.5: Install pip the google python Directions API library.
Install the pip installation program for python. This may already be installed.
[code language=”text ” light=”true”] sudo apt-get install python-pip [/code]
Documentation is available on at Github. Run the following command in a terminal window:
[code language=”text ” light=”true”] sudo pip install -U googlemaps [/code]
Step 11.6: Edit crontab with TestBootScript.sh.
This will be used while the Nixie Clock is being tested. Then this file will be replaced with BootScript.sh.
[code language=”text ” light=”true”] crontab -e [/code]
place this command in the file on a line at the end:
[code language=”text ” light=”true”] @reboot /home/pi/ETANixieClock/TestBootScript.sh[/code]
Step 12: Attaching Raspberry Pi to Display
We are now ready to test a single Nixie tube and see if the system is working correctly. Solder R24. To attach the anode of the Nixie tube to 165v
Plug in the Raspberry pi and power the board. After 30 seconds you should see that the Display is showing the current time. If you don’t see this, then see the Additional Notes Section below to help you debug.
Step 13: Assembling the tubes
One at time, attach another tube and ballast resistor then repeat step 12 until. All six displays are showing the same time
- For tube 2, solder ballast resistor R32
- For tube 3, solder ballast resistor R40
- For tube 4, solder ballast resistor R48
- For tube 5, solder Ballast the resistor R56
- For tube 6, solder ballast resistor R64
The TestBootScript.py will run a program that displays the current time on one Nixie tube and then duplicated to all size digits. In the video, the current time shows 12:11PM.
Step 14: Mounting the power supply board
Use M2 standoffs to mount the power supply to the Nixie Display Board. You will notice only three mounting holes are used. One corner is not connected. Solder wires into the Nixie Tube Display Board and assemble the power supply.

Step 15: Attach the PIR Motion Sensor

Step 16: testing the ETA Nixie Clock Code
Run crontab -e again and adjust the file to run the final boot script, BootScript.sh.
[code language=”text ” light=”true”] @reboot /home/pi/ETANixieClock/BootScript.sh[/code]
Python script for testing and burning in Nixie Tubes
The TestDigits.py python script at Github is useful for testing, debugging, and fixing nixie tubes with Cathode poisoning. In my experience, most tubes can benefit from some amount of burn-in. My testing has been with IN-4 Nixie Tubes, both the coarse grid and fine grid versions of the IN-4 tubes. The TestDigits.py has the following features:
- Display each digit, one second at a time.
- Display any particular digit.
- Burn-in any single digit (i.e. to fix Cathode poisoning)
- Burn-in all digits.
- Burn-in each even digit.
- Burn-in each odd digit.
- Turn on any number of Nixie Tubes
This is an Open Source Hardware Project
Are you interested in contributing to this project? I would like to expand this project to include other types of Nixie Tubes (i.e. the IN-14, etc). In addition, the code can be improved to add more display options and to easily add new ETA locations directly from a smartphone. I would also like the clock to have it own web server to show status. Let me know if you have an interest in helping bring this to the next level or send me a pull request at Github.
I hope you enjoyed this project and can use some or all of it on your next Nixie Tube Project.
Additional Notes
If the TestBootScript.sh does not work to show Digits on the first Try, you should try the following steps to help debug and determine if it is a hardware or software issues. The quick steps are to remotely log into the raspberry pi, kill the current python process and then run one of three different python program to determine if any errors occur.
Log into the Raspberry pi
- ssh pi@ipaddressofRaspberrypi
Kill the current python process
- Go do the ETANixieClock directory
- Use ps aux | grep python to find the current python process ID
- Run sudo kill ID
Run each of the following programs to determine if an error occurred.
- TestDigits.py: This will just test the Nixie Digits, cycling through them
- TestETAclock.py: This will show the time 1 digit at a time.
- ETAclock.py This is main ETA Nixie clock file.
Determine if you see any error messages. If you don’t see any error messages then it is a hardware program is related to your nixie display circuity.
References:
- EEVblog episode . #952: A video from “Dave” I based my Nixie Driver Schematic on. Part of a 5 part series you that has some good info on Nixie Tubes.
- Bi-Quinery Wikipedia page.
- Instructions for getting and using the Google Direction API. and github location
Cool stuff! I think you need to customize this: add a little wireless implant that will zap you if you don’t get out the door when the Nixie Tube tells you to leave. 😜
> >
That is a perfect idea for a future blog . 🙂
Wow, Mark! Impressive work and write up! I will forward to you dad for technical review!
I am currently sourcing parts for this great power supply to build your Nixie ETA clock. I have been able to find everything at Digikey except for the 100uf 16V 1210 Ceramic Cap. Is 16V necessary or will 6.3-10V do. Or is there another option I had not thought of.
Very Cool. The 16v rating was chosen so I could, If needed, power the supply from 12v. If you power the supply from 5v as designed, Lower capacitor voltage ratings are fine. Try to use 10v if you can. The capacitance tends to drop on ceramic capacitors as you operate them near their operating voltage, but this is not critical.
Mark,
Thank you very much. I have on order a few from Newark, as they may have sufficient stock by January. According to the representative that flagged my order, apparently there is a global shortage on the materials needed to create dual layer ceramic caps. keeping fingers crossed that I don’t get bumped by one of the big guys. 😉
By the way I have become somewhat addicted to nixie clocks recently as I explore whats out there. I think what you have done here is great. I loose track of time regularly. This will be amazing. I may have to add some accent RGB LEDs under the tubes though. My wife would probably prefer I didn’t though.
Collin
Good luck and let me know if u have any questions . I like the accent LED idea…:)
I finally got my nixie clock assembled. There were some delays as the first nixies I ordered from the Ukraine were damaged in shipment.
1. I found I had to increase the cathode current to fully light all the digits. Perhaps if I had run the de-poisoning longer/hotter that would not have been necessary.
2. I chose not to use the ETA part of the eta nixie. I live in a town of 10k and I am not a fan of google surveillance. (Go DuckDuckGo.)
3. I found a minor problem with RepeatedSyncTimer that caused 2 threads to try to update the clock at the same time. When started cold the pi zero w has the wrong time. Shortly after booting, the system ntp process updates the time and the update can cause a second sync thread to be queued. If unlucky both will try to update the clock at the same time scrambling the display. While there are many ways to fix this, I choose to add an additional thread lock.
4. On one tube I see some 4/5 ghosting while displaying 4. I saw your note on how you corrected this. I wondered about simply connecting the screen to ground via a large (1M+) resistor. I vaguely remember reading about that in some nixie datasheet.
5. I’ve been experimenting with using bluetooth RSSI as an alternative to the PIR sensor.
6. Next step, a case….
Once again thank you again for creating a nice project and the detailed report.
Hi,
It is super cool you are getting things to work. Your root cause for the RepeatedSynTimer (#3 in your list) is great. I would love if you could share your code (possibly by asking for a pull on the Github page) to show how you added this “thread lock” to the code. On occasions, I have seen this time scrambling occur and I solved it by adding delay’s in the startup script. However, it looks like your solution is more elegant. For the screen ghosting issue, the best solution is to solder the 1Mohm between the center screen and the “4” pin if the “5” is ghosting or vice versus if the “4” is ghosting. This works better to just fix just this ghosting sensitivity and not change other digits. My blog on the subject is really a summary of trying many combinations. I tried just adding the 1Mohm to ground and it did not work great overall.
thanks for your comments and fixes.
Unfortunately my new and improved RepeatedSyncTimer also does not work. I observed it stop updating the clock following the ntp sync.
At this point, I’d like to step back and reconsider RepeatedSyncTimer. I’m not much of a python programmer and its threading and precision timing seems to be, ehem, baroque.
I’ll be happy to share my code when and if it works.
I have RepeatedSyncTimer working. Its implementation is subtle. Because the system time is changing, it interacts in non-obvious ways with the Timer class.
While I was there I also adjusted it so updates happen on seconds boundaries (rather than ½ second). I also added some code for tuning the latency that I think you intended.
After completing this I found it unsatisfactory. The code is too complicated and the performance is not great. Time updates were happening with typical 5ms variance with an occasional excursion to 20ms or more. I am told a good musician can notice a 1ms variance.
I then reimplemented it using the time.sleep method rather than Timer. This is much simpler and performs better. Time updates have a typical variance of less than 50us but it still has the occasional excursion to 10ms.
It might be possible to further improve it by using a combination of sleep and a short busy-wait loop.
I’ll test it some more and clean up the code and send it on to you to do as you wish.