Talking to an automotive ECU

So I want to use an Arduino to process a serial data stream from a motorcycle's ECU (Suzuki SV650). The data stream is what the ECU sends to the dashboard. I already know that the stream looks like:

10 messages/second @ 30ms apart
each message is 8 bytes @ 10ms apart

I need to process the 8 bytes together (last byte is CRC) and do some quick parsing to illuminate an LED/7 segment display. No big deal.

So far the best idea I've come up with is using SoftwareSerial (I have an Uno and I want to use the USB serial for debugging) to read the bytes and just measure the time by calling micros() each time to measure the delta between bytes to figure out where I am. Seems kinda hackish, so I figured I'd ask here if there are better ways.

One thing I'd like to add in the future is to process a 2nd analog line and output on a 3rd analog line. Basically I want to fake the ECU into thinking that there still is an electric motor and it's position sensor are still attached. Not sure how quickly I need to respond to it's inputs to keep the ECU happy (technically there shouldn't be any lag, but I'm sure it would be OK with some), but 10-30ms might be too much???

I've heard about programming via interrupts before- maybe that would allow me to do both on the same Arduino elegantly? Not sure what kind of limitations that has?

Anyways, looking for advice on how to proceed and any links to things I should read about. Thanks!

...a serial data stream from a motorcycle's ECU...

Are you certain it's not CANBUS or LINBUS?

Yeah, it's not LINBUS or CANBUS. It's single wire, uni-directional and point-to-point. The message format is very simple. First two bytes are water temp, followed by a bit mask for various error codes and the last byte is a simple CRC. Even the tachometer is on a separate line and is a different protocol.

This thread on SV Rider has the details if you're interested: SV650 ECM Serial Data Stream Hack | Suzuki SV650 Riders Forum

So I did more reading on interrupts... sounds like they only work for digital pins, so probably not viable to deal with both inputs asynchronously. Guess the easiest thing is to just do something like this:

int last_ms = millis();
void loop() {

if (ecu.available()) {
ms = millis();
delta = ms - last_ms;
if (delta < 20) {

process byte

} else {

process message

}
} else {

read analog pin

}
}

synfinatic:
Guess the easiest thing is to just do something like this:

As long as the rest of your sketch follows the same blink-without-delay / state machine pattern then, yes, that is most certainly the easiest thing to do.

Hmmmm... we'll I've got something that I thought should work but seems pretty broken:

https://dl.dropbox.com/u/10783986/ecu-reader.ino

I tried hooking it up to the ECU and no luck at all... doesn't see any packets at all. If I hook it up to another Arduino running the simulator code I saw on the SV forum, it sees data; but only if I change it to 9600 baud (the emulator is running at 7800?) Even then though, things are broken- seems like I'm missing occasional bytes on the wire and looks like the data is corrupted.

Not sure if this is a limitation of the SoftwareSerial library or if my code is subtly broken. I looked at the limitations about the library on it's web page, but since I'm using an Uno and only one pin for serial, it doesn't sound like either apply to me.

Anyways, hopefully the logic analyzer I ordered shows up tomorrow and I can see the ECU protocol for myself rather then relying on some descriptions by other people.

You said, you didn't see anything at all.

And then you said, some bytes are missing .

To me that seems inconsistent. Are you seeing anything happen, what do you see ?

synfinatic:
seems like I'm missing occasional bytes on the wire and looks like the data is corrupted.

That would be consistent with a speed difference between the sender and receiver. If you're receiving data at all they must be pretty close.

Can you have any speed you like with serial ? is 7800 a permissible number ?

michinyon:
Can you have any speed you like with serial ? is 7800 a permissible number ?

Look at the documentation for Serial.begin(). You can specify any speed you like (within limits) and also have control over the other connection parameters. However, I seem to remember reading that the underlying hardware has some limitations on the supported line speed (for example, it can produce 9600 bps but might not be able to produce 9601 bps) so you may find that if you specify an arbitrary frequency it may produce something that is close, but not exactly what you requested. Give it a try - what do you have to lose?

michinyon:
You said, you didn't see anything at all.

And then you said, some bytes are missing .

To me that seems inconsistent. Are you seeing anything happen, what do you see ?

If I run at the same speed as the Arduino emulator (7800 baud, but it's using the UART) I see nothing.

If I run at 9600 baud (emulator still at 7800) then I get data, but it seems corrupted.

Here's the emulator code I'm using:

https://dl.dropbox.com/u/10783986/ecu-emulator.ino

Good news. Fully able to read the ECU data stream. Have to set the SoftwareSerial to 9600 baud (nothing else works at all), and I'm getting some odd timing errors, but I've been able to work around them so far and I'm so far able to parse the messages.

USPS wanted a signature for the logic analyzer and I was at work so didn't get it yet- so not able to compare the actual data stream to what the arduino is reading, but so far so good. Thanks!

synfinatic, how did you get on with this? I'm looking to decode the data from a GEN2 ECU to display on an OLED display, cna you share your latest code?

Thanks