These are pictures taken 2015-12-14 of some digital electronics hackery I did recently (over the last week or two). I built circuitry to drive a vacuum fluorescent display, controlled by a serial line from a computer. This file sketches the design of the circuitry and outlines what the various image files here are. The images are stills taken from a USB video camera, which is in large part why they are as small as they are. The 0* images are pictures of the circuitry I built; the 1* images are examples of display. In each sequence, the numbers are frame numbers from the camera capture. In the 0 sequence these numbers are pretty much meaningless (I made sure I got everything, but not in any particular order). Many of the images show blue reflections. These are mostly from the blue activity light the camera I used has. I have converted all the images to JPEGs; the file names reflect that, but in the text here only the number part of the name is mentioned (00709 not 00709.jpg). References to chips as numbers with an apostrophe before them (as in '164) means the chip is from one of the 74xx lines. For example, '00 could mean 7400, 74LS00, 74HCT00, 74ALS00, etc. In some cases the exact chip numbers are readable in the images. For power, I have a wallwart (see image 00709) connected with a short extension cord to a powerbar (see image 00730). I connect to the wallwart's output via a clip lead on the outer shell of the barrel connector and a resistor lead stuck into the inner pin space. This is visible in 00539, though you have to know what you're looking for; the black object against the dark wood just to the right of the power bar is the barrel connector and the shiny wire connected to nothing up and right from it is the other lead of that resistor. The red and yellow clips are clipped onto the end stuck into the connector. The black plastic object just below the red and yellow clips is the clip clipped onto the outer shell; this is hard to see because of the wires in front of it. This power is fed to two things. Power to the logic circuitry is fed through four resistors (a 1/5 ohm which I use as a current-sense resistor and three large brown high-power six-ohm resistors which function solely to drop voltage down to some 7-8 volts - the former is on top of the blue box, barely visible end-on at the top of 00539; the latter are the three brown cylindrical objects in 00539). This then feeds a 7805 which is out-of-frame for 00539 but can be seen in the upper right of 00404 (it's got a heat sink on it and is seen from directly above). Power is also tapped off, before the dropping resistors, to produce high voltage (which here means some 30-40 volts) for the VFD. Except for the red clip on the lead stuck into the wall-wart connector, this is out of frame for 00539. There is a three-ohm resistor involved, which is the thing in the middle of 00586; everything else involved in this is on the breadboards and will be discussed in turn. The host computer interface is a serial line. The wires for this are visible as left-to-right bi-colour wires in 00539, in front of all the power connections. Most of the pins are not connected anywhere (the wires are stuck into otherwise unused breadboard tie points); the only pins used are ground and the data wire the computer transmits on (whether this is TxD or RxD depends on whether you prefer to think in a DTE or DCE mindset). The serial-line wiring is partially visible in many other pictures; it is perhaps clearest in 00866 (an overview shot of the power wiring) and 00484 and/or 00987. The serial line is used, from the computer's point of view, to carry only one bit per character. The computer sends either 0x00 or 0xff, which amounts to either a long pulse or a short pulse on the data line. The voltage level is cleaned up with a transistor, visible in the upper left of the breadboard in 00386 and 00987. This is then used to trigger a '123 (just to the right of the transistor), which is adjusted so its pulse expires roughly midway through the character. The ending of this pulse clocks the data line's state at that point into two cascaded '164s (just to the right of the '123). It also triggers a cascade of two more '123 one-shots (the other half of the first one and one half of a second, the second being visible on the second row of 00987, around breadboard pin row numbers 40-50). These later one-shots have much shorter pulse widths (about two orders of magnitude shorter); the first functions solely as a delay, to give other logic settling time; the second is combined with the low four bits of the shift register outputs in an 8-input NAND gate operating as a five-input gate (three inputs are wired high) - this is the '30 visible as the fourth chip on the top row of 00987. (The second row of 00987 has a chip at the left, visibly marked 74HCT164N; this is an additional 8 bits of cascaded shift register, which former versions of the circuit used but the current version does not.) The upshot of this is that the serial line data is accumulated in a shift register; when four 1s appear in immediate succession, an additional pulse is generated. Let's put this aside for a moment in favour of describing the matrix scanning for the display. Data is kept in a 21L02, which is a 1Kx1 static RAM. This is visible in the upper right of the breadboard, near the 7805; the best pictures for this are 00404, 00431, and 01022. (It's perhaps most visible in 01022; it's under a bunch of seven 33K resistors.) There is a 555, visible at the right edge of the breadboard in 00340 and 01105 - it's the only 8-pin package in the whole circuit. This is configured as an astable, running at close to 110KHz. This drives the '4017 (that's a 74HCT4017, not whatever CMOS chip a 4017 is in 4000-series logic) just to the left of it. The '4017 is a Johnson decade counter; in this case I'm using it to turn the about-100KHz clock from the 555 into ten about-10KHz clock phases. (Eleven, actually; the chip has ten outputs which pulse in a ring, each pulsing for the width of just one clock pulse, plus an eleventh which outputs a square wave at 1/10 the frequency of the input, effectively the OR of five consecutive ring outputs.) Ten of these eleven phases are used, but, for the moment, we're interested in only three of them. Clock phase 9 clocks the '4040 counter just to the left of the '4017. The '4040 is a simple 12-bit counter; I'm using only the low seven bits of it. These bits drive (indirectly - see the discussion of the write circuit, below) seven of the address pins of the 21L02. Clock phase 1 is used to clock the data-out from the 21L02 into a '595 at the bottom right of the breadboard, perhaps best visible in 01105. This is an 8-bit serial-in parallel-out shift register and an 8-bit latch in a single package. Phase 1 clocks the shift register; phase 2 is NANDed (half of the '21 visible just to the left of the '4040) with the low three bits of the '4040 to clock the latch. The upshot of all this is that, every 8 counts, the last 8 bits of data from the memory appear on the output pins of the '595. The next four bits of the '4040 counter are fed to a '174 latch, clocked with the same thing as the '595's latch; the '174 is the second chip to the left of the '595, just to the left of the big '154. The resulting four output bits drive the '154, which is a 4-to-16 decoder. The VFD is a matrix-scan device. There is a filament (ie, a directly-heated cathode), then eight grids, one per digit space. Behind each grid is a set of anodes with phosphors. If the grid and anode are both driven positive, electrons strike the anode and make it glow. Normally, these are driven as matrix-scan devices, scanning the digit grids and driving the anodes with the segments for the digit in question. This circuit reverses this, scanning the 16 anode lines and for each one driving the digit grids for the digits for which that segment should be lit; this could be swapped around, and I've considered doing so - instead of a 4-to-16 decoder and an 8-bit shift register, I'd want a 3-to-8 decoder and a 16-bit shift register. With the chips I have on hand, this would be fairly easy to do. The outputs of the '154 are the 16 scan lines, controlling the segment anodes; the outputs of the 595 are the other side of the matrix, controlling the digit grids. The VFD itself can be seen perhaps most clearly in 00179 and 01268; it has sixteen segments per digit space. (00179 also shows part of a seven-segment VFD which is shown on its own in 00140; a former version of this circuit was designed to drive that one instead. The seven-segment one has 11 digit grids and 9 segment anodes; the 11th digit is the "M" "A" column to the left of the leftmost digit. Presumably it was designed for use in a calculator.) Most of the discrete circuitry visible on the second breadboard in 00260 is converting between the 5V TTL logic levels used by the bulk of the circuitry and the 30-40 volts used to drive the grids and anodes of the VFD; there are 24 copies of the same small one-transistor circuit to convert a single line. Also, partially visible in 00260 and much more clearly visible in 01200, at the left of the second breadboard, are two yellow capacitors and two 1N914 diodes (one of them with white spaghetti on its leads). These form a voltage doubler circuit, driven off circuitry on the main breadboard, which supplies the high voltage. But, of course, scanning and displaying the contents of a RAM is of little use unless there is some way to write into that RAM. Most of the rest of the logic is for that. The first thing we need to do is change the applied address. Recall that I said, above, that the '4040's outputs drive the 21L02's address pins only indirectly? This happens through a '245. Two '245s are visible in 00404, 00431, and 01022, at the right end of the second row of the breadboard, just below the 21L02. You may also note seven resistors from each of them, up to the row above. During normal scanning, the right-hand one is driving the address lines, with the left-hand one high-Z. (The resistors are me being paranoid. I was just unsure enough of myself that I did not want to risk having both chips trying to drive the lines at the same time and probably blowing output drivers. Those resistors are 100 ohms, low enough that the '245 can drive the 21L02's address pins just fine even against the 33K pullups that straddle the 21L02, but high enough that even if the two '245s start arguing, it shouldn't blow any output drivers.) During a write, the right-hand '245 is set high-Z and the left-hand one drives the 21L02. The 33K pullups on the 21L02's address pins are there because, as explained below, there are two periods during which the address pins are driven by neither '245; those pullups keep the pins from floating. Now, let's go back to where we left the serial-line interface logic. We'd left that at a 16-bit shift register and a pulse produced midway through the character when we've just clocked the last of four 1 bits into the shift register. That pulse is used to set a flip-flop. This is a '109 on the third row of the main breadboard, third chip from the left, perhaps most visible in 00361. (The metallic-looking circular thing just up and right of it is a clear-package LED, not lit, seen end-on.) The other half of that '109 and both halves of the '109 just to the left of it are clocked with clock phases 3, 4, and 5; the effect is that, after an incoming character sets the first flipflop, it ripples into the next three with the next clock phases 3, 4, and 5. The output of the first of these three flipflops, the one clocked with phase 3, is used to control the output enable line of the right-hand '245 mentioned above. The second one is combined with the first (by two of the gates in the '00 quad NAND on the last breadboard row, the chip flanked by discrete transistors, just below the second '109) to generate the output enable for the left-hand '245. (The reason for not using the flipflop output directly is that, while the sequencing does not try to enable both chips at once, on power-up the flipflops may come up in an `impossible' state, one that cannot be generated during operation. While any such state will be fixed within a few clock cycles, that's hundreds of microseconds, quite long enough to cause trouble if the '245s argue over the address lines. Using both the resistors and this NAND was somewhat in the nature of belt-and-suspenders: prevent trouble two different ways and you will be OK even if one of them doesn't work as expected.) The third flipflop's output is the write-enable signal for the 21L02. Fortunately for us, the 21L02 has separate data-in and data-out pins, so we don't have to worry about tri-stating the data signal as well. Then, to finish the write sequence, clock phases 6, 7, and 8 clear the various flipflops: first the 21L02's write signal, then the left-hand '245's output enable and the '109 half set by the serial-line circuitry, then the right-hand '245's output enable. The address bits feeding the left-hand '245 come from other, higher, bits from the 16-bit shift register fed by the serial line; the data-in bit to the 21L02 is another of those. We use only three of every four bits above the bottom four, so we can ensure we don't get four 1 bits in a row until we mean to even if we're writing to a bit address that involves lots of 1s. (We need only 8 bits, seven address and one data, and we have 12 bits available, so using three out of every four not only works but gives us one bit to spare.) Note that the whole write cycle happens during clock phases when nothing is happening in the scanning circuitry. This means that the scan is not disrupted by the write; there is no display glitch as the data-out line does not display the expected data for a moment during a write. Also, a full cycle through the '4017 takes about a ten-thousandth of a second - about 100 microseconds. The serial line is run at 38400 baud, so each character takes 1/3840th of a second, or some 260 microseconds. Thus, after a bit is clocked into the shift register, if it's a write, the write starts within at most 100 microseconds and is complete before 200, whereas another bit can't come along for well over 200. This means there is no concern over another serial-line bit arriving before the last one has been fully handled. The '555 is actually oscillating faster than 100KHz, so we have even more time than this analysis indicates. The chip to the left of the two '109s is an '04, a hex inverter. This is used to convert the high-going clock-phase pulses from the '4017 to the low-going pulses necessary to clear the '109 flipflops. The LED provides a visible indication of something happening when a character arrives on the serial line. The transistors flanking the '00 on the bottom row, and the remaining two gates in the '00, are used to generate both the filament drive for the VFD and the AC to drive the voltage doubler that gives the high voltage. The square-wave output of the '4017 (which is about 10KHz) is fed to one of the '00 gates (both inputs tied together so it is operating as an inverter). This then drives the other gate, which is wired similarly. The resulting two phases then drive six 2N3904s (NPN transistors). There are also four 2N3906s (the PNP analog). Two of the 3904s just drive two 3906s each. The left-hand four transistors are the HV drive oscillator; the 3906s there have their emitters tied to the undropped, unregulated input voltage through the three-ohm resistor mentioned above. (The three-ohm resistor was intended to deal with nanosecond-level glitches derived from the switching time of the second gate; for a very short time, it's possible for both transistors in one pair to be turned on. The resistor was intended to limit damage if/when this happens. So far I've seen no reason to think any damage is occurring, but I haven't cut out that resistor, either.) The resulting collector join points drive the voltage doubler mentioned above, converting the input power into about 30V for the VFD. The filament drive circuit is similar, except that the 2N3906s have their emitters connected to +5V by a 68-ohm resistor, and of course the resulting push-pull power drives the filament instead of the HV voltage doubler. (The 68-ohm value was determined empirically, as the smallest value that does not make the filament glow visibly. Larger values, like 100 ohms, work, but the resulting display is visibly dimmer.) There are eight capacitors in the circuit which are not covered in the above. Four of them are basic power-supply filtering (two next to the 7805 and two on the right-hand vertical strip) and four are decoupling caps, probably unnecessary but added when I was trying to debug various problems (one above the '164s forming the serial-line shift register, one two chips to the right of the first, one directly at the 21L02, and one straddling the right-hand '245). The '555 has two capacitors next to it rather than just one because it was easier to connect two caps in series than to find a cap of half the capacitance. The 1xxxx series of images show the resulting circuit in action. The gaps in the numeric sequence are times when nothing interesting is happening, when the display is not changing. On power-up, the 21L02 holds "random" data. It actually is semi-predictable, in that it tends to be similar for any given 21L02, but it is not otherwise deterministic. 10117 shows the state it powered on in. Then I had the computer write all 128 bits; since writing a bit takes 16 characters, they are written at the rate of 240 a second. The camera appears to run at about 10 fps, so about 24 bits are written per frame, and a complete write of all bits can be expected to take some five or six frames. In this case, 10117 is the initial state. 10118 is the first frame showing any differences; this continues until 10124, which is the first frame showing the final state. Then I sent another string, from 10171 through 10178. Because I sent the bits in address order, and the scan is reversed from the usual per-digit scan, the visual effect is that all character positions mutate in parallel rather than each one changing completely before the next one begins. Then 10217 through 10220 show the fade-out when I unplug power. 10238 through 10242 show a power-up sequence. Then I started a clock program I wrote, which maintains the time on the display. Obviously, it can update the display by writing only the bits which have changed each second, which makes each update much faster than the half-second or so that writing all bits takes. As a whimsy, rather than having it write all 128 bits on the first update, I made it effectively skip the first update, so it just writes changed bits, leaving unchanged bits holding whatever they held. However, it does enforce a write of one bit each update (= second), cycling through all 128 bits, so after 128 seconds the display is fully up-to-date. The sequence from 10284 through 11546 is this, from first starting the clock program through full correctness and a second or two beyond. Then 11710 through 11717 demonstrate letters A through H in a simple font I devised for the display, 11750 through 11756 letters I through P, etc: 11790-11797, Q through X; 11844-11850, YZ012345; 11994-12001, 6789+-*/; and finally 12170-12172, power-down. (I have a few more characters designed, but I couldn't easily recall exactly which ones and it didn't strike me as critical to show them all off.) /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mouse@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B