Yes, another nixie clock design! They seem to be everywhere these days. But I have finally got around to getting mine going, and I am quite pleased with the result. (If you are not familiar with them, 'nixie' tubes are numerical display devices, used before 7 segment LED displays were developed. Each digit is displayed via a shaped electrode inside what is essentially a neon lamp.)
I first saw Mike's clock design many years ago, and immediately decided that I had to have one. At the time, I was busy with other projects, so it was a while before I got around to doing anything about making one. The first step was to secure some tubes, and I eventually found some from eek-bay. I could have got ones with pigtail leads, but I thought these were too ugly, and got some with solid pins. As Mike has noted on his site, finding sockets for the tubes can be problematic, but I decided to make my own.
I got as far as making one socket, with connector contacts hot glued inside an aluminium ring, but I was never really satisfied with the outcome. Therefore, the project ended up on hold.
A couple of years later, I happened to spot an old digital bench voltmeter at a radio swap meet. It had a tag on it saying "dead". I thought the metal case would be good for a power supply I was building, and also noted that it had Nixie tubes for the display. I can't remember what I paid for it in the end - only a couple of dollars, I think.
Old digital voltmeter. The tubes are made by 'National Electronics', part NL-842.
I brought it home, and took it apart. After removing many layers of metal shielding panels (this thing was very solidly built!), eventually the four Nixie tubes were revealed, complete with sockets. At that point, I decided to get back on to my clock project.
The features I wanted for the design were as follows:
Power is supplied to the circuit via a 9 way D connector. This is shared with the RS-232 GPS interface, so that only one connector is required. The "ring indicate" line is used for power, which is not needed by the GPS. The input of 12-24VDC is stepped up to around 180VDC by a boost converter based around IC8, an MC34063. Note the voltage divider formed by R22 and R23, to limit the amplitude of the MOSFET gate drive when running from a 24V input. Q45 and Q46 form a low impedence buffer. L1 is an inductor out of my junk box - I didn't measure its value.
Most of the functionality is provided by IC7, an ATMega88. Its power supply is derived either through IC9, or from a 3V lithium coin cell, via isolating diodes. It has a 3.6864MHz quartz crystal for the main timing reference. (I chose this value to suit the serial communications, but I probably would have been better off with an 8MHz crystal, to make the PWM code run a bit faster.) There are inputs for two setting switches (reed switches, as in Mike's design), the RS-232 data (I stole the interface circuit from a Silicon Chip design), and an LDR. An ISP header is also present.
The microcontroller is interfaced to the display tubes using shift registers. Unfortunately, the shift registers are only 8 bit, while the tubes have 11 segments each, therefore there is a mismatch in the wiring between the registers and tubes. This is all taken care of by the software. The tubes are switched with MMBTA42 transistors, which are rated to 300V. Note that the limiting resistors are connected to the emitters, rather than the bases. This enables the resistors to be shared between the transistors, and reduces the component count considerably. As this could cause problems when more than one segment is lit, the decimal point driver transistors have their own resistors. Although the crossfade transition effect does appear to light more than one digit at once, the individual digits are actually illuminated at different points in time, via PWM.
I decided to use surface mount components as much as possible for the design, to make it as compact as possible. I decided to use a double sided PCB, and to have it commercially fabricated. Although I have made PCBs myself for most of my other projects, it doesn't really make sense to do this today unless it is needed in a hurry.
The PCB came out at 100x62mm, with components on both sides. In retrospect, I probably could have made it a bit smaller - I was still thinking in terms of the design constraints imposed by home made toner transfer boards! I had the boards made by Itead Studio, and ended up with quite a few spares. Let me know if you want one, though they won't be much use unless you have some NL-842 nixies and matching sockets!
I got the boards back from Itead after a couple of weeks, and soon had one built up. I started with the HV converter section, then soldered in the micro after checking the 5VDC supply was present. Communication with the AVR programmer was tested, after which the rest of the components were added. I quickly put together a test program, and finally had the tubes glowing. (I had tested them previously, as it would have been pointless to get this far only to discover they were duds!)
With the hardware working, I could then turn my attention to the software. This was written in C, using AVRGCC. The main problem was the control of the digits in the tubes. To enable display dimming in low light, and the digit crossfading, the PWM duty cycle of each segment in each tube had to be controlled individually. And to switch an individual segment on or off, the entire 48-bit shift register chain had to be reloaded. I started off with a 44 byte array, giving a brightness value from 0 to 255 for each segment. The entire shift register was then reloaded 256 times per PWM cycle. This proved to be too slow, so I had to reduce the number of brightness levels to 16. Also, as the PWM code was run from the main loop, delays in other parts of the program would result in brightness variations.
Therefore, I decided on a different approach. The PWM cycle was run from one of the internal timers in the AVR chip. When the timer overflows, the shift register is updated to turn on the segments that are to be displayed. The compare match B interrupt updates the shift register again, turning off all the digits. Therefore, changing the output compare B value enables the brightness to be varied.
To perform the digit crossfading, the other compare match interrupt is used. When this interrupt occurs, the shift register is also updated. In this update, the digits that are being faded out are switched off, and the digits being faded in are switched on. Therefore, varying output compare A value between the output compare B value and 0 will fade in the new digits and fade out the old ones. Any digits that are not to be changed are illuminated during both timing periods, and therefore remain static. This allows the PWM to be performed using only three updates per cycle, rather than 256. Furthermore, since all of this is done by the interrupt routines, the timing is not affected by code in the main loop.
The code is still not ideal, as updating the shift register still takes around 20 PWM clocks. Additional logic tests were necessary to inhibit the shift register update if it would overrun the available time, resulting in some dead bands in the brightness control. However, this is not really noticable in practice. The PWM runs at around 200Hz, as the next available clock division option would place it at around 50Hz, which could result in some flicker. If the processor clock was increased, a higher division ratio could be used, which would reduce the proportion of the PWM cycle need to update the shift register.
The rest of the code is fairly straightforward. Another hardware timer is used to produce an interrupt once a second, for updating the current time. This interrupt updates the display according to the current mode (run or set time), flashes the 'hours' decimal point, updates the brightness according to the current ambient light, and processes the input from the setting switches. The left hand switch cycles through the modes (run -> set hours tens -> set hours units -> set minutes tens -> set minutes units -> set seconds -> set GMT offset -> set time correction), and the right hand switch increments the curerntly selected item (or resets to zero for the seconds).
The GMT offset is necessary for the automatic setting by GPS to function correctly, as the time is sent as GMT. The time correction will be used to compensate for any frequency error of the quartz crystal, by periodically adding or subtracting a fixed amount of time from the current count. This was not implemented initially, as I had no idea of the magnitude of the correction required. The time correction and GMT offset are preserved in the EEPROM.
The only other significant piece of code is for the GPS time setting. There isn't really much to this - it just accumulates data received from the serial port, and when it has a full line, it is parsed in NMEA format and used to set the current time, in conjunction with the offset value previously described. I wasn't able to get a GPS signal inside when I was writing this code, so I was quite surprised when I took the clock and GPS outside, and it worked first go! I had thought I would have to go back and forth quite a few times before I would get it to work.
The main loop of the code is actually left with nothing to do, so it puts the chip in idle mode to reduce power consumption. This is to make the backup battery last as long as possible when the main power supply is disconnected. To further this end, only the micro itself runs from the battery, not any of the other circuitry. However, it is necessary to keep the main oscillator running for timekeeping, so the full power-down mode cannot be used, and the current draw from the battery is still around 1.5mA. It would be possible to use a separate 32kHz oscillator for timekeeping, and therefore enable the use of the power down mode. but I chose not to do this. The battery should still provide plenty of life to cope with temporary supply interruptions.
While developing the software, I found that I had to make a few hardware modifications. A 4.7uF/200V electro was added to the HV rail, to stabilise the output of the converter. I also had to change the value of the LDR divider resistor. During testing, it was found that the number '2' for the tens of hours digit did not light uniformly. I tried adjusting the supply current and duty cycle, which made some improvement, though it is still not perfect. However, I can't get any more nixie tubes easily, so I will have to live with it.
The final, and hardest, part of the project was making the enclosure. I started off by making a quick 3D CAD model of what I wasnted to produce. While this was probably not really necessary, it is good for checking that two parts won't have to occupy the same space at the same time, as this is a really annoying thing to discover when you go to assemble the unit!
I then started milling the case from a solid block of aluminium. This entailed hours of carefully twiddling handwheels, knowing that a mistake would probably mean starting all over again. While I did encounter a few problems, fortunately they did not affect the external appearance of the part. After polishing the case using a buffing wheel, it looked quite reasonable.
Completed enclosure after polishing. The cutout is for the D-9 connector at the back.
With this done, I installed the PCB in the case, plugged in the tubes, and the clock was just about complete. There are still a couple of things to do - I need to get some rubber feet for the case, and the timing correction code still needs doing, but the unit is quite usable as it is. It has been running for a few weeks now, and has only drifted a few seconds, so I have got something to go on for writing the rest of the code.
In conclusion, while it has taken me a long time to get this project finished, I am quite pleased with the result. Although the design is not novel, it may give you a few ideas if you have a similar project in mind. I have not yet tidied the source code up for publication, but let me know if you would like a copy. I have also got plenty of spare PCBs, which are available for the cost of postage if you have a use for them.
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
loopgain.net