Monday, 16 April 2012

Nixie tube, arduino tomfoolery

Is there anything cooler than Nixie tubes and arduinos?  The objective answer is no. When I stumbled across some discarded physics lab equipment featuring these elusive, glassy beauties. I knew what I had to do.

The discarded junk gods also granted me 11 working relays, and a high voltage (~250V) DC power supply to injure myself play with. Given that I dont have any 250V-capable semiconductors handy, I decided it would be interesting to pursue a relay-based design.

My initial thoughts were to use the relays to directly translate one-hot encoding from the arduino. However, I only have 11 relays, and each nixie tube has 10 digit inputs and one common anode input.... so in other words this would suck.

After much ingenuity and input from local exchange student Patrick the King of Sweden, I realized I could take advantage of the double-pole-double-throw relays and reduce the amount required. This freed up relays I was able to use to multiplex the nixie tubes (by activating only one anode at a time):

Freaky binary to one-hot encoding tree - optimized!!!!

Encoding tree relay connections on the left, common-anode multiplexing diagram on the right

Essentially, by connecting the relays in a clever way, I can stick redundant operations on the same DPDT relay.

Moving on with the implementation,  I kajiggered a transistor for each relay, and soldered a shitload of wires to make the magical tubes work:

11 relays, taped together with care.  A common supply, they all must share...
Diligently colour-coded connections, that need to be tediously redone...

Colour-Coding: screw that
The whole kit.  Not pictured: the kaboodle

I then fired up the tubes, with a ridiculously noisy 40Hz refresh rate, and programmed the arduino such that I could send data to it (via USB serial port) to be displayed:

Arduino code as follows:

pins 0 and 1 are required for serial communication
#define R0 2
#define R1 3
#define R2 4
#define R3 5

#define SEL1 6
#define SEL2 7
int disp[4];
void setup() {               
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  //disp = new int[4];
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  disp[0] = 2;
  disp[1] = 2;
  disp[2] = 2;
  disp[3] = 2;


int sel1v = 0;
int sel2v = 0;
void loop() {
 // if (i == 11)
 //   i = 0;
  for(int i = 0; i < 10; i++)
    for(int dig = 3; dig >= 0; dig--)
        case 0:
          sel1v = 0;
          sel2v = 0;
        case 1:
          sel1v = 0;
          sel2v = 1;
        case 2:
          sel1v = 1;
          sel2v = 0;
        case 3:
          sel1v = 1;
          sel2v = 1;
      digitalWrite(SEL1, sel1v);
      digitalWrite(SEL2, sel2v);
      for(int i = 0; i < 4; i++)//increase i for slower switching


//write digit (0-9) to the current tube.
void writeInt(int in)
    digitalWrite(R1, (in/2)%2);
    digitalWrite(R2, (in/4)%2);
    digitalWrite(R3, (in/8)%2);

void updateDisplay()
 if (Serial.available() == 4)
   disp[3] = (int);
   disp[2] = (int);
   disp[1] = (int);
   disp[0] = (int);
  } else if (Serial.available() > 4)

Eventually, I decreased the refresh rate to 4 Hz and implemented the following bash script to get a basic clock effect:

stty -F /dev/ttyUSB0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts

while :
        sleep 1
        echo -n `date +%H%M` > /dev/ttyUSB0

...and thats as far as I'm willing to chase this dragon.  If I were to move forward with this, I would change:
-notably, replace freaky relay setup with high voltage semiconductors


No comments:

Post a Comment