I have always had a fondness of the electronics of yesteryear, and the creativity of the pioneers in electronics. I actually find the old valve (tube) equipment beautiful to look at, which always surprises my wife, who sees it as "old junk", in her words. But the work and learning that went into creating the old equipment is something to be awed at!
Especially the visual display devices they developed from thermionic vacuum tubes, such as the 'Magic Eye' valves for viewing analogue signals, and the Decatron valves for counting digitally, and Nixie tubes for viewing the 'newly developed' digital electronics. Later, they developed VFD displays (Vacuum Flourescent), and Numitron and Minitron tubes, that used lower voltages, and were filament based, just like bulbs are. But, to me, they do not have the charm of the original displays.
This article is about Nixie tubes, and they came in many glass case types, and a few of them are shown below. Aren't they beautiful?
However, purchasing such items as Nixie tubes is becoming a problem because sellers want too much money for them, so I have developed a method of emulating a Nixie tube on a small OLED display, so it looks very similar to a real Nixie tube displaying digits. The OLED display is an SSD1331 type, with a display of 96 pixels by 64 pixels, so it is very small, and could easily be placed within a glass tube of some sort, to give the Nixie tube an even more realisitic look.
Another good thing about emulating a Nixie tube on an OLED display, is that it does not need the high voltage that a real Nixie tube requires, which is around 200 volts, and the emulator will happily work from 3.3 Volts.
Below is a photo of the Nixie tube emulator on the SSD1331 OLED display, illuminated with the digit "5". Please excuse the poor quality of the image, but that is the best my phone will do. The actual OLED display is very clear, and the metal grid can also, sometimes, be seen, as well as the other, non-illuminated, digit grids of a Nixie tube:
Below is a code listing, written in the Positron8 Compiler, for a simple Nixie Tube demonstration. It circulates the digits from 0 to 9 every second. The PIC must be a PIC18F device with 128K bytes of flash memory, so it can hold the Nixie tube images as 'Dim xxx As Flash8' tables.
'
' /\\\\\\\\\
' /\\\///////\\\
' \/\\\ \/\\\ /\\\ /\\\
' \/\\\\\\\\\\\/ /\\\\\ /\\\\\\\\\\ /\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\\\ /\\\\\\\\\
' \/\\\//////\\\ /\\\///\\\ \/\\\////// /\\\/////\\\ \////\\\//// \////\\\//// \////////\\\
' \/\\\ \//\\\ /\\\ \//\\\ \/\\\\\\\\\\ /\\\\\\\\\\\ \/\\\ \/\\\ /\\\\\\\\\\
' \/\\\ \//\\\ \//\\\ /\\\ \////////\\\ \//\\/////// \/\\\ /\\ \/\\\ /\\ /\\\/////\\\
' \/\\\ \//\\\ \///\\\\\/ /\\\\\\\\\\ \//\\\\\\\\\\ \//\\\\\ \//\\\\\ \//\\\\\\\\/\\
' \/// \/// \///// \////////// \////////// \///// \///// \////////\//
' Let's find out together what makes a PIC Tick!
'
' Emulate a Nixie Tube on an SSD1331 96x64 OLED.
' The images of the numbers 0 to 9 are displayed on the OLED, as if on a real Nixie tube.
'
' This demo counts from 0 to 9, and display the digits on the SSD1331 OLED, using the name of an image table.
'
' Written by Les Johnson for the Positron8 BASIC compiler.
' https://sites.google.com/view/rosetta-tech/home
'
$if _code < 120000 ' Does the PIC device have enough flash memory for the image tables?
$error "The program needs a PIC18F device with 128K of flash memory" ' No. So give an error message
$endif
Device = 18F27K40 ' Tell the compiler what device to compile for
Declare Xtal = 64 ' Tell the compiler what frequency the device is operating at (in MHz)
Declare Access_Upper_64K = True ' Tell the compiler to use the 24-bit TBLPTRL\H\U SFRs
Declare Auto_Variable_Bank_Cross = On ' Make sure all multi-byte variables remain within the same RAM bank
'
' Define the pins used for the SSD1331 OLED display
'
$define SSD1331_CLK_Pin PORTC.3 ' Connects to the SSD1331 CLK pin (named SCL on some displays)
$define SSD1331_CLK_PPS_Pin Pin_C3 ' Define the CLK Pin to use for PPS
$define SSD1331_DTA_Pin PORTC.5 ' Connects to the SSD1331 DTA pin (named SDI on some displays)
$define SSD1331_DTA_PPS_Pin Pin_C5 ' Define the DTA Pin to use for PPS
$define SSD1331_CS_Pin PORTC.2 ' Connects to the SSD1331 CS pin
$define SSD1331_DC_Pin PORTC.1 ' Connects to the SSD1331 DC pin (named RS on some displays)
$define SSD1331_RST_Pin PORTC.0 ' Connects to the SSD1331 Reset pin
$define cIMAGE_X_RES 58 ' The X resolution of the Nixie images (in pixels)
$define cIMAGE_Y_RES 96 ' The Y resolution of the Nixie images (in pixels)
'
' Load the flash memory Nixie image tables into the program
'
Include "Nixie_Images_96x58\Nixie_0.inc" ' Load the flash memory image data for the Nixie digit "0"
Include "Nixie_Images_96x58\Nixie_1.inc" ' Load the flash memory image data for the Nixie digit "1"
Include "Nixie_Images_96x58\Nixie_2.inc" ' Load the flash memory image data for the Nixie digit "2"
Include "Nixie_Images_96x58\Nixie_3.inc" ' Load the flash memory image data for the Nixie digit "3"
Include "Nixie_Images_96x58\Nixie_4.inc" ' Load the flash memory image data for the Nixie digit "4"
Include "Nixie_Images_96x58\Nixie_5.inc" ' Load the flash memory image data for the Nixie digit "5"
Include "Nixie_Images_96x58\Nixie_6.inc" ' Load the flash memory image data for the Nixie digit "6"
Include "Nixie_Images_96x58\Nixie_7.inc" ' Load the flash memory image data for the Nixie digit "7"
Include "Nixie_Images_96x58\Nixie_8.inc" ' Load the flash memory image data for the Nixie digit "8"
Include "Nixie_Images_96x58\Nixie_9.inc" ' Load the flash memory image data for the Nixie digit "9"
Include "SSD1331_OLED.inc" ' Load the SSD1331 96x64 OLED library into the program
Include "HSPI_K40.inc" ' Load the SPI peripheral library into the program
'------------------------------------------------------------------------------------------------------------
' The main program starts here
' Count from 0 to 9, and display the digits on the SSD1331 OLED, as if a real Nixie tube is used.
'
Main:
Setup() ' Setup the program and any peripherals
GLCD_Rotate(4) ' Rotate the display to a 64x96 format
SSD_hWriteCommand(cSSD_Cmd_SetRemap) ' \ Mirror the image on the SSD1131 because .bmp file data is reversed
SSD_hWriteCommand(%01110011) ' /
Do ' Create a loop
Display_Image(Nixie_0) ' Display the image for a Nixie digit "0"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_1) ' Display the image for a Nixie digit "1"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_2) ' Display the image for a Nixie digit "2"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_3) ' Display the image for a Nixie digit "3"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_4) ' Display the image for a Nixie digit "4"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_5) ' Display the image for a Nixie digit "5"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_6) ' Display the image for a Nixie digit "6"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_7) ' Display the image for a Nixie digit "7"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_8) ' Display the image for a Nixie digit "8"
DelayMS 1000 ' Wait 1 second
Display_Image(Nixie_9) ' Display the image for a Nixie digit "9"
DelayMS 1000 ' Wait 1 second
Loop ' Do it forever
'-------------------------------------------------------------------------------------------------------
' Display an image, read from flash memory, on the OLED
' Input : pImageAddr holds the flash memory address of the image to display on the OLED
' Output : None
' Notes : The image data must be in 16-bit RGB565 format
' : The converted .bmp file's, 70 byte, header information has been removed in the flash memory data
'
Proc Display_Image(BycRef pImageAddr As Long)
Global Dim wImagePixelsAmount As Word Access Shared ' Holds the amount of pixels in the image
Global Dim wImagewPixelColour As Word Access Shared ' Holds the RGB565 pixel colour
Dim wTBLPTR_SFR As TBLPTRL.Long = pImageAddr ' Load TBLPTRL\H\U with the flash memory address of the image data
wImagePixelsAmount = cIMAGE_X_RES * cIMAGE_Y_RES ' Calculate the amount of pixels in the image
'
' Read and display the image data
'
GLCD_Window(3, 0, cIMAGE_X_RES, cIMAGE_Y_RES) ' Create a window for the X and Y positions and sizes of the image
SSD_SPI_Start() ' Start the SPI interface
Repeat ' Create a loop for the amount of pixels in the window
Tblrd*+ ' Read the low byte of the pixel colour into TABLAT
wImagewPixelColour.Byte0 = TABLAT ' Place it into the low byte of wImagewPixelColour
Tblrd*+ ' Read the high byte of the pixel colour into TABLAT
wImagewPixelColour.Byte1 = TABLAT ' Place it into the high byte of wImagewPixelColour
SSD_hWrite16(wImagewPixelColour) ' Write the 16-bit RGB565 value to the LCD
Dec wImagePixelsAmount ' \ Loop until all the image is read and displayed
Until wImagePixelsAmount = 0 ' /
SSD_SPI_Finish() ' Finish the SPI interface
EndProc
'------------------------------------------------------------------------------------------------------------
' Setup the program and any peripherals
' Input : None
' Output : None
' Notes : None
'
Proc Setup()
'
' Setup the SPI1 peripheral (if used)
'
$ifndef _cSOFTWARE_SPI_ ' Is the SSD1331 library using bit-bashed SPI routines?
PPS_Unlock() ' No. So Unlock the PPS
Set_PPSForSCK1(SSD1331_CLK_PPS_Pin) ' Setup the SPI1 peripheral's PPS, CLK for the LCD's SCK pin
Set_PPSForSDO1(SSD1331_DTA_PPS_Pin) ' Setup the SPI1 peripheral's PPS, SDO pin for the LCD's DTA pin
Set_PPSForSDI1(Pin_C4) ' Setup the SPI1 peripheral's PPS, SDI pin (not used)
HSPI1_Init_Mode0_MaxMHz() ' Setup the SPI1 peripheral to operate in Mode 0 at its fastest speed
$endif
SSD_Init() ' Initialise the SSD1331 OLED
GLCD_Cls(clBlack) ' Clear the display black
EndProc
'------------------------------------------------------------------------------------------------------------
' Setup the config fuses to use the internal oscillator at 64MHz on PIC18FxxK40 devices
' With pins RA6 and RA7 as general purpose I/O
'
Config_Start
RSTOSC = HFINTOSC_64MHZ ' HFINTOSC with HFFRQ = 64MHz and CDIV = 1:1
FEXTOSC = Off ' External Oscillator not enabled
WDTE = Off ' Watchdog Timer disabled
CLKOUTEN = Off ' CLKOUT function is disabled
CSWEN = On ' Writing to NOSC and NDIV is allowed
FCMEN = Off ' Fail-Safe Clock Monitor disabled
MCLRE = EXTMCLR ' MCLR pin is MCLR
PWRTE = On ' Power up timer enabled
LPBOREN = Off ' ULPBOR disabled
BOREN = Off ' Brown-out disabled
BORV = VBOR_245 ' Brown-out Reset Voltage (VBOR) set to 2.45V
ZCD = Off ' ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
PPS1WAY = Off ' PPSLOCK bit can be set and cleared repeatedly
STVREN = Off ' Stack full/underflow will not cause a reset
Debug = Off ' Background debugger disabled
XINST = Off ' Extended Instruction Set disabled
SCANE = Off ' Scanner module is not available for use. SCANMD bit is ignored
LVP = Off ' Low Voltage programming disabled
WDTCPS = WDTCPS_2 ' Watchdog Divider Ratio 1:128 (4 milliseconds)
WDTCWS = WDTCWS_7 ' Watchdog Window always open (100%). Software control
WDTCCS = LFINTOSC ' Watchdog Timer reference clock is the 31.2kHz HFINTOSC output
WRT0 = Off ' Block 0 (000800-001FFF) not write-protected
WRT1 = Off ' Block 1 (002000-003FFF) not write-protected
WRTC = Off ' Configuration registers (300000-30000B) not write-protected
WRTB = Off ' Boot Block (000000-0007FF) write-protected
WRTD = Off ' Data EEPROM not write-protected
Cp = Off ' User NVM code protection disabled
CPD = Off ' Data NVM code protection disabled
EBTR0 = Off ' Block 0 not protected from table reads executed in other blocks
EBTR1 = Off ' Block 1 not protected from table reads executed in other blocks
EBTRB = Off ' Boot Block not protected from table reads executed in other blocks
Config_End
Below is a circuit diagram that can be used with the demonstration Nixie Tube emulator firmware:
A video of the above demonstration program is shown below. Again, please excuse the poor quality of the video, but my phone camera is dreadful and flares the illuminated digits too much, and sorry about the thumping noises in the video, but I have not worked out how to remove sound on a youtube video yet. :-)
The code listing for the Nixie tube emulating programs can be downloaded from here: Positron8 - Nixie_Tube_Emulation.zip . The zip file contains four emulator demos.:
SSD1331_Nixie_Demo_1.bas will cycle the digits every second, and uses the name of the image table for the digit to be shown.
SSD1331_Nixie_Demo_2.bas will cycle the digits every second, and uses the address of the image table for the digit to be shown.
SSD1331_Nixie_Digits_Display.bas will display a digit, depending on which pin is brought low.
SSD1331_Nixie_BCD_Display.bas will display a digit depending on the BCD value it sees on the pins 0 to 3 of PORTB. So it also emulates the TTL 7441 driver chip, that is required for a high voltage Nixie tube.
Please note that the code listings are written for a PIC18F27K40 device, because it has 128K byte of flash memory to store the image data in, and also has a flexible SPI peripheral in it, so the display gets updated extremely quickly.
The zip file also includes an SSD1331 OLED display library, and an SPI peripheral library for the PIC18FxxK40 devices.