Thursday, November 1, 2012

Oscar Wilde does Electronics

He did describe the event himself, but it is more usually told as a story; Oscar comes down to lunch one day and a friend of his asks, "Hard at work all morning, were you?"

To which the novelist and playwright responded "Indeed.  I just inserted a comma."

After lunch he vanishes back upstairs and is not heard from until dinner.  At which point the same friend asks "Another productive session, I hope!"

Unperturbed by the sarcasm, Oscar replies, "Most productive.  I deleted the comma I had inserted this morning."

Well, Oscar's excuse was that he was a perfectionist.  My excuse is procrastination.  Plus a middling amount of physical and mental exhaustion from opening weekend.  Being both a designer and a show operator takes a lot out of me mentally and emotionally.  And the long hours (and short rations) don't do much good for me physically, either!

So this morning, I inserted a resistor.

Well, not exactly.  Here's the ugly board as of early last week (when I simply had to stop and switch to soldering back together wireless microphone elements and transmitters):

And here it is now, with the ICSP finished (I did that last week), and the Recom DC-DC converter and Supertex HV5812 wired in.  Plus a resistor for filament voltage.

This thing is really getting crowded!  And I still have to stuff in a speaker driver and the "tank" resistor required for the software capacitance sensor.  And, no...none of the I/O lines are soldered in yet, and that includes the 16 (!!) matrix connections from HV5812 to the VFD.

Because I've been through stuffing spaghetti too many times, my intent is to route the leads short and hot-glue the circuit board directly to the back of the front panel.  And once again, it would be better if I had made a two-part thin-shell casting so I could glue the circuit board down and route the leads in situ.

And next big project, I'll have a proper board fabbed.  This time I promise.

Anyhow, the reason for soldering the resistor this morning was to perform a basic functionality test of the high-voltage end of the circuit ("high voltage" only in comparison with the 5V regulated of the digital side.  The Recom is putting out 24VDC -- but it is enough to make the cathodes happy).

And here's the test:

Quite a mess, eh?

That's the ISP dangling there -- the USB cable is disconnected because the high-voltage end has to run off the 9V rail.  There's only one HV output hooked up, which I jumpered to a random cluster of cathode and grid leads.  The other jumper is supplying filament voltage.

The code is almost entirely bogus.  It sets the Data pin HIGH, then toggles the Clock pin, followed by the Strobe pin, 20 times (the word width of the shift register).  Then after a delay statement, it toggles the Data pin LOW and goes through the cycle again.

I was really, really expecting to have to juggle the timing more.  Even have to delve into proper serial (I'm really not sure how to use any of the built-in serial libraries on an odd-length word).  But it fired up first time; the random segments I clamped in the jaws of the jumper turn on and off at regular intervals.

(This doesn't actually confirm I'm writing a good word to the latching buffer of the HV5812, but it is extremely suggestive.  I consider it good enough to go forward with adding the rest of the connections).

Now all I have to do is write the software!

Well, and put the rest of the connections in.  I see no reason to add the complexity of terminals so this will all be hard-soldered.  And since the VFD is the greatest mass of wire involved, what I really have to do is turn a little to solder up the speaker driver (and test the tone library), so I can nail down those connections first.

But it is progress.  A few more hours of soldering, and then if I am lucky it will all be software.

The VFD is wired into the board now.  Plus since the last pic I added a TIP120 as a square-wave speaker driver, the 1 meg resistor for the capacitance sensor, and a decoupling cap on the ATmega's power pins.  Since I haven't touched the software that's in the ROM, the entire VFD now flashes "888" on and off.

The software is more of an adventure.  The assumption is, again, it would take me longer to find, understand, and adapt someone else's code than it would to write my own from scratch.

I am thinking, though, based on a recent discovery I may bypass the built-in "digitalWrite" function and do a direct pin write.  Still; at a 16 MHz clock even 56 CPU cycles per pin write means I write a whole word to the VFD in 16,000,000 /(56 + 56 + 56) x 8 x 8  = 1,500 times a second.  Which means even if I assume 20x the time (for lookup tables and housekeeping and whatever) the flicker rate should still be below human perception.

The current idea is to break the write two bytes as one byte per pass, doing this one time for each character to be displayed out to the total display word length.  On each pass, write a HIGH in the right incremented spot to turn a grid pin high, and write out (using the bitRead function), a serial string pulled as a binary byte from a character lookup table.  The original word is loaded into the buffer as an indexed char string.

This should make it easier to do the high-level programming; I simply have to make up the "word" (whether it is "anthrax" or a made up numeric value) and then the code will chop it into characters and use a lookup to translate it into proper seven-segmentese.  Unfortunately, although the HV5812 latches, the display is multiplexed; meaning I have to call the display routine constantly in order to display anything other than a repeating decimal.

I did flirt with ideas of lossless compression prior to display write; such as, writing to every digit that had the top segment lit, then ever digit that had the top left segment lit...but I decided these were too silly.  I don't need that kind of optimization at my clock speed!

.....and my math is off, again.  I have to write the width of the shift register for each digit with lit segments.  The first version I calculate refreshed about 200 times a second. But it turns out I don't need to pulse the Strobe pin with each clock; I can hit that at the end of a digit write.  That saves almost half the calls to digitalWrite().

Also, it was necessary to use the Blanking pin to enable some interdigit blanking (otherwise there was a lot of garbage showing up.)  So the current code turns on Blanking, writes a digit, pulses the Strobe pin to lock, turns off Blanking, and holds for a 250 micro-seconds.  Even with that delay, it should be refreshing about 400 times a second. 

And, you know, now that I'm not running the Strobe pin with each clock pulse, I could probably figure out a way to use the built-in UART instead of using my own inefficient version.

But it writes alphanumerics now.  And big surprise; the alphanumeric lookup table worked write first time (well, second time; I had written all the binary in MSB order when they needed to be LSB!)

No comments:

Post a Comment