When I set out to make my last VFD clock, I decided to drive the tubes with a MAX6921 chip. However, I couldn't for the life of me figure it out. I looked at a bunch of other projects online and tried to reverse engineer them, but I just couldn't get that chip to do anything. In the end, I gave up and decided to just drive the whole thing with transistors.
Since this new clock is going to have six characters, instead of four, I'm going to have to add even more transistors. There's also going to be three additional VFD tubes for the colons and the PM indicator. That adds to the complexity, and will also need more transistors.
I need to figure out this chip.
I hit up the datasheet again and double checked everything against my schematic. Lo and behold, I discovered that the pinouts for my MAX6921 chip did not match that of the one in my EAGLE library
The image on the left matches the pinouts of pretty much every EAGLE schematic I've seen online that uses a MAX6921. However, the chip that I ordered from Digi-Key has the marking "AUI" on it and matches the pinouts of the TSSOP package. Go figure.
In order to try it out, I connected my boost converter to my breadboard and set it to output 25 volts. I also added a 3 volt regulator to the board for the VFD filament.
I then made the new connections to the MAX6921 breakout board.
Bingo! With a little code, I was able to shift out some bits and cycle through all the segments.
For example, this array will shift out a 1 to power the grid, and a 1 to power the 'A' segment.
int a[20] = {1, //GRID
0,
0,
0,
0,
0,
1, //A
0, //B
0, //C
0, //D
0, //E
0, //F
0, //G
0,
0,
0,
0,
0,
0,
0
};
Using some code samples that I found online, I was able to figure out how to shift the array out:
int clk = 3;
int load = 5;
int din = 4;
int a[20] = {1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0};
int k = 0;
void setup() {
pinMode(din, OUTPUT);
pinMode(load, OUTPUT);
pinMode(clk, OUTPUT);
digitalWrite(clk, LOW);
digitalWrite(load, LOW);
digitalWrite(din, LOW);
}
void loop() {
for (int i = 0; i < 20; i++) {
if (i == k) digitalWrite(din, 1);
else digitalWrite(din, 0);
digitalWrite(clk, HIGH);
delay(10);
digitalWrite(clk, LOW);
delay(10);
}
digitalWrite(clk, LOW);
for (int i = 19; i >= 0; i--) {
digitalWrite(din, a[i]);
digitalWrite(clk, HIGH);
delay(10);
digitalWrite(clk, LOW);
delay(10);
}
digitalWrite(load, HIGH);
delay(10);
digitalWrite(load, LOW);
delay(200);
k = k + 1;
if (k > 19) k = 0;
}
After figuring that out, I created an array for all the segments and then just cut and pasted the code over and over to shift out each segment.
int a[20] = {1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0};
int b[20] = {1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};
int c[20] = {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0};
int d[20] = {1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0};
int e[20] = {1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0};
int f[20] = {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0};
int g[20] = {1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0};
Here it is in action:
After that, it was then a matter of constructing some arrays to hold numbers. You just set a "1" for the segments that need to be turned on.
A "3", for example:
int a[20] = {1, //GRID
0,
0,
0,
0,
0,
1, //A
1, //B
1, //C
1, //D
0, //E
0, //F
1, //G
0,
0,
0,
0,
0,
0,
0
};
And all the numbers:
byte zero[20] = {1,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0};
byte one[20] = {1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0};
byte two[20] = {1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,0,0,0,0};
byte three[20] = {1,0,0,0,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0};
byte four[20] = {1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0};
byte five[20] = {1,0,0,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,0,0};
byte six[20] = {1,0,0,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0};
byte seven[20] = {1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0};
byte eight[20] = {1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0};
byte nine[20] = {1,0,0,0,0,0,1,1,1,1,0,1,1,0,0,0,0,0,0,0};
Here it is in action:
It should then be pretty easy to construct arrays for hours, minutes, and seconds and then just do a bunch of statements like "if hours = x then shift out x". Then I'll just have to write a routine to cycle through all six digits.
Something like this:
Here it is in action:
From there, it was pretty easy to figure out how to add another two digits.
I then added a RTC and some buttons to set the time. I updated my code to pull in the time from the RTC. I also added some ILT1-5 L displays to use as a PM indicator and a colon. It's officially a clock!
Finally, I added two more displays for the seconds.
I'm a display short for the minutes/seconds colon, so I'll have to order another ILT1-5 L. That won't stop me from pushing on. I still have the audio for the alarm to work out. Since I'm pushing all this data out to the MAX6921 with just three pins on the Arduino, there's plenty of I/O left over for other things.
Awesome.
See this project from start to finish:
More VFDs!!! VFD Breakouts Large VFD Clock - Part I
VFD AC Filament Driver Large VFD Clock - Part II VFD AC Filament Driver V1.1 Large VFD Clock - Part III Large VFD Clock - Part IV Large VFD Clock - Part V