Map
Grand Prize Winner
(Dec 2012)
Second Prize Winner
(July 2012)

VFD Driver Demo

In order to control DP501 HNV-07SS61 VFD in an effortless and efficient manner the following software driver has been implemented. The functionality is encapsulated in HT16512.cpp and HT16512.h files and designed for AVR processors. To drive communication interface the logic uses PinMode and DigitalWrite functions provided by Arduino low level library. Also new HT16512 class inherits Arduino’s Print class to simplify output to display even more. However, despite those Arduino’s dependencies the code might be easily ported to PIC or ARM architectures.

The driver’s logic is subdivided into several groups: initialisation and low-level methods, tests and visual effects, methods for direct access to HT16512 without intermediate buffer and methods for intermediate buffer operations.

1. Initialisation and low-level methods

1.1. HT16512 constructor

Description
Constructs a new instance of HT16512 class and assigns three interface pins for communication. For more information about mapping between pins and pin numbers please refer to pins_arduino.cpp;

Prototype
Constructor HT16512(uint8_t cs, uint8_t sclk, uint8_t data);

Parameters
CS, SCLK and DATA pin numbers appropriately for physical communication with VFD;

Returns
None;

1.2. Reset method

Description
Sets three pins as outputs and their initial states, sets VFD driver mode (7 digits, 15 segments), switches display on with maximum brightness. Resets flashing attributes;

Prototype
void reset(void);

Parameters
None;

Returns
None;

1.3. DisplayOnCmd method

Description
Switches display on and sets display brightness;

Prototype
void displayOnCmd(uint8_t dimming);

Parameters
The 8-step dimmer value from 0 to 7 defines accordingly 1/16, 2/16, 4/16, 10/16, 11/16, 12/16, 13/16 and 14/16 pulse width. The 1/16 pulse width indicates minimum lightness. The 14/16 pulse width represents maximum lightness;

Returns
None;

1.4. DisplayOff method

Description
Switches display off;

Prototype
void displayOffCmd(void);

Parameters
None;

Returns
None;

1.5. DisplayWriteCmd method

Description
Writes data to display memory. The address might be set in advance by means of addrSetCmd(uint8_t addr) method;

Prototype
void displayWriteCmd(uint8_t addr_inc, uint8_t nodata);

Parameters
If addr_inc is set to true then HT16512 increments address after data has been written.
If nodata is set to false then CS line is set back to HIGH after command byte is sent to HT16512 meaning end of command transmission;

Returns
None;

1.6. AddrSetCmd method

Description
Sets the address of the display memory;

Prototype
void addrSetCmd(uint8_t addr);

Parameters
Addr has the value to be set to. If address 0x16H or higher is provided, data is ignored until a valid address is set;

Returns
None;

1.7. Command method

Description
Low level function for sending a command;

Prototype
void command(uint8_t value, uint8_t nodata);

Parameters
Value is a command to be sent, nodata set to true if there will be data bytes following the command;

Returns
None;

1.8. Data method

Description
Low level function for sending data;

Prototype
void data(uint8_t value, uint8_t init_cs, uint8_t finalise_cs);

Parameters
Value is a data byte to be sent,
init_cs should be set to true to pull CS line LOW before initiating data transmission (and normally this parameter is set to false because CS is already set to LOW before command byte transmission),
finalise_cs must be set to true only for the very last data byte in a single transmission;

Returns
None;

2. Tests and visual effects

Tests and visual effects are represented by methods with Test and Effect suffixes in method names. Each method has to be invoked more than once in order to be completed. Upon completion methods return FALSE. In order to perform all available tests one by one there is a testStep(void) method that might be invoked from user code by a timer routine. Current test is kept in _tstState variable that can be assigned to one of the following values:

NOT_STARTED, COLUMN_TEST, SEGMENT_TEST, DIMMING_TEST, GLOWING_TEST, CHARSET_TEST, CHARSET_TEST2, ROTOR_TEST, SLASH_EFFECT, SCROLL_EFFECT, COMPLETED

To run through all available tests subsequently, it is enough to invoke uint8_t HT16512::testStep() on a periodic basis and do it until the method returns COMPLETED result. Internally, this method invokes one by one the following tests:


uint8_t columnTest();
uint8_t segmentTest();
uint8_t dimmingTest();
uint8_t glowingTest();
uint8_t charsetTest();
uint8_t charsetTest2();
uint8_t rotorTest();
uint8_t slashEffect();
uint8_t scrollEffect();

3. Methods for direct access to HT16512 without intermediate buffer

3.1. Write byte method

Description
Outputs ASCII character to display memory using current address. The address should be set in advance by means of void HT16512::addrSetCmd(uint8_t addr). When address is set more than one character might be sent to display memory as address is automatically incremented by VFD driver. To display one character two bytes are used so the address is incremented twice per a character resulting maximum of 7 (seven) consecutive invocations of this method after which address must be set to 0 (zero) again. Not all characters from ASCII table could be displayed – please refer to const PROGMEM uint8_t FONT_PGM array;

Prototype
void write(uint8_t value);

Parameters
value – ASCII character to be displayed;

Returns
None;

3.1. Write byte array method

Description
Outputs raw byte array to display memory using the provided address start value. No need in setting address in advance as it will be overriden in this method. Unlike the previous void write(uint8_t value) method no conversion of ASCII code to VFD segment codes is performed;

Prototype
uint8_t HT16512::write(uint8_t* buffer, uint8_t dstIndex, uint8_t len);

Parameters
buffer points to an array of raw bytes to be displayed,
dstIndex defines address in display memory,
len is a number of bytes to be written;

Returns
Number of bytes written;

4. Methods for intermediate buffer operations

The is no way to read data from display memory and there are situations when it would be extremely good to have that feature – for example, to read and modify the content that is currently being displayed. Introduction of an intermediate buffer allows us to have this feature and it makes possible to implement ‘blinking’ (or ‘flashing’) functionality.

4.1. Write_f byte method

Description
Outputs ASCII character to intermediate buffer. Similar to 3.1 Write byte method but uses intermediate buffer instead of direct access to display memory;

Prototype
void write_f(uint8_t value, uint8_t dstIndex, uint8_t dispColon);

Parameters
value – ASCII character to be sent to buffer,
dstIndex defines address in buffer,
dispColumn is set to TRUE if ‘:’ colon should be displayed as well (applicable only for digits 3 and 5, counting from left to right starting from 1);

Returns
None;

4.2. Write_f byte array method

Description
Outputs raw byte array to intermediate buffer. Similar to 3.2 Write byte array method but uses intermediate buffer instead of direct access to display memory;

Prototype
uint8_t write_f(uint8_t* buffer, uint8_t dstIndex, uint8_t len);

Parameters
buffer points to an array of raw bytes to be displayed,
dstIndex defines address in intermediate buffer,
len is a number of bytes to be written;

Returns
Number of bytes written;

4.3. Print_f_p method

Description
Outputs string located in program memory to intermediate buffer. Clears internal buffer and sets start address to 0 (zero) then uses internally 4.1. Write_f byte method in a loop;

Prototype
void print_f_p(const prog_char str[]);

Parameters
str char array stored in program memory;

Returns
None;

4.4. ClearFrame method

Description
Initialises intermediate buffer by filling it with zeroes;

Prototype
void clearFrame();

Parameters
None;

Returns
None;

4.5. FlipFrame method

Description
Sends the content of whole intermediate buffer to display memory;

Prototype
void flipFrame();

Parameters
None;

Returns
None;

4.6. SetFlashAttr method

Description
Sets one digit or whole row to blinking state;

Prototype
void setFlashAttr(uint8_t index, uint8_t value);

Parameters
index defined as zero or greater but less than VFD_DIGITS sets appropriate digit to blinking state. Otherwise all 7 (seven) digits will be blinking;

Returns
None;

4.7. GetFlashAttr method

Description
Gets blinking state of a particular digit or whole row;

Prototype
uint8_t HT16512::getFlashAttr(uint8_t index);

Parameters
index defined as zero or greater but less than VFD_DIGITS gets a blinking state of a digit. Otherwise blinking states for all digits will be given as a result;

Returns
TRUE if a digit is in blinking mode and FALSE otherwise. If as input argument a value equal to VFD_DIGITS or greater was used then the result indicates blinking states of all 7 (seven) digits in 0…6 bits;

4.8. FlipFlashState method

Description
Flips flash state of the display content. Should be periodically invoked by user code to visualise blinking. Note, than this method only changes the logical state of blinking, immediately after 4.5. FlipFrame method should be invoked;

Prototype
void flipFlashState();

Parameters
None;

Returns
None;

The code below demonstrates how to initialise our VFD driver:

#include <avr/interrupt.h> #include <util/delay.h> #include "wiring.h" #include "HT16512.h" #define VFD_CS_PIN 15 //PD7 #define VFD_SCLK_PIN 14 //PD6 #define VFD_DATA_PIN 13 //PD5 #define STANDBY_PIN 12 //PD4 HT16512 vfd(VFD_CS_PIN, VFD_SCLK_PIN, VFD_DATA_PIN); //VFD display int main(void) { pinMode(STANDBY_PIN, OUTPUT); digitalWrite(STANDBY_PIN, HIGH); //Enable VFD power supply digitalWrite(STANDBY_PIN, LOW); _delay_ms(100); digitalWrite(STANDBY_PIN, HIGH); //Initialise VFD tube vfd.reset(); vfd.addrSetCmd(0); vfd.clearFrame(); vfd.flipFrame(); sei(); while (1) { vfd.testStep() _delay_ms(200); } }

As you can see, apart from VFD_CS_PIN, VFD_SCLK_PIN, VFD_DATA_PIN pins that are dedicated to VFD communication there is also STANDBY_PIN pin that simulates POWER button and instructs to switch +5V power rail on.

Let’s get down to the hardware part. In this demo we will be using Freeduino board. In total we would need 4 (four) signal wires to connect it to the VFD panel. Of course, we will also need GND and +5V power rail.

Freeduino Schematic Pinout for VFDDemo

Here is the signal mapping table between Freeduino board and VFD panel (please also refer to DVP630 Schematic Diagram):

Signal Freduino connector-pin VFD panel connector-pin
VFD_CS J3-8 RB502-2
VFD_CLK J3-7 RB502-1
VFD_DATA J3-6 RB502-3
STANDBY J3-5 CN503-3
+5V Standby JP1-3 RB501-5
GND JP1-4, 5 RB502-4

And here is the result: Freeduino board running VFDDemo, connected to the VFD panel and power supply from broken Philips DVP 630:

To download VFD Demo library and VFD example for AVR please feel free to hit this button: Magictale VFD Demo lib and example for AVR Rev1.0

Stay tuned, the most interesting things are still yet to come!