IN-1 Nixie single digit calendar

Hi guys!

I have a thing for classic tubes. Just last year I built this clock with some very much appreciated guidance on this forum. Yet again I'm tuning in for some advice.

Aim of the project:
I want the IN-1 Nixie to continuously show me DD/MM/YYYY with a +/-1.5 sec interval between each digit.

Project outline
Just last week I received a couple of IN-1 tubes from a Ukrainian seller, which I plan using to build a single-digit calender. Esthetics will be important as I'm using 2.5mm2 copper wire for the frame (I am aware of the discouraging side-effects of touching certain areas). For esthetic purposes I am planning to use a barebone DS1307 IC with crystal oscillator and a barebone Atmega328. Due to availability and simplicity I do not plan on using a SN74141 or Russian/Chinese equivalent. As my single IN-1 nixie just uses 10 pins. To pull each cathode to ground I will make use of a couple of MPSA42 NPN transistors. Of course taking a base resistor into account.

My question:
Is fairly straight forward, but I can't seem to find out how to (properly) split and convey each value from eg. now.day() into a single arduino output pin.

Many people have built nixie clocks/calenders before, but there don't seem to be that much single-digit ones around. Of course I have been searching this forum and the web prior to posting, but I can't seem to find any resemblance. Therefore I'm reaching out to the Forum for some guidance.

Test sketch so far...

#include <Wire.h>
#include "RTClib.h"
#include <TimeLib.h>

RTC_DS1307 rtc;

void setup () {
  while (!Serial);
  Serial.begin(57600);
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");

    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(2022, 11, 22, 20, 18, 0));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}
void loop () {
  DateTime now = rtc.now();

  Serial.print(now.day(), DEC);
  Serial.print('-');
  Serial.print(now.month(), DEC);
  Serial.print('-');
  Serial.print(now.year(), DEC);
  Serial.println();


  delay(1500);
}

General idea of what I'm building:
Disregard the spare nixies. They will be for future projects. And yes, I very much enjoy the ancient voltage regulator!


Take a look at arduino.cc/reference and the operators & % >> <<.

Those IN-1 tubes have a relatively short lifetime because these are not doped with mercury. I'd suggest having PIR detector so these are active only if someone is in the room.

You'll still need 10 Arduino pins and 10 MPSA42 transistors (each with a base resistor) even if you have only one tube.
How are you intending to display the date, say the 03 in 3rd of January ? Something like:

something like ?:

display 0
pause 1 sec
display blank
pause 1 sec
display 3
pause 1 sec
display blank
pause 3 sec

Thanks for your reply. I don't expect splitting the numbers will be the greatest obstacle as I've done it before:

        displayVFD[0] = ((Hour) / 10 % 10);   // array starts at 0
        displayVFD[1] = (Hour) % 10;
        displayVFD[2] = ((Minute / 10) % 10);
        displayVFD[3] = (Minute % 10);

It is however conveying the nummerincal outputs from the RTC to each Arduino pin which I don't seem to grasp.

For example:

now.day() gives friday (so 5) -> Arduino pin 5 HIGH.
now.day() gives saturday (so 6) -> Arduino pin 6 HIGH.
etc...

Hey, many thanks for your guidance in the past!

Those IN-1 tubes have a relatively short lifetime because these are not doped with mercury. I'd suggest having PIR detector so these are active only if someone is in the room.

I wasn't aware of the lifespan until I had ordered them. Oh well...

You'll still need 10 Arduino pins and 10 MPSA42 transistors (each with a base resistor) even if you have only one tube.

Indeed correct, I have a transistor soldered to each (cathode) leg which suspends the IN-1 in midair.

How are you intending to display the date, say the 03 in 3rd of January ? Something like:

something like ?:

display 0
pause 1 sec
display blank
pause 1 sec
display 3
pause 1 sec
display blank
pause 3 sec

Exactly the idea. So today would be:

1
wait 1.5 sec
6
wait 1.5 sec
1
wait 1.5 sec
2
etc...

You can build an array of what pins need to be high for a certain digit.

Zero would index to the first location of the array of segments...

Make sense?


How does the user know the sequence to read them ... output sequence something like 6-5-6-5-6-5 ?

:smiley_cat:

You can build an array of what pins need to be high for a certain digit.

Zero would index to the first location of the array of segments...

Make sense?

Thanks, good call! This sounds like the thing I'm looking for. I'll be reading up on this array.
Any suggestions on further implementation?

How does the user know the sequence to read them

You mean someone else interpreting the nixie? I have no idea to be honest. I like it being a mysterious, dangerous, copper 'box' as a decorative ornament in my living room.

Suppose You allocate pin D2 to D11 for the segments. Then use digital.write( 2 + value, HIGH ); or LOW.

1 Like

If I remember correctly, each nixie has it's own digit. So you'll have to deal with 10 bits...

You are going to need 10 bits (0 -> 9). You will need to check for digits that will be over and 8 bit shift to get it out the right port.


If digit 0 is wired to pb2 and digit 1 is wired to pb4, then the array would have pb2 in location zero and pb4 in location 1...

Make sense?

I've done this with 7 segment displays...


I'm sure you could probably do something like ... you have the 'value', portb = 1 << value; You will still have to deal with 10 bits... most of these only are 8 bit ports.

Might want to check out the EEVblog here about driving nixie tubes ... maybe it will save you some pins and grief...

:smiley_cat:

1 Like

If value is 6, you will set 8, high? Maybe I missed what you were doing here...


There's no way that I know of where you can successfully write 10 bits to an 8 bit port.

:smiley_cat:

I put some code in a simulator for you to try. It uses a bar graph to represent the Nixie digits but should give the general idea. Be aware that the simulator runs slower that real time.
I imagine that you may review your decision to display a full DD/MM/YYYY date.

Unlike with 7-segment displays only 1 cathode is active at a time. An array[10] of int can hold the pin numbers for the digits. Eventually pin (digit+2) can be used with the pins 2 to 11 for digit 0 to 9. Then the Arduino firmware splits each logical pin number into physical port and bit.

Oh, @Railroader already suggested that solution in #8.

Yes.

That's correct.

I put some code in a simulator for you to try. It uses a bar graph to represent the Nixie digits but should give the general idea. Be aware that the simulator runs slower that real time.
I imagine that you may review your decision to display a full DD/MM/YYYY date.

Thanks so much for your effort. I used the simulator with your code and replacing the bar graph with each digit of the nixie this is exactly what I'm aiming to do.

Only difference is that we need to read from the RTC and somehow assign each received number to 0-9 to the corrosponding nixie cathode pin. Reading all the suggestions above I don't think an array will satisfy that task.

Wait, so it can be done with an array? I'm confused.

I thought it was quite clear from the code in post #11 (simulator : Single Nixie V0_01 - Wokwi Arduino and ESP32 Simulator).

This is the only part left to complete:

// set these globasl from the RTC
// sample data 16 December 22

uint8_t date_high = 1 ;
uint8_t date_low = 6 ;
uint8_t month_high = 1 ;
uint8_t month_low = 2 ;
uint8_t year_low = 2 ;
uint8_t year_high = 2 ;

You have to read the day month and year from the RTC and break these down into individual digits and assign the parts to the above variables.

I'm sorry, I think I misread. Thanks, I'll change my code accordingly!

I think we're getting somewhere now. This is what I have so far. It's still missing some parts, but in the meantime I'm receiving a persistant error while compiling:

/*-------------------------
  DS1307 RTC I2C test module

  SCL - pin 5
  SDA - pin 4
  VCC - 5V
  ---------------------------*/

#include <Wire.h>
#include "RTClib.h"
#include <TimeLib.h>

RTC_DS1307 rtc;

//------------------------------------------------

uint8_t pinArray[10] = { 2, 3, 4, 5, 6, 7, 8, 9, 12, 13 } ; // digits 0 to 9 in order

uint8_t day_tens = ((now.day() )      / 10 % 10); // set these globals from the RTC
uint8_t day_units = ((now.day() )     % 10);
uint8_t month_tens = ((now.month() )  / 10 % 10) ;
uint8_t month_units = ((now.month() ) % 10) ;
uint8_t year_tens = ((now.year() )    / 10 % 10) ;
uint8_t year_units = ((now.year() )   % 10);

//------------------------------------------------

void setup () {
  while (!Serial);
  Serial.begin(57600);
  for (uint8_t n : pinArray )  pinMode( n , OUTPUT) ; // all pins output
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
  }
}

void loop () {
  DateTime now = rtc.now();

  displayDate() ;
}
exit status 1
request for member 'day' in 'now', which is of non-class type 'time_t() {aka long unsigned int()}'

Perhaps this should read
day_tens = ((now.day )