It looks like you're new here. If you want to get involved, click one of these buttons!
Hello,
I reached out a while back about the custom VPW payload support and had my first track weekend last weekend. It worked great! I now have brake module data that I never had before which is awesome.
I have a question about how the software handles VPW packets with different headers.
Since the GM VPW bus is very slow (10.4 kbps), GM has DPID support. Which basically allows you to cut down on the number of requests needed. You can request up to 4 PIDs with a single request message. This has the advantage of getting rid of up to 3 messages transmitted on the bus.
Does the software do a request, and then wait for a reply before moving onto the next request/PID?
Reason I ask is that I am able to achieve higher throughput with some diagnostic tools I programmed (for development of hardware) by taking advantage of DPIDs.
The general process is to send a request message to a module, asking for up to 4 parameters. The module replies with 4 seperate messages like normal, of the PIDs in question as quickly as it can, and time synched. As the messages come in, i know the response prefix since I know I sent the DPID request. So i don't necessarily have to do a single request/response when polling, which helps my throughput.
I'm not sure if this is something that's possible to support, as it would require multiple responses to a single request to be processed for different PIDs. Almost like a filter as they come in.
You can see on the green and yellow traces (brake and throttle), the refresh rate can be a bit slower, which i know is due to the fact that they come from different modules, and probably waits for one to respond before requesting a pid from the other. I poll multiple parameters from the ECU so using DPID could help.
Comments
Sure, It's similar to a regular request, expect that the first byte is different, signaling a DPID mode to the module. Then the module will give responses back.
Here's an example from a bus datalog. Headers and the checksum are shown.
1) 6C 28 F1 2A 03 20 21 40 41 A6
2) 6C F1 28 6A 20 00 00 00 00 00 FF 42
3) 6C F1 28 6A 21 9B 00 A5 00 82 01 4F
4) 6C F1 28 6A 40 83 05 7F 00 00 00 11
5) 6C F1 28 6A 41 00 00 05 00 00 00 B9
1) Request from tool ($F1) for DPID data (mode 2A). 03 corresponds to an internal time interval for automatic sending, but for a single poll event, you can use 01 instead. 20, 21, 40, and 41 are all the PIDs that the module is requesting be sent (in a single request message). You can request up to 4 PIDs at a time, I believe. For my custom PIDs, I am using this mode (ABS module only supports mode $2A for data requests), but I specify only 1 PID since the software throws the rest away, and requesting more would be a waste of throughput.
2-4) The module sends the requested data as separate messages, but you can see the affirmative response ($6A) followed by the PID that is being send (20, 21, 40, 41), followed by the data.
The way I understand your implementation is that you do a single request, single response method and throw any additional responses away. This implementation would require that you have a way to tie a single request to multiple logged PIDs/groups of PIDs, and then parse the messages as they come in/filter them to determine which PID they correspond to.
I realize this is likely a large undertaking. A potential work around for me might be to make a custom piece of hardware that handles this efficient polling by itself and can send the data over BLE as requested by RaceChrono. It would be nice if multiple response support were possible.
In addition to DPID support, these OEM scanning tools also send a "bus silence" message out that will ask the modules not to transmit lower priority messages in order to help throughput further, but this is probably not needed.
To summarize, the main difference is that you can request a vehicle module send multiple messages with a single request message instead of the 1 request = 1 response model that is used now.
With this, 1 request = up to 4 responses, with very little time between the responses (as short as the module can possibly deliver), to further improve throughput.
Try this
Channel 1:
PID: 0x 2A 03 20 21 40 41 A6
Response prefix: 0x 6A 20
Channel 2:
PID: 0x 2A 03 20 21 40 41 A6
Response prefix: 0x 6A 21
And so on... Of course it's not very nice to have to manually stack the requests. And it makes it hard to select different channel combinations. But if it makes your bus more efficient then why not
RaceChrono already bundles channels with same PID as one single request, so this should work in theory...
I'll explain in more detail what a DPID is. Basically, it's a group of PIDs that get mushed together into a single response.
A basic example of this is requesting a DPID #FE from the ECU with
61 f1 10 2A 01 FE. I've requested only a single DPID, but within this DPID, there are 4 PIDs (you can see why this is so helpful for throughput).
The ECU will respond with
6C F1 10 6A FE 00 00 00 00 00 6C. This is on a bench ECU, so al lthe values are 0 right now, but bytes [0:1] = RPM, [2:3] = MAF, [4]=TPS, [5]=map.
This is helpful with the support you have, but what if I don't want to record MAF and instead want to record spark? Well, I can build a custom DPID with mode $2C. The downside is that it must be built every time the ECU is power cycled and it takes multiple initialization messages to do it.
So here's an example of building a DPID (we'll use #26 as an example, I'm not 100% sure what the acceptable range is by the ECU, but I know in the 20s works).
Lets build a DPID with the following PIDs, we have up to 5 bytes to return data with
1) $000C: high res RPM (2 bytes)
2) $000B: MAP (1 byte)
3) $0005: ECT (1 byte)
4) $000F: IAT (1 byte)
Initialization requirement with the ECU to build the DPID:
1) 6C 10 F1 2C 26 4A 00 0C: the 4A assigns the byte location, and number of bytes for the PID. Bits [7:6] say its a PID, [5:3] explain which return byte, [2:0] say how many data bytes are returned for the PID
2) 6C 10 F1 2C 26 59 00 0B
3) 6C 10 F1 2C 26 61 00 05
4) 6C 10 F1 2C 26 69 00 0F
Once these are loaded up, then we can request the DPID with our normal DPID request PID for the remainder of the time the ECU is powered.
TX: 6C 10 F1 2A 01 26
Response with 4 PIDs: 6C F1 10 6C 26 aa aa bb cc dd xx
where:
aa is RPM
bb is MAP
cc is ECT
dd is IAT
Any chance the software already supports sending these DPID request initialization commands on the start of a datalog?
Only thing I'm noticing now. I made sure to group my DPIDs into fast and slow groups, so that all the fast PIDs would use 1 DPID and all the slow would use another.
I'm seeing when I sniff the bus that it simply polls between fast and slow. It's not hitting the fast one several times and then hitting the slow. So my fast and slow channels have the same sample rate right now. I'd like to prioritize engine RPM and stuff and let air and trans temps be slow.
Few things:
1) Fast vs slow channels don't seem to get differentiated when I look at data bus with a sniffer. It seems the software is literally just alternating between the two PIDs, even though I have 1 set to slow and one set to fast. Realistically, my "slow" channels can be read every 2-5 seconds (oil, intake, trans temps). I'd rather read my RPM and throttle/brake data quickly.
2) Since they both seem to fire off at the same rate, I tried combining my PID request into 1. RC did NOT like this. Remember I have 2 separate DPIDs (groups of PIDs), one is fast (0xFE), and the other is my slow PIDs (0xFD). I can request them both at the same time with
6C 10 F1 2A 01 FD FE: This says send me DPIDs FD and FE once.
Response is 2 separate messages
1) 6C F1 10 6A FD aa bb cc 00 00 00 xx
2) 6C F1 10 6A FE dd dd ee ff gg 00 xx
aa = air temp
bb = ect
cc = trans temp
dd dd = rpm (2 bytes)
ee = oil pressure
ff = throttle %
gg = knock
xx = crc
My thought process here is that by combining all of my PIDs into the single request, I at least get rid of 1 request and improve my overall throughput (they have the same header and PID now, only different is the response prefix).
Race chrono seemed to only look at the first response it got to the request.
Since the first response is the FD DPID, only the PIDs with the 6a FD response prefix recognized it. All the 6A FE prefix PIDs showed red text with the raw data in the menu.
If I swapped FD and FE around in the request, the opposite became true of the PIDs.
It seems like RC is unable to handle getting 2 responses for some reason? Once I split the PIDs back to either FD or FE only, RC was happy and processed the data, but my throughput went down since it would send FD request, wait for response, then send FE request, wait for response.
Ultimately, i'd like to see the slow data sample slower than the fast.
**** Stuff for your debugging if it's helpful ****
Here's what I put in my initialization part of the profile: atsh6c10f1\n2cfe4a000cffff\n2cfe59115cffff\n2cfe610011ffff\n2cfe6911a6ffff\n2cfd49000fffff\n2cfd510005ffff\n2cfd591940ffff\n
It just sets up the DPIDs as I illustrated above
Here's the raw dump from my bus when RC was data logging: I stripped the module heart beat messages out to make it only RC's traffic
6C 10 F1 2C FE 4A 00 0C FF FF CC <-- This is where RC starts its custom initialization
6C F1 10 6C FE 4A CB
6C 10 F1 2C FE 59 11 5C FF FF 5C
6C F1 10 6C FE 59 21
6C 10 F1 2C FE 61 00 11 FF FF 59
6C F1 10 6C FE 61 83
6C 10 F1 2C FE 69 11 A6 FF FF F4
6C F1 10 6C FE 69 6B
6C 10 F1 2C FD 49 00 0F FF FF 34
6C F1 10 6C FD 49 38
6C 10 F1 2C FD 51 00 05 FF FF A2
6C F1 10 6C FD 51 1D
6C 10 F1 2C FD 59 19 40 FF FF 18
6C F1 10 6C FD 59 F5
6C 10 F1 01 00 E2 <-- No idea what this is. I assume this is you in RC doing something
6C F1 10 7F 01 00 11 A8 <-- ECU didn't like whatever request this was, sends a "Mode not supported" message
6C 10 F1 2A 01 FD B1 <--- This is the first time RC starts polling, asks for the low speed PIDs first (FD)
6C F1 10 6A FD 01 01 01 00 00 00 3A <-- The response, with 3 PIDs in this response
6C 10 F1 2A 01 FE 96 <-- Now RC asks for the high speed
6C F1 10 6A FE 00 00 01 00 00 01 EC <-- The response with RPM and other high speed PIDs
6C 28 F1 2A 01 41 19 <-- It now asks my ABS module for brake pressure (fast PID)
6C F1 28 6A 41 00 00 05 00 00 00 B9 <- Gets response
6C 10 F1 2A 01 FD B1 < - Back to slow PID??
[Cycle repeats below]
6C F1 10 6A FD 01 01 01 00 00 00 3A
6C 10 F1 2A 01 FE 96
6C F1 10 6A FE 00 00 01 00 00 01 EC
6C 28 F1 2A 01 41 19
6C F1 28 6A 41 00 00 05 00 00 00 B9
6C 10 F1 2A 01 FD B1
6C F1 10 6A FD 01 01 01 00 00 00 3A
6C 10 F1 2A 01 FE 96
6C F1 10 6A FE 00 00 01 00 00 01 EC
6C 28 F1 2A 01 41 19
6C F1 28 6A 41 00 00 05 00 00 00 B9
6C 10 F1 2A 01 FD B1
6C F1 10 6A FD 01 01 01 00 00 00 3A
6C 10 F1 2A 01 FE 96
6C F1 10 6A FE 00 00 01 00 00 01 EC
6C 28 F1 2A 01 41 19
1) Slow/Fast channels work like this: All fast channels are requested once. After that one of the slow channels are requested. Then the loop starts from beginning. It does not really work if you have only one fast and one slow channel.
2) No idea where "6C 10 F1 01 00 E2" comes from... shouldn't be me... something in the configuration.
3) So the request "bundling" does not work like I described? RaceChrono looks at all the response lines, but it maybe failing for other reasons. What does the response look like when requesting multiple PIDs in one? Please be exact I will use it to write an emulator.
Here's where I'm at. Here's an exact datalog for when I request 2 PIDs with a single request.
6C 10 F1 2C FE 4A 00 0C FF FF CC <== ECU DPID request for 0xFE
6C F1 10 6C FE 4A CB
6C 10 F1 2C FE 59 11 5C FF FF 5C <== ECU DPID request for 0xFE
6C F1 10 6C FE 59 21
6C 10 F1 2C FE 61 00 11 FF FF 59 <== ECU DPID request for 0xFE
6C F1 10 6C FE 61 83
6C 10 F1 2C FE 69 11 A6 FF FF F4 <== ECU DPID request for 0xFE
6C F1 10 6C FE 69 6B
6C 10 F1 2C FD 49 00 0F FF FF 34 <== ECU DPID request for 0xFD
6C F1 10 6C FD 49 38
6C 10 F1 2C FD 51 00 05 FF FF A2 <== ECU DPID request for 0xFD
6C F1 10 6C FD 51 1D
6C 10 F1 2C FD 59 19 40 FF FF 18 <== ECU DPID request for 0xFD
6C F1 10 6C FD 59 F5
6C 10 F1 01 00 E2 <== Still no idea where this came from
6C F1 10 7F 01 00 11 A8
6C 10 F1 2A 01 FD FE 93 <== First request by RC for polling. This requests DPIDs 0xFD and 0xFE
6C F1 10 6A FD 01 01 01 00 00 00 3A <== Response for 0xFD from ECU
6C F1 10 6A FE 00 00 01 00 00 00 F1 <== Response for 0xFE from ECU
6C 28 F1 2A 01 41 19 <== Request for ABS module PIDs
6C F1 28 6A 41 00 00 05 00 00 00 B9 <== Response from ABS
6C 10 F1 2A 01 FD FE 93 <== Request from ECU for DPIDs 0xFD and 0xFE again thigns repeat again
6C F1 10 6A FD 01 01 01 00 00 00 3A
6C F1 10 6A FE 00 00 01 00 00 00 F1
6C 28 F1 2A 01 41 19
Race chrono does not like this for some reason. In this case, all the PIDs that ahve OBD response prefix of "0x6A FE" are just read, even though the data is valid. I have a screenshot, but can't show it to you on this forum for some reason...
all of my PIDs have a OBD header of "0x6C 10 F1" and a PID of "0x2A 01 FD FE", and the OBD response prefix varies between "0x6A FE" and "0x6A FD"
I went from logging 4 PIDs at ~2-3 Hz to logging 8 PIDs at 5-6 Hz
I think many of the newer Bosch ECUs have $2C implementation in stock form though.
Got your email. Thanks for the update.
I just tested 7.2.4. I can confirm that this multiple responses from single PID request now works as expected! Thank you!
One thing i see still is that when I import a profile, it overwrites my existing profile instead of adding another (they have different names).
I would like to be able to have a few profiles for specific data sets, since each PID has to be custom built using this approach.
Awesome. Thank you!
I think I understand the general concepts here.
- Input init string to "build out" the DPIDs are desired....in the example some params were loaded up into FD and FE locations.
- Define a "custom PID" in RaceChrono that is basically requesting to read FD and FE locations: 6C 10 F1 2A 01 FD FE
- From what I understand, as part of the init DPID building process, you know what byte will be which param in the response.
But how do I set up RC so that it knows that FD byte 5 is air temp, FE byte 6 is knock (for example), etc.? @aol I poked around the software, but I can't seem to find anything along those lines.....but I could very well be missing it.
Thanks!
@jvaldez has the following:
OBD-II header: "0x6C 10 F1"
PID: "0x2A 01 FD FE"
OBD-II response prefix: "0x6A FE" for one channel and "0x6A FD" for the other channel
I guess now we just need a way to parse out the individual bytes into known parameters such as RPM, oil pressure etc?
https://i.imgur.com/AhF6Nmj.png
https://i.imgur.com/C7Ka7X2.png
https://i.imgur.com/TxxEIf8.png
Everything you mentioned about understanding the DPID above is correct.
I had to create new custom PIDs for each of the bytes in the responses to pull out the specific bytes of interest. @aol updated the software to recognize when multiple PIDs use the same request message and it only sends it once and is able to use the same response for multiple custom PIDs.
FWIW the C5 ABS module does report steering angle, but for some reason it doesn't seem to work on my car. When I poll it with my Tech 2, it always shows 0*, even though the raw voltage output of the steering sensor changes. I'd like to get some steering sensor input data...
Events are non existent right now by me, so I'm off track until September at least.
As you saw I got it working for CAN stuff. I'm not quite as familiar with VPW message format, but I'm sure I can figure it out when I re-visit this soon...
Thanks for leading the way on this and @aol for supporting/implementing in the app as needed!