Final Piece Completed!

    I completed the installation of an aftermarket stereo in my 2018 Tesla Model 3 back in March of 2019. At that point all the basic functionality was present, but there were a few odds and ends I never had time to wrap up. I love the minimalist interior design of the Model 3 and I didn't want to disturb that cleanliness by adding in visible aftermarket stereo components or controls, so I was a bit sad when I ended up gluing an aftermarket control box onto the center display. That aftermarket box allowed me to control the aftermarket stereo volume and bass levels via the aftermarket DSP, and from day one I really wanted to get rid of that and control the system using the built-in steering wheel controls, just as you would control the OEM stereo.

Three iterations of the interface PCB

    For the past year I've had this final feature on my to do list and the current quarantine gave me an opportunity to actually complete it. I wasn't sure exactly how to go about it when I started, but I knew the end result would be a combination of hardware and software that would read the OEM stereo volume controls and pass that information along to control the aftermarket stereo volume (and maybe also bass, though I don't adjust that very often). In the previous blog post I got the easy half out of the way. I took apart the aftermarket control box to figure out what signals I needed to generate. The box receives 3.3VDC from the aftermarket DSP and returns two analog voltages. I replaced that with a microcontroller that sent PWM signals through RC filters to produce analog voltages. That was all pretty simple.

(image taken from Jack Rickard)

    The second part took a bit more work. I read a bunch of forum and blog posts and eventually I came across the Diagnostic Port and Data Access thread on TeslaOwnersOnline. A group of people there have been reverse engineering the entire CAN bus network on the Model 3. There are (as far as I know) four CAN buses connecting various computers throughout the car, each carrying a different type of data. After talking to people there I found out that unfortunately the OEM stereo's volume level is contained entirely within the ICE computer and as far we could tell there was no way to read it from the outside. However, all of the steering wheel button and knob states are published on the Vehicle/Chassis CAN bus. And I could do what I wanted to do using that information.

Final Interface Schematic

    I threw together another microcontroller project with a CAN interface and wired that into the car's diagnostic connector at the back/bottom edge of the center console. From there I could read the Chassis bus, which contained the steering wheel left scroll wheel position in Message ID 0x03C2. That message is published at ~50Hz and contains the number of scroll ticks that the wheel has moved since the last message in unsigned integer format. After I worked the bugs out of that project, I combined the two projects together so a single microcontroller would read the left scroll wheel position from the CAN bus and then generate a corresponding analog voltage to control the aftermarket volume. After a bit more tweaking and behavior design, it all works almost perfectly. There are two imperfections that don't really bother me. One, I can't use the on-screen volume controls. But I never used those anyway. And two, my microcontroller will read the steering wheel dial and modulate aftermarket volume 24/7, even when this multi-purpose scroll wheel is temporarily being used for other functions, like adjusting the side view mirror or steering wheel position. But those are extremely infrequent edge cases and I'm not bothered by them either.

    Next up is bass control. The original idea was that I would tap into whatever system controlled the OEM stereo's bass level and parrot that value on to the aftermarket system. Then I would use the car's on-screen stereo settings menu to control aftermarket bass level just as I would control OEM bass level. In retrospect, considering how I actually use and adjust the aftermarket bass level, this original plan would have been a bad idea. I've tuned the hell out of my stereo to produce the most neutral, natural sound possible and 99% of the time I leave my bass set to a single predetermined level. The only time I change that level is for individual songs that sound good with extra bass. So digging through the car's audio settings menu when a particular song came on would have been very inconvenient. In this case a physical knob on the dashboard makes a lot more sense. And on top of that, I can't access the OEM stereo levels anyway because they're locked inside the ICE computer along with OEM volume. So, I went ahead and threw together my own physical controls for bass level.

Bass Control Installed inside Center Console

    The aftermarket box used a rotary potentiometer, but this gives us absolute position indication which can be a bit limiting. For my first test setup I used buttons, which are really slow and tedious when you want to change level by five or ten steps and, you know, you're driving a car. So I replaced these with a rotary encoder, 24PPR with quadrature and a mechanical button underneath. This allows me to change level quickly and conveniently by turning, and then to reset level instantly with a click. I mounted the encoder inside the front cubby in the center console, which I almost never use. This keeps the knob conveniently within arm's reach and also normally out of view and completely out of the way. I ran the appropriate cables through the center console and then back to the DSP in the trunk, mounted the microcontroller inside the center console next to the diagnostic port, and closed everything up.

MCU Installed underneath Center Console

    That's it. My stereo was functionally complete a year ago, but now it's finally finished. I have the full convenience of the original built-in steering wheel controls just like I wanted, combined with an aftermarket system that sounds amazing. Source code and PCB schematics are available on Gitlab and other parts are posted on GrabCAD. And an enormous thank you to all the people at TeslaOwnersOnline who mapped out the CAN buses ahead of me. I never would have been able to do that myself.

    Additionally, if you don't want to cut and splice the car's CAN and power wiring, you can alternatively buy a jumper that will allow you to tap into the required signals without cutting anything. It's a bit pricey, but it might give you better peace of mind. An example is this jumper here.