Improving yet another nixie clock design

Hello all! I wanted to start by thanking @pcbbc and @6v6gt for all the help provided in the past in getting my clock up and running.

I recently discovered Dalibor Farny who is making big brand new nixie tubes. If you'd like you can read about him here.
https://www.daliborfarny.com/

One of his customers made an awesome nixie clock called the covert Bombe. While watching the video I saw how they had implemented a gradual fade out of the previous nixie number segment, and a rapid roll of the number segment when transitioning to a new tens of seconds. The effects can be seen in the video below at the 1:05 segment. (I think I linked it so it would start there?)
https://youtu.be/S_mfCRBaQsM?t=65

I'd like to know if I can accomplish these effects using the SPI transfer that I have used in my sketch. Please see my full write up here.
https://www.hackster.io/Goldbrick_Gangboss/i-1-nixie-tube-clock-1st-prototype-c4902e

Here is my sketch for review. It's still a work in progress as I intend on adding a way to change the time along with a de-sputtering routine.

#include <Wire.h>
#include <RTClib.h>
#include <SPI.h>
#define NX 10
#define latchPin 10
#define blankPin 8
#define ledPin 12
int ledState = LOW;
int testpattern = 0;
/*#define burnPin 11
#define minutesPin 7
#define hoursPin 5 
int burnState = 1;
int minutesState = 1;
int hoursState = 1; */

RTC_DS1307 RTC;
DateTime now;
unsigned long previousMillis = 0;
const long interval = 1000;
unsigned long MinuteCount = 0;
unsigned long SecondCount = 0;


uint32_t Symbol[10]={0x1, 0x2, 0x4, 0x8 , 0x10, 0x20, 0x40, 0x80 , 0x100, 0x200};
/*Logic arrangement [ 0,   1,   2,   3 ,   4  ,  5  ,  6  ,  7  ,    8  ,   9  ]
                     LSB          << Shifts this way ------->
                                  >> Shifts this way <-------            MSB
                                     Personal Notes only */
void setup() {
  pinMode(ledPin,OUTPUT);
  pinMode(blankPin, OUTPUT);
  digitalWrite(blankPin, LOW);
  pinMode(latchPin, OUTPUT);
  /*pinMode(burnPin,INPUT);
  pinMode(minutesPin,INPUT);
  pinMode(hoursPin,INPUT); */
  Serial.begin(9600);
  RTC.begin();
  Wire.begin();
  SPI.begin();
  SPI.setDataMode(SPI_MODE2);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  //RTC.adjust(DateTime(F(__DATE__),F(__TIME__)));
  if (! RTC.isrunning()){
    Serial.println("RTC is NOT RUNNING!");
    RTC.adjust(DateTime(F(__DATE__),F(__TIME__))); 
  }  
  delay(1000);
  }

void loop() {
  digitalWrite(blankPin, HIGH);
  if (millis()-MinuteCount > 40000) {
    MinuteCount = millis();
    if (testpattern == 0) {
        testpattern = 1;
    } else if (testpattern == 1) {
      VegasProtocol();
      testpattern = 0;
    }
  } else if (millis()-SecondCount > 1000) {
    SecondCount = millis();
    GetTime();
    Timex();
  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval){
    previousMillis = currentMillis;
    if (ledState == LOW){
      ledState = HIGH;
    }else{
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
  /*burnState = digitalRead(burnPin);
  if (burnState == LOW){
    burnCycle();
  }
  minutesState = digitalRead(minutesPin);
  if (minutesState == LOW){
    setMinutes();
  }
  hoursState = digitalRead(hoursPin);
  if (hoursState == LOW){
    setHours();
  } */
  
  /*Uncomment to see serial monitor output of time
  Serial.print(now.hour(),DEC);
  Serial.print(':');
  Serial.print(now.minute(),DEC);
  Serial.println();
  delay(1500); */
  }

void VegasProtocol()
{
  uint16_t digitValue=0x200;
  for (int i=0;i<NX; i++){
    digitalWrite(latchPin,LOW);
    SPI.transfer16(digitValue);
    SPI.transfer16(digitValue);
    SPI.transfer16(digitValue);
    SPI.transfer16(digitValue);
    digitalWrite(latchPin,HIGH);
    digitValue=digitValue>>1;
    delay(100);}
  for (int i=0;i<NX; i++){
    digitalWrite(latchPin,LOW);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]);
    digitalWrite(latchPin,HIGH);
    delay(100);}
  for (int i=0;i<NX; i++){
    digitalWrite(latchPin,LOW);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]<<1);
    SPI.transfer16(Symbol[i]<<2);
    SPI.transfer16(Symbol[i]<<3);
    digitalWrite(latchPin,HIGH);
    delay(150);}
  for (int i=0;i<NX; i++){
    digitalWrite(latchPin,LOW);
    SPI.transfer16(Symbol[i]<<1);
    SPI.transfer16(Symbol[i]<<2);
    SPI.transfer16(Symbol[i]<<3);
    SPI.transfer16(Symbol[i]<<4);
    digitalWrite(latchPin,HIGH);
    delay(200);}
}
   
void Timex()
{
  digitalWrite(latchPin, LOW);                                      
  uint32_t Timemm;
  uint32_t Timehh;
  Timemm=now.minute();
  uint32_t Var32;                                  
  Var32=0;
  Var32|=(uint32_t)(Symbol[Timemm%10]<<16);//NX4 xx:x0
  Timemm=Timemm/10;  
  Var32|=(uint32_t)(Symbol[Timemm%10]);//NX3 xx:0x
  //Register 2 controlling NX3 and NX4    
  SPI.transfer(Var32>>24);
  SPI.transfer(Var32>>16);
  SPI.transfer(Var32>>8);
  SPI.transfer(Var32);
  Timehh=now.hour();
  Var32=0;
  Var32|=(uint32_t)(Symbol[Timehh%10]<<16);//NX2  x0:xx
  Timehh=Timehh/10;
  Var32|=(uint32_t)(Symbol[Timehh%10]);//NX1 0x:xx
  //Register 1 controlling NX1 and NX2
  SPI.transfer(Var32>>24);
  SPI.transfer(Var32>>16);
  SPI.transfer(Var32>>8);
  SPI.transfer(Var32);
  digitalWrite(latchPin, HIGH);  
}
void GetTime(){
  now = RTC.now();
}

/*void burnCycle(){
  {
  uint16_t digitValue=0x200;
  for (int i=0;i<NX; i++){
    digitalWrite(latchPin,LOW);
    SPI.transfer16(digitValue);
    SPI.transfer16(digitValue);
    SPI.transfer16(digitValue);
    SPI.transfer16(digitValue);
    digitalWrite(latchPin,HIGH);
    digitValue=digitValue>>1;
    delay(5000);}
  for (int i=0;i<NX; i++){
    digitalWrite(latchPin,LOW);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]);
    SPI.transfer16(Symbol[i]);
    digitalWrite(latchPin,HIGH);
    delay(5000);}
  }
}

void setMinutes(){
}

void setHours(){
}
} */This text will be hidden

It looks a great project and I know these are a lot of fun to design and build. I currently have 3 Nixie clocks, one of which I published here, and the tubes for another 2 six digit clocks so I'll have something to do during the next lock down.

The tubes you have chosen (IN-1) tend, apparently, to have a relatively short lifetime because they are not doped with mercury. See: Nixie tubes (paragraph 4). If I had those, I'd probably also consider having a PIR sensor to switch the tubes off when the room is not occupied.

As for the fade in/out, I guess this could be achieved by varying the duty cycle on the cathodes of the two digits to be switched, over say a half second. You should be able to do that relatively easily, without having to deal with nuisance flicker, because your tubes are directly driven (not multiplexed).

Perhaps I’ll consider the sensor in the redesign of the project. That’s a bummer on the tube life. It has been ticking away on my desktop since November. Only thing I’ve noticed is the sputtering on some digits. I’ll see what I can think upon for your suggestion. Thank you

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.