Deep Dive: Real-Life Mario Kart & OBD2 Mayhem

← Back to Projects

Curiosity: Turning Fantasy into Reality

Not too long ago, I found myself pondering as I played Mario Kart on my Nintendo Switch. Personally, I'm not a big fan of the Switch controls, so I was thinking about how I could change my control inputs to something more comfortable. During this brainstorming session, I had a funny idea: What if I used my car to control the game?

Now this was nothing more than a thought created out of boredom, but... it really got me thinking. Would something like this even be possible? Fueled curiosity and a pinch of madness, I embarked on a project that promised to transform my car into a makeshift Mario Kart controller. Sounds insane, right? I thought so too until I started digging deeper.

Mario Kart Real Life Concept

The Great Data Hunt: Discovering OBD2

My first step was research. At this point I have no idea what I'm doing, so I spend hours scouring forums, articles, and YouTube videos until I figured that OBD2 (On-Board Diagnostics II) was the way to go. OBD2 is the standardized system that lets modern cars post their data somewhere including its speed, engine RPM, fuel data, and a lot more info. This is transmitted through a stream of raw CAN messages.

So to be able to listen to my car, I needed a way to tap into this data stream. Since the OBD2 port is under the dashboard, all I need is a device that can read the data and send it to my laptop through some special cables.

Hardware & Setup: USB2CAN Module & Jumper Wires

To interface with my car’s OBD‑II port, I used the InnoMaker USB2CAN module. It’s a self‑contained CAN transceiver with an onboard STM32 microcontroller that plugs straight into my laptop’s USB port—no Raspberry Pi or extra SBC required.

I then bought an OBD2 to DB9 cable to plug into the microcontroller. I was escatic to test my new doohickey ASAP and I plugged it into my laptop to find... absolutely nothing happening. Yeah, it turns out the OBD2 cable had a different pinout than my car's port (duly noted: always do proper research before impulse purchases).

Me being on a college student budget, I didn't want to buy another cable. So I asked my TA for permission to take a few jumper wires from our lab. At first he was reluctant, but after telling him about my project, he had a seemed to be impressed enough and thankfully agreed.

After that, I did a quick dive through my cars manual and I confirmed the pinout, connected the jumper wires accordingly, and I was good to go.

InnoMaker USB2CAN Module

With the module connected, I installed the python-can library on my laptop:

            pip3 install python-can
        

Then I configured SocketCAN (on Linux) to bind the virtual device to can0:

            sudo ip link set can0 up type can bitrate 500000
            sudo ifconfig can0 txqueuelen 1000
        

Finally, a short Python script to capture and log CAN messages:

            import can
            
            bus = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000)
            for msg in bus:
            print(f"{msg.timestamp:.6f}  ID:{msg.arbitration_id:X}  Data:{msg.data.hex().upper()}")
        

Now my laptop reads the car’s CAN bus directly, logging every frame for visualization and eventual control automation.

The Hexadecimal Horror Show

Now the data dump. My terminal started spitting out thousands of lines like these each second:

            (1722899760.287644) can0 43F#004061FF71480A00
            (1722899760.287825) can0 220#C303000000002410
            (1722899760.288147) can0 164#000800000000060E
            (1722899760.288372) can0 1F1#0000000000000000
            (1722899760.288623) can0 370#0020008800000000
            ...
        

At first, I was euphoric. I spent several hours researching and preparing for every intricate detail of this project... up to this point.

Once the excitement wore off, I realized I was staring at nothing more than a wall of hexadecimal gibberish. I had no idea what any of it meant. If I was expecting to see something like "Speed: 60 mph" or "Engine Temp: 180°F," I was sorely mistaken.

I felt like a kid who just opened a treasure chest, only to find it filled with rocks instead of gold. I had no clue how to interpret the data, and the online resources were as helpful as a GPS in a black hole.

See, the problem is is that each car model—and even each year—seems to have its own way of communicating. My 2013 Hyundai Elantra was speaking in a dialect that no one had documented online. The reason is because car makers treat the hex decoding as intellectual property. In other words, they do not post what this diagnostic data means anywhere.

Panic started to set in: what am I supposed to do with this data now? Did I just waste all this time and money on a project that was going nowhere? Do I really have nothing to show for this?

But as I was getting ready to wallow in my own despair, I realized something. In the hexadecimal mess, there were some patterns. The first three characters of hex were the IDs, meaning they correlated to specific car functions (e.g speed, RPM, etc). The rest of characters after that was the actual value of those IDs.

Putting this idea fully together, it began to register to me that if I wanted to see this project fully, I would have to reverse engineer possibly hundreds of seemingly random hex values if I wanted any actionable data.

Challenge accepted.

Decoding the Data: Test Drives and Visualizations

With a newfound determination, I took my car out for a series of test drives. I recorded the raw data as I performed various maneuvers—accelerating, braking, turning—and then cross-referenced the changes in the hexadecimal messages.

Mind you, I can't just pick a random hex ID in this data and compare it to see how it changed over time. Just as a reminder, the stream gives thousands of lines of data each second, so even a short test drive is an immensely huge file to fish through. So I had to come up with a better plan.

To get around this roadblock, I decided to build an entire visualization dashboard on my laptop. This is a python program that features live charts that plot the data over time. Since the data already has timestamps and the hex values correspond from 0-255 in decimal, this was relatively simple.

I added controls that let me select individual hex values and view their corresponding timelines. In theory, this will allow me to pinpoint which numbers are tied to specific functions, like speed changes or steering adjustments.

Speed Data Visualization

The dashboard was a game changer. By correlating the timing of my test drives with the data spikes and dips on the charts, I could start decoding the car’s communication protocol.

I will bore you with the details of the decoding process, but I will say that it was a mix of trial and error, educated guesses, and a lot of caffeine. Overall, the process of creating the application and decoding enough IDs took up most of this projects time. It was at least two weeks of my life and an endless amount of headaches.

Long story short, I reverse engineered dozens of data points and mapped them to specific car functions. Now, Mario Kart time.

Bringing It All Together

With a solid understanding of the data, the next step was integration. I connected the live CAN bus data to my laptop and used pyautogui to automate keyboard inputs based on the incoming data. In essence, if a certain hex value indicated that I was stepping on the brake pedal, the script simulated pressing 'W' on my keyboard. Certain values of my steering wheel angle would correspond to 'A' and 'D' for left and right turns, respectively.

Finally, I connected everything to Dolphin Simulator running a Mario Kart ROM. Take a look at the video below to see the final result:

Conclusion: A Wild Ride from Fantasy to Function

This project was a wild ride. I learned a lot about OBD2, CAN bus communication, and the intricacies of automotive data. I also learned that sometimes the most ridiculous ideas can lead to the most rewarding experiences.

In the end, my project evolved from a whimsical thought experiment into a full-blown adventure in automotive data hacking. I navigated unreadable hex codes, tamed a rebellious 2013 Hyundai Elantra’s data stream, and turned raw information into a dynamic control system for a Mario Kart dream.

And always keep a sense of humor—after all, who else would think of turning their car into a real-life video game controller?

← Back to Projects