资源说明:A Lua module/API for VFD control in eLua
-------------------------------------------------------------------------------- -- -- Vacuum Fluorescent Display control for eLua -- -- Dado Sutter, Fev 2010 www.eluaproject.net -- -------------------------------------------------------------------------------- These are the notes for the vfd module for eLua. They are based on the tube we had (IV-18) and the decoder we've chosen (MAX6921) but they can be easily adapted to interfacing with other VFD tubes and panels. ## This is a work-in-progress document, not a final version yet ## ## Corrections, refinements and suggestions are welcomed ## -------------------------------------------------------------------------------- -- -- The tube -- -------------------------------------------------------------------------------- In our first VFD interfacing project we are using this tube brought to us by Bogdan Marinescu (www.eluaproject.net/###/authors.html) when he first came to Brasil for the Lua Workshop 2009 (the video of the talk we presented together can be downloaded from here ##). Bogdan's gift was two IV-18, a very neat, Russian made, cheap and not too hard to find VFD tube. It has 8 numeric digits and a 9th extra position that has only two symbols. We will call this extra symbol-only position a "digit" too, to keep things simple. You can thus consider this tube a 9 digit, with a different segment aarrangement in it's 9th position. FIG 1 - IV18 Pinout Figure 1 shows that each independent segment of all digits are connected together, creating a sort of Bus with 8 (segment) lines. Each individual digit has a sort of "enable" or "select", creating another Bus but this time with 9 lines. To light up any IV-18 segments, all we need is to do is to feed it's segment line AND it's digit line with the high voltage Vbb that we'll talk about further down. We can light up at the same time any combination of segments and digits. We also note now that we cannot address/light up at the same time two different segments of different digits. To do that, we must light one at a time for short periods, so we fool our eyes to see them as if they are both lit simultaneously. This is the only way to "write" different numbers in different digits at the same time and we will call this "multiplexing" our segment and digit buses. To complete our IV-18 description we must mention the filament, which is a simple (but fragile!) internal resistance that needs to be powered by a DC voltage (see power supplies below). We also note that the segments forming the digits are not equal and this is one of the things that make the IC-18 more appealing too. -------------------------------------------------------------------------------- -- -- The Controller -- -------------------------------------------------------------------------------- To be able to send the higher voltage required by the VFDs, we used some nice serial to parallel decoders that also offer us the advantage of controlling all the lines with only 3 PIO pins. For this implementation we used the MAX6921. It's data sheet can be found here #### and the model we'll be discussing is the AWI (be careful! Different models have different pinouts!). Of the 20 available outputs, to control one IV-18 we only need to use 17; 8 for the segment bus and 9 for the digit bus. The MAX6921 is a simple serial to parallel converter that converts TTL levels serialized to it to high voltage (up to 76Vcc) parallel outputs. It also has a controlled latch so the outputs can be kept stable while new data is being clocked/serialized in. Everything is done by 3 control pins: DIN (data in) - Receives the logic state of a bit you want to serialize to one of the outputs. CLK (clock) - Receives a positive pulse each time you want to shift in the DIN data. Once you have clocked all your data into this shift register (17 bits in our case) we give a positive pulse on the ... (below) LOAD (load/latch) - Informs the internal latch to transfer the clocked in data to the outputs and retain it until the next load pulse. This simple protocol can be resumed like: - Set DIN with the MSB you want to clock in (DOUT16 on the chip) - Clock it in setting the CLK pin high and then low - Repeat the steps above for the other 16 bits until LSB - Set the LOAD pin high than low The MAX6921 is powered by 5Vcc on a single pin and the high voltage to be sent to it's outputs (Vbb) is fed through another single pin. -------------------------------------------------------------------------------- -- -- The Power Supplies -- -------------------------------------------------------------------------------- The voltages required for the VFD tube and controller are: - TTL (Vcc) A regulated 5Vcc to power the MAX6921. The consumption of one chip is under 1mA. - High Voltage (Vbb) The literature says we should power the segments and digit lines with around 20Vcc for direct uses and around 50Vcc for multiplexing. Our experience shows that the tube lights quite nicely from 15Vcc up and 20Vcc seems to be enough even for slower multiplexing times. But we have not tested it with higher voltages yet so we expect to update this impressions soon. The current consumption with all the segments lit at 20Vcc is 11mA. - Filament Voltage (VFilament) Again, the literature says we must power the filament with something between 4.2 and 5.6 Vcc. Five volt seems to be a good choice, so we can use the same source used to power the MAX6921 (above). Our experience shows that the tube begins to light with 2Vcc on the filament and the intensity of the segments doesn't vary significantly from 2.5 to 5.6 Vcc (at least for 20Vcc being used as "high voltage"). We are using 3Vcc hoping to save some tube's life but it is expected to last for decades even when powered by the maximum allowed voltages. The current consumption here is 50mA at 2.5Vcc and 81mA at 5.0Vcc. This maximum current consumption is actually achieved when all the segments are off. We powered our assembly from a workbench variable power supply so we won't help you too much with analog and regulation details. Good tips and neat switching power supply projects can be found in some of the links below: http://www.aplomb.nl/TechStuff/Switcher/Switcher.html http://www.desmith.net/NMdS/Electronics/NixiePSU.html http://www.electricstuff.co.uk/nixpsu.html -------------------------------------------------------------------------------- -- -- The VFD eLua module -- -------------------------------------------------------------------------------- Hardware control drivers are usually coded in C or assembly, because of critical timings, fast response and predictable execution times requirements. We decided to implement our VFD driver in Lua, to show how you can achieve the same results in eLua with much more simplicity (and Fun! :). To use the eLua VFD module in your application, all you need to do is to include a: require( "vfd" ) ... which will load the vfd module and make available the main control functions in the "vfd." name-space To keep things simple, we are doing our control in a bit-bang manner, using 3 pio pins (for CLK, DIN and LOAD). Once the VFD module is loaded by require(), we need to call only once one of it's functions to initialize the module and configure it to your hardware. vfd.init() Initializes the VFD module and configures it to your hardware. Default pio outputs are assumed for the currently known boards: EK-LM3S8962: DIN - pio.PG_0 CLK - pio.PC_5 LOAD - pio.PC_7 eLua PUC-Rio: DIN - pio.P0_24 CLK - pio.P0_26 LOAD - pio.P0_28 You can optionally pass one table as argument with some initialization parameters, if your board is not known to eLua or if you want to change the control pins used by default. The fields are all optional and described below: t = {} t.din_pin = the port/pin you want to use for the DIN line (ex: pio.PB_3) t.clk_pin = the port/pin you want to use for the CLK line t.load_pin = idem vfd.init( t ) Now we come to the fun part of it, which is using the VFD module to write what we want to the VFD. The basic primitive is the set() function that takes two arguments: segments and digits vfd.set( segments, digits ) - segments: An 8 bit Lua number, where each bit represent a segment. A logic 1 sets the segment on and a 0 sets it off. As our IV-18 VFD has (mostly) 7-segment digits with a decimal point, we wired our assembly in a way that it reproduces the usual notation for 7-segment led displays: a ------- | | f| |b | g | ------- | | e| |c | d | ------- dp Figure 2 Figure 2 shows the segment identification letters. They are arranged in the "segments" argument of the set() function with "a" being the MSB and "dp" being the LSB, as shown in Figure 3. a b c d e f g dp bit7 ............................. bit0 Figure 3 Obs: the ninth "digit" on the left of IV-18 has only two segments. The dot is lit by the "a" bit and the dash by the "b" bit. - digits: Like the segments argument above, digit is a Lua number, this time with 9 bits, each representing a digit position on the VFD. The rightmost digit on the tube correspond to bit0 and the leftmost (actually the dot & dash symbol) to bit8. Some examples of the set( segments, digits ) function usage may worth more than my bad english words. It is also easier if we use the 0x Lua hexadecimal notation for numbers in our examples: 1) Write the number 1 in the leftmost digit: vfd.set( 0x60, 0x001 ) 0x60 is 01100000, which means segments b and c set (lit) 0x001 is 000000001, which means the leftmost digit selected/enabled. 2) Write 66 right aligned: vfd.set( 0x3A, 0x003 ) 0x3A is 00111010, meaning segments c, d, e, f, g lit 0x003 is 000000011, meaning digits 1 and 2 selected 3) Write 33 centered: vfd.set( 0xF2, 0x018 ) 0xF2 is 11110010, meaning segments a, b, c, d, g lit 0x018 is 000011000, meaning digits 4 and 5 selected 4) Light up the decimal points of the four leftmost digits: vfd.set( 0x01, 0x0F0 ) 0x01 is 00000001, meaning the dp segment lit 0x0F0 is 011110000, meaning digits 5,6,7,8 selected 5) Light up the dot symbol on the 9th digit (symbols) on the left: vfd.set( 0x01, 0x100 ) 0x01 is 00000001, meaning the dot symbol (and dp segments) lit 0x100 is 100000000, meaning digit 9 selected. 6) Light up the dash symbol on the 9th digit (symbols) on the left: vfd.set( 0x02, 0x100 ) 0x02 is 00000010, meaning the dash symbol (and g segments) lit 0x100 is 100000000, meaning the digit 9 is selected The examples above show how simple it is to light up segments of a digit or equal segments in more than one digit. To write numbers (or some possible letters) that have a different set of lit segments to form it, we need to write them separately and quickly alternate between them (multiplex), to our eyes see them as all ### (continue .......) Writing strings, numbers and symbols: To write numbers, symbols and the few possible letters we use the setstring() primitive. As it has to multiplex the numbers for some time to make our eyes think they are all lit at the same time, there is a second argument that controls this "time". It is simply a loop limit control number though, not a time-calibrated value. (Experiment with numbers between 100 and 500 first...). In future implementations, this primitive could return only the segments and digits mapped to the wanted string and the caller program could take care of the multiplexing. Some coroutine-coordinated schemes might bring some fun too. The primitive function to write strings is vfd.setstring( str, time ) and it's arguments are: - str: The string of numbers and/or possible symbols and letters to be written to VFD. The string is rendered right aligned. Maximum length is 8 characters but the dots (one or more, up to 8) do NOT count as positions (because they will be rendered on the same position of the preceding character). No check is being made for valid strings and sizes, so be careful. - time: A number to control the time the string will be shown on the VFD. Pls read the introductory text above. VFD is cleared after the string is shown for this "time" (not time-calibrated !) and the control is given back to the caller program or interpreter. Easy using all of this: To illustrate the uses of the set() and setstring() primitives we wrote two simple programs that define some functions to play with the VFD. artvfd.lua defines some (questionable :) art functions and numvfd.lua defines functions to write strings, numbers and symbols on the VFD. To use them, simply call Lua from the eLua shell, loading the program you want to try first: # lua -l artvfd or # lua -l numvfd For each one of them, you will then have the following functions defined, that can be called from the interpreter command line or used in directly typed simple scripts: #### Describe the functions ........ ART VFD -- Blink all segments of all digits function blinkall() -- Wide dashes going up & down function art1() -- Wide dashes going up and paralell dashes comming down function art2() -- As art2() but digits are kept lit while going up or down function art3() -- Vertical dashes dancing function art4() -- A dash going all arround the digits' edges function art5() -- A dash going all arround the digits' edges and centers function art6() -- Show simultaneously each possible segment in a different digit function art7() -- Bubbles going "up" in random side positions function bubble1() -- Bubles on random sides and on random digit positions function bubble2() -- Random seg pattern in a random digit position function random1() -- Random seg patterns in random digit positions function random2() -- One dot, bouncing between the edges function dots1() -- One dot at a random digit position function dots2() -- Random number of dots at random digits positions function dots3() -- eLua written statically in the middle function elua1() -- eLua scrolls in both directions function elua2() -- Letters comming one by one from right to left function elua3() NumVFD -- Upper counter right aligned function num1() -- Random 8 digit numbers right aligned function num2() -- The number Pi with 7 decimals function pi() -- The version number of eLua running on the platform function eluaversion() -- The version number of Lua running on the platform function luaversion()
本源码包内暂不包含可直接显示的源代码文件,请下载源码包。