Archive

Electronics

♫ SEEEEEEEEEGAAAAAAAAAAAAAAA!!! ♫

Ahem.

To complement my previous post, here is a schematic of the regular Sega Genesis controller. You could actually make one of these from scratch from non-specialty items; unlike the NES controller, which uses a proprietary 7-pin connector, Sega used the common-as-dirt DE-9 female D-sub connector, following in the footsteps of Atari both physically and electrically.

The circuit above could be built in fairly little time using almost exclusively items from RadioShack, if it’s well stocked. There’s probably still a DE-9 connector kicking around there. You’re not likely to find a 74HC157 in a local store, but it’s easy enough to make a 2-1 mux using 74HC00 quad NAND ICs. If you can’t track those down, it appears to be possible to make a non-inverting 2-1 mux in as few as 9 or so transistors (probably MOSFETs), but my personal recommendation, which is more time-intensive but overall less masochistic, is to have a working stock of a key few 74HC-series ICs available for when you get curious.

If I were to do it this way, I’d pull a couple of 74HC00 from my stash. A 2-1 mux—let’s call it MUX(M,N,S)—implements the expression MS OR N(NOT S); that is, “reflect M if S is high; reflect N if S is not high”. That’s equivalent to the expression (M NAND S) NAND (N NAND (S NAND 1)), which is four NAND gates. One 74HC00 = 4 NAND gates = 1 mux.

A 74HC157 packs four of these, but only two are genuinely in use. Most game software probably ignores the left and right signals while the select line is low, so it’s most likely okay to pass the left and right buttons directly out pins 3 and 4 of the port (as is already the case with up and down). As for the rest, pin 6 would be MUX(A button, B button, select) and pin 9 would be MUX(start button, C button, select).

Of course, as if it even bore mentioning, this controller would be a cinch to implement on an Arduino-like platform using just a DE-9 breakout cable. (Hint: Vcc on pin 5, ground on 8, an input on 6, and the rest are outputs.) Do this only on a temporary basis, though—you have better things to do with an Arduino. :-)

A couple of weekends ago I found myself in conversation with Jon, my brother-in-law, a vintage game systems collector and proud owner of an Action 52 cartridge, about NES controllers—specifically, how all eight buttons can be crammed down only seven controller pins (a trivial setup would require nine). I just happened to know most of the mechanism already and gave him the surprisingly simple rundown. I got curious about the parts I didn’t know, so here’s a digest of my research.

Read More

Do you get a lot of use out of the scroll wheel on your mouse? How about that Griffin PowerMate you got for your birthday? If so, chances are that rotary encoders are responsible for some of the joy in your life.

15-period code wheel

A 15-period code wheel for a rotary encoder. Believe it or not, this hypnotic image is an important part of an analog-digital converter! Generated using the script at the end of this post.

Read More

First of all, I got the demo USB peripheral running. The thing has a button and a light; software on a Windows PC can switch the light and read the button. Also, in a surprisingly unrelated fashion, I had a lovely experience at Fry’s yesterday that somehow made me optimistic on behalf of the casual hobbyist. I shall describe both forthwith.

Read More

Somewhat out of my current character, I lead with a lyric from They Might Be Giants:

Turn it up, turn it down
Turn it up when the cold brings you down
When the heat bothers you turn it down
Turn it up, turn it down

— They Might Be Giants, “Thermostat”

This is a song about a thermostat, a brilliant device contrived in 1883 to either turn off or turn on a heating/cooling system in order to favor a certain temperature. The traditional version of the thermostat is among the simplest examples of a negative-feedback control system, a very important class of device.

An “on-off” control system basically repeats the following ad infinitum. The following example is for a thermostat controlling a heater (with a generalized version in parentheses).

  1. Is the current temperature the same as the temperature we want? (Is the current state the same as—or similar enough to—the desired state?)
  2. Which direction, higher or lower, is the desired temperature relative to the current temperature? (How is the current state different than the state we want? Which direction should we be going?)
  3. If the right direction is higher, am I already heating? If lower, am I already not heating? (Am I already moving in the right direction?)
    • If so, then we’re already doing what we need to be doing. (Our effort is already in the right direction.)
    • If not, switch off (if on) or on (if off). (Switch our effort to the right direction.)
  4. Start over.

Note that the typical thermostat is an on-off control, meaning that there are exactly two modes to its operation—0% and 100%. In the middle of winter, when it’s 68°F in your house and you decide to crank it to 78°F, well, first of all, you must like it hot and enjoy high energy bills; 68′s always fine in my house. Anyway, you as a human know that you’ve turned up the set point by 10 degrees, which is a lot to do at once. What you may or may not have realized is that your furnace isn’t making any special effort to work faster than if you’d only turned it up 2 degrees. It’s just going to stay on as long as it takes to do its job and then kick off.

This is because an on-off system asks “if I’m too far in either direction, which direction?” but not “and by how much?” This is the domain of a linear control system.

One might liken a linear control system with a human being with his foot on the accelerator pedal of a car. (For the time being, we’ll ignore that the brake is also pretty handy for slowing down a car.) The new process is as follows:

  1. Is my current speed the speed I want? (Same as 1 above.)
    • If not, continue.
  2. Which direction, faster or slower, is the desired speed relative to the current speed? (Same as 2 above.)
    • If faster, push the pedal harder (if possible).
    • If slower, ease off the pedal (if possible).
  3. In inexact terms (this is important), how different than the desired speed is the current speed? (What is the error, the magnitude of the necessary change?)
    • If the desired speed is a little faster, push the pedal a little harder.
    • If the desired speed is a lot faster, push the pedal a lot harder.
    • If the desired speed is a little slower, ease off the pedal a little.
    • If the desired speed is a lot slowed, ease off the pedal a lot.
  4. Start over.

What’s remarkable about a system like this is that it’s inexact by design. For example, if I’m driving 60mph and need to 70mph, I’m going to push the pedal harder. But how much harder? Can I state it with an exact measurement of radians per mile per hour? No. (It could possibly be done, but I hope nobody is that bored.) So I just push the pedal (control) and see what happens (feedback). If I end up too slow, I push harder. If I undershoot, I let up on the pedal. This trial-and-error is called oscillation and a system generally benefits from it being kept to a minimum.

The system seems to work in situations where

  • the directions of feedback and control have a consistent relationship; e.g. pushing harder always means increase in speed and, conversely, an increase in speed requires pushing harder
  • the magnitude of change at the control is at least somehow proportional to the magnitude of the resulting change in the feedback; e.g. pushing a little or a lot harder means going a little or a lot faster, respectively, with the ratio of change at the control to the change at the feedback being adjusted on the fly as necessary; if we push the pedal a little and the car bolts, we adjust our definitions so that pushing the pedal a little means a much smaller push than before

One application of this that I consider fun is a phase-locked loop (PLL), which is able to arbitrarily multiply a clock signal from e.g. a crystal. I’ve never messed with one directly, but the ones in some of the Microchip PIC devices are able to bump the 20MHz CPU clock to a whopping 96MHz, which is then divided (a much simpler operation) to 48MHz in order to implement the onboard USB peripheral.

If the driver analogy above made any sense, then PLLs are a piece of cake: For every 20 million pulses that are generated by the crystal, it has to generate 96 million pulses. Or, if you’re clever, for every 5 pulses from the crystal, generate 24—probably easier to count that way. It’s by no means trivial, but it’s straightforward.

Control: The PLL train is produced by a voltage-controlled oscillator (VCO), which is able to generate really, really fast pulse trains but must be tuned on the fly. (This can be replaced with some other form of controlled variable-frequency oscillator.) When it’s first kicked, it delivers a pulse train that is most likely not the right frequency.

Pre-processing: To correct it, the first thing we do is have available a frequency divider for each of the crystal (divide by 5) and the VCO output (divide by 24). A frequency divider is dead simple; for example, to divide a pulse train by 5, just do a transition on output for every 5 you count on input. Simple! Our goal is to make the pulse train of the crystal/5 match the VCO/24 as precisely as possible. When they match, the VCO output is exactly 24/5 of the crystal’s input. Then, we just pass the VCO output directly to wherever it’s needed.

Error: A phase detector sets about finding the difference between the VCO/24 and the crystal/5 trains, noting where the trains are not the same width as well as where they don’t line up even if they are the same frequency. A low-pass filter cleans up places where the difference is so slight that it should be ignored (i.e., where the differences are so insignificant that acknowledging them would hurt rather than help).

Feedback: The error value from the phase detector is fed back into the VCO.

And, as they say, viola…96MHz from 20MHz. Nifty, right?

If I get my way this weekend, I’ll have turned a PIC18F4550 into a bona fide peripheral. Just figured that a note or two about how this is possible might be in order…