Jeep Sway Bar CAN Hacking
The sway bar in my Jeep can be electronically disconnected, but the engineers decided that it must re-engage above 18MPH and/or in 2WD. I don’t especially like this because I’m often going over 18MPH over very uneven terrain that can benefit from no sway bar.
Some people do things like remove the motor and add a pneumatic actuator, or take out all the electronics and run a switch directly to the motor (don’t press the switch too long or it’ll burn out!). I figured it’d be fun to do it by intercepting CAN messages and modifying them before sending them on to the sway bar.
I designed a small PCB with an STM32F4 (excessive, but sure to have plenty of power and cost isn’t really an issue here). This has two CAN transceivers and a serial port for diagnostics.
I wasn’t sure quite what the protocol was going to be and went into it knowing that some protocols might not really allow this hack to work well. I put a script on that forwarded CAN messages over a crude UART communication channel and a VB app that downloaded them for display.
The sway bar runs on the CAN drivetrain network. This of course constantly has lots of bus traffic and changing messages so I needed some way to filter out the traffic. To do this I setup the VB app to be able to filter out any byte that is changing over a given time span. First start scanning for changing messages, leave it for 30 seconds, then turn off the filtering. At this point all the random messages containing various engine stats are filtered out. Press the sway bar button and watch for new changing messages. Sure enough, all that’s actually being transmitted to the sway bar is a button-press or button-release signal. If the sway bar connector was attached to the vehicle, there was also a response message indicating that the sway bar successfully disconnected. Now I knew that CAN ID 0x325 byte 6 contained the state of the sway-bar button, and that likely any message transmitted from the sway-bar should just be forwarded to the Jeep.
Now I cut the CAN wires going to the sway bar and put my board in-between with the vehicle on CAN1 and the sway bar on CAN2. Since I now knew the CAN addresses and bytes containing the control button as well as the response telemetry packet from the sway bar, I figured I’d start by trying just forwarding these messages and ditching all the other CAN traffic.
Unsurprisingly, this did not work. The sway bar didn’t respond to the button press at all and remained locked. The sway bar needs to be receiving vehicle speed information to know when it’s safe to stay disconnected. First I tried taking a snapshot of all the messages on the bus and sending them all out periodically, figuring it would emulate a Jeep going 0MPH in 4WD. This also did not work, although I knew some variation of this had to work since if the Jeep is properly emulated the sway bar must work. It ended up being that the message timing was fairly important. I found a dominant telemetry loop speed (I think it was around 10hz) and every time one of those messages appeared on the CAN1 port, I send out the dummy message set on CAN2 port. When the timing exactly matched up with what the sway bar was expecting, it worked! I used trial-and-error to determine exactly which of the roughly 40 CAN messages were actually needed for the sway bar to remain locked. It turned out only two messages were necessary, 0x428 and 0x215. I just stored a snapshot of the Jeep going 0MPH in 4WD and used those messages. I don’t actually know what these messages are, but presumably one is speed and one contains the 4WD shifter position.
I got lucky in that all the logic on whether or not the sway bar should be connected or disconnected resides in the sway-bar module itself. I was actually surprised by this since if I were designing this system I would keep the sway bar as simple of a module as possible and put the lock/unlock safety logic in the main vehicle computer. Fortunately, that’s not how the engineers at Jeep decided to solve the problem which made it fairly easy for me to hack. Had the logic been in the main computer, this wouldn’t have worked so well since the Jeep would send out a re-connect packet whether I like it or not, there’d be no relevance to emulating a Jeep at low speed.
I’ve had this in for many months and never had a problem with it. I can now disconnect the sway bar at any speed and in 2WD if I want.
Repo with code and board design: https://bitbucket.org/christensent1/swaybar/src/master/