VFD Trilateral Clock




About: Now retired but have a passion for robot design and construction. Also enjoy programming, my career was largely commercial programming and design work using Cobol, Fortan, and industrial automation and integ...

Project Date: Feb – May 2019

Author: Christine Thompson


While waiting for the delivery of parts for another project I decided to push ahead with this project. At its heart is two IN-13M Nixie tubes. These tubes are designed to provide a linear scale between maximum and minimum points using an illuminated column. The project uses two of these IN-13M, three wire Nixie tubes to show, time (Hours and Minutes), temperature (Celsius and Fahrenheit), Humidity (percentage), and Pressure (millibars).

At this point I would like to thank Dr. Scott M. Baker for his great web site, which provided me with all the information I needed to get these Nixie tubes to work. In particular the Current Regulator as displayed and detailed on his web site.

The project uses a BME280 sensor to determine the temperature, pressure and humidity and RTC clock to monitor time. As the system needs to display six different values it was necessary to construct a rotating central display which showed these values against six scales. In order to achieve this an equilateral triangle of wood was fashioned, each side showing two sets of values. A stepper motor was mounted under the top platform and this motor rotates through 120 degrees in time for the next set of values to be displayed on the two Nixie tubes.

NOTE: The IN-13M nixie tube cannot be considered as accurate at displaying a numerical value as say the IN-14, or any of the other Nixie tubes.


Step 1: Equipment


1. Arduino Uno R3

2. 16X2 LCD display (Used for testing only, removed upon final assembly)

3. BME280 sensor

4. RTC Real time Clock with battery backup

5. 12V – 150V DC-DC boost converter

6. 12V – 5V DC-DC step down converter

7. 12V 1A – Power Adapter

8. 5V Stepper Motor 28BY-48 and Controller ULN2003

9. Wood for base, platform and scale.

10. Glass dome

11. 3mm brass rod

12. 3mm brass dome nuts

13. Brass sheet, 2mm (300mm x 600mm)

14. Black 100gsm paper

15. Various cables

16. Single pole switch

17. 5v red LED

18. 12V positive center adapter inlet

19. Various screws, plastic mounts, heat shrink, PCB pins, wire

20. PCB board (3 X 40mm X 20mm)

21. 5mm red LED

22. Current Regulator:

a. 1K resistor

b. 1uF Capacity

c. 470ohm resistor

d. 220K resistor

e. 2K trim pot, 3296

f. MJE340 NPN transistor


I have attached a Fritzing diagram showing the complete wiring of this project.

I have attached the original Russian IN-13 datasheet, MJE340 datasheet, TSR-3296 datasheet, MS Publisher Scales format, and Current Regulator schematic

When examining the IN-13 you will notice a pink dot inside the glass at the bottom of the tube. With this on the right-hand side the wires as read from left to right are: Aux-cathode, Ind-cathode, and Anode. It is important that the anode is not over loaded and a maximum of 140v is recommended.

When examining the 2K trim-pot the wiper connection is the center connection and either of the two outside connections can be used. When examining the MJE340 transistor view the black plastic side, not the heat sink side, reading the connections from left to right gives Emitter (E – 1), Collector (C – 2), and Base (B – 3).

When constructing the Current regulator resistors can be installed in either direction, however the capacitor must be installed with the “minus” grey strip facing the GND. Also ensure that all GNDs return to a single point, this is most important for the High Voltage GND which must also return to the same point.

The most common mistake to is wire the MJE340 the wrong way around.


The Current Regulator converts the PWM digital pulses from the Arduino Uno to analog current pulses which are used by the IN-13 IND-Cathode to power the display.

Two Current Regulators are required one for each Tube. As per the schematic the Arduino Uno through pins 3 and 6, both PWM enabled, controls the Collector of the MJE340 via a 1K resistor. Fluctuations in the current are smoothed by the 1uF capacitor. A 470 ohm resistor provides current to the 2K trim pot wiper, and a 220K resistor provides power to the Aux Cathode. The trim pot allows maximum and minimum display values to be set. The Trim pot provides power to the Emitter of the MJE340 and the Base pin is connected to the Ind Cathode.


After testing the system with a 360-degree servo motor I decided to use a stepper motor which provided more accuracy. The stepper motor is controlled via four control lines from the Arduino Uno. The stepper motor arm is attached to a 3mm rod of copper which has been drilled to pass through a triangular block of wood. The top of the rod was tapped and passes through a copper plate and secured with a domed brass nut.

The stepper motor is matched to the display of each set of values, hours + minutes, Celsius + Fahrenheit, Humidity + Pressure. Each face is 120 degrees from the other. To work out the number of steps which need to be made to rotate the arm once, we have: 360/11.25= 32 steps (4 step sequence, stride angle of 11.25). Together with a gear ratio of 64 we get (32*64) = 2048 to complete one turn of the arm.

Therefore, we need a value of 683 to turn the arm through 120 degrees.

The stepper motor is attached to the bottom of the top plate and via the controller wired to the Arduino Uno through pins 8,9,10, and 11, and to the 5V power supply.


I have attached two Arduino NCO files, one showing the calibration of the Nixie tubes and a second showing the complete program used to control the project. The values obtained for the Celsius, Fahrenheit, Pressure and Humidity are all converted to integers, and also limited by use of the CONSTRAIN Arduino function. In addition, the MAP function is also used to map these integer values into a fixed range of 40 to 255, (minimum and maximum of IN-13 tube) the critical code is as follows:

For Hours and Minutes:

hours = constrain(hours, 0, 23);

minutes = constrain(minutes, 0, 59);

new_hours = map(hours,0,23,40,255);

new_minutes = map(minutes,0,59,40,255);

For Celsius and Fahrenheit:

celsius = constrain(celsius, 10, 35);

fahrenheit = constrain(fahrenheit, 50, 100);

new_celsius = map(celsius,10,35,40,255);

new_fahrenheit = map(fahrenheit,50,100,40,255);

For Pressure and Humidity:

Bar_pressure = constrain(Bar_pressure, 980, 1030);

Percentage_humidity = constrain(Percentage_humidity, 30, 80);

new_Bar_pressure = map(Bar_pressure,980,1030,40,255);

new_Percentage_humidity = map(Percentage_humidity,30,80,40,255);

NOTE: The fixed range of 40 to 255 was determined via
calibration of the IN-13M using fixed values and observing the resultant position of the light column.

NOTE: Version V2 of the software has been added. This version corrects two problems one being the turning of the three face wood block using the stepper motor and the other being the processing of the light detection.


This project has been an interesting one as it allowed me to work with a stepper motor and the IN-13 Nixie tubes both for the first time. The stepper motor was in the end the better choice for the movement of the central display as the servo motor could not provide the accuracy I required.

It was necessary to use the calibration program in order to provide as much accuracy as possible in the display or height of display each IN-13 Nixie tube illuminated. While the time, temperature, pressure and humidity readings where accurate mapping these values onto the IN-13 was not easy, the Arduino MAP function providing great help with this process.

I have included a MS Publisher file which holds the printed scales for each value. I decided to print these onto yellow 100 GSM paper to provide the maximum contrast between background and printed letters and numbers.

A You Tube Video of this project can be found at:VFD Trilateral Clock

Arduino Contest 2019

This is an entry in the
Arduino Contest 2019



    • Party Challenge

      Party Challenge
    • Fandom Contest

      Fandom Contest
    • IoT Challenge

      IoT Challenge

    8 Discussions


    5 days ago

    Great project. I've been looking for some inspiration for the nixie tubes I have. Thanks, you really got the grey matter churning.


    10 days ago

    Nice, I love clocks of all kinds
    If you go Wifi using Wemos ESP8266, I recomand you to use NTP to get time.

    2 replies

    Reply 9 days ago

    Yes I agree, good upgrade for version 2, replacing the Arduino Uno with Wemos, gives Wifi, saves space, and removes the ETC module.


    Reply 10 days ago

    // programme Wemos pour la connection sur Wifi
    // Recherche de l'heure via NTP
    // L. BAGHLI 03/2019
    #include "FirebaseESP8266.h"
    #include <ESP8266WiFi.h>
    #include <WiFiUdp.h>
    #include <NTPClient.h>
    #include <Time.h>
    #include <TimeLib.h>
    #define SSID "yourssid"
    #define PW "yourpw"
    WiFiUDP ntpUDP;
    NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 60000);
    int led = 0;
    String getFormattedDateTime(NTPClient * timeClient) {
    unsigned long rawTime = timeClient->getEpochTime();
    time_t t = rawTime;
    String dayStr = day(t) < 10 ? "0" + String(day(t)) : String(day(t));
    String monthStr = month(t) < 10 ? "0" + String(month(t)) : String(month(t));
    String yearStr = String(year(t));
    unsigned long hours = (rawTime % 86400L) / 3600;
    String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);
    unsigned long minutes = (rawTime % 3600) / 60;
    String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);
    unsigned long seconds = rawTime % 60;
    String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);
    return yearStr + "/" + monthStr + "/" +dayStr + " " + hoursStr + ":" + minuteStr + ":" + secondStr;
    void setup(void) {
    int attempt;
    Serial.println("Exp6.1 ESP Wemos");
    // connect to wifi.
    while(WiFi.status() != WL_CONNECTED)
    Serial.print("Connecting ");
    WiFi.begin(SSID, PW);
    while ( (attempt<15) && (WiFi.status() != WL_CONNECTED) )
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    void loop(void) {
    Serial.println("Update DTH");
    String datetime_str = getFormattedDateTime(&timeClient);
    led = !led;
    digitalWrite(BUILTIN_LED, !led);


    9 days ago


    This is a great project!! Could you tell me where you purchased the 12V – 150V DC-DC boost converter?

    1 reply

    10 days ago

    I have a thing for clocks and Nixie Tubes. This project is absolutely fabulous! Thanks for the inspiration, I think I will work on something similar!


    11 days ago

    I love the look of this! Great design :D