Thomas Burns
Published © GPL3+

Driving VFD tubes with an Arduino Nano

A simple method for incorporating vacuum fluorescent display tubes into your projects!

IntermediateFull instructions provided6 hours2,930
Driving VFD tubes with an Arduino Nano

Things used in this project

Hardware components

IV-6 VFD tube
These are Soviet-made tubes that are no longer manufactured, though they are still relatively available. I only used three for this project, but during the build one of them stopped working, so I recommend getting an extra just in case.
×4
ULN2803 Darlington Transistor Array
×2
Arduino Nano R3
Arduino Nano R3
×1
110/220VAC to 25VDC power supply
×1
25V-to-8V buck converter
×1
8V-to-1.2V buck converter
×1

Software apps and online services

EasyEDA

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Wire Stripper & Cutter, 32-20 AWG / 0.05-0.5mm² Solid & Stranded Wires
Wire Stripper & Cutter, 32-20 AWG / 0.05-0.5mm² Solid & Stranded Wires
Breadboard, White
Breadboard, White
Premium Male/Male Jumper Wires, 40 x 3" (75mm)
Premium Male/Male Jumper Wires, 40 x 3" (75mm)

Story

Read more

Schematics

Circuit schematics

Code

Arduino code for driving three VFD tubes (with multiplexing)

Arduino
This code counts up from 0 to 999.
//  Code developed by Thomas Burns
//  www.thomasburns.net
//  Feel free to use and modify as you see fit!

// Pin assignments for segments
const int SEG_A = 2;
const int SEG_B = 3;
const int SEG_C = 4;
const int SEG_D = 6;
const int SEG_E = 5;
const int SEG_F = 7;
const int SEG_G = 8;

// Pin assignments for digits
const int DIG3 = 9;  // 1s
const int DIG2 = 10;  // 10s
const int DIG1 = 11;  // 100s

int digit = 1;
int dig_number = 0;
int number = 0;

unsigned long previousMillis = 0;  // will store last time number changed
const long period = 40;         // period at which to change number (in milliseconds)

void setup() {

  Serial.begin(9600);
  
  // Set segment pins as outputs
  pinMode(SEG_A, OUTPUT);
  pinMode(SEG_B, OUTPUT);
  pinMode(SEG_C, OUTPUT);
  pinMode(SEG_D, OUTPUT);
  pinMode(SEG_E, OUTPUT);
  pinMode(SEG_F, OUTPUT);
  pinMode(SEG_G, OUTPUT);
  
  // Set digit pins as outputs
  pinMode(DIG1, OUTPUT);
  pinMode(DIG2, OUTPUT);
  pinMode(DIG3, OUTPUT);

  // Turn off digits
  digitalWrite(DIG1, HIGH);
  digitalWrite(DIG2, HIGH);
  digitalWrite(DIG3, HIGH);
}


void loop() {
  
  //  DIGIT 1  //
  if (digit == 1) {
    digitalWrite(DIG1, HIGH);   // turns off digits
    digitalWrite(DIG2, HIGH);
    digitalWrite(DIG3, HIGH);
    dig_number = number / 100;  // isolates first digit of number
    if (number < 100) {
      dig_number = 99;   // triggers "default" in the switch/case (no segments)
      display_number(dig_number);   // activates segments
    } else {
      display_number(dig_number);
    }
    delay (1);   // pause to eliminate "ghosting" effect on unusued segments  
    digitalWrite(DIG1, LOW);  // turns on digit
    delay (5);   // keeps digit on for 5ms
    digit = 2;
    }  

  //  DIGIT 2  //
  if (digit == 2) {
    digitalWrite(DIG1, HIGH);   // turns off digits
    digitalWrite(DIG2, HIGH);
    digitalWrite(DIG3, HIGH);
    dig_number = (number / 10) % 10;   // isolates second digit of number
    if (number < 10) { 
      dig_number = 99;   // triggers "default" in the switch/case (no segments)
      display_number(dig_number);   // activates segments
    } else {
      display_number(dig_number);
    }
    delay (1);   // pause to eliminate "ghosting" effect on unusued segments  
    digitalWrite(DIG2, LOW);  // turns on digit
    delay (5);   // keeps digit on for 5ms
    digit = 3;
  }

  //  DIGIT 3  //
  if (digit == 3) {
    digitalWrite(DIG1, HIGH);
    digitalWrite(DIG2, HIGH);
    digitalWrite(DIG3, HIGH);
    dig_number = number % 10; 
    display_number(dig_number);
    delay (1);
    digitalWrite(DIG3, LOW);
    delay (5);
    digit = 1;      
  }
  
  /*  COUNTER  */ 
  unsigned long currentMillis = millis(); // store the current time
  if (currentMillis - previousMillis >= period) { // check if interval has passed
    previousMillis = currentMillis;   // save the last time we changed number
    number++;
  } else {
    number = number;
  }
  if (number == 1000) {
    number = 0;
  }

}

//  Segment configuration for each number  //
void display_number(int dig_number) {

  switch (dig_number) {
    case 0:
      digitalWrite(SEG_A, LOW);   
      digitalWrite(SEG_B, LOW);
      digitalWrite(SEG_C, LOW);
      digitalWrite(SEG_D, LOW);
      digitalWrite(SEG_E, LOW);
      digitalWrite(SEG_F, LOW);
      digitalWrite(SEG_G, HIGH);
      break;        

    case 1:
      digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
        break;

    case 2:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, LOW);
        break;
        
    case 3:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, LOW);
        break;
        
    case 4:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;
        
    case 5:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;
        
    case 6:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;
        
    case 7:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
        break;
        
    case 8:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, LOW);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;
        
    case 9:
        digitalWrite(SEG_A, LOW);
        digitalWrite(SEG_B, LOW);
        digitalWrite(SEG_C, LOW);
        digitalWrite(SEG_D, LOW);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, LOW);
        digitalWrite(SEG_G, LOW);
        break;
    
    default:
        digitalWrite(SEG_A, HIGH);
        digitalWrite(SEG_B, HIGH);
        digitalWrite(SEG_C, HIGH);
        digitalWrite(SEG_D, HIGH);
        digitalWrite(SEG_E, HIGH);
        digitalWrite(SEG_F, HIGH);
        digitalWrite(SEG_G, HIGH);
        break;
    }
}

Credits

Thomas Burns

Thomas Burns

4 projects • 53 followers
Father, maker, and lover of analog electronics. Check out more of my builds on my YouTube channel!

Comments