Introduction: USB Paddle Game Controller
My son was having a retro video games night for his birthday, and on the morning of the day I decided to see if I could make a pair of USB paddle game controllers for Pong with the help of a 3D printer and electronics from my stash. While I did manage to get them basically working in time, people were too busy with other games for Pong in the end.
The controllers can be used for Pong with the DICE circuit-level emulator or with my fairly accurate pygame version, for Atari 2600 games with an emulator, and for Etch-a-Sketch-like functionality with a painting program like Tux Paint.
There are three switchable modes:
- Stelladaptor paddle emulation: they should work with all Atari 2600 emulation software that supports the Stelladaptor; in Stelladaptor mode, the paddles function as two-axis two-button joystick, each paddle controlling one axis and one button
- dual joystick emulation: each paddle functions as a joystick with one button (with the paddle movement translating to movement on both joystick axes)
- mouse: each paddle controls one direction of motion for an absolute mouse, and the buttons are mouse buttons; together with a painting program you can get a high-tech device similar to an Etch-a-Sketch.
Supplies
You will need:
- stm32f103c8t6 blue pill
- 2x linear potentiometer (I'd recommend 20K-100K)
- 2x 12mm-width microswitch with button
- 3D printer
- miscelleanous (filament, wires, solder, soldering iron, hot glue)
Step 1: Prepare Board and Arduino Environment
- Solder the six header pins in the middle of your stm32f103c8t6 board.
- Check the resistance between A12 and 3.3V. It should be 1.5K for fuller USB compatibility. Many boards have 10K instead. If your is one of those, ideally solder in a 1.8K resistor from A12 to 3.3V, though you might be lucky and have your computers work with the 10K.
- Install a bootloader. There are instructions in Step 2 of this Instructable. One thing to make note of is what the flash size reported by the STM Demonstrator is. If it's 32K, you have a fake stm32f103c8 which is probably a relabeled stm32f103c6. This project should still work with that, but make a note that you have the fake board for a future step.
- Install Arduino, Arduino Zero and Roger's libmaple-based core following the instructions in Step 3 of the Instructable you used in the previous step. Ignore the library instructions in that step.
- Download the latest release of my USB Composite library and unzip it in your Arduino/Libraries folder.
- Download my paddlecontrollers sketch and unzip it in your Arduino folder.
- In Arduino, go to Tools | Board | Generic STM32F103C Series, unless you have the fake c6 board, in which case choose Generic STM32F103C6/fake STM32F103C8 instead. If you're not sure which you have, choosing the fake option is actually safer.
Step 2: Upload
Plug board into your computer's USB adapter, load the paddlecontroller sketch, and click the Upload button (right pointing arrow). If all goes well, the sketch should upload, and the board should show up on your computer as a two-axis two-button joystick called "Stelladaptor". In Windows, you can verify this with Windows-R, joy.cpl[enter].
Of course, this won't do anything until you have the rest of the hardware assembled.
Step 3: Print
- Download the stl and/or scad files from my Thingiverse page for this project. Please note that the paddle knob is modified from here.
- If your microswitch housing width is different from 12mm, you will need to adjust the button width parameter in the paddlemain-standalone.scad file. You can do that in OpenSCAD or in the Thingiverse Customizer.
- You may need to tweak the measurements in the paddleknob.scad file to fit your potentiometer.
- Print these files (do only one copy of the "2x" files if you just want one paddle). I used PLA, but ABS should work well, too.
- 2x paddlemain.stl
- 2x paddleknob.stl
- 1x paddleconverter.stl
- 1x pcbholdernarrower.stl
- 2x buttoncap110.stl (optional)
- 1x 12.stl (optional; print in a different color and glue on to label the two paddles)
Step 4: Wiring
You will need to run four wires from the stm32f103c board to each paddle controller. You could use old USB cords for these wires. I happened to have nice standalone wires from an ethernet cable which I bound together with shrink wrap.
Each paddle has one microswitch and one potentiometer. Use a multimeter to identify a pair of adjacent (not diagonal) pins on the microswitch that are connected/disconnected by pressing the button. I will label these pins S1 and S2 in the diagram. The three pins on the potentiometer I've labeled P1, P2 and P3 from top to bottom, looking from the underside of the potentiometer, with pins pointing right.
Push the four wires from the board through the hole on the side of the paddle housing (paddlemain.stl).
When connecting wires to the microswitch, first push the wires through the holes in the side of the paddle housing and solder to the switch while the switch lies on the outside of the housing. Then pull the switch to the housing, making the pins and attached wires fit in the holes. I cut off the unnecessary pins.
Both paddles:
- P1 to S1
- P1 to board 3.3V (3.3)
- P3 to board GND (G)
Paddle 1:
- P2 to board A1
- S2 to board A2
Paddle 2:
- P2 to board A3
- S2 to board A4
Now test the connections by connecting to your computer and using a joystick test program. On windows, Windows-R, joy.cpl[enter], select Stelladaptor, click on Properties. Paddle 1 should control the X-axis and the first button; paddle 2 should control the Y-axis and the second button.
Step 5: Final Assembly
The microswitches can be glued (hot glue did the job for me) in their locations on the side of the paddle box. Button caps can be snapped on, with a bit of hot glue for stability.
The potentiometer attaches to the big hole in the top of the paddle box. The knob should slide on and stick on. Enlarge holes with a drill as needed. Push the bottom cover on, adding a bit of hot glue if you like.
The blue pill board fits inside the PCB slide, which then screws to the bottom of the converter box, which also has a lid that can cover it up.
I added a bit of Shoe Goo where wires meet the housing to protect the wires. And I glued on "1" and "2" labels on the paddles.
Step 6: Modes of Operation
The paddles have three modes of operation. You can switch the mode of operation by pressing a particular combination of buttons while plugging them into a USB port, releasing once the board LEDs stop flashing. Once you switch the mode of operation, it will be saved to flash memory, and will stay until you next change it. (So, if you don't want to change the mode, don't press any button while plugging the paddles into a USB port.) Here are the options:
- Left paddle button only: One two-axis two-button joystick, with each axis and button controlled by one paddle. Moreover, the paddles identify as a Stelladaptor, a discontinued USB adapter for Atari 2600 controllers, and so Atari 2600 emulators like Stella and Z26 that are Stelladapter compatible should work perfectly.
- Both paddle buttons: Each paddle shows up a separate joystick. The joystick has one operational button, and turning the paddle moves the joystick diagonally, so either the X or the Y axis works for the paddle.
- Right paddle button only: The paddles show up as a two-button absolute mouse. You can now use this similarly to an Etch-a-Sketch with a drawing program.
Step 7: Pong
Pong was the great original paddle game. I recommend the original version, because clones often fail to include all the lovely subtle functionality, like the changes in speed with repeat hits, the angle changes depending on the part of the paddle that hits the ball, or the subtly but not easily predictable position of the serve after a miss. For a careful analysis of the original, see here.
One of the best way to play Pong is with the DICE circuit-level emulator if your computer is fast enough to use it at full speed. (My Windows laptop is, but the Raspberry PI 3+ is much too slow.) I recommend version 0.8.
If you use the Stelladaptor mode in the paddles, go to Settings | Configure Inputs... in DICE and choose Joystick 1 and Absolute for Player 1 Paddle, and set both Horizontal and Vertical to Joy 1 X-Axis. Then do the same for Player 2 Paddle, except with Y-Axis.
If your computer is too slow for DICE, I made a Python3+pygame version whose timings and functionality are meant to be very close to the original Pong (I am grateful for help from Dr. Hugo Holden in this regard).

Participated in the
3D Printed Contest
21 Comments
Question 4 months ago
- Solder the six header pins in the middle of your stm32f103c8t6 board.
What do you mean by this? What six headers? Which one? Can you be more specific? Is this the six headers that will connect to the paddles? And hence leave as open end at this stage and only solder to the board? I still need to know which ones you are talking about. TQ.2 years ago
I was going to order some linear potentiometers for this project. Any idea on the size of the shaft (length/diameter) so that the knob will it properly.
3 years ago
I figured it out. Now a have a worse problem. It keep never shows the controller page.
Reply 3 years ago
When you plug in the board, what do the lights do?
Reply 3 years ago
The blue pill stays red as shown above and when I plug in the UART to USB, it turns red and then off but that always happens. Usually the pill is flashing red and green but it isn't this time.
Reply 3 years ago
Did you succeed in uploading the bootloader?
Reply 3 years ago
Yes
Reply 3 years ago
I have three questions:
How are you supposed to plug in the blue pill to the computer?
Are you supposed to change anything in the code before running it?
If it goes right does the Stelladaptor window pop up or do I have to go somewhere to find it?
Reply 3 years ago
Since you've figured out how to upload the bootloader, instead of compiling the code you might see if you can just upload the .bin file. You can download the .bin file from here: https://github.com/arpruss/paddlecontrollers/relea... Then upload it in exactly the same way you did the bootloader (in fact, it will replace the bootloader).
3 years ago
I am currently trying to work the boot loader and something is very wrong. I am very inexperienced in this kind of stuff and would like help.
Reply 3 years ago
What did the previous screen identify the chip as?
Reply 3 years ago
COM4
Reply 3 years ago
No, I meant your stm chip. How much memory, for instance, did it say it had?
Reply 3 years ago
Did you mean the sd card size? Sorry I don't know much about all of this and you have been very patient. Thank you for all your help so far. Hopefully these images can help you pinpoint the problem. This is all located on the "SIDE" Disk.
Reply 3 years ago
No, the chip on the blue pill board. After selecting the COM port, it should give you some information on the chip.
Reply 3 years ago
I clicked "enter" adter selecting the COM port. It gave me a blank page. Nothing else.
3 years ago
What does it mean when it says "Solder the six header pins in the middle of your stm32f103c8t6 board" ?
Reply 3 years ago
Does your board already have six pins soldered in the middle?
Reply 3 years ago
I have been looking over this instructable and do not yet have a board for this.
Question 3 years ago on Introduction
Hi! Looking into 3D printers and wondering if you could recommend a good brand.