EEVblog Electronics Community Forum

Electronics => Projects, Designs, and Technical Stuff => Topic started by: arantius on December 14, 2014, 01:27:42 am

Title: Wireless retrofit for video game controller
Post by: arantius on December 14, 2014, 01:27:42 am
Hi eevblog forum members.  I've been watching Dave for some time but never posted before.  I've spent most of my free time since Thanksgiving working on it, and I'm starting to think it might be done.  I'm hoping for some advice before I finalize anything.  Retrofitting game controllers to be wireless is not an original project by any stretch.  I've found others online (1 (http://andygoetz.org/2012-8-20-a-wireless-SNES-controller.html), 2 (http://www.ppl-pilot.com/SnesHack/index.htm), 3 (http://imgur.com/a/8H3Ci)) and even taken inspiration and ideas from them.  But this is largely a case of the joy being in the making.  Plus I think if I put my mind to it, I can produce a prettier final product.

I'm working on my second ever electronics project big enough to require a custom PCB.  And this one requires two!  I've read all the data sheets twice (OK, I skimmed the ATMega sheet ...) and tried my best, but I'm still quite the amateur.  I'd love any suggestions or corrections anybody would like to make.  I know I've made some compromises due to physical constraints, but there's others that I may have missed completely.

Since this is a wireless project, there's two parts to it.  First the simpler one, the receiver side.  The schematic:

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/rx_sch.png)
(Scalable PDF (https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/rx_sch.pdf) version.)

Overall straightforward.  An ATMega microcontroller, hooked up to:
I'm not worried about this one really.  Where it gets interesting is the board.  I measured carefully, and if I trim off some of the internal bits of it, I'm convinced I can fit this board inside the plug that the wired controller originally used to hook up to the console.  The indicator LED even fits in the hole where the wire used to come out.  Awesome!  But I had to really squeeze to fit it all in there:

Front:
(https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/rx_brd_f.png)
Back:
(https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/rx_brd_b.png)

This is 1.13 by 0.74 inches.  I've only got one bypass cap.  I'm not sure I could fit a second on there (where it needs to be) and still be able to route all the traces.  But it's simple and small enough that I'm pretty confident it's OK.

Then comes the transmitter half, which goes inside the controller:

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/tx_sch.png)
(Scalable PDF (https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/tx_sch.pdf) version.)

Here I'm using the same LDO regulator (http://www.ti.com/lit/ds/symlink/tps79301.pdf) to power the nRF daughter board.  I was powering the ATMega from that as well (lower voltage = less battery consumption), but ended up running it straight from the battery.  Plan there is to use the ADC to compare the internal 1.1v reference to AVcc as a battery gauge.  And the extra power usage should be minimal.  Both sides' controllers will be running off of the 8MHz internal RC clock.

What I'm really concerned about here is the battery charging circuit.  Am I missing something important?  I don't want to blow up a LiIon (and I can't fit much of anything else inside the case).  Do I need anything besides the charge controller (http://ww1.microchip.com/downloads/en/DeviceDoc/20001984g.pdf) and its support caps & resistor?

Besides that: same RF daughter board, same ISP programming header, same reset and SPI enable pullups.  The indicator LED is combined inside the pushbutton power switch here, and a 4-way 3.5mm jack will get charging power in.

The board again is interesting:

Front:
(https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/tx_brd_f.png)
Back:
(https://dl.dropboxusercontent.com/u/6784911/nesRF/v0/tx_brd_b.png)
(Shrunk a bit, click for full size.)

This one is 4.96 by 1.77 inches, and again I don't have much of any control about that.  The particular shape of the perimeter and the location of the mounting holes are, of course, beyond my control.  As is, generally, the support structure elsewhere.  The pins that used to do stress relief for the wire come out, to make space for the switch.  As does some of the plastic around the opening where the wire left the case, to fit the charging port.  (Which is why I picked the 3.5mm connector; plus I already have some USB adapter cables from other devices.)  The board also extends a bit further than the original, into the space where some of this plastic was, so I can mount the switch and jack at exactly the right depth relative to the case (visible on the bottom layer image).

I made my own footprint for the carbon pill switches for all the buttons, except the two shoulder buttons where I plan to reuse the original daughter boards (those of course being 90 degrees orthogonal to this board.)  KiCad/pcbnew hates that, complaining about unconnected pads all over, but it's the best I could do, and as far as I can tell even checking the gerbers, it looks like it will be a solid connection. Each of those is made of seven overlapping (in two groups of course)

I plan to ENIG this board so I'm not mashing the carbon pills directly against exposed copper (or more likely factory solder plated copper).  The battery will tuck in some empty space near the bottom left (as viewing the front board layer, around where the project text is), there's a bit of space in the case where the PCB doesn't extend there which makes that spot just big enough.  Wires will run about an inch from there to the battery connector.  About all the space that remains is filled with support structure or the 3 main parts (switch, jack, RF daughter board) I'm adding.

The battery I've got which will fit is a 130mAh LiIon (formerly for a small helicopter), which doesn't seem terribly big.  The power budget should be around 7ma whenever the indicator LED is lit (perhaps all the time, perhaps blinking if it turns out to be a big deal), 11mA when the nRF24L01+ (https://www.nordicsemi.com/eng/nordic/download_resource/8765/2/30081569) is transmitting (I plan on using pin change interrupts to transmit exactly when buttons are pressed/released), and (if I'm reading the sheet right, based on figure 35-2) around 3mA to run the ATMega.  If they all go full out nonstop, that's 21mA or around five hours of run time on 130mAh with headroom for efficiency losses and whatnot.  Which seems very usable.  In reality I'd be surprised if the RF board or controller spend more than 25% of the time running, so that seems fine I guess.  If I've done the math right there?

This will also be the first time doing SMD soldering for me.  I've already swapped out one part after I realized how small it was (another charging IC which was 8 pins in a 2x2 mm package!).  I've got some solder paste and no stencil but I'm pretty sure I can make it work with some patience.  Given the space constraints I expected, I figured I needed to take that leap.

Thanks in advance for anybody that takes the time to read all that, and huge thanks for any replies at all!
Title: Re: Wireless retrofit for video game controller
Post by: ajb on December 14, 2014, 03:51:12 am
Sounds like a pretty cool project!  A couple of thoughts:

- You could definitely fit another bypass cap on the receiver board.  You've already got the MCU at a 45 degree angle, may as well do that with your bypass caps.
- Since you're sharing the ISP lines with a peripheral, you should put a resistor between the RF module's MOSI pin and the MCU+Programmer.  This will prevent ensure that the programmer has priority on the bus during programming. 
- It looks like there's an enable pin on the RF module.  You should include a suitable pullup or pulldown resistor to ensure that the module remains disabled while the MCU is in reset.
- You don't really need to ground unused GPIOs on the MCU, but good on ya for thinking of that!  It's certainly good practice when dealing with other ICs.  Instead you can just set them as outputs or enable the built in pullup resistors to prevent them from floating.  They'll still float briefly during power on reset and programming, but this has the advantage of allowing you to easily put those pins to use during debugging or future hacking.  Never underestimate the value of being able to twiddle a spare GPIO while debugging!
- If you're going to be doing short flying leads to your connector/LED in the receiver, then there's no real need to use a standard header footprint for those connections.  You can just leave a single pad for each signal wherever's convenient if that makes your layout easier.  You can also probably use slightly smaller pads.
- Looks like you're running the receiver MCU at 5V and the RF module at 2.5V.  Are the RF module's inputs 5V tolerant at 2.5V?
- I'd consider moving the reset pullup closer to the IC, and include a footprint for a cap from reset to ground.  You probably won't need that cap, but better to have the footprint and not need it than need it and not have it, and empty footprints cost nothing.
- The ATMega328 is not spec'ed to run at 8MHz over its full supply voltage range.  You may find that you can only run it up to 4MHz as the battery runs low.
- Your LDO appears to have built in undervoltage lockout, so I'd consider moving the transmitter's MCU to the output of the LDO to make sure that total current draw is minimized when the battery voltage gets too low.  You can still do your primary battery management in the MCU, but it's nice to have the LDO's UVLO there as a backstop.  The MCU's current draw will also be slightly lower at 2.5V versus the raw battery voltage.
- For the soldering, opinions vary, but I wouldn't bother with solder paste if you're not doing a stencil.  With the footprints you have, you should do just fine by tacking a pin and drag soldering.  (Dave's shown that technique on the recent time circuit rework video, and there are other tutorials out there.)  Just be sure to use plenty of flux and have some solder wick on hand. 

Overall looks like you've put a lot of thought into this, good job  :-+
Title: Re: Wireless retrofit for video game controller
Post by: arantius on December 14, 2014, 06:28:26 pm
Thanks for your feedback!  Very helpful.

Quote
- You could definitely fit another bypass cap on the receiver board.
- If you're going to be doing short flying leads to your connector/LED in the receiver, then there's no real need to use a standard header footprint for those connections.
The LED's leads are 0.1 inch spaced anyway, so that 0.1 inch pin header makes sense.  But yes, the connection to the console will be wires which I can connect anywhere!  I've done that and also expanded the board out to a rectangle rather than that unnecessary L shape and yes, now I've got plenty space to add a decoupling cap on the Vcc/GND pins on the other side of the MCU.

Quote
- Since you're sharing the ISP lines with a peripheral, you should put a resistor between the RF module's MOSI pin and the MCU+Programmer.  This will prevent ensure that the programmer has priority on the bus during programming. 
I saw varying suggestions online about how to handle this.  Some say put a resistor on every pin.  I followed a simpler suggestion and put a pullup on just the "chip select not" pin.  I'll think about this, and probably double check on a breadboard before I try to stuff extra pull up/downs in.

Quote
- It looks like there's an enable pin on the RF module.  You should include a suitable pullup or pulldown resistor to ensure that the module remains disabled while the MCU is in reset.
That sounds like a great idea.

Quote
- Looks like you're running the receiver MCU at 5V and the RF module at 2.5V.  Are the RF module's inputs 5V tolerant at 2.5V?
Yes, the RF chip wants 1.8 to 3.3 volts for supply, but is tolerant of 5v on inputs.

Quote
- The ATMega328 is not spec'ed to run at 8MHz over its full supply voltage range.
I checked this when I was planning to run it from the 2.5v regulator output.  As I read the sheet, it can do 8MHz down to 2.4v, and I don't expect the lithium battery to ever drop below 3 volts.

Quote
- I'd consider moving the reset pullup closer to the IC, and include a footprint for a cap from reset to ground.
Done.  The shuffle above left room for this!

Quote
- Your LDO appears to have built in undervoltage lockout, so I'd consider moving the transmitter's MCU to the output of the LDO ...
I'll think about that.  Like I said I started that way.  But that would put the MCU's Vcc at 2.5v, and it's data sheet says the maximum rating for all pins is Vcc + 0.5v; sending the raw battery voltage into any pin to try to read it would then violate that rating.  But I strongly agree that UVLO is very worth having. 

So I went to check that detail, and I realize I've linked the wrong LDO sheet.  I was first planning on using the Toshiba TCR2EF (http://toshiba.semicon-storage.com/info/docget.jsp?pid=TCR2EF41&lang=en&type=datasheet), which does not mention any UVLO.  The TI TPS793xx I accidentally linked above was also in the running, and now it seems worth switching.

So the TI part does say "UVLO Threshold; Vcc rising; 2.25 - 2.65 v".  I didn't see that line until I went looking specifically for it!  And I'm not 100% confident how to read it.  It seems to say that it will cut the output when the input falls below the 2.25 to 2.65 volt range?  But if I get all the way down to 2.65 volts, I've already destroyed my LiIon battery (or come dangerously close) haven't I?  The safe lower bound seems to be 3.0v?

Perhaps I simply re-evaluate my LDO part selection, and concentrate on finding one with the right UVLO protection built in.  Then maybe a resistor voltage divider to safely measure the raw battery's capacity.
Title: Re: Wireless retrofit for video game controller
Post by: ajb on December 15, 2014, 04:10:51 am
Quote
- Since you're sharing the ISP lines with a peripheral, you should put a resistor between the RF module's MOSI pin and the MCU+Programmer.  This will prevent ensure that the programmer has priority on the bus during programming. 
I saw varying suggestions online about how to handle this.  Some say put a resistor on every pin.  I followed a simpler suggestion and put a pullup on just the "chip select not" pin.  I'll think about this, and probably double check on a breadboard before I try to stuff extra pull up/downs in.

You only need a resistor on any pin the RF module might try to drive.  The idea is that if both the programmer and the RF module try to drive a bus line at the same time, the programmer will override the RF module, and no potentially damaging currents will flow.  Putting a pullup on the CS line is a good idea in general, but using that to avoid contention on the SPI bus relies on the RF module behaving itself and reliably shutting up when CS is high.  Not all devices are that well behaved, so the resistor is a good general practice.  Note that if you had a device that may try to become the SPI master, you'd want to put a resistor on MISO and SCLK as well. 

Quote
Quote
- The ATMega328 is not spec'ed to run at 8MHz over its full supply voltage range.
I checked this when I was planning to run it from the 2.5v regulator output.  As I read the sheet, it can do 8MHz down to 2.4v, and I don't expect the lithium battery to ever drop below 3 volts.

The current datasheet (dated 2014-10) says "0 - 4MHz@1.8 - 5.5V, 0 - 10MHz@2.7 - 5.5.V, 0 - 20MHz @ 4.5 - 5.5V", I don't see any more detail than that.  But if you're running at 3V then yeah, you should be fine.

Quote
Quote
- Your LDO appears to have built in undervoltage lockout, so I'd consider moving the transmitter's MCU to the output of the LDO ...
I'll think about that.  Like I said I started that way.  But that would put the MCU's Vcc at 2.5v, and it's data sheet says the maximum rating for all pins is Vcc + 0.5v; sending the raw battery voltage into any pin to try to read it would then violate that rating.  But I strongly agree that UVLO is very worth having. 

So I went to check that detail, and I realize I've linked the wrong LDO sheet.  I was first planning on using the Toshiba TCR2EF (http://toshiba.semicon-storage.com/info/docget.jsp?pid=TCR2EF41&lang=en&type=datasheet), which does not mention any UVLO.  The TI TPS793xx I accidentally linked above was also in the running, and now it seems worth switching.

So the TI part does say "UVLO Threshold; Vcc rising; 2.25 - 2.65 v".  I didn't see that line until I went looking specifically for it!  And I'm not 100% confident how to read it.  It seems to say that it will cut the output when the input falls below the 2.25 to 2.65 volt range?  But if I get all the way down to 2.65 volts, I've already destroyed my LiIon battery (or come dangerously close) haven't I?  The safe lower bound seems to be 3.0v?

Perhaps I simply re-evaluate my LDO part selection, and concentrate on finding one with the right UVLO protection built in.  Then maybe a resistor voltage divider to safely measure the raw battery's capacity.

Another option is to use the LDO's enable pin (both the Toshiba and the TI parts have this) and use a voltage divider so that the enable pin falls below it's "off" threshold when the battery hits whatever minimum voltage you want.  You'll see exactly this arrangement a lot, and it's part of why those enable pins typically have hysteresis. 

A voltage divider is definitely the way to go for measuring battery voltage.  Use the internal bandgap reference and size your divider such that at maximum battery voltage the ADC pin is less than the reference voltage.  With both dividers, remember that they will necessarily be directly across the battery at all times, so the total resistance should be high enough to not draw too much current and discharge the battery.
Title: Re: Wireless retrofit for video game controller
Post by: arantius on February 23, 2015, 02:19:19 am
I finally finished (this phase of) the project!  Lots of little things changed including plenty of items based on your feedback.  Just to close the loop, here's what I ended up with:

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-rx.png) (PDF (https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-rx.pdf))

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-rx-front.png)

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-rx-back.png)

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-tx.png) (PDF (https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-tx.pdf))

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-tx-front.png)

(https://dl.dropboxusercontent.com/u/6784911/nesRF/v1/nesrf-tx-back.png)

Everything even worked the first time!  (Except one tiny part of the larger board that I had to dremel away ...)

All put together:

(http://static.arantius.com/images/015rx-assembled.jpg)

(http://static.arantius.com/images/019tx-assembled-error.jpg)

Thanks again.