Has anyone reverse-engineered ECM-CCM comms?

Looking back through some old datalogs in attempt to find anything related to that "running total fuel" item, I noticed a column for "economy". It was filled with zeros, but I found its entry in my ADX file:
<desc>MPG calculation. Not exact but a good representation. Must adjust Injector Constant item in this definition to match your setup.
MPH/(INJ*0.0000212*(RPM)*(BPW))</desc>
<flags>0x00000004</flags>
<units>MPG</units>
<packetoffset>0x00</packetoffset>
<range low="0.010000" high="25.000000" />
<alarms low="8.000000" high="18.000000" />
<digcount>2</digcount>
<outputtype>3</outputtype>
<datatype>56</datatype>
<unittype>77</unittype>
<MATH equation="X/(C*0.0000212*(Y+.0001)*(Z+.0001))">
<VAR varID="X" type="link" linkIDHash="0xEC88EB35" />
<VAR varID="C" type="link" linkIDHash="0xF9003BEB" />
<VAR varID="Y" type="link" linkIDHash="0x33458A94" />
<VAR varID="Z" type="link" linkIDHash="0xCD53DC5B" />
</MATH>
</ADXVALUE>
- Speed
- Injector flowrate
- Engine speed
- Injector base pulsewidth
Something else that occurred to me might be a clue is the behavior of the MPG display when datalogging. The instant reads "69", which seems to be the error value indicating that ECM/CCM comms were lost. However, the average mpg display slowly ticks downward as if it's currently registering 0 mpg. I think this makes sense: the CCM is still getting data from the fuel sender, but it's lost the other piece of the calculation that it gets from the ECM. I'm assuming this is running total distance traveled (word 51 in A115).
I can't quite reconcile this with the datastream item you just found though. I would think that a running total of fuel would be used for average MPG, not for instant. It doesn't make sense that the CCM would be needlessly forced to differentiate.
I also don't quite get the comment "uSEC = ([N49]*256 + [N50])*15.26". This says that some time value in microseconds is a linear combination of the previous two words (IPFUEL most significant byte and least significant byte). However, shouldn't a running total of fuel be a volumetric or weight measurement? Maybe I'll try to add those values to my ADX file and see what comes out.
My ADX says it was written by Mark Mansur, the creator of TunerPro. It might be worth reaching out to him. However, the TunerPro site seems to be down?
You're totally right about the oil light reset procedure. I'm not sure what I was thinking of.
Last edited by C4ProjectCar; Jan 19, 2021 at 09:04 AM.
As for your ADX, if you "believe" 'INJ' is 'IP Injector Flow Rate' in the BIN, confirm it. The ADX isn't a black box; it tells you exactly what it's querying. I don't have your ADX in front of me, but since you do have it in front of you, I'd cross-reference what the ADX is actually pulling there and confirm 100% for sure what 'C' is in that estimated MPG calculation. You are correct however that this is not querying the ECM for the MPG, but is rather performing the math on your computer and then displaying the result in TunerPro RT.
For reference, the instant MPG on a 94-95 is blank when a scan tool is connected.
An ADX will be unable to query the economy value is that value is not actually part of an ECM's datastream. That's why it's curious if the 90-91 L98 would have it yet the 92-93 and 94-95 would not.
From a dimensional analysis perspective, INJ would have to be in gal/hr for the calculation to yield MPG: (mi/hr)/((gal/hr)*(1/min)*(ms)) <> (distance/time)/((volume/time)*(1/time)*time) = (distance/time)/(volume/time) = (distance/time)*(time/volume) = distance/volume <> mi/gal.
I'm adding the IPFUEL bytes to my ADX, and this evening I'll see what it spits out. Maybe that will tell us something.
My understanding is that mode 1 gives you the "diagnostic datastream", but that's not necessarily everything the ECM "knows". Or am I misremembering? Is it possible that with a (off the top of my head) mode 3 query you could get data not included in the diagnostic datastream?
My understanding is that mode 1 gives you the "diagnostic datastream", but that's not necessarily everything the ECM "knows". Or am I misremembering? Is it possible that with a (off the top of my head) mode 3 query you could get data not included in the diagnostic datastream?
Mode 3 is for requesting data from ROM, not from active parameters like Mode 1. I highly doubt the CCM is requesting anything via Mode 3, especially while the engine is running.
Mode 3 is for requesting data from ROM, not from active parameters like Mode 1. I highly doubt the CCM is requesting anything via Mode 3, especially while the engine is running.
I think we can agree the ECM calculates values (such as manifold air density for my ECM) that are not reported to the DDS. If the ECM were directly calculating economy, I see no reason it would report it to the DDS. Economy is not useful for diagnostic purposes, especially since it is a derived parameter.
I did not realize the datastream definition was from GM. I thought it, like the ADX files, was reverse-engineered by private parties. In that case, I agree that it's unlikely there are DDS values omitted from the datastream definition. However, I still think it's possible that we're looking for something not found in the DDS.
Last edited by C4ProjectCar; Jan 20, 2021 at 10:38 AM.
I think we can agree the ECM calculates values (such as manifold air density for my ECM) that are not reported to the DDS. If the ECM were directly calculating economy, I see no reason it would report it to the DDS. Economy is not useful for diagnostic purposes, especially since it is a derived parameter.
I did not realize the datastream definition was from GM. I thought it, like the ADX files, was reverse-engineered by private parties. In that case, I agree that it's unlikely there are DDS values omitted from the datastream definition. However, I still think it's possible that we're looking for something not found in the DDS.
That said, if you sniff the CCM comms, it would be very easy to see which mode is being commanded.
The Best of Corvette for Corvette Enthusiasts
Alright, I added running total fuel to my ADX and grabbed a datalog. It seems to be just that - a running total of fuel. In hindsight it's obvious that the calculation ((IPFUEL_MSB*256 + IPFUEL_LSB)*15.26) is just combining the LSB and MSB and applying some scaling value. I'm not sure why it's labeled usec; perhaps it is given in terms of injector pulse time?
Regardless, I'm still curious why this value is transmitted. I'm fairly certain the CCM uses the gas level sender for average MPG, and for instant you would want an instantaneous fuel consumption.
Last edited by C4ProjectCar; Mar 14, 2021 at 12:13 PM.

Maybe I'll bust out the Arduino tomorrow.
Edit: my math in my previous post was horrible. See corrections.
Last edited by C4ProjectCar; Jan 23, 2021 at 05:54 PM.
I'm starting to figure out the plan for sniffing serial with my Arduino, and I'm hoping I can make it happen this weekend.
If I can resolve this thread, I don't think it should be hard to make a device that does the trick. Of course, there's a difference between making something work on my own car and making something that works on anyone's car. There's always unforeseen differences.
Which harness adapter are you talking about? I think most of the electrical connectors on these cars can be bought online if you know the part number.
Last edited by C4ProjectCar; Jan 30, 2021 at 04:58 PM.
I see
- Protecting the Arduino - I think the ALDL serial line is +5V, but if it's a 12V line it would cook my Arduino without a protection circuit.
- Protecting the ECM - I don't expect this will be an issue, but it's possible drawing too much current over the serial line could hurt the ECM. I would expect the ECM has protection circuits built in, but I want to be extra sure I don't hurt it.
- Syncing the datastream - as I understand it, I need to sync the Arduino to the datastream somehow. I have a lead on this, but everything I'm finding is based on getting the diagnostic datastream, not passively listening. I suspect the procedure is not quite the same. At least in theory, it seems like it wouldn't be too hard to detect the serial line's timing by just looking at the rising or falling edge of the signal.
- Preventing floating signals - I'm not sure if I'll need pull-up or pull-down resistors where the serial line connects to the Arduino. Whether these are needed is probably painfully obvious to someone smarter with circuits than I.
I'm doing a lot of reading, and I'll post back when I have answers.
Edit:
1. Here's someone saying ALDL serial is 7 volts. It also implies that the implementation is TTL, where the line is held at VCC when idle. However, this source implies that 8192 baud ALDL is 5 volts. I measured with my DMM, and it was ~5v. I'm not sure the meaning, but this source claims the 5v level does not mean it's TTL. Not sure if that's relevant.
2. Arduino input pins have an impedance of ~100MΩ. I can't think of a way I could draw too much current with that.
3. I'm guessing 8192 ALDL is asynchronous serial, which means I don't need to do anything to synchronize the clock?
4. I don't think I need to do this? I get really confused when combining two systems with different power supplies. All voltages are relative of course, so the Arduino needs to be wired to both the serial line and the ground to read the system. I'll be powering the Arduino with my laptop, so my laptop's ground will be connected to my car's ground through the Arduino. I'm probably overthinking this: I guess because voltages are relative it doesn't matter?
I'm thinking if I get gibberish, I might just use the Arduino as a logic analyzer to visualize the waveform and inform my strategy.
Does anyone know the differences and similarities between 160 baud and 8192 baud ALDL? Is it just the bitrate?
160 baud info I've found (think this is irrelevant, but something I read implied the bus is 160 baud until you command Mode 1 or similar):
Last edited by C4ProjectCar; Jan 30, 2021 at 09:05 PM.
I see
- Protecting the Arduino - I think the ALDL serial line is +5V, but if it's a 12V line it would cook my Arduino without a protection circuit.
- Protecting the ECM - I don't expect this will be an issue, but it's possible drawing too much current over the serial line could hurt the ECM. I would expect the ECM has protection circuits built in, but I want to be extra sure I don't hurt it.
- Syncing the datastream - as I understand it, I need to sync the Arduino to the datastream somehow. I have a lead on this, but everything I'm finding is based on getting the diagnostic datastream, not passively listening. I suspect the procedure is not quite the same. At least in theory, it seems like it wouldn't be too hard to detect the serial line's timing by just looking at the rising or falling edge of the signal.
- Preventing floating signals - I'm not sure if I'll need pull-up or pull-down resistors where the serial line connects to the Arduino. Whether these are needed is probably painfully obvious to someone smarter with circuits than I.
I'm doing a lot of reading, and I'll post back when I have answers.
Edit:
1. Here's someone saying ALDL serial is 7 volts. It also implies that the implementation is TTL, where the line is held at VCC when idle. However, this source implies that 8192 baud ALDL is 5 volts. I measured with my DMM, and it was ~5v. I'm not sure the meaning, but this source claims the 5v level does not mean it's TTL. Not sure if that's relevant.
2. Arduino input pins have an impedance of ~100MΩ. I can't think of a way I could draw too much current with that.
3. I'm guessing 8192 ALDL is asynchronous serial, which means I don't need to do anything to synchronize the clock?
4. I don't think I need to do this? I get really confused when combining two systems with different power supplies. All voltages are relative of course, so the Arduino needs to be wired to both the serial line and the ground to read the system. I'll be powering the Arduino with my laptop, so my laptop's ground will be connected to my car's ground through the Arduino. I'm probably overthinking this: I guess because voltages are relative it doesn't matter?
I'm thinking if I get gibberish, I might just use the Arduino as a logic analyzer to visualize the waveform and inform my strategy.
Does anyone know the differences and similarities between 160 baud and 8192 baud ALDL? Is it just the bitrate?
160 baud info I've found (think this is irrelevant, but something I read implied the bus is 160 baud until you command Mode 1 or similar):
I found another resource describing the 8192 protocol:
ALDL on our cars is 5V TTL, 8N1, and with collision since the RX and TX lines are both the same line. You cannot just hack a USB cable apart and connect it directly because USB is not a TTL protocol. You can, however, fairly easily acquire a cable that includes an FTDI chip to allow the cable to act like a serial TTL device (and expose itself as a serial port in Windows and other operating systems). One such cable designed for 5V TTL is here: https://www.sparkfun.com/products/9718
If your Arduino is a 5V Arduino (some are, some aren't; my proto board is 5V and my Uno is 5V, but many smaller boards are 3.3V) then you can hook it directly to the ALDL serial line and be just fine. You just can't hook it to the +12V power line, but that shouldn't matter; it's only used for power, not for signaling. You can't draw too much current over the serial data line unless you plug something into it that isn't serial data. For example, if you tried to do the paperclip and accidentally shorted the serial data line to +12V. Synching the datastream is why I kept saying that you need a logic analyzer (or need to find an Arduino sketch that converts it to operate as a logic analyzer). You should not be sending any commands over the data line--you should be passively listening and recording all of the data currently flowing over the bus for later analysis. You are correct that there's no need to synchronize the clock signal; you just need to make sure you're at 8192 baud, 8N1. If you're at the wrong baud rate or have the data types set incorrectly, you won't interpret the signals correctly.
A logic analyzer shouldn't -need- to be grounded to the car to detect the rising and falling logic levels over the serial data line. My actual logic analyzer needs only to be hooked up to the ALDL serial data pin to operate correctly. No need to hook up to the ECM ground. Similarly I wouldn't go hooking an Arduino up other than one of its digital pins to the ALDL serial data pin.
Hopefully that helps.
Yes. The Torqhead conversion for the 94-96 Corvette is an 0411 PCM with the 94-96 Corvette PCM connectors (plus an extra connector for the coil harness) that is plug-and-play and makes the CCM and dash happy. So whatever they did, they did it right. But like I said, they're in it for the money, so I highly doubt they'd be willing to divulge the software side of things.
Also, didn't they ditch the +12v ALDL pin around the time they switched to 8192? I thought I read that.
A logic analyzer shouldn't -need- to be grounded to the car to detect the rising and falling logic levels over the serial data line. My actual logic analyzer needs only to be hooked up to the ALDL serial data pin to operate correctly. No need to hook up to the ECM ground. Similarly I wouldn't go hooking an Arduino up other than one of its digital pins to the ALDL serial data pin.
Can you explain the difference between synching the datastream and synching the clock signal? I'm not sure what else you'd synch other than the clock.
My brain hurts. How can a logic analyzer/Arduino read voltage levels without a complete circuit?
In summary: I think I can just wire RX to pin M with a 1k resistor in series. Resistor should not be necessary, but it also shouldn't hurt anything with currents this low. I'll connect the board's ground to pin A, and I think that's it. Now I just need to figure out how to display the serial data real-time.
I just came across an excellent resource. This page explains an engineering student's senior design project, which was to make a Mega read serial data from a 1227727/1227730 ECM. Right on the money. Unfortunately, it's much more complicated than what I want to do.
I found another resource describing the 8192 protocol:
It's for a device that reads both 160 baud and 8192 baud, but I think I can just pick whichever one I need (90% sure I need 8192). For 8192, the diagram shows the serial line connected to TX and RX in parallel, which I've read is necessary due to the fact the ALDL is half duplex. There's a 1k resistor on the RX pin and a diode on the TX pin for some reason? As expected, the vehicle ground goes to the board's ground.
Here's a GitHub project to read 8192 ALDL with an Arduino. It's for the 1227165 ECM though, which is before the CCM was added (1227727 ECM). This certainly means that it will not decode the datastream properly, but I wonder if the wiring description holds:
- Arduino Rx1 and DIO 4 pins are connected together to the ALDL data pin "E" on the ALDL connector
- The Tx1 Arduino pin connects to the cathode of a 1n4001(or similar) diode with the anode connected to ALDL pin "E". This allows Tx to pull down pin "E" during transmission without interfering with the ECM serial output.
- Arduino GND is connected to ECM Gnd at ALDL pin "A"
- A 10K resisor between ALDL pins "A" and "E" puts the ECM into ALDL mode.
For the '94-'95 guys, here's a schematic from a now-defunct webpage (thanks Wayback Machine).
Last edited by C4ProjectCar; Jan 30, 2021 at 10:12 PM.
In summary: I think I can just wire RX to pin M with a 1k resistor in series. Resistor should not be necessary, but it also shouldn't hurt anything with currents this low. I'll connect the board's ground to pin A, and I think that's it. Now I just need to figure out how to display the serial data real-time.
I just came across an excellent resource. This page explains an engineering student's senior design project, which was to make a Mega read serial data from a 1227727/1227730 ECM. Right on the money. Unfortunately, it's much more complicated than what I want to do.
I found another resource describing the 8192 protocol:
Another page on that site gives a wiring diagram:
It's for a device that reads both 160 baud and 8192 baud, but I think I can just pick whichever one I need (90% sure I need 8192). For 8192, the diagram shows the serial line connected to TX and RX in parallel, which I've read is necessary due to the fact the ALDL is half duplex. There's a 1k resistor on the RX pin and a diode on the TX pin for some reason? As expected, the vehicle ground goes to the board's ground.
Here's a GitHub project to read 8192 ALDL with an Arduino. It's for the 1227165 ECM though, which is before the CCM was added (1227727 ECM). This certainly means that it will not decode the datastream properly, but I wonder if the wiring description holds:
I'd want to skip step 4 for sure, and I don't see why I'd need to connect pin 4. Otherwise this basically describes the wiring above.
For the '94-'95 guys, here's a schematic from a now-defunct webpage (thanks Wayback Machine).
Last edited by ThatOneKid; Jan 30, 2021 at 11:01 PM.








