RomRaider Logo

RomRaider

Open Source ECU Tools
 FAQ •  Register •  Login 

RomRaider

Documentation

Community

Developers

It is currently Sat Feb 21, 2026 4:16 pm

All times are UTC





Post new topic Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Mon Sep 22, 2014 10:48 pm 
Offline
RomRaider Developer

Joined: Thu May 21, 2009 1:49 am
Posts: 7323
Location: Canada eh!
humjaba wrote:
So I'm trying to construct my serial command; does what I have make sense?

http://www.romraider.com/RomRaider/SsmProtocol


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Mon Sep 22, 2014 11:37 pm 
Offline
Newbie

Joined: Tue Feb 12, 2013 5:06 am
Posts: 23
dschultz wrote:
humjaba wrote:
So I'm trying to construct my serial command; does what I have make sense?

http://www.romraider.com/RomRaider/SsmProtocol


Yes that's what I'm using, I was looking for validation that I had calculated the checksum and data length correctly (first time doing anything byte-wise). I guess I can just try it when my resistors come in :P


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Thu Sep 25, 2014 11:42 pm 
Offline
Newbie

Joined: Wed Jul 09, 2014 4:11 pm
Posts: 24
I'd like to help, but am too lazy to figure out what the correct addresses are for your car; in my experience, I used learning view to find my ecu ID, then used the romraider definition file to find the ECU polling address. You've listed out some addresses, but I haven't tried to verify them, and I was not able to make sense of the strange ordering/phrasing of the number translations ( "0xffbfac:   16760748 " = huh?).

As an attempt to be helpful I'll give a packet example that works for me (2005 wrx), and I'll explain it:

Poll for:
IAT, IDC, MRP direct

128 -begin packet
16 -to ECU
240 -From diagnostic tool
23 -twentythree bytes of data (count all data after this, excluding checksum)
168 -A8, the read single address byte
0 -set to 1 for fast polling
2 -MRP
24 -MRP
32 -MRP
2 -MRP
24 -MRP
33 -MRP
0 -IAT
0 -IAT
18 -IAT
0 -IDC
0 -IDC
32 -IDC
0 -IDC
0 -IDC
14 -IDC
0 -IDC
0 -IDC
15 -IDC
0 -defogger
0 -defogger
100 -defogger
103 -checksum


the checksum is calculated from: sum all bytes = 871 = (binary) 1101100111
the 8 least significant bits are: 01100111, or 103. Hence the checksum.

Does this help?

Please post your project when you get finished! I like to hear about this kind of thing.


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Fri Sep 26, 2014 11:25 pm 
Offline
Newbie

Joined: Tue Feb 12, 2013 5:06 am
Posts: 23
Thanks for the response - I think I have my packet organized correctly.

Now my problem is this. I try to send it to the ecu using HWSERIAL.write() (Teensy has hw serial - #define HWSERIAL Serial1). Then, I when I try to do HWSERIAL.read() it reads the packet I sent back to me. I'm using the circuit you posted on the wrx forums, but I got the same result using this circuit here. If I unhook 12v to the rx circuit I receive nothing. Connecting/disconnecting to the k-line high doesn't seem to make any difference. Any ideas?

Source code:
http://pastebin.com/ZfeNjJM5


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Sat Sep 27, 2014 2:24 pm 
Offline
RomRaider Developer

Joined: Thu May 21, 2009 1:49 am
Posts: 7323
Location: Canada eh!
That's K-Line (ISO9141), one wire for both TX and RX so you will always see the packet you send followed by the response from the ECU (assuming the packet was accepted). The order of values in the response will be the same as the order in which you requested them.

You also need to keep track of 1 byte and 2 byte parameter responses and reassemble the two bytes response to get the parameter value, i.e.: RPM, MAF, etc.

If you need code examples for k-line look at ecuExplorer (C++), FreeSSM (C++), .Net SSM (C#), RomRaider (Java)


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Sat Sep 27, 2014 5:59 pm 
Offline
Newbie

Joined: Tue Feb 12, 2013 5:06 am
Posts: 23
dschultz wrote:
That's K-Line (ISO9141), one wire for both TX and RX so you will always see the packet you send followed by the response from the ECU (assuming the packet was accepted). The order of values in the response will be the same as the order in which you requested them.

You also need to keep track of 1 byte and 2 byte parameter responses and reassemble the two bytes response to get the parameter value, i.e.: RPM, MAF, etc.

If you need code examples for k-line look at ecuExplorer (C++), FreeSSM (C++), .Net SSM (C#), RomRaider (Java)


I thought that might be the case, so just for diagnostics I do HWSERIAL.read() 100 times. I receive the packets I sent, but nothing after that (all -1). The packets I send look like this:
Code:
[128, 16, 240, 29, 168, 0, 0, 0, 14, 0, 0, 16, 0, 0, 8, 0, 0, 18, 0, 0, 70, 0, 0, 48, 0, 0, 36, 0, 0, 17, 255, 191, 172, 34]

I got the addresses from the romraider file for my ecu (really only the knocksum seems specific for my ecu). I'll have to add return size to my ecudataobject struct - no big deal. I just need some kind of response.

Edit: We have communication! I was calculating the checksum wrong. I was summing the number of bytes, instead of the contents of the bytes themselves. Thanks guys! Now on to the response size...

Edit 2:
So I've got communication pretty reliable. Just looking at some of the responses now. For RPM, I am requesting from address 0x00, 0x00, 0x0e as the logger.xml file says, but the ECU is only returning one byte. It changes with engine speed, but I don't know how to interpret it. Wastegate duty cycle and knock sum do not seem to change. My ecu is A2WC511C, or ecuid 2F12505306. Any ideas why this might be?

Code:
Request:
128
16
240
29
168
0
0 RPM
0
14
0 Speed
0
16
0 CLT
0
8
0 IAT
0
18
0 AFR
0
70
0 WGDC
0
48
0 MRP
0
36
0 Total Timing
0
1
255 Knock Sum
191
172
130

Response:
128
240
16
10
232
3 RPM
0 Vehicle Speed
107 Coolant Temp
83 IAT
132 AFR
0 WGDC
67 Mani Rel Pressure
47 Timing
0 Knock sum
70


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Tue Sep 30, 2014 12:26 am 
Offline
Newbie

Joined: Tue Feb 12, 2013 5:06 am
Posts: 23
Updates!

So, it looks like wastegate duty cycle does work after all. Sitting there revving in neutral just didn't open it - after driving, it's responsive. So I now have the following problems left to address:

* Why do I only get one byte back from RPM? It's not really necessary, but I'd still like to know how to make it work.
* Why doesn't knock sum return anything? Can it be access with the same A8 command? It works in romraider.
* Obeisance - did you get this communicating through one of the pins on the clock connector? Mine works through the k-high pin on the obdii port, but not when I run it through the UART/pin 5 on the clock connector


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Tue Sep 30, 2014 2:40 am 
Offline
RomRaider Developer

Joined: Thu May 21, 2009 1:49 am
Posts: 7323
Location: Canada eh!
Go back and review my previous post, your answer is there and everything you need is in the logger.xml.


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Sat Oct 04, 2014 12:45 pm 
Offline
Newbie

Joined: Wed Jul 09, 2014 4:11 pm
Posts: 24
humjaba wrote:
Updates!

So, it looks like wastegate duty cycle does work after all. Sitting there revving in neutral just didn't open it - after driving, it's responsive. So I now have the following problems left to address:

* Why do I only get one byte back from RPM? It's not really necessary, but I'd still like to know how to make it work.
* Why doesn't knock sum return anything? Can it be access with the same A8 command? It works in romraider.
* Obeisance - did you get this communicating through one of the pins on the clock connector? Mine works through the k-high pin on the obdii port, but not when I run it through the UART/pin 5 on the clock connector


My communication is through the k-line too- I don't think that my GD-wrx has a fancy UART connector in the clock pod. Is it possible that the UART connection needs 5V rather an your 12V buffer?

I inadvertently ask for RPM when getting the injector duty cycle (IDC); I use 0x0 0x0 0x0e and 0x0 0x0 0x0f (that is 0,0,14 and 0,0,15) to get the two parts of it (I actually found my polling addresses by spoofing the ecu via the arduino and getting romraider and learning view to poll it for the values I had selected, it was not until afterwards that I realized that the logger definitions had all the answers). It is quite possible that I'm interpreting the numbers wrong, but I just append the two response values together to get my rpm: if my response gives 11 and 83, I coded the arduino to have 1183 as the rpm. So far, the IDC values don't seem unreasonable. Someone please correct me if I'm wrong

What is knocksum?

edit: some of the parameters do not have a straightforward interpretation; I didn't know that the romraider code was posted online, so I racked my brain for a few weeks trying to figure out how to interpret the manifold relative pressure bytes; finally, I realized that the logger math had the number like 32768 in its math (and a conversion factor) that the numbers returned are two halves of an 16 bit binary integer.


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Sat Oct 04, 2014 3:04 pm 
Offline
RomRaider Developer

Joined: Thu May 21, 2009 1:49 am
Posts: 7323
Location: Canada eh!
Obeisance wrote:
I use 0x0 0x0 0x0e and 0x0 0x0 0x0f (that is 0,0,14 and 0,0,15) to get the two parts of it. It is quite possible that I'm interpreting the numbers wrong, but I just append the two response values together to get my rpm: if my response gives 11 and 83, I coded the arduino to have 1183 as the rpm. So far, the IDC values don't seem unreasonable. Someone please correct me if I'm wrong

edit: some of the parameters do not have a straightforward interpretation; I didn't know that the romraider code was posted online, so I racked my brain for a few weeks trying to figure out how to interpret the manifold relative pressure bytes; finally, I realized that the logger math had the number like 32768 in its math (and a conversion factor) that the numbers returned are two halves of an 16 bit binary integer.

Yes the interpretation of the values returned is wrong if you are using them as you describe above. RPM = (MSB*256 + LSB)/4
MRP psi = (value-128)*37/255
The logger.xml has all the info you need to request and convert the hex response to a real value.
For parameters that return two or four bytes you are asking the ECU to return to you the two or four bytes that make up the parameter response value.
For a two byte response this is a hex integer word value big endian. You always request the MSB then the LSB separately. When you have the two bytes shift left 8 or *256 the MSB then add or OR the LSB to it, this is known as 'x' in the conversion formula. Now apply the conversion formula to get the real value in units according to the logger.xml conversion.
The bytes of a four byte response make up a IEEE-754 floating point number. Shift each byte starting with the MSB to LSB into position interpret the float value and use the conversion to get the real number. Such as lambda *14.7 to get AFR gas.

For IDC you need to read the dependent parameters defined in the logger.xml, convert them to their real values and perform the math of the IDC conversion formula on them.
IDC units="%" expr="(P8*[P21:ms])/1200" where P8 is Engine Speed in RPM and P21 is Injector PW in msecs.

The UART in the clock pod uses a serial protocol (2400baud, 0-12VDC inverted) to communicate with the combination meter to display the temp, and fuel consumption info. The combo meter gets most of its info from the ECU over the CAN bus.


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Sat Oct 04, 2014 7:18 pm 
Offline
Newbie

Joined: Wed Jul 09, 2014 4:11 pm
Posts: 24
Thanks for the reply. The logger.xml file has been rather opaque to me; I saw the math being performed and could work out unit conversions and see how the named values were used to calculate the end value, but the interpretation of the ecu response bytes to get the named value is challenging. Hence I didn't realize that the rpm was calculated incorrectly...

Here are the lines from the defns. which I used:

MRP direct: (two bytes)
<conversion units="psi relative" expr="(x-32768)*0.01933677" format="0.00" />

IDC: (one byte for IPW, two for RPM)
<conversion units="%" expr="(P8*P21)/1200" format="0.00" />


thank you again for your correction- my IDC value should be much improved! This explanation of how to read the logger definitions was much needed for me.

For external reference, the other relevant logger defn. lines are:

RPM (P8): (two bytes)
<conversion units="rpm" expr="x/4" format="0" />
IPW (P21):
<conversion units="ms" expr="x*256/1000" format="0.00" />

I believe that conversations like this- where enthusiasts can learn about any facet of their cars- make Subaru ownership a worthwhile and unique experience.


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Mon Oct 06, 2014 11:12 pm 
Offline
Newbie

Joined: Tue Feb 12, 2013 5:06 am
Posts: 23
I've been off this project for about a week now because other stuff has come up but I'll be returning to it soon. My problem with the knock sum was an error in the code I wrote to parse the xml file (too lazy to look up the values myself), so I was using the wrong address. I've put the code here (it's in Python). You can find the ecuid in the xml file for your ecu (mine is A2WC511C for example)
Code:
import xml.etree.ElementTree as ET
import pandas as p
p.set_option('display.max_rows',500)
tree = ET.parse('logger_IMP_EN_v269.xml')
root = tree.getroot()
ecuparams = {}

ecuid = '2F12505306'

for child in root[0][0][0]:
    for ids in child.iter('parameter'):
        temp = child.find('conversions')[0].attrib
        temp['address'] = ids[0].text
        temp['name'] = child.attrib['name']
        temp['desc'] = child.attrib['desc']
        ecuparams[child.attrib['id']] = temp

# ECU-Specific Parameters
for child in root[0][0][3]:
    for ids in child.iter('ecu'):
         if ids.get('id').find(ecuid) >= 0:
            temp = child.find('conversions')[0].attrib
            temp['address'] = ids[0].text
            temp['name'] = child.attrib['name']
            temp['desc'] = child.attrib['desc']
            ecuparams[child.attrib['id']] = temp
           
ecuparams=p.DataFrame(ecuparams).T[['name', 'address', 'desc', 'expr', 'format', 'storagetype', 'units']]
display(ecuparams)


Thanks for the explanation on how to interpret multibyte responses - I had suspected that is how it was done but I haven't gotten around to writing the code to try it. I did get it to send the correct message though. Is it safe to assume that the address of the second/third/fourth byte is the address of the first+1,2,3 ?

As far as the UART on the clock goes, it seems that the airbag controller also expects some kind of response from the microcontroller for the on/off light. I'll just put my controller in the middle and sniff out the packets so I can duplicate them, but is there any documentation of what is sent/received over that line?


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Tue Oct 07, 2014 2:54 am 
Offline
RomRaider Developer

Joined: Thu May 21, 2009 1:49 am
Posts: 7323
Location: Canada eh!
humjaba wrote:
Is it safe to assume that the address of the second/third/fourth byte is the address of the first+1,2,3 ?
Yes

humjaba wrote:
As far as the UART on the clock goes, it seems that the airbag controller also expects some kind of response from the microcontroller for the on/off light. I'll just put my controller in the middle and sniff out the packets so I can duplicate them, but is there any documentation of what is sent/received over that line?
I know of this:
|temperature|unknown|instant MPG|avg MPG A|avg MPG B|miles remaining|00|A/B|checksum|
This 9 byte data packet is sent every 0.1 seconds.


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Thu Oct 09, 2014 1:47 pm 
Offline
Newbie

Joined: Tue Feb 12, 2013 5:06 am
Posts: 23
Thanks. Still working on parsing the multi-byte response.

However, one thing I can't figure out is this. Asking for address FF5CEC gives "68" as the response. After some driving it sometimes goes to "69". In the logger.xml file this address is listed as the address for the knock sum on my ECU. Any idea why it doesn't show knock sum?
EDIT: Because I'm an idiot; A2WC510N is my ECU. A2WC511C is for the auto trans.
EDIT2: Nope, address is still FF5CEC for that as well. ECU ID = 2F12785206


Top
 Profile  
 
 Post subject: Re: Arduino Based SSM Gauge
PostPosted: Thu Oct 09, 2014 9:27 pm 
Offline
RomRaider Developer

Joined: Thu May 21, 2009 1:49 am
Posts: 7323
Location: Canada eh!
humjaba wrote:
However, one thing I can't figure out is this. Asking for address FF5CEC gives "68" as the response. After some driving it sometimes goes to "69". In the logger.xml file this address is listed as the address for the knock sum on my ECU. Any idea why it doesn't show knock sum?
Not really. The value is a single byte response and starts at 0 and goes to 35 then is resets to 0 again. It increments 1 count per knock event.
Are you parsing your response correctly? You need to keep track of the order of your requests as the response is in the same order. You need to keep track of the number of bytes per response you expect as that is how you will know which byte index is the start byte of each response item.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 50 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Style based on FI Subsilver by phpBBservice.nl