Saturday, January 24, 2015

Experimenting with Numitron filament tubes

A while ago I built a battery-powered single digit Numitron clock. There was nothing challenging about it. Each segment of a Numitron takes less than 20mA, like a LED, and requires between 3.5V and 4.5V to light up. So the segments can be driven directly from the processor or other TTLs (shift registers etc).

Since Numitrons behave so similar to (7-segments) LEDs, why not use one of my old LED matrix shields to multiplex 4 of them, I thought. And instead of the current limiting resistors, I would use Schottky diodes, to bring them even closer functionally to LEDs. I would even be able to use the same interrupt-based code for multiplexing.

I started the practical experiment with just one Numitron. The 7 segments are driven by a 595 shift register and the common electrode gets grounded through a ULN2803 gate. The diodes insure the current flows in one direction only and they also guarantee a maximum voltage of 4.5V on each segment.

In practice, multiplexing does not work very well with filaments. The reason is, I think, the "switch" time, the interval between the moment the voltage is applied to the filament and the moment the filament becomes incandescent and glowing. Unlike LEDs, which are diodes and "switch" quite fast (microseconds), filaments (which are essentially resistors), are orders of magnitude slower to emit light.

The sequence of 3 photos below shows one Numitron multiplexed at a 4:1 ratio, 2:1 and 1:1 respectively.
The 4:1 ratio is too dark; 2:1 is acceptable and 1:1 is optimal.

Here is the sketch I used for the experiment. I changed the number of multiplexed tubes (in the ISR), between 1, 2 and 4.

byte digitDefinition[10] = {B11110110, B11000000, B10101110, B11101010, B11011000, B01111010, B01111110, B11100000, B11111110, B11111001};

// pins used for LED matrix rows (multiplexed);
#define SHIFT_CLOCK_PIN   4
#define STORE_CLOCK_PIN   5
#define SER_DATA_PIN      6

// pins assigned to tubes' common electrodes (in theory board can drive max 8 Numitrons);
byte pinTube[8] = {8, 9, 10, 11, 12, 13, 7, 3};

byte activeTube = 0;

void setup()
  // Calculation for timer 2
  // 16 MHz / 8 = 2 MHz (prescaler 8)
  // 2 MHz / 256 = 7812 Hz
  // soft_prescaler = 15 ==> 520.8 updates per second
  // 520.8 / 8 rows ==> 65.1 Hz for the complete display
  TCCR2A = 0;           // normal operation
  TCCR2B = (1<<CS21);
  TIMSK2 = (1<<TOIE2);  // enable overflow interrupt

   // outputs for ULN2803;
  for (int i=0; i<8; i++)
    pinMode(pinTube[i], OUTPUT);

  // outputs for serial shift registers;
  pinMode(SER_DATA_PIN,    OUTPUT);

 * ISR TIMER2_OVF_vect; gets called 7812 times/second.
    // turn off current tube;
    digitalWrite(pinTube[activeTube], LOW);

    // change the number of multiplexed tubes here;
    activeTube = (activeTube + 1) % 4;

    // activate the next tube;
    digitalWrite(pinTube[activeTube], HIGH);

void shiftOutRow(byte digitDefinition)
  digitalWrite(STORE_CLOCK_PIN, LOW);
  shiftOut(SER_DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, digitDefinition);
  digitalWrite(STORE_CLOCK_PIN, HIGH);

byte getDigit(byte activeTube)
  return activeTube;

void loop()

In conclusion, I could build a 4-digit clock using the LED matrix shield (which has two 595 shift registers) with 2:1 multiplexing, or better, I could use the dual LED matrix shield (featuring four 595s) without multiplexing.

I'll report back when I'm done soldering.

PS Most of the Numitron schematics out there do not use multiplexing (thus confirming my finding). The few that do (like this one), use a higher voltage (>4.5V) to make them brighter. This solution may have an impact on the life of the tubes though. In addition, if for some reason (program bug, processor failure etc) the multiplexing stops working, the Numitrons will be toast, quite literally.

No comments:

Post a Comment