Modifying can transmit sample app to control retrofit electric power steering

So I’m back on the project of using a photon and can-hitch to send an rpm signal and a VSS signal to the electric power steering (EPS) column from a Toyota Prius that I’ve integrated into a 1967 Ford Fairlane. I have the can bus wiring setup and can use an OBD2 connector to read data and codes from the EPS module. However the module goes into a limp in mode since it isn’t receiving an RPM or VSS signal from the ECM/ABS over the can bus. I would like to program the photon/can-hitch to output the two (or possibly more, not sure yet if the EPS is looking for a single vss or individual vss readings) signals. I’m not real great at coding yet so I’m not sure how to modify the sample code to output two messages. So far I have this:

// This #include statement was automatically added by the Particle IDE.
#include <carloop.h>

#include “application.h”
#include “carloop/carloop.h”

// Don’t block the main program while connecting to WiFi/cellular.
// This way the main program runs on the Carloop even outside of WiFi range.
SYSTEM_THREAD(ENABLED);

// Tell the program which revision of Carloop you are using.
Carloop carloop;

// Send a message at a regular time interval
void sendMessage() {
static uint32_t lastTransmitTime = 0;
uint32_t transmitInterval = 100; /* ms */
uint32_t now = millis();
if (now - lastTransmitTime > transmitInterval) {
CANMessage message;

// A CAN message has an ID that identifies the content inside
message.id = 0x2C4;

// It can have from 0 to 8 data bytes
message.len = 8;

// Pass the data to be transmitted in the data array
message.data[0] = 0x06;
message.data[1] = 0x8A;
message.data[2] = 0x00;
message.data[3] = 0x19;
message.data[4] = 0x00;
message.data[5] = 0x00;
message.data[6] = 0x92;
message.data[7] = 0x09;

// Send the message on the bus!
carloop.can().transmit(message);

lastTransmitTime = now;

}
}

void setup() {
// Configure the CAN bus speed for 500 kbps, the standard speed for the OBD-II port.
// Other common speeds are 250 kbps and 1 Mbps.
// If you don’t call setCANSpeed, 500 kbps is used.
carloop.setCANSpeed(500000);

// Connect to the CAN bus
carloop.begin();
}

void loop() {
sendMessage();
}

Which should output a set 1674 rpm signal which will “wake up” the EPS module so the steering powers up immediately at key on instead of waiting 15 seconds and going into limp mode. With no other message the EPS will still see a “loss of communication with ABS module” and will default to the minimal assist strategy. So I would like to also output the VSS signal. How would I incorporate that into this code.

A sample message would be: 0B4= message ID, 8 length, 00 00 00 00 8D 06 66 B5 which should be 10mph

I can change the mph settings (the 06 66 here, 06 66=1638*.0062=10.15MPH) to make the EPS believe the car is moving at different speeds until I found an assist level that would work for now (minimal isn’t quite enough). If I can get this basic system working then I plan to eventually figure out how to read a vss signal with the photon and have it output so the system will work as it did on the Prius, but that is a ways off.

@TimC,

I like your idea of hard-coding RPM and Vss data as you do development. It is always easier to break down a problem into more manageable chunks.

Have you been able to find a datasheet or specification for the EPS?
I would assume that the EPS needs to receive the RPM and Vss on a certain frequency.
It would make sense that if it goes too long without an update, then it switches to limp mode.

You might want to experiment with timers and see if sending the same message at different frequencies.
Hopefully you can find a frequency that will work to keep the EPS woken up and in its regular operating mode.

Well with the sample app like I posted above it didn’t wake up the module.

First I realized that because I had tested it at work and the photon wasn’t set up for my work wi-fi, only home wi-fi, that it may not have been transmitting since it was flashing green fast. I added the code for SYSTEM_MODE(MANUAL) so the thing wouldn’t try to connect to wi-fi at all. Now it breathes white almost immediately on power up.

I read on another forum where a person said they had to transmit every 20ms to get the module to wake up on a Yaris (which doesn’t use the CAN for wheel speed, so it only needs rpm for wake up) so I changed mine to transmit every 20ms and that still didn’t help.

So I added this into the code (in bold) figuring the Prius may also need the abs data:

if (now - lastTransmitTime > transmitInterval) { CANMessage message;

// A CAN message has an ID that identifies the content inside
message.id = 0x2C4;

// It can have from 0 to 8 data bytes
message.len = 8;

// Pass the data to be transmitted in the data array
message.data[0] = 0x06;
message.data[1] = 0x8A;
message.data[2] = 0x00;
message.data[3] = 0x19;
message.data[4] = 0x00;
message.data[5] = 0x00;
message.data[6] = 0x92;
message.data[7] = 0x09;

// Send the message on the bus!
carloop.can().transmit(message);

// A CAN message has an ID that identifies the content inside
message.id = 0x0B4;

// It can have from 0 to 8 data bytes
message.len = 8;

// Pass the data to be transmitted in the data array
message.data[0] = 0x00;
message.data[1] = 0x00;
message.data[2] = 0x00;
message.data[3] = 0x00;
message.data[4] = 0x8D;
message.data[5] = 0x06;
message.data[6] = 0x66;
message.data[7] = 0xB5;

// Send the message on the bus!
carloop.can().transmit(message);

lastTransmitTime = now;

}

Which should be around a 10mph wheel speed signal too, along with the original rpm signal every 20ms.

That worked!

Now the EPS powers on nearly immediately on key on. There is a very slight delay maybe less than 1/2 a second where the photon is booting up or whatever but that is much better than the original delay of 10 to 15 seconds which was so long there were times I was having to drive with no power assist as I pulled away. Like after cranking and leaving the gas pump for example, or pulling out of the parking spot at work, there were times I was already moving and trying to steer before the fail safe mode would kick in. You could sit there an extra few seconds and it was fine, but that’s annoying LOL.

Not sure yet if the thing is giving the extra assist levels, I have only tested it on the glass smooth concrete floor of my garage today. The torque sensor in the column only gives enough assist to steer as needed and the floor is so smooth its not too hard to turn even with plain manual steering. Tomorrow I plan on backing it out onto the rough textured concrete driveway where the assist level was previously not enough to see if its better. I will play with the wheel speed message some to try different speeds. I may have given it enough CAN data to immediately turn on, but I’m not sure what this EPS module is looking for exactly, so I have to see if it is still throwing loss of communication (Uxxxx) codes or not. Plus I’m not sure I’ve given it the correct speed data. I’ve seen where both IDs 0x0B4 and 0x610 are speed PIDs. plus 0x0B1 and 0x0B3 are front and rear axle individual wheel speeds (left and right on individual bits) and I have no idea which ones or if there may be others the EPS is looking for. The plan is to hook it to the scan tool at work to see if it is reporting the speed I want, to try differing speeds to see how it affects the assist level and the “dead band.” The dead band where assist is reduced is supposed to get wider at faster speeds to keep the steering from feeling “twitchy” 0 dead band at low speeds for parking, +/- 5 degrees from center dead band at medium speed, and 10* above 45mph

I still plan to try to get this working, but I also just purchased a non abs Yaris EPS module on Ebay, so I may switch over to it. The non abs Yaris module is hardwired to a speed sensor and only needs a rpm signal over CAN to turn on. So that may be simpler on my car, I can use this project to turn on the EPS with the original sample transmit app and hook a speed sensor directly to the EPS. The Yaris and Prius EPS are the same physical size, mounting bracketry and connectors.

I’d still like to get this working even if its just a set hard coded MPH signal because these swaps are getting to be more common place (Hot Rod Magazine recently did a web article on them, with lots of people commenting about it being interesting) and while the system works pretty good in fail-safe, there are lots of people who may prefer having extra control and there’s not a whole lot of info out there on the CAN-BUS side of it. Also because the non-abs Yarus (Yarii?) are harder to find in the junk yards as there were less made. I have been looking nearly a year to find one in a local yard, or online and just found this one yesterday. The ABS equipped Yarus and Pruis use the exact same part number module, column and operate the same way. They are much easier to find and thus will probably be the more commonly swapped.

I believe it is working. On the rough concrete at key on within a half second the assist kicks in. About a half a steering wheel rotation, or within another half second I can feel the assist level increase (easier to turn). The initial assist seems to feel like the fail-safe mode did only no real delay. The second bump in power is noticeable, you can steer one handed. If you don’t touch the wheel at all and wait a second after key on you don’t feel the increase in power as you turn, but it is still easier than before in fail-safe.

I’ll report back after I drive it to work this week. I have the carloop stuff on a breadboard on the passenger floor. I’m going to see if there is a noticeable difference in the way the car drives on the road, and in parking lots as well as scanning it to see if there is any codes stored. Depending on how that goes I will decide if I will change the speed PID’s around to test or not.

Any update on this project? Did you decide on a single speed setting as sufficient or did you develop a way to detect speed via a sensor on the driveshaft,etc…?
I am working on an identical project in a ‘53 studebaker and have yet to find any other threads where someone successfully simulated CAN signals like this.

Thanks!

@behodge:

I decided after I got it working on single speed that I was happy with it as it was, so I never implemented the variable speed setup. On my car I have the can simulator broadcasting a simple message, which is basically "Vehicle speed = 10 MPH, engine speed = 1600 RPM over and over again. That is what is in the last section of code I posted above. As a result, the system works as if it were in a stock Prius driving through a parking lot, maximum assist, no “dead zone” and instant on with key on. I like the max assist level on my car as I have a relatively heavy big block v8 on top of the front tires. The Prius system on max assist is not quite as easy to turn as my stock 60s hydraulic steering was (but it will turn the tires on roughed concrete standing still), but I like that because it was over sensitive with the stock hydro steering as many 60s cars were, however with the minimum assist in failsafe mode it was better than manual steering but on rough concrete you had to be rolling or it didnt really assist. You can change the code above to get the three different assist levels if max isn’t what you prefer. All you have to change is the message data lines in the bold section in my last post.

Best I can tell from factory service manuals and other info on the net, there were three assist levels, roughly 15mph and slower is max assist, with no dead zone. Roughly 15 to 40 mph is medium assist and roughly a 5 degree left or right of center dead zone with less assist. Above 40 mph is minimum assist with a roughly 10 degree dead band. The dead band makes the Prius more sporty feeling at speed and less sensitive to twitches on the steering input at speed.

I noticed once I got the canloop stuff working that besides the instant on thing (which the 5 or 10 second delay in failsafe mode was a huge annoyance to me!) another huge benefit was my return to center got better. In failsafe mode, my car would not return to center fully after turning into a driveway or intersection for example. It would get within a 1/4 turn from center, but I would have to manually turn the wheel back the last 90 degrees or so manually to make the car go straight. After I got the canloop working, that improved I’d say 95%. Its so close to fully returning to center now that its like a whole different car, and I cant remember for sure if it ever actually returned that last 5%, LOL.

I have wired the canloop, the Prius EPAS module, and a Prius OBD2 under dash connector together, and I can now use the Snapon scan tool at work to read codes and data. Before the canloop, it would have a code for missing ABS CAN signal and therefore it would default to failsafe mode, and you could not make any adjustments like centering the torque sensor. With the canloop broadcasting the above code, the ABS missing data code could be cleared, and I was able to successfully recalibrate and recenter the torque sensor using the scan tool, which I believe is what actually fixed the return to center issue.

I actually drove the car the other day to work and plugged the scan tool in for the first time in a long time and it still has no codes, and the datastream shows VSS = 9MPH and Engine is ON.

Long story short, I never got the variable setup working but I’m more than happy with the single assist level and if you need any help with that I’ll be glad to do what I can to help you get yours working if I am able.

// THIS PROGRAM IS LOADED ON MY PHOTON IN THE CAR!!!

// This #include statement was automatically added by the Particle IDE.
#include carloop.h> %%%%%%%%%%%

#include “application.h”
#include “carloop/carloop.h”

// Don’t block the main program while connecting to WiFi/cellular. system_thread(enabled)
// This way the main program runs on the Carloop even outside of WiFi range.
// System_mode(manual) turns off wifi, immediately runs code. Must put in safe mode to reflash!
// SAFEMODE= press both buttons, release reset when flashing magneta, then flash.
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);

// Tell the program which revision of Carloop you are using.
Carloop CarloopRevision2> carloop;%%%%%%%%%%%%%

// Send a message at a regular time interval
void sendMessage() {
static uint32_t lastTransmitTime = 0;
uint32_t transmitInterval = 20; /* ms */
uint32_t now = millis();
if (now - lastTransmitTime > transmitInterval) {
CANMessage message;

// This message (2C4) is Engine speed = 1674 RPM
// A CAN message has an ID that identifies the content inside
message.id = 0x2C4;

// It can have from 0 to 8 data bytes
message.len = 8;

// Pass the data to be transmitted in the data array
message.data[0] = 0x06;
message.data[1] = 0x8A;
message.data[2] = 0x00;
message.data[3] = 0x19;
message.data[4] = 0x00;
message.data[5] = 0x00;
message.data[6] = 0x92;
message.data[7] = 0x09;

// Send the message on the bus!
carloop.can().transmit(message);

 // This message(0B4) is Vehicle speed = 10MPH
 // A CAN message has an ID that identifies the content inside
message.id = 0x0B4;

// It can have from 0 to 8 data bytes
message.len = 8;

// Pass the data to be transmitted in the data array
message.data[0] = 0x00;
message.data[1] = 0x00;
message.data[2] = 0x00;
message.data[3] = 0x00;
message.data[4] = 0x8D;
message.data[5] = 0x06;
message.data[6] = 0x66;
message.data[7] = 0xB5;

// Send the message on the bus!
carloop.can().transmit(message);

lastTransmitTime = now;

}
}

void setup() {
// Configure the CAN bus speed for 500 kbps, the standard speed for the OBD-II port.
// Other common speeds are 250 kbps and 1 Mbps.
// If you don’t call setCANSpeed, 500 kbps is used.
carloop.setCANSpeed(500000);

// Connect to the CAN bus
carloop.begin();
}

void loop() {
sendMessage();
}

This is my current code in full, (where the %%%%%%% is you need to add a < in front of carlooprevision2 and the carloop.h on the first include statement then delete the %%%%%%%%s. I wasnt sure how to edit the code to show those lines correctly without doing it this way.
If you add the SYSTEM_MODE(MANUAL); line near the top of the code, your canloop will not connect to WiFi at all and will begin transmitting the data on the can almost immediately. To get back into the canloop if you need to make changes to the code or programming you have to get the canloop to boot in safe mode by holding the reset button while powering up I believe. So for testing purposes you can leave that line off (or type a // in front of it turning it from a command to a comment in the code) once your sure the assist level is where you’re happy with it and every thing seems to work you can go back in and change it back where it will turn off the WiFi and lock the canloop down for the long run. That is how mine has been setup now for 3 years, although I took the EPS off for a year and a half and went back hydraulic due to a bad Prius part. I eventually put the EPS back on (with a new Prius column motor/sensor) over a year ago and its been working flawlessly ever since

This is awesome thanks so much! I’ve just got a couple more, probably dumb, questions. I’m totally new to CAN.

On the obd diagnostic port you added, is that just wired in to CAN high and low or are there ground/power wires that need to be wired in as well?

I saw where you were using a can hitch, but I can’t find that available for sale anywhere. Is that something you got from carloop as well?

Thanks!
Ben

I can help with the CAN part pretty well, I am an auto tech so I mess with these systems regularly, I will be a little slacking as far as the programming or hardware part goes, however LOL.

For the CAN wiring, I got a Prius OBD2 connector(DLC). I wired up the Prius EPS module’s three data wires to the OBD2 connector. CAN H which is pin 1 on the EPS and black goes to pin 6 on the DLC. CAN L pin 7 EPS white, goes to pin 14 directly below it. SIL pin 2 EPS also white, goes to DLC pin 7 beside pin 6 it may not be needed but Toyota uses the SIL circuit for some flash programming I believe, so I hooked it up. You’ll need battery hot to pin 16 on the DLC as well as a ground on pins 4 and 5 on the DLC for a scan tool to be able to power up and function. You can make these wires as long or short as necessary to put the connector where you want it but the CAN H & L wires need to be a twisted pair. I have my CAN simulator, the EPS module and the DLC all mounted to the same bracket under my dash, so all my CAN wiring is less than 1 foot long. You want DLC 16 to be battery hot not ignition too because you’ll need to switch the ignition power several times doing a torque sensor relearn and if the DLC is tied to Ignition power the scan tool will disconnect. You can twist the wires easily if its a longer run by cutting the two wires long and clamping one end in a vise and chucking the other in a drill and spinning it slowly. The CAN wiring MUST be twisted to prevent EMI or RFI interference. You’ll need to have two 120 ohm resistors (terminating resistor) on each end of the twisted wires also for the CAN to operate. If your CAN simulator has a built in term resist then you only need to add one resistor. The CAN hitch did not (or I didn’t take advantage of it if it did, I honestly cant remember at this point) so have a 120 resistor on each end of the twisted pair, soldered and heat shrinked in place, then I came in an inch or so and skinned back the twisted wires and spliced the EPS module wiring in on one end the CAN simulator an inch from the other end and the DLC can be tied in at one of those spots or anywhere in between (or even DLC on one end and the EPS and simulator on one end, CAN is flexible like that).

As far as what I’ve been calling the CAN simulator, that is a Particle Photon WIFI development module the CAN Hitch, and a 5v buck convertor power supply all mounted inside a plastic project box that’s roughly 2" x 3" and 2" tall. The Photon is the computer that you program with the code, it outputs a signal to the CAN Hitch, which converts the signal into a CAN message, and the 5v power supply is simply the guts from an old cigarette lighter cell phone charger, but you can buy a 12v to 5v buck convertor all over the place, including Amazon. It takes the 12 to 15v from the car and converts it to 5v for the Photon to use as power, the Photon has a 3.3v output pin that sends the CAN Hitch its needed 3.3v input power.

I did use the CAN Hitch with my setup, and I see it isn’t available anymore from Carloop. I’m not sure the Particle Photon is available anymore either. The Carloop CANHitch was really similar to this on Amazon: Waveshare Can module, AISN B00KM6XMXO. I’m not sure if the mods will allow this since its not their product, If so I’m sorry, they can edit or delete this. The Particle Photon may have a replacement or substitute, or you could possibly use something like an Arduino instead. That is about the limit of my electronics hardware knowledge unfortunately, and I’m not sure if the Waveshare module could use the Carlooop programming or if something there would need to be changed in the code. Of course if you used something other that the Photon, some of the code would need to be changed as well since they would most likely use different library registers. Which is the INCLUDE application and carloop lines in the code.

This forum is pretty dead anymore, so I’m not sure anyone from carloop is still active, but they may have some more info about hardware or something that will work.

The important part though is the message data and the time interval it is transmitted at in the code, so even if you use different hardware, you may be able to find someone to help you convert this code to work, unfortunately, that is also getting beyond my abilities, it has been over 25 years since I did any programming in high school:)

If you need any other help or have any more questions, contact me here or in a PM.

The Carloop Pro may be able to do everything the separate Photon and CANHitch did but I am not sure about that or the programming portions so maybe someone will answer that for us.

If so you’ll either need to get two DLC connectors, one for the Carloop Pro and one for a scan tool, or figure out a way to bypass the Carloop DLC connector and hard wire your can wiring to it to just have one DLC. But the CAN simulator will need to be attached and working to keep the EPS from defaulting to failsafe. And you cannot re calibrate the EPS if it is in failsafe, so you cant unplug the Carloop to plug in a scan tool.

Hey TimC,

Just wanted to let you know I ended up getting a photon and the Waveshare CAN board you listed and the steering column worked first try! Thanks a lot for the help! I only tested it on my bench, so I’ll still have to see if the assist level is good for me, but I expect it will be fine.

@behodge:

That’s great news. If you can hook up ignition “turn on” power to both the EPS module and the CAN simulator and it pretty much instantly has assist on the bench test it most likely works fine. If the CAN was not transmitting properly, there would be the usual 5 or 10 second wait before the assist kicks in when you bench test it due to it being in the “fail safe mode”. Just throwing that out there for anyone who stumbles on this thread in the future.

Once you get it installed, come back here and post a follow up if you don’t mind, I’m interested in how your project turns out and all this may help other hot rodders in the future.