Hacking an Equinox electric power steering ( EPS ) unit

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
Hello everyone,


So let me start by saying I stumbled across your forum while searching the internet for any information regarding GM class 2 data network over J1850 bus. You see the rabbit hole I voluntarily threw myself down brought me here. I've victoriously resurfaced and I'm here to share everything I learned so that the next guy/gal who is starting down that hole doesn't have as far to go as I did.

I have a 65 Chevy II SS that I've had the privilege of owning and driving since 1993. Bought from the original owners for $900.00. Since then, she’s had 2 paint jobs and lots of modifications. Right now, she's way back on the back burner because of life and the many kids that I have now. I'm always yearning to get her back on the road, but life seems to be winning that tug-a-war for now. I've always wanted to add power steering to my Nova and since I'm now running a Fat Man Strut conversion kit on her with rack and pinion steering, I really wanted that extra help when maneuvering in tight spaces. I just recently learned of this anomaly called Electric Power Steering which has been available for some time unbeknownst to me. After doing some research I discovered that most of the options out there are manufactured by Koyo Seiko. They basically own the market on Electric Power Steering. So, after looking at all the options of using one from a Toyota model or some other import models. I decided on a model from a 2006 Chevy Equinox. I decided on this model as I had learned that there were ready made solutions available on E-Bay that would allow you to connect to your Equinox EPS unit and wake it up. I’m a tinkerer at heart and if there’s an opportunity for me to achieve a goal and gain knowledge in the process then I’m all for it versus just shelling out the bucks for a solution to be handed to me. I have experience with Arduino so I decided to take the plunge. So here we go.


I set off to the salvage yard to pull one of these new-fangled EPS’s from a 2006 Blue Equinox. The hardest part of removing it was removing the airbag from the steering wheel. After that it basically fell out from under the dash. The unit has 3 connectors going to it. One connector has ground and power to the motor and one connector has ground and power to the controller. This power wire goes directly to the battery. The third smaller connector has two tiny wires coming out of it. One of the small wires is a pink wire which takes 12v when the ignition is on, and it tells the unit to come on or go off when the car is turned on and off. This causes a relay inside the unit to click. The second tiny wire is a purple wire and this wire comes from the J1850 transceiver chip inside the EPS controller. This connects to the J1850 bus. You can find a document for the SAE J1850 Bus specification if you want some heavy reading. I found multiple Arduino libraries and examples that talk on a J1850 bus.



After you grab one of these Arduino libraries/examples and you hook up your Arduino to the purple wire you should start receiving hex codes like the following.


08FF30032D​
8AEA3020C90064​
C952300437​
A9283002E0​
49FE3006C2​
C9FA300285​
What you’re looking at here is data that’s being sent out over the one wire bus. This data protocol is defined by the SAE J2178 document. There are 4 parts of this document, and you should be able to find all 4 of them on the Internet. You don’t need to purchase the latest copy from SAE. Each line of the data is called a frame and the frame is made up of data in Hex format and 2 characters represents a Byte of data. The first 3 bytes of the frame are defined as the header and depending on that header and the function that is specified in the header, the next several bytes can be defined as the data that goes along with that function. The last byte of the frame is called the CRC byte. Using the SAE2178 documents you will decipher these packets of data and determine what the controller is saying or asking for.

There are two pieces of information that the controller requires to wake up and start providing power assistance to the input shaft of the EPS unit. One is the vehicle speed and two is the request for the status of the engine being on. Using the J2178 documents you will find that the frame of data in the above example (C952300437) contains the second byte Hex 0x52 and is the message from the EPS asking if the engine is on. After looking through the SAE J2178 documents and online resources I discovered that the message/frame (88531184AE) is a valid response to send to the EPS and tell it that the engine is indeed on. The next request from the EPS is the frame (A9283002E0) and that the message from the EPS is asking for the vehicle speed. After looking through the SAE J2178 documents and online resources I discovered that the message (8829110200003B) is a valid response to send to the EPS and tell it that the speed of the vehicle is 0MPH which will provide you with the maximum assistance from the EPS.

After some trial and error, I was able to send these two messages/responses to the EPS using my Arduino and all of a sudden my EPS was alive and working. My plan is to read the data from the speed sending unit that came with my aftermarket gauges and send real time vehicle speed messages to the EPS so that the power assist will lower as the speed of the car increases and the power assist is not needed.

Tip: I had my EPS unit hooked up to a benchtop Power Supply and it would show how many milliamps it was drawing which helps in determining what the controller is doing. You’ll notice the controller before it get’s turned on will hang around 350-380 milliamps and once it turns on you’ll see it jump up into 400 milliamps.

Here are some links to the online resources I relied on and that you may find helpful.

Thanks and happy tinkering!


Great info here with real examples of J2178 data, especially the Google Sheets

ELM327 & Class 2 Serial Data | GMTNation


Good introduction to J2178

Digital Tachometer for Harley Davidson Sportster (Part 3 - Harley Davidson and SAE J1850 VPW) · Momex


CRC page to generate the CRC byte if you choose to create your own responses for your application.

Use for the CRC parametrization option CRC8_SAE_J1850

Sunshine's Homepage - Online CRC Calculator Javascript (sunshine2k.de)


Arduino Code used to capture and transmit data on the J1850 bus

GitHub - matsekberg/j1850decoder: An Arduino based OBD2/J1850 decoder.

GitHub - matsekberg/j1850emitter: Arduino that emits J1850 messages used for testing of j1850decoder
 

Mooseman

Moderator
Dec 4, 2011
26,010
Ottawa, ON
One helluva first post. Welcome! Although most of that went over my head, I think we have a couple of guys that might be interested in the J1850 and SAE 2178 info (paging Dr. @TJBaker57 )

That must have been a really deep rabbit hole!
 

NJTB

Member
Aug 27, 2012
612
Flemington, NJ
How much fabrication was involved to get the steering column to fit? Were the splines the same for the shaft, or was welding involved, did you have to make plates to mount it to the firewall? Mounts under the dash?
Sounds like a fun project.
 

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
Hi,
My plan originally was to install the EPS in line with the existing linkage in the engine compartment. After acquiring one it was apparent it's not weather proof. So now the plan is to modify the 70's GM van tilt column that I have in the car right now. Bringing it inside is where it was designed to live. I have a lathe so some modification will be made to the column shaft to interface (weld and pin) to the EPS units column shaft that engages with the splines of the input shaft on the EPS. The output shaft of the EPS I believe is 16.5 mm - 36 spline. I'll either go back and grab the rest of the steering linkage off the equinox rack or purchase an adapter to convert to double D shifting. I already have a plate for the firewall to support the shaft through the firewall. Here's a picture of my bench test.
20211211_102441.jpg
 
  • Like
Reactions: azswiss and Mektek

TJBaker57

Lifetime VIP Donor
Member
Aug 16, 2015
3,178
Colorado
I have experience with Arduino so I decided to take the plunge


My knowledge of Arduino or similar devices is doodley-squat/zip/nada. But I have had for some time an idea for a project. Let me throw this at you.

Your Arduino can interface with the J1850 bus and both request and receive data as set forth in J2178. Can such a device/project also be outfitted to read a user supplied analog sensor (or two or three), similar to say a coolant temperature sensor. And can the device be programmed to respond to a properly formatted J1850 data bus request for said sensor?? I am of the mind that these things are possible.

The notion is that with such a project a user could add a sensor like a temp sensor on any part of a vehicle they wanted to monitor, wire it to the Arduino project and have the Arduino respond to requests for said data sent by an App like Torque Pro, OBD Fusion, etc. using the existing vehicle data bus.
 

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
That would be possible as long as the data PID is defined by J2178 for said sensor/s. You would also have to use a data PID not in use as an existing module on the bus would be sending conflicting answers. My arduino is basically mimicking the ECU and sending speed/engine status messages so there are no other modules on the bus to contend with. I guess you could use a data pid for a non-existing sensor on the vehicle to ensure no over lap.
 

TJBaker57

Lifetime VIP Donor
Member
Aug 16, 2015
3,178
Colorado
That would be possible as long as the data PID is defined by J2178 for said sensor/s. You would also have to use a data PID not in use as an existing module on the bus would be sending conflicting answers


Precisely what I was thinking. Use of a functional target address for a parameter that is non-existant on the vehicle, maybe even use one designated as manufacturer defined. Easy enough to query the existing network to be certain no other module answered.

For the physical node address of the Arduino that too should be simple to assign it a node address that is not in use.

Years ago I had some third gen Trans Ams and had issues with overheated fuel causing the pump to cavitate. I would lose pressure and stall out if stopped in traffic. I bought some indoor-outdoor remote sensing thermometers and routed the sensors through the firewall to attach to the fuel supply and return lines (insulating them as well) so I could tell when I was nearing the temperature when the trouble would surface.

This Arduino project would be a more flexible modern day equivalent.
 

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
For the physical node address of the Arduino that
Years ago I had some third gen Trans Ams and had issues with overheated fuel causing the pump to cavitate. I would lose pressure and stall out if stopped in traffic. I bought some indoor-outdoor remote sensing thermometers and routed the sensors through the firewall to attach to the fel supply and return lines (insulating them as well) so I could tell when I was nearing the temperature when the tre would surface.
This Arduino project would be a more flexible modern day equivalent.
The Arduino is very powerful. My first project with the Arduino was a controller for my power windows. It would monitor the current to each motor for an all down/up function via remote. I also had a touchscreen to operate each window but ultimately decided a touch screen to operate the windows was not such a good idea.
 
  • Like
Reactions: TJBaker57

TJBaker57

Lifetime VIP Donor
Member
Aug 16, 2015
3,178
Colorado
After some trial and error, I was able to send these two messages/responses to the EPS using my Arduino and all of a sudden my EPS was alive and working.


@itstallion

Care to share insights into getting the Arduino communicating with J1850?? I am getting nowhere rapidly! I have tried several different Github projects and have only succeeded in one attempt which only reads the data stream.
 

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
Here's a copy of my code that I'm running on my nano for this project. It waits for certain messages/requests and then sends the appropriate response. I'm using 3 pins on my arduino. One pin for sending data (8), one pin for receiving data (9) and one pin for monitoring the bus and triggering the interrupt to read the data (3). All three pins are tied to the bus. I did manage to fry a Nano by trying to use an old school battery charger that can put out 120 amps but not at 12volts. It does it at 18 volts which fried the Arduino's onboard voltage regulator. Documentation is all over the place but I found the datasheet for that specific voltage regulator and it specified 15 volts is the max so I'm incorporating a buck converter that can handle up to 28 volts and bring it down to 5volts. I guess connecting the car electrical directly to an Arduino is a bit 'how ya doin' - Davy Jones. I'm using an MP1584EN buck converter now.
 

Attachments

  • Arduino_J1850.txt
    7.8 KB · Views: 37

TJBaker57

Lifetime VIP Donor
Member
Aug 16, 2015
3,178
Colorado
Here's a copy of my code that I'm running on my nano for this project


Thanks so much! It will take me quite some time to wade into this. A portion of the code you shared is the one that I got to read after some trial.

The readme for the code stated to connect to pins D2 & D9 so there I was trying to get anything to work and getting nothing. Eventually looked at the code and it at least looked to me that I should be connected to pins D3 & D9....

Screenshot_20211231-181641.png

Screenshot_20211231-181715.png

Another thing I altered may or may not be correct. I found an instance where the code did not match the comment. I changed the code to match the comment.

Screenshot_20211231-181538.png


I have also tried some other codes/libraries from Github as well as some circuitry to interface between the J1850 bus and the Arduino. I had read somewhere that connecting the Arduino directly to the J1850 bus might not work due to the voltage differences but at least for reading the bus it seems to work with the code you shared. And thus far I have nothing working with the circuitry I have tried. That circuitry was copied from the ELM327 datasheet.

Screenshot_20211219-091141.png

I'll keep tinkering with various approaches. Today I received some optocouplers to try that approach!! Saw them used on an old "Nerdkits" video.

 

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
Thanks so much! It will take me quite some time to wade into this. A portion of the code you shared is the one that I got to read after some trial.

The readme for the code stated to connect to pins D2 & D9 so there I was trying to get anything to work and getting nothing. Eventually looked at the code and it at least looked to me that I should be connected to pins D3 & D9....

View attachment 102598

View attachment 102599

Another thing I altered may or may not be correct. I found an instance where the code did not match the comment. I changed the code to match the comment.

View attachment 102600


I have also tried some other codes/libraries from Github as well as some circuitry to interface between the J1850 bus and the Arduino. I had read somewhere that connecting the Arduino directly to the J1850 bus might not work due to the voltage differences but at least for reading the bus it seems to work with the code you shared. And thus far I have nothing working with the circuitry I have tried. That circuitry was copied from the ELM327 datasheet.

View attachment 102601

I'll keep tinkering with various approaches. Today I received some optocouplers to try that approach!! Saw them used on an old "Nerdkits" video.


Thanks so much! It will take me quite some time to wade into this. A portion of the code you shared is the one that I got to read after some trial.

The readme for the code stated to connect to pins D2 & D9 so there I was trying to get anything to work and getting nothing. Eventually looked at the code and it at least looked to me that I should be connected to pins D3 & D9....

View attachment 102598

View attachment 102599

Another thing I altered may or may not be correct. I found an instance where the code did not match the comment. I changed the code to match the comment.

View attachment 102600


I have also tried some other codes/libraries from Github as well as some circuitry to interface between the J1850 bus and the Arduino. I had read somewhere that connecting the Arduino directly to the J1850 bus might not work due to the voltage differences but at least for reading the bus it seems to work with the code you shared. And thus far I have nothing working with the circuitry I have tried. That circuitry was copied from the ELM327 datasheet.

View attachment 102601

I'll keep tinkering with various approaches. Today I received some optocouplers to try that approach!! Saw them used on an old "Nerdkits" video.


I initially attempted an insulating circuit design between the Arduino and the bus using transistors but was unsuccessful. I then hooked the Arduino pins directly to the J1850 bus (purple wire) after referring to the sae_j1850.pdf the dc parameters basically specify a TTL voltage range of 5v so the Arduino is able to talk directly on the bus. I know this doesn't provide any protection between the two but it's something I'm willing to live with.

Regarding the code I uploaded you can ignore the analog pin code that's something I was playing with the last time I was working in the code. I was starting to incorporate a potentiometer to adjust the speed reported to the Koyo controller. I've since stopped developement on that and I'm now working on designing an enclosure in FreeCAD to 3D print to hold the nano + buck converter and mount to the Koyo controller. When I get it finished I'll post the link to it on Thingiverse.

I eventually plan on reading the speed sensor output that came with my aftermarket gauges and correlating that to a speed and reporting it to the Koyo to fully implement an automated self adjusting power steering system like factory. For now my Nova is 900 miles away from me so it'll have to wait till I can get a place to have the car here with me.

My next project after all this is to develop an electric fan controller to adjust the fan speed (PWM) based on the radiator output temperature. Basically a homegrown Derale Fan controller. Right now my fan just turns on and off based off the temperature sensor located on the output side of the intake manifold. Adding variable speed to the fan will be a nice addition.
 
  • Like
Reactions: TJBaker57

TJBaker57

Lifetime VIP Donor
Member
Aug 16, 2015
3,178
Colorado
Well I haven't been fiddling with any interface circuitry but I have been noodling about your posted code trying to learn how this all works. I have made some progress here and there. Much is still beyond me and there are things on the horizon that I will struggle with when I need to add them like CRC checking and generation and message arbitration.

I have changed the message monitoring to resolve the full addressing of Primary ID, Secondary ID, and where required for message types 9 & 10, Extended address.

Here is a screenshot showing 3 "load command extended" messages for 'change engine oil' (5th byte 0x82), 'check gauges' (5th byte 0x85), and 'reduced engine power' (5th byte 0xB7) and their respective "status report" messages in response. The first two lights are off and the last light, 'reduced engine power" is on. Currently the reports are still fixed as I cannot yet do the CRC generation.

Screenshot_20220104-130545_Serial Bluetooth Terminal.jpg
 

Saleh

Member
Mar 10, 2022
6
Qassim
Well I haven't been fiddling with any interface circuitry but I have been noodling about your posted code trying to learn how this all works. I have made some progress here and there. Much is still beyond me and there are things on the horizon that I will struggle with when I need to add them like CRC checking and generation and message arbitration.

I have changed the message monitoring to resolve the full addressing of Primary ID, Secondary ID, and where required for message types 9 & 10, Extended address.

Here is a screenshot showing 3 "load command extended" messages for 'change engine oil' (5th byte 0x82), 'check gauges' (5th byte 0x85), and 'reduced engine power' (5th byte 0xB7) and their respective "status report" messages in response. The first two lights are off and the last light, 'reduced engine power" is on. Currently the reports are still fixed as I cannot yet do the CRC generation.

View attachment 102647

I have some question to you about car scanning, OBD2 and Arduino, I have search everywhere and I saw most of your post are the closest to my questions and I think you are the right person to ask.

How can I get hold of you? if that's possible
 

Mooseman

Moderator
Dec 4, 2011
26,010
Ottawa, ON
You could send him a PM or start a thread so it can be shared with everybody.
 
  • Like
Reactions: TJBaker57

Saleh

Member
Mar 10, 2022
6
Qassim
You could send him a PM or start a thread so it can be shared with everybody.
I looked everywhere to send him a private message but I didn't see that option anywhere, I thought maybe because I just created my account. that's why I posted here.
 

mrrsm

Lifetime VIP Donor
Supporting Donor
Member
Oct 22, 2015
8,196
Tampa Bay Area
The existing CAN-Bus Technology standard in the World Wide Automotive Industry makes such Hacks possible. And in this Video Webinar, the Group cover has some interesting information on ECU-PCM Hacking worth understanding and thinking about.

The VOP and his Panel address some very scary scenarios via White Board and Hardware use explanations involving an inexpensive Raspberry PI System, some Auto Industry CPU Micro-Processors and a few other off-the-shelf components to explain how easily these well understood and completely naked CAN-Bus Systems "CAN" Become Vulnerable:


The implications of Knowing HOW to do this in a way that might sidestep any meager in-dwelling OEM ECM-PCM Security and defeat it by penetrating any CAN-Bus System presents us with a REAL DANGER in what might happen if someone actually managed to take External Control over the Electronic Steering Mechanism in any Moving Vehicle equipped with any such Hardware and Software.

So I'm suggesting (without impugning the suggested benign motives of the OP) that we should Tread Very Lightly here before delving much deeper into something so potentially dangerous ...in such a public way.


 
Last edited:

Mooseman

Moderator
Dec 4, 2011
26,010
Ottawa, ON
Click on the user name or avatar and you will have the option to start a conversation.
 

Roudter

Member
Apr 5, 2021
12
NJ
I wrote an app that can send data into the CAN...You can also set headers...CAN App
Go to the bottom of the page where you can grab an *.apk file for android...or whatever..
 

Starflare5

Member
Nov 30, 2022
9
United States
Quick question: I find all of this amazing what you have done so far, however, couldn't you just use a BCM from a 2007 or newer Equinox to connect to activate it and send and receive data? Of course, you'd also have to install an ECM to send and receive data to the BCM from the engine. The thing is, as I understand it, the EPSU receives data from the transmission, engine and other components to "feel" as normal as fluid controlled power steering, and the BCM is basically the bridge, or in GM's case, the GMLAN network hub between it all as well as what wakes up and bridges the data to and from the EPSU, ABS, Engine, and transmission.

Just wondering,

Thank you,
Starflare5.
 

itstallion

Original poster
Member
Dec 2, 2021
7
Cincinnati
You could go out and grab all those modules and then you would probably have to grab all the sensors that those modules are looking for to get them all to play ball. I circumvented all that by generating enough of the messages on the CAN network for the EPSU controller to come on line. It's a bit of a hack but it's also a stand-a-lone solution.

Since my initial upload on this subject I've taken some pics of how the install turned out in the Nova.

You can see the arduino nano mounted to the top of the EPSU controller. The installation of the EPS motor to the existing steering column was pretty straight forward. I have a lathe so machining the tilt column shaft to slide into the shaft sleeve that slides over the input shaft of the EPS motor allowed this all to be a bolt together solution. I used the controller mount holes as a mounting spot so that the motor could be tucked up under the dash. The EPSU controller is mounted off one of the ears of the motor via a custom bracket. It's not mounted in this picture.

20220727_132207.jpg


20220727_132249.jpg
 

Starflare5

Member
Nov 30, 2022
9
United States
Interesting, but the only 2 sensors that should be needed are the crank position sensor and speed sensor. The CPK input acts as the power steering pulley, where as the wheel speed sensor makes it speed sensitive. Both these most vehicles should already have. as far back as the 1950s. IT's cool that you created a compact controller however to serve those functions.... Worth looking into.
 

Laminar

Member
Jan 11, 2024
2
Iowa
This is the only place on the internet I've found so far doing DIY comms to the Vue/Equinox power steering, most other mentions just buy the little controller. I have a canbus-capable standalone ECU and would like to set up speed-sensitive assist, so I'm trying to figure out the actual messages to the power steering controller. From some code posted in this thread, I see this:

// Vehicle Speed Status Message 8829110205A6B5
//uint8_t spd[] = {0x88, 0x29, 0x11, 0x02, 0x05, 0xA6, 0xB5}; 7MPH
uint8_t spd[] = {0x88, 0x29, 0x11, 0x02, 0x00, 0x00, 0x3B}; //0MPH
//uint8_t spd[] = {0x88, 0x29, 0x11, 0x02, 0xE0, 0x00, 0x6D}; //60MPH

From what I can tell,
0x88, 0x29, 0x11, 0x02
are common to each message, the 5th and 6th groups are the speed, and the final group is the CRC.

So two questions -
1. How to we get from mph (or kph) to the hex messages for speed?
2. If I want to continuously vary the speed value I'm sending to the controller, do I also need to continuously calculate the correct CRC for that message so that the controller accepts the message?

Thanks!
 

Laminar

Member
Jan 11, 2024
2
Iowa
Another Resource:

Was there more than that linked thread? It looks like someone asks, "Can I do this?" and someone else responds, "Yes." Was there info on decoding the canbus or converting speed to the correct hex value that I missed?
 

mrrsm

Lifetime VIP Donor
Supporting Donor
Member
Oct 22, 2015
8,196
Tampa Bay Area
Make your contact with the Folks at that site and ask them about their course of instruction and forums, and SMEs on this topic, etc.
 

Forum Statistics

Threads
23,676
Posts
641,857
Members
19,113
Latest member
SCr

Members Online