Phone

    00852-6915 1330
  • Contents

A few months ago,I have see an article about desinging a nixie tube clock with an ATmega328 and ESP8266,and I had a big interest in it and I made one immediately according to the article's step.The ESP8266 connected to a Network Time Protocol (NTP) server was cheaper to implement than using an RTC due to the discrepancies between the defined clock speed and actual clock speed.

 

 

You can see the picture,nixie tubes came into existence during the time of vacuum tubes and before LEDs (at least in the context of the Soviet Union). Once LED technology made its way into the USSR, nixie tubes began to fade out. Even today when shopping for nixie tubes online, all of the tubes I’ve purchased have been sent from either Russia or Ukraine. It seemed fitting that I would follow in history’s footsteps and switch over to the cheaper, easier and safer LED technology (I may or may not have shocked myself a few times on the 170VDC supply when testing).

 

 

I would like to use seven-segment displays to solve this problem. However,I think it's a little expensive even today. I would like to try something different, something that you don't really see sommercially. Suddently,binary clocks come to my mind,it's interested programmer like me. After a time of consideration, I sticked with a digital display and kept going back to the seven-segment variety.

 

Using our OLED breakout allowed me to recreate the look of a 7-segment display, but I can add animations when the digits change. I added animations that make the individual segments drop in and fall off of the display when the time changes.

In my nixie tube clock,I first tried using ESP8266 control both WIFI and the nixie tubes,but the WiFi stack was just too large to avoid seeing the multiplexed nixie tubes flicker any time the 8266 needed to do something WiFi-related. This meant that I had to have two controllers on the board; an ATmega328 would handle the nixies, and the ESP8266 would be responsible for the time and web GUI for settings. After that, I found ESP32 Thing from Sparkfun when I browse google, The ESP32 have two cores, one is to hanle the wifi stack and the other for programming. and I thought of my clock immediately and  how much easier it would be to just have one device to program and not worry about how I would transfer information between the two.

 

About the Clock Stands

 

 

See the above picture,my clock is still work in progress currently,the code requires hard coding the SSID and password for the wireless access point. I really liked the web GUI I made, which I can access from the ESP8266 to change settings for the access point’s SSID and password or to select the NTP server location, time zone and whether or not to adjust for daylight saving time.

 

I have two problems now. The one is that I haven’t been able to implement the GUI quite yet due to library changes in WiFi.h to serve web pages, and this is where I could use some help. If you’ve made a web server for your ESP32, please let me know how you handled multiple pages. I’ve been scratching my head throughout the build on how to get this done. With the ESP8266, there’s on(const String &uri, handler function), but that seems to have been removed on the ESP32. And the another problem with both clocks is how I handle daylight saving. Currently with the nixie clock, I have a selection box that removes an hour, but I would like to have that happen automatically. The NTP time returned will allow me to figure out the date, but given that daylight saving time begins on the second Sunday of March and ends on the first Sunday of November, how would you efficiently program in that functionality?

 

The clock is far from finished, and aside from the problems I’ve mentioned above, there are some minor things I would like to touch up and a couple of extra features I’d like to add. And a part of my code is as following:

#include <SPI.h>  // Include SPI if you're using SPI

#include <TimeLib.h>

#include <WiFi.h>

#include <WiFiUdp.h>

#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library

 

const char ssid[] = "************";  // your network SSID (name)

const char pass[] = "************";  // your network password

 

static const char ntpServerName[] = "time.nist.gov";

const int timeZone = -6;  // Mountain Daylight Time

 

WiFiUDP Udp;

unsigned int localPort = 8888;  // local port to listen for UDP packets

 

time_t getNtpTime();

void sendNTPpacket(IPAddress &address);

 

//IO Pin Constants

//Digit 0

#define PIN_RESET_0 12

#define PIN_DC_0    22

#define PIN_CS_0    13

 

//Digit 1

#define PIN_RESET_1 17

#define PIN_DC_1    22

#define PIN_CS_1    16

 

//Digit 2

#define PIN_RESET_2 4

#define PIN_DC_2    22

#define PIN_CS_2    0

 

//Digit 3

#define PIN_RESET_3 2

#define PIN_DC_3    22

#define PIN_CS_3    15

 

 

//7-Seg Pixel Constants for OLED

#define A_X 59

#define A_Y 14

 

#define B_X 35

#define B_Y 38

 

#define C_X 6

#define C_Y 38

 

#define D_X 0

#define D_Y 14

 

#define E_X 6

#define E_Y 7

 

#define F_X 35

#define F_Y 7

 

#define G_X 29 

#define G_Y 14

 

//Initialize Displays

MicroOLED oled0(PIN_RESET_0, PIN_DC_0, PIN_CS_0);

MicroOLED oled1(PIN_RESET_1, PIN_DC_1, PIN_CS_1);

MicroOLED oled2(PIN_RESET_2, PIN_DC_2, PIN_CS_2);

MicroOLED oled3(PIN_RESET_3, PIN_DC_3, PIN_CS_3);

 

bool updateTime=1;

byte old_minute=0,old_hour=0;

 

time_t prev = 0, prevNow=0;

 

void setup() {

  Serial.begin(115200);

 

  //Setup Displays

  oled0.begin();

  oled0.clear(PAGE);

  oled1.begin();

  oled1.clear(PAGE);

  oled2.begin();

  oled2.clear(PAGE);

  oled3.begin();

  oled3.clear(PAGE);

  

  // Connect to WiFi

  WiFi.begin(ssid, pass);

 

  pinMode(5,OUTPUT);  //Use the built in LED for WiFi Connection Status

  bool state = 0;

  while (WiFi.status() != WL_CONNECTED) {

    delay(500);

    Serial.print(".");

    state = !state;

    digitalWrite(5,state);

  }

  digitalWrite(5,HIGH);

 

  Serial.print("IP number assigned by DHCP is ");

  Serial.println(WiFi.localIP());

  Serial.println("Starting UDP");

  Udp.begin(localPort);

  Serial.println("waiting for sync");

  setSyncProvider(getNtpTime);

  setSyncInterval(300);

 

  //Display Current Time

  Update_Digit(oled0,hourFormat12()/10,32);

  Update_Digit(oled1,hourFormat12()%10,32);

  Update_Digit(oled2,minute()/10,32);

  Update_Digit(oled3,minute()%10,32);

  prev = now();

  prevNow = now()/60;

}

 

void loop() {

  yield();  //Let the ESP32 handle the wifi stack

 

  //Print the current time to Serial (debugging)

  if(now() != prevNow)

  {

    prevNow = now();

    Serial.print(hour());

    Serial.print(' ');

    Serial.print(minute());

    Serial.print(' ');

    Serial.print(second());

    Serial.println();

  }

 

  //Only update when the minutes change

  if(now()/60 != prev)

  {

    prev = now()/60;

 

    //Update Display

    for(byte i=0;i<33;i++)

    {

      if(hour() != old_hour)  //Does hour need to be updated?

      {

        if((hour()/10)!= old_hour/10) //Which hour digit needs to update? Both?

        {

          Update_Digit(oled0,hourFormat12()/10,i);

          Update_Digit(oled1,hourFormat12()%10,i);

        }

        else  //Just update the first hour digit

        {

          Update_Digit(oled1,hourFormat12()%10,i);

        }

        

      }

 

      if(minute() != old_minute)  //Does the minutes need to updated?

      {

        if((minute()/10)!= old_minute/10) //Which digit needs to be updated? Both?

        {

          Update_Digit(oled2,minute()/10,i);

          Update_Digit(oled3,minute()%10,i);

        }

        else  //Just update the first minute digit

        {

          Update_Digit(oled3,minute()%10,i);

        }

        

      }

      delay(5); //Wait 5ms to slow down the animations

    }

    old_hour = hour();

    old_minute = minute();

  }

}

 

//Animations for changing numbers

void Update_Digit(MicroOLED &oled,byte number, byte i)

{

  oled.clear(PAGE);

  switch(number)

  {

    case 0:

      if(i<17)

      {

        oled.rectFill(A_X+(64-i*4),A_Y,4,22); //A

        oled.rectFill(A_X-(i*3.6),A_Y,4,22); //A

        oled.rectFill(B_X,B_Y,22,4); //B

        oled.rectFill(C_X,C_Y,22,4); //C

        oled.rectFill(E_X+(32-i*2),E_Y,22,4); //E

        oled.rectFill(F_X+(32-i*2),F_Y,22,4); //F

        oled.rectFill(G_X-(i*4),G_Y,4,22); //G

      }

      else

      

    break;

 

    case 1:

      oled.rectFill(A_X-(i*2),A_Y,4,22); //A

      oled.rectFill(B_X,B_Y,22,4); //B

      oled.rectFill(C_X,C_Y,22,4); //C

      oled.rectFill(D_X-(i*2),D_Y,4,22); //D

      oled.rectFill(E_X-(i*2),E_Y,22,4); //E

      oled.rectFill(F_X-(i*2),F_Y,22,4); //F

    break;

    

default:

    break;

  }

  oled.display();

}

Kynix

Kynix was founded in 2008, specializing in the electronic components distribution business. We adhere to honesty and ethics as our business philosophy and have gradually established an excellent reputation and credibility in our international business. With the accurate quotation, excellent credit, reasonable price, reliable quality, fast delivery, and authentic service, we have won the praise of the majority of customers.

Join our mailing list!

Be the first to know about new products, special offers, and more.

Leave a Reply

We'd love to hear from you! Feel free to share your thoughts and comments below. Rest assured, your email address will remain private.

Name *
Email *
Captcha *
Rating:

Kynix

  • How to purchase

  • Order
  • Search & Inquiry
  • Shipping & Tracking
  • Payment Methods
  • Contact Us

  • Tel: 00852-6915 1330
  • Email: info@kynix.com
  • Follow Us

authentication

Kynix

© 2008-2026 kynix.com all rights reserved.