A friend recently upgraded the cash registers in his shop to iPad based ones and had two surplus displays. These were decently sized 2x20 Vacuum Fluorescent Displays (VFD) which appeared to be driven by serial data.
I was able to take a copy of a demonstration program (for Windows) from the original PC that they connected to and with the help of my super cheap Chinese logic probe was able to determine the data packets sent to the displays. This then greatly assisted me in creating a simple program to drive the displays. I duplicated the sequence of the commands as sent by the demonstration program, and reported by the logic probe. I may be that some of the steps are not required but as I couldn't turn up a datasheet for the display, I simply recreated the sequence of commands sent by the demo program. If they look odd, sorry, I just copied the original.
The displays originally were powered at (what I thought I measured at) 5V. This needs to be at a minimum of 1A, I found the displays wouldn't power up below around 5.5V, but that could be decoupling issues on my breadboard.
When powered up with no serial data, the displays announce themselves as:
CD5220 9600 N-8-1
U.S.A. /PC437(V1.H)
This then clears and the displays go blank.
As soon as serial data is presented, the displays show the supplied data.
I don't give any warranty regarding the robustness of the program, but it may at least give a start to anyone else trying to use similar displays.
The displays seem to have a display buffer of 48 bytes (which were sent by the original program each time) the last eight bytes should be null (0x00). The display shows the last 40 characters sent, if there are characters in the last eight bytes, the first eight bytes will be lost.
'A program to drive a serial Vacuum Fluorescent Display.'(c) MkStevo, Mark Stevenson, MkEDS 2021''The displays require a 5.5V supply, at a minimum of 1A''When powered up the display identified itself as:''CD5220 9600 N-8-1'U.S.A. /PC437(V1.H)''The display has a 2x20 character display.''Printing to the display beyond the line length limits causes the text to wrap onto the next line,'or back to line 1.''There are 20 "Cursors" below line 2 which can individually be turned on or off.''The baud rate is 9600, 8bits, 1 stop bit, Inverted polarity. The polarity is inverted with the'command:'Let SCKP=1''Each command to the display seems to be sent as eight bytes.'All eight bytes appear to be needed to be sent.''The subroutine "SendOctet" has eight parameters, any parameters not passed are sent as'zero value bytes. This is how the original program sent the serial data and I simply'duplicated the same sequence.''To send the command for turning one of the bottom arrow (cursors) on the original serial sequence was:''0x1F,0x23,0x01,0x06,0x00,0x00,0x00,0x00' | |'Turn on cursor |'Cursor number six''To send the same command, call "SendOctet"''SendOctet(0x1F,0x23,0x01,0x06)'The trailing four "0x00" bytes are automatically sent, they do not need to be added to the call.''The display buffer appears to be 48 bytes long. All 48 bytes were sent by the original program.'Again, I have duplicated this sequence.''The final eight display bytes should be null (0x00). If they have character values in them, they will be'printed, with the first eight bytes truncated.''The array "DisplayArray" can be filled with null characters by calling "ClearBuffer"''The display can be cleared by calling "ClearDisplay". This also sets the cursor to line 1, character 1.''If the buffer has not been cleared, when it is next printed using VFDString, "old" characters not cleared'or updated will still remain in the buffer and will be written to the display.''Null characters in the display may not be written, merely skipped over.''It is possible to move the cursor to a specific position on the display.'The position of the top most, left most character is at co-ordinates 1, 1.''The position of the right most, bottom most character is 2, 20.''Call "SetPosition(2, 10)" to move to the middle of line 2.#Chip12F1840,32#OptionExplicitDimDisplayArrayAsString*48DimArrayPosAsByteDimDataPosAsByteLetArrayPos=1DimCntDownAsLong#DefineStartValue1000#DefineSerTXPortA.0'Pin7#DefineSerRXPortA.1'Pin6DirSerTXOutDirSerRXIn#DefineUSART_BAUD_RATE9600#DefineUSART_TX_BLOCKING#DefineUSART_DELAY0LetSCKP=1'Inverted serialClearBufferClearDisplayCursorZeroDo' 12345678901234567890x2345678901234567890LetDisplayArray=" Hello VFD Display World! "VFDStringWait2000mSClearBufferClearDisplay' 12345678901234567890x2345678901234567890LetDisplayArray=" Thanks Sam for the Displays "VFDStringWait2000mSClearBufferClearDisplay' 12345678901234567890x2345678901234567890LetDisplayArray=" Hello Great Cow Basic from MkStevo.."VFDStringWait2000mSClearBufferClearDisplay' 12345678901234567890x2345678901234567890LetDisplayArray="Move to 2,19"VFDStringSetPosition(2,19)ClearBufferWait750mSLetDisplayArray="@"VFDStringWait2000mSClearBufferClearDisplay' 12345678901234567890x2345678901234567890LetDisplayArray=" Move to 1,17"VFDStringSetPosition(1,17)ClearBufferWait750mSLetDisplayArray="@"VFDStringWait2000mSClearBufferClearDisplay' 12345678901234567890x2345678901234567890LetDisplayArray="Cursor 7 On"VFDStringWait750mSSetBottomArrow(7,1)Wait2000mSCursorZero' 12345678901234567890x2345678901234567890LetDisplayArray="Cursor 3 On"VFDStringWait750msSetBottomArrow(3,1)Wait2000mSCursorZero' 12345678901234567890x2345678901234567890LetDisplayArray="Cursor 3 Off"VFDStringWait750mSSetBottomArrow(3,0)Wait2000mSCursorZero' 12345678901234567890x2345678901234567890LetDisplayArray="Cursor 7 Off"VFDStringWait750mSSetBottomArrow(7,0)Wait2000mSClearBufferClearDisplayLetCntDown=StartValue' Let CntDown = 1000000' 12345678901234567890x2345678901234567890LetDisplayArray="Time to armageddon.."VFDStringDoSetPosition(2,1)IfCntDown<1000000ThenHSerSend(48)'0EndIfIfCntDown<100000ThenHSerSend(48)EndIfIfCntDown<10000ThenHSerSend(48)EndIfIfCntDown<1000ThenHSerSend(48)EndIfIfCntDown<100ThenHSerSend(48)EndIfIfCntDown<10ThenHSerSend(48)EndIfHSerPrintCntDownLetCntDown=CntDown-1LoopUntilCntDown>StartValueWait2000mSClearBufferClearDisplayLoopSubClearDisplaySendOctet(0x0C)Repeat20SendOctet(0x1F,0x23,0x00,DataPos)LetDataPos=DataPos+1EndRepeatEndSubSubCursorZeroSendOctet(0x1B,0x6C,0x01,0x01)SendOctet(0x18)SendOctet(0x1B,0x6C,0x01,0x01)EndSubSubVFDStringLetArrayPos=1Repeat48HSerSend(DisplayArray(ArrayPos))LetArrayPos=ArrayPos+1EndRepeatEndSubSubSendOctet(OptionalD1AsByte=0,OptionalD2AsByte=0,OptionalD3AsByte=0,OptionalD4AsByte=0,OptionalD5AsByte=0,OptionalD6AsByte=0,OptionalD7AsByte=0,OptionalD8AsByte=0)HSerSend(D1)HSerSend(D2)HSerSend(D3)HSerSend(D4)HSerSend(D5)HSerSend(D6)HSerSend(D7)HSerSend(D8)EndSubSubSetPosition(InLinePosAsByte,InCharPosAsByte)IfLinePos>2ThenLetLinePos=1EndIfIfLinePos<1ThenLetLinePos=1EndIfIfCharPos>20ThenLetCharPos=1EndIfIfCharPos<1ThenLetCharPos=1EndIfSendOctet(0x1B,0x6C,0x01,LinePos)IfCharPos>1ThenLetCharPos=CharPos-1RepeatCharPosSendOctet(0x1B,0x5B,0x43)EndRepeatEndIfEndSubSubClearBufferLetArrayPos=1Repeat48'Fill Buffer with null charactersLetDisplayArray(ArrayPos)=0LetArrayPos=ArrayPos+1EndRepeatEndSubSubSetBottomArrow(InArrowPosAsByte,InArrowOnAsByte)IfArrowPos>20ThenLetArrowPos=1EndIfIfArrowPos<1ThenLetArrowPos=1EndIfIfArrowOn>1ThenLetArrowOn=0EndIfSendOctet(0x1F,0x23,ArrowOn,ArrowPos)EndSub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Needless to say, I had no idea regarding the VT100 codes. That might have been easier than reverse engineering with a logic probe.
You live and learn.
Mind you, I've got the text on the display, I can move to a specific point and can clear the display. For re-purposing into a clock, that's all I'll need. I felt quite smug to have got that done so didn't go any further. Don't want to push my luck.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was given the displays, I thought I could do something with them.
It was a challenge.
I like a challenge.
It kept me entertained.
I'll be able to make a clock that has room to show the full day, date, year and time and still read from across the room.
I might make something else.
Who knows.
I accepted the challenge.
Used my cheap Chinese logic probe.
Decoded the protocol all by myself.
Wrote a program that emulates that protocol which worked.
Challenge defeated.
You never know, it might also help someone else get to grips with similar displays.
Last edit: mkstevo 2021-04-18
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I managed to get a 8 digit 7 segment working driving it from a 16F887 (with the help of transistors - 17 if I recall correctly).
They are fascinating as essentially they are cathode ray tubes, but we are looking down at the anode coated with a phosphor through the grid and cathode. As with all CRTs you need to heat the cathode so there is a low voltage (high-ish current) supply for the heater which ideally should be a.c. with d.c. one end would be at a lower voltage and so the display less bright( at that end).
If you ever messed with vacuum tubes you will also know that you need a grid bias voltage - these displays are no exception (I did it with a zener). The other thing is you need at least 30V on the anode (relative to the cathode, with the grid, in an off state, pulled a further 5V below below the cathode).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As luck would have it, these displays are entirely self contained with the inverter for the HV and heaters all running from a single 5-6V supply. They also have the full driver/decoder built in making their use so much easier.
I've also got a much smaller unit that Noritake Itron sent me as a sample that was suggested could be a replacement as the standard 20x2 LCD character displays. While it is a similar size to a 1602 (or 2002) LCD, they are so much more expensive I never got any further than powering up the sample. It is a lovely display, no doubt, but not worth paying in the region of ten times the cost of a Winstar LCD equivalent (£71 + £14 VAT from Farnell!).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
A friend recently upgraded the cash registers in his shop to iPad based ones and had two surplus displays. These were decently sized 2x20 Vacuum Fluorescent Displays (VFD) which appeared to be driven by serial data.
I was able to take a copy of a demonstration program (for Windows) from the original PC that they connected to and with the help of my super cheap Chinese logic probe was able to determine the data packets sent to the displays. This then greatly assisted me in creating a simple program to drive the displays. I duplicated the sequence of the commands as sent by the demonstration program, and reported by the logic probe. I may be that some of the steps are not required but as I couldn't turn up a datasheet for the display, I simply recreated the sequence of commands sent by the demo program. If they look odd, sorry, I just copied the original.
The demonstration program can be seen working in a YouTube video. https://youtu.be/hPBVKtx01Us
The displays originally were powered at (what I thought I measured at) 5V. This needs to be at a minimum of 1A, I found the displays wouldn't power up below around 5.5V, but that could be decoupling issues on my breadboard.
When powered up with no serial data, the displays announce themselves as:
CD5220 9600 N-8-1
U.S.A. /PC437(V1.H)
This then clears and the displays go blank.
As soon as serial data is presented, the displays show the supplied data.
I don't give any warranty regarding the robustness of the program, but it may at least give a start to anyone else trying to use similar displays.
The displays seem to have a display buffer of 48 bytes (which were sent by the original program each time) the last eight bytes should be null (0x00). The display shows the last 40 characters sent, if there are characters in the last eight bytes, the first eight bytes will be lost.
Brilliant. Video is great!
Thanks. I know you like a video!
It may be worth looking up the VT100 terminal codes, they are the most commonly used for serial displays.
Needless to say, I had no idea regarding the VT100 codes. That might have been easier than reverse engineering with a logic probe.
You live and learn.
Mind you, I've got the text on the display, I can move to a specific point and can clear the display. For re-purposing into a clock, that's all I'll need. I felt quite smug to have got that done so didn't go any further. Don't want to push my luck.
2 x 20...why bother? Get a 320 x 240 glcd supported and have fun with using graphics.
Bit of imagination and display anything.
Repurpose rather than Repurchase Stan.
It is not about saving money it is about being creative and saving the Planet.
Why bother?
I was given the displays, I thought I could do something with them.
It was a challenge.
I like a challenge.
It kept me entertained.
I'll be able to make a clock that has room to show the full day, date, year and time and still read from across the room.
I might make something else.
Who knows.
I accepted the challenge.
Used my cheap Chinese logic probe.
Decoded the protocol all by myself.
Wrote a program that emulates that protocol which worked.
Challenge defeated.
You never know, it might also help someone else get to grips with similar displays.
Last edit: mkstevo 2021-04-18
I managed to get a 8 digit 7 segment working driving it from a 16F887 (with the help of transistors - 17 if I recall correctly).
They are fascinating as essentially they are cathode ray tubes, but we are looking down at the anode coated with a phosphor through the grid and cathode. As with all CRTs you need to heat the cathode so there is a low voltage (high-ish current) supply for the heater which ideally should be a.c. with d.c. one end would be at a lower voltage and so the display less bright( at that end).
If you ever messed with vacuum tubes you will also know that you need a grid bias voltage - these displays are no exception (I did it with a zener). The other thing is you need at least 30V on the anode (relative to the cathode, with the grid, in an off state, pulled a further 5V below below the cathode).
As luck would have it, these displays are entirely self contained with the inverter for the HV and heaters all running from a single 5-6V supply. They also have the full driver/decoder built in making their use so much easier.
I've also got a much smaller unit that Noritake Itron sent me as a sample that was suggested could be a replacement as the standard 20x2 LCD character displays. While it is a similar size to a 1602 (or 2002) LCD, they are so much more expensive I never got any further than powering up the sample. It is a lovely display, no doubt, but not worth paying in the region of ten times the cost of a Winstar LCD equivalent (£71 + £14 VAT from Farnell!).