Copyright © 2007 Mark Feldman. All Rights Reserved.
NES/SNES Controller Overview
The original NES controller essentially consists of a single 4021 chip, i.e. 8-bit parallel-in serial-out shift register with asynchronous load. The NES console sends a signal to latch the button states then shifts them down the data line one at a time. The SNES works basically the same way but with an extra 4021 in series to accommodate the additional buttons.
The pin-out for the SNES controller is as follows (courtesy of everything2) :
Pin Description Color of wire in cable
=== =========== ======================
1 Ground Brown
2 ? no wire
3 ? no wire
4 Serial data Red
5 Data latch Orange
6 Data clock Yellow
7 +5v White
7 | o o o o | x x o | 1
| | | | |
| | | | +-> Ground
| | | +------------> Data
| | +---------------> Latch
| +------------------> Clock
To read the button states the data latch, which is normally held low, is brought high by the console for 12uS and then returned low for 6uS. A series of pulses are then sent down the data clock, which is normally held high. Each clocking pulse is held low for 6uS then returned high for another 6uS. Each time the clock transitions from high to low a button press state can be read from the serial data port; a low state indicates the button is being pressed. The sequence of buttons returned on the SNES is B, Y, SELECT, START, UP, DOWN, LEFT, RIGHT, A, X, LSHOULDER and RSHOULDER.
Important: An earlier version of this article stated “The NES is identical but with only the first 8 buttons being returned”. This was based on a document I obtained which turned out to be incorrect. Implementing the NES version of the controller myself revealed that the controller returns buttons in the order A, B, SEL, START, UP, DOWN, LEFT, RIGHT. I’ve developed a NES version of the firmware to accommodate for this difference.
The wireless chip I selected is the TXC1, which pairs up with the RXB1 receiver chip. The transmitter is extremely tiny, has very low power requirements and has a surprisingly long range. Its operation couldn't be more simple: whatever you send to the transmitter data pin appears on the receiver data pin.
The TXC1 uses ASK encoding, which is simply an amplitude-modulated carrier wave. If the data line is kept low for too long then noise starts to appear on the receiver, which I'm guessing is due to some automatic gain circuitry trying to compensate for what it thinks is a weak and/or lost signal. In any case, the simple data sheet provided for the device specifies that the data rate is between 300bps and 4k-5kbps. Exactly what constitutes a "bit", and how long you can go without sending one, isn't exactly clear.
Wireless Packet Format
I use a very simple packet format for streaming across the wireless link. First of all, I use a fixed data rate of 4000 bps, as specified in the data sheet. Each packet consists of 14 bits: a start bit (1), 12 data bits (one for each button) and a stop bit (1). Packets are separated by 14 bits of 0. The total distance between the start of each packet is therefore 28/4000=7mS exactly, with the first 3.5mS used to send the packet itself.
In theory, this should be almost enough to maintain 300bps. Each packet contains at least two "bits" (the start and stop bit), and since packets are sent at 7mS intervals we wind up sending at least 285 bits every second. As an added layer of protection I alternate the polarity of the 12 button bits. When no controller buttons are being pressed the wireless packet looks like this:
The upper trace is the signal being sent into the data pin on the transmitter chip, the lower trace is the signal as it appears on the receiver chip data pin. Pressing a controller button toggles the state of the corresponding data bit in the packet (i.e. one of the middle 12 bits). As you can see, there is bandwidth limitation somewhere along the transmission path that results in the received pulses having longer rise and fall times. This doesn't really matter, as pulse states are read roughly half-way along the bit anyway.
Since the controller is effectively a "dumb" logic device, a microcontroller must be added to generate the clocking signals normally sent by the console. The PIC I've chosen to use is the Microchip 16F84A running at 4MHz (20MHz crystals are smaller but increase the power requirements of the circuit). There are several 8-pin PICs that are much smaller and would do the job just as well (e.g. the 12F509) but the 16F84A is most popular among hobbyists and more likely to be readily available. If you're feeling adventurous then the code can be easily modified to accommodate other PICs.
The code for the microcontroller is fairly straightforward, it sits in a loop repeatedly reading the buttons states and sending the data to the wireless transmitter chip. Two PIC pins are configured to control the latch and data signals, a third pin reads the button states while a fourth sends the raw data to the transmitter. The execution time of the main loop is 7mS exactly. The first 3.5mS are spent sitting idle and reading the button states, the second 3.5mS are spent streaming a data packet to the transmitter. This results in a transmission rate of about 142 packets-per-second.
The 4021 chip inside the controller can operate over a very wide range of frequencies, so it's not really necessary to maintain the exact same timing as the original console. Even so, I chose to do so anyway. There's always a chance that some weird hardware clone is out there and expecting to be clocked at the "normal" rate, and since there are plenty of cycles available on the controller PIC anyway I figured I may as well do it right.
At 4MHz the PIC executes 1 million instructions per second, i.e. each instruction lasts 1uS. Timing during during the reading of button states from the controller must therefore be carefully controlled; a 6uS pulse allows for just 6 single-cycle instructions to be executed.
The power requirements of the modified controller circuitry can broken down as follows:
Note that the transmitter chip is officially rated at 10mA, and that was also what I measured when sending a continuous stream of pulses. ASK encoding simply modulates a carrier by the value of each data bit; the lower-than-expected power the chip requires in this circuit is apparently due to the fact that it is only sending high pulses approximately 30% of the time.
The power source that I've selected for this project is a replacement IPod-Mini lithium-ion battery which can be purchased from any consumer electronics retail outlet. There are several features of this device that make it ideally suited to this application:
This last point is important. Undercharging can damage a battery while overcharging can result in them leaking or exploding...not the kind of thing you want happening inside a device you hold in your hands!
With regards to charge and discharge characteristics, I had to revert to careful experimentation in the absence of data sheets. A rapid discharge was achieved by hooking the battery up to an electric motor; the battery took 1 hour and 10 minutes to drain, during which time internal electronics apparently regulated the amperage at a fixed rate of 185mA. The voltage remained more or less constant before quickly dropping at the end, at which point the electronics automatically switched the battery off:
To charge the battery, a regulated 4.5V power supply was connected directly to the terminals and the voltage and current measured over a 3 hour time frame. This was a deliberate attempt at overcharging in order to see how the internal electronics reacted. As you can see, the final voltage slightly exceeded the battery rating while the current flowing into the battery started at 180mA and dropped exponentially. There was no detectable increase in battery temperature at any point.
Important: While recharging the battery in this manner seems to work, it's almost certainly outside the range of conditions that the battery was designed to be operated under. While internal electronics have been added to reduce the risk of fire and/or explosion, they probably weren't intended to be used to regulate a charge cycle...a fact apparently supported by the exponentially decreasing flow of current. The only safe way to recharge an IPod mini battery is to place it inside an IPod and charge it properly. If you do decide to charge it in this manner then I recommend that you don't exceed 4.5V (charge at 3.7V if you can), that you wait until the battery cuts out before recharging (even though it reduces battery lifespan) and that you never recharge for more than 3 hours. Also keep in mind that every charge cycle could very well be damaging the battery, so don't be surprised if the lifespan is considerably shorter than expected. Standard disclaimers apply, you assume all risk and liability.
Update: I've received a number of emails from someone regarding the safety issues of recharging batteries in this manner, I strongly suggest reading the information he has passed on to me before deciding to recharge the batteries in this manner.