Multiplex Nixie Tube or similar

Hi, I am working on a nixie display and my first idea was about usin some 595 shift register with the nixie driver, the 74141 driver.
In this way for driving 6 tubes I need 3 595 and 6 74141 drivers.

I have seen some cool project where a single 74141 driver is used with a tlc5940 and multiplexing.

Now, I don't understand precisely how multiplexing works with arduino, I have done some really basic test with arduino alone (without IC's) and leds tryng to wire it correctly and switching in the loop section HIGH and LOW the ports, but I see the leds on and off, so I have no persistence of vision.

I suppose that I am lacking of knowledge... Could someone explain or point to any tutorial?
Thanks everyone,
Federico

It really depends on HOW you are doing it... what does your code look like?

I am doing it in the wrong way for sure :slight_smile: This code looks pretty stupid to me too but I have no clue on how to do it.

void loop() {
  if (i==1) {
    
    digitalWrite(9,HIGH);
    digitalWrite(11,LOW);
    led( ledPin, RGB(0,0,255) );
    i=0;
    }
  else {
    
    digitalWrite(11,HIGH);
    digitalWrite(9,LOW);
    led( ledPin, RGB(255,0,0) );
    i=1;
    }
  delay(3);
}

Basically I was testing with 2 rgb leds, connected with the 3 catodes R G B together to pwm's on arduino, and the two anodes on digital pin. "They" always say "switching fast enaugh" you get POV. But I imagine that it's not enaugh :slight_smile: :slight_smile:

Fede

can you show me the led() function code? or is that in a library?

Also, let my preface by saying I'm currently learning about multiplexing, myself. Here's my code for a common anode 7-segment display I'm multiplexing using the arduino and one 595 shift register. As a test, it just counts up in hundredths of a second. I connected the anodes to digital pins 2, 3, 4, and 5 (digits 0, 1, 2, and 3 respectively).

long time;

//for communicating with the 595
int latchPin = 7;
int clockPin = 6;
int dataPin = 8;

int nums[] = {  //The numbers correspond to their indexes for ease of use
  B11000000,  //0
  B11111001,  //1
  B10100100,  //2
  B10110000,  //3
  B10011001,  //4
  B10010010,  //5
  B10000010,  //6
  B11111000,  //7
  B10000000,  //8
  B10011000 };  //9

void setup()
{
  //display digit anodes, [b]these will be doing the actual multiplexing[/b]
  pinMode(2, OUTPUT); //0th digit
  pinMode(3, OUTPUT); //1st digit
  pinMode(4, OUTPUT); //2nd digit
  pinMode(5, OUTPUT); //3rd digit
  
  //for communicating with the 595
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  
  //start with all the digits off
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  
  //zeroing out the counter for the timer
  time = millis();
  
}

void loop()
{
  //how much time has passed?
  long temp = millis() - time;
  
  //display the time in hundredths of a second (passed to the display function)
  display( temp / 10 );
}

void display( long num )
{
  num = num%10000; //prevents numbers larger than 4 digits
  burst( num/1000, 0 );  //gets the 0th digit, passed to burst function, 0th place
  burst( (num/100)%10, 1 ); //gets the 1st digit, passed to burst function, 1st place
  burst( (num/10)%10, 2 );//gets the 2nd digit, passed to burst function, 2nd place
  burst( num%10, 3 );//gets the 3rd digit, passed to burst function, 3rd place
}

void burst( int num, int place ) {
  boolean dot = false; //display a dot
  if( place == 1 ) {
    dot = true; //there will be a dot in the 1st position (I could do this in a less lazy way I'm sure)
  }
  
  //send the digit to the 595
  digitalWrite(latchPin, 0);
  int temp = nums[num];
  if( dot ) {
    temp = temp ^ B10000000;  //uses XOR to add the dot to the binary to be sent to the 595
  }
  shiftOut(dataPin, clockPin, MSBFIRST, temp);
  digitalWrite(latchPin, 1);


  digitalWrite(place + 2, HIGH);  //turns on the digit (again, lazy: 0th digit is digital pin 2)
  delay(4); //digit stays on for 4ms
  digitalWrite(place + 2, LOW);  //turns of the digit
}

I hope my annotation helps explain the process. Basically each digit is turned on and off in order, and all the digits can share the same 595 shift register.

While we're on the subject of nixies...

What's the input voltage of the 74141 (the Vcc pin)?

I have not tested the 74141 but the Vcc is 5v.
Btw, I have just lighted my first nixie. Too cool!

Unfortunatly I don't have a couple 7-seg display for testing your code but I am going to read it now and test it in some way...
I was doing basical test with the 595 so i suppose I am going to redo it all :slight_smile:

This was the first test to drive the 74141, and it's my backup option if I dont' get how to multiplex :slight_smile:

ps:
By the way, this is the whole code abot rgb leds, but it's not so useful for the nixies but it's useful for the rgb's :slight_smile:

/*
 * Set RGB Led Color
 * Use only pwm pins and common anode rgb leds
 */

int ledPin[] = {3,5,6};
int i=0;

void setup() {
  for (int i=0; i<3; i++){
    pinMode(ledPin[i], OUTPUT);
  } 
}

short * RGB(short r,short g, short b){
  //short tmp[3];
  short *tmp=(short *)malloc(sizeof(short)*3);
  tmp[0]=abs(255-r);
  tmp[1]=abs(255-g);
  tmp[2]=abs(255-b);
  return tmp;
}

void led(int *pin,short *color) {
  for(int i=0;i<3;i++) {
    analogWrite(pin[i],color[i]);
  }
}

void loop() {
  if (i==1) {
    
    digitalWrite(9,HIGH);
    digitalWrite(11,LOW);
    led( ledPin, RGB(0,0,255) );
    i=0;
    }
  else {
    
    digitalWrite(11,HIGH);
    digitalWrite(9,LOW);
    led( ledPin, RGB(255,0,0) );
    i=1;
    }
  delay(3);
}

This may be a cleaner way to code your loop / led methods.

int onTime = 3;

void led(int *pin,short *color, int anode) {
  for(int i=0;i<3;i++) {
    analogWrite(pin[i],color[i]);
  }
  digitalWrite(anode, HIGH);
  delay(onTime);
  digitalWrite(anode, LOW);
}

void loop() {
  led( ledPin, RGB(0,0,255), 9 );
  led( ledPin, RGB(255,0,0), 11 );
}

Not sure what you are trying to do but that code will flash alternate LEDs on and off. If you are sing the analogWrite function then you are using the PWM signals and these do not mix well with multiplexing due to the beats between the two frequencies.

As I suspected. My final goal is to multiplex the Nixies, I have seen that someone is able to do this:

I suppose that it is the same as multiplexing a 7-digit display (except the voltage, but this is not going to be a problem)
But, as I don't have 7-digit to try (and I don't want to get shoked while experimentig with the nixies) I thought that rgb leds were similar...

I'd like to wire toghetes all the "digits cables" and swithc the anodes with a tlc5940. The thing that I don't get is how to do this... I am studying right now the code posted by pmodernme

'd like to wire toghetes all the "digits cables" and swithc the anodes with a tlc5940. The thing that I don't get is how to do this

Simple, just connect the common anode to 5V and each of the three cathodes to a separate TLC5940 output.

Grumpy_Mike:

'd like to wire toghetes all the "digits cables" and swithc the anodes with a tlc5940. The thing that I don't get is how to do this

Simple, just connect the common anode to 5V and each of the three cathodes to a separate TLC5940 output.

I knew this, it's mostly a software problem the one I have (plus the language problem! sometimes it's hard for me to explain clearly =( ) Thanks to yours advice I am starting to understand and tomorrow I am going to create a new test hardware and a new code to multiplex/pov with the 595, then I will switch to the tlc5940 wich is my optimal choice (but for now I know just how to use the 595 :slight_smile: )

I can't still try this with nixies because I still don't have optocouplers or transistors to work at 180v.
Fede

Hmmm: I don't see why you need opto couplers. The 74141 can directly drive NIXIE pins. The 74141 (based on the original 7441 that was designed specifically for NIXIES) has open collector, zener protected outputs.

I was planning to drive the anode of the nixies with the tcl5940, so I can do a bit of PWM to set "brightness" or create visual effect while wiring the cathodes to the 74141 so I can specify the cipher to light on. With this setup I think I need not to put high voltages on my 5940.
Am I wrong?
Thanks, Fede

I find that processing+wiring is much too slow for multiplexing (commands like shiftout take way too long), but using some AVR-C I have been able to multiplex nixie tubes (or at least some neon tubes while I wait for my nixies to arrive) as well as vary the brightness to do fading effects.
Picture here.
What you are seeing is two separate groups of four neons. Tube 1x4 is at about 10% brightness, tube 1x3 is at about 70%, and tube 1x2 and 1x1 are at 0%. Tube 2x4 and 2x3 are at zero percent while tube 2x2 is at 70% and tube 2x1 is at 10%. These tubes are driven off of four cathodes and two anodes.

I'll probably post schematics and code on that site this weekend, once I have some more time, but basically, I just compute the values to send to the shift registers BEFORE my multiplex loop, then shift out the first set of data really fast, turn on the first tubes, turn them off, shift out the second set of data really fast, turn on the tubes, and turn them off a few hundred times. Of course, there are some delay routines involved as well to get variable brightness and ensure the transistors work properly.

That sounds interesting! Are you experimenting directly via arduino or with some IC? Can I ask you what type of transisrors are those? I have similar neon bulbs but I don't know wich transistor should I use...
Thanks!
Fede

Federico:
That sounds interesting! Are you experimenting directly via arduino or with some IC? Can I ask you what type of transisrors are those? I have similar neon bulbs but I don't know wich transistor should I use...
Thanks!
Fede

Hey, I posted some more info to the google site. Code and schematics are available at sites.google.com/site/willyager/nixie-clock. I am using MPSA42 transistors and 100K anode resistors at 170V on the little A1A neon tubes (200K is probably better if you are not multiplexing them). The A1As are very cheap and easy to get, I got 10 of them for about $5 shipped off ebay.

Cool! thanks!

no problem!

I work on the same project. I am going to make an LED secondpointer which drive around a round plate at the centre there would be 4 nixie Tubes. All the "output" are driven by 74HCT595 to get away from Multiplexing the tubes to get the chance of full light of the tubes (the main Voltage would be driven with an PnP Transitor to contol the brightness over the full spectrum 0-100%. The only "special" is an 8*8 Matrix for the second (without using the last 5 digits) driven by 2 74HCT595.
My first problem was dividing the minutes and hour to 4 4Bit BCD-Code and take them into the last 2 74HCT595. All the 74HCT595 are Dasychained and i get no problems of to slow shifting. There is another Solution to shift out via SPI this is much faster shifting than the normal shiftout()-Function.
For testing i put all the thing together with 32 LED´s for testing the code. I also get an 5=>200VDC converter for the nixiesupply . And these code is working fine. You only have to upgrade the code for an workable time recierver RTC or Radio Clock.

//#include <Wire.h>

#define LEDlatchPin 3      // 3 Pin connected to latch pin (ST_CP) of 74HC595
#define LEDdataPin  2      // 2 Für Ring LED Pin connected to Data in (DS) of 74HC595
#define LEDclockPin 4     //4  Für Ring LED Pin connected to clock pin (SH_CP) of 74HC595
int ss=45;
int mm=33;
int hh=22;
byte zero=0;
byte Puffer1=0;      //Puffer für 1. Register aktive Spalte aktiv=HIGH Anoden über 220Ohm Widerstand
byte Puffer2=255;    //Puffer für 2. Register aktive Rheihe akiv=LOW Kathoden
byte Puffer3=0;      //Puffer beide Minutenstellen Bit 7-4 Minutenzehner/Bit3-0 Minuten Einer
byte Puffer4=0;      //Puffer beide Stundenstellen Bit 7-4 Stundenzehner/Bit3-0 Stunden Einer


void setup() {
  //Serial.begin(9600);
  //Wire.begin();
  pinMode(LEDlatchPin, OUTPUT);            
  pinMode(LEDdataPin, OUTPUT);  
  pinMode(LEDclockPin, OUTPUT);
  for (int i; i<=3;i++){
    shiftOut(LEDdataPin, LEDclockPin,MSBFIRST,zero);      // 4 Bytes lässt z.B. nach Reset die Register alles vergessen 
  }
}

void loop() {
  if (ss>=0 && ss<=59){
    ss=ss++;
  }
  if (ss>=60){
    mm=mm+1;
    ss=1;
  }
/*  if (mm>=60){
    mm=0;
    hh=hh++;
  }
  if (hh>=24){
    hh=0;
  }*/
  PufferSekunden(ss);
  Puffer3=Pufferbuild(mm);
  Puffer4=Pufferbuild(hh);  
  digitalWrite(LEDlatchPin, LOW);      // Latch aussetzten um Flackern der LED beim Shiften zu vermeiden 
  shiftOut(LEDdataPin, LEDclockPin, MSBFIRST, Puffer4);                    //Shift out der einzelenen Puffer wobei im letzten
  shiftOut(LEDdataPin, LEDclockPin, MSBFIRST, Puffer3);                    //Register Chip das erste Puferbyte sitzt 
  shiftOut(LEDdataPin, LEDclockPin, MSBFIRST, Puffer2);
  shiftOut(LEDdataPin, LEDclockPin, MSBFIRST, Puffer1);
  digitalWrite(LEDlatchPin, HIGH);                                            // Aktiverien des Latches zum Anzeigen
  delay(1000);
}

byte Pufferbuild(int Wert){
  // Puffer 3+4
  int zehner;
  int einer;
  byte PufferA;
  byte PufferB;
  byte PufferC;

  zehner=Wert/10;                // Zehnerstellen da Integer Berechung
  einer=Wert%(zehner*10);       // Einerstellen aus dem Gesamten Wert
  PufferA=zehner;                // PufferA wird gefüllt 
  PufferA=zehner <<4;              // PufferA um 4 nach links schieben 
  PufferB=einer;                 // Puffer B wird mit Einer ggefüllt
  PufferC=PufferA|PufferB;          // AnzeigePuffer mit zusammenführung Puffer A+B
  return PufferC;
}


void PufferSekunden(int Wert){                              //Diese Funtkion schreibt die Pufferwerte für die Sekundenmatrix 8*8
  Puffer1=0;
  Puffer2=255;
  if (Wert >=1 && Wert <=8){
    bitWrite(Puffer1,(Wert-1),HIGH);
    bitWrite(Puffer2,      7,LOW);
  }
  if (Wert >=9 && Wert <=16){
    bitWrite(Puffer1,(Wert-9),HIGH);
    bitWrite(Puffer2,      6,LOW);
  }
  if (Wert >=17 && Wert <=24){
    bitWrite(Puffer1,(Wert-17),HIGH);
    bitWrite(Puffer2,      5,LOW);
  }
  if (Wert >=25 && Wert <=32){
    bitWrite(Puffer1,(Wert-25),HIGH);
    bitWrite(Puffer2,      4,LOW);
  }
  if (Wert >=33 && Wert <=40){
    bitWrite(Puffer1,(Wert-33),HIGH);
    bitWrite(Puffer2,      3,LOW);
  }
  if (Wert >=41 && Wert <=48){
    bitWrite(Puffer1,(Wert-41),HIGH);
    bitWrite(Puffer2,      2,LOW);
  }
  if (Wert >=49 && Wert <=56){
    bitWrite(Puffer1,(Wert-49),HIGH);
    bitWrite(Puffer2,      1,LOW);
  }
  if (Wert >=57 && Wert <=64){
    bitWrite(Puffer1,(Wert-57),HIGH);
    bitWrite(Puffer2,      0,LOW);
  }
}

Thanks for the code, volvodani. BTW, you don't have to use SPI to get a faster shiftout, you only have to use AVR-C instead of processing+wiring (but SPI is probably the fastest).

Also, if anyone is interested, I posted schematics and code for an RTC+temp sensor circuit that I just finished on my site. It might save you some time and frustration.