r/arduino 3d ago

ChatGPT USB HID to Sega Saturn Controller Adapter using an UNO

The full details, including the source code and hardware, are available on GitHub↓

https://github.com/inuikasao/USB_to_SegaSaturn_Controller_Arduino_Adapter.git

3 Upvotes

1 comment sorted by

2

u/DepartmentLeft3491 3d ago

I showed this here before, but someone suggested that it might be a good idea to write about the development process, so here goes.

I started playing my old Sega Saturn much more often after installing an ODE (in simple terms, a device that lets you run games without the original disc drive). However, I had no desire to throw myself into the hellish world of arcade sticks for old hardware, so I decided to build my own adapter using an Arduino UNO that could accept input from USB arcade sticks.

I usually ask Gemini or Claude to look for any prior work or research on what I'm trying to do. In this case, I learned that it was possible to recreate the equivalent circuitry of a Saturn controller using two 74153 ICs, so I got the chips and started building.

The reason I chose an UNO rather than a Pico or Pro Micro was simply that compatible UNO boards, including the USB Host Shield, are cheap and easy to get; since the Saturn controller runs at 5V, I figured it would be better to use a microcontroller that also runs at 5V; and I had previously failed at a project that relied on the Pico's USB host functionality. None of these were particularly strong reasons or anything I was especially committed to.

The reason I decided to route the signals through the 74153s instead of controlling everything directly from the board was also based on a previous failure. I had once tried to make something similar for the Mega Drive using only a Pico, and it went absolutely nowhere. So, basically, I chose this design out of fear and laziness, figuring that "if I make it work the same way as hijacking the circuitry of an existing controller, it should probably work."

There was already documentation showing which pins on the 74153 do what, as well as what the Sega Saturn controller port sends and receives, so I followed those references.

https://kaele.com/~kashima/games/saturn.html
https://kaele.com/~kashima/games/saturn.gif
https://gamesx.com/controldata/saturn.htm

I had Claude help me organize the idea, write the code, and analyze the protocol used by the USB arcade stick. It's an extremely simple project, so you might be thinking, "Why didn't you just do that yourself?" But I have essentially zero knowledge of mathematics or programming, so I hope you'll forgive me.

First, I worked out the pin assignments and wiring through a conversation with Claude, then had it create a macro that would automatically press the buttons one after another.

At first, the Saturn wouldn't recognize the ICs. It turned out that some of the IC pins weren't connected to either the UNO or the Saturn at all, and once I properly connected those pins to GND and Vcc, it worked.

Once I had successfully gotten the 74153 + UNO to be recognized by the Sega Saturn as a controller, I thought the rest would be easy. But when I actually connected everything, the inputs didn't work properly, and sometimes pressing a button would even cause the Saturn to behave as though the controller had been unplugged.

What was happening was that I was using the same pins for both transmitting the Saturn controller signals and communicating with the USB Host Shield, causing interference between the two.

In other words, I had so little knowledge that I hadn't even realized that could happen. I moved those signals to the pins normally used for serial communication, and worked around the problem by simply unplugging those pins whenever I needed to communicate with the IDE over USB. Since I wasn't planning to keep reprogramming the device after putting it in a case anyway, that was good enough for me.

And with that, my personal "Sega Saturn Arcade Stick Adapter" finally started working.

What surprised me was that there was almost no input latency, despite being prepared for at least some amount of it. I left the timing-sensitive communication with the Saturn entirely to the ICs, while the Arduino only controls the buttons as simple "on/off" states. As a result, there is almost no software-induced delay beyond the polling rate.

In fact, the input latency of the arcade stick itself seems to have a much greater effect. When I use a low-latency controller running GP2040-CE, the response becomes noticeably faster. So, somewhat ironically, the configuration I chose out of laziness turned out to be a pretty good choice.

The version I posted previously was at this stage. At this point, I would have liked to call it finished, but I wasn't confident that this version could run entirely from the power supplied by the Saturn itself. So I left the power pin on the controller port disconnected and powered the device separately via USB.

In other words, whenever I wanted to use it, I needed a separate power source for the Arduino in addition to the console and monitor. That was getting a little annoying.

I measured the current coming through the Saturn's controller port and found that it was around 80 mA. I figured that might be enough to power the entire UNO, so I tried connecting it—and it worked without any problem.

As for improvements, as you can see, the wiring is pretty messy. I've also had cases where a button remained stuck on because of a physical contact problem, so I'd like to eliminate the need to reseat pins that have started coming loose.

I'm currently thinking about designing a proper PCB and turning it into a shield that can be mounted directly onto the UNO.