This is the one we’ve been waiting for.
After ten parts of reverse engineering — cracking CAN bus IDs, extracting SDD VMs, breaking Ford’s KeyGenMkI security, fixing the LilyGO TX hardware, building a Python UDS diagnostic tool, and mapping every signal the air suspension ECU broadcasts — the answer was simpler than we thought. And it came from replacing a module we weren’t even focusing on.
Previously in this series: Parts 1–5 covered OBD-II pins, LilyGO ESP32 setup, CAN bus capture, and finding the height sensor values. Part 6 — Reverse Engineering JLR SDD. Part 7 — Cracking Ford Security. Part 8 — LilyGO CAN TX Fix. Part 9 — Building a UDS Diagnostic Tool. Part 10 — EXML Files & Calibration.
The Problem That Wouldn’t Go Away
Even after we mapped every air suspension CAN signal, there was an intermittent behaviour we couldn’t explain. The Discovery 3 would occasionally react to road undulations as if it were climbing a steep hill — compressor kicking in, front levelling valves opening, the suspension adjusting itself for a pitch change that wasn’t there.
We captured it on the CAN bus: a phantom front-left height sensor glitch at b7=0x0D that the ECU interpreted as “corner collapsed.” The ECU would wake the compressor (ID 0x17B80030 to 0x20) and trigger front levelling (0x17CCE6A0 b3=0x65) to compensate.
But the corner heights never actually changed. The sensor recovered before any air moved. And the event only happened at the resting height — a single-frame ~100ms dropout, exactly where the sensor wiper sat on its resistive track dead spot.
We were chasing a sensor glitch. The real problem was one step back.
The Longitudinal Accelerometer — The Missing Signal
Modern air suspension systems don’t just react to height sensors. They also factor in longitudinal acceleration — how quickly the vehicle is accelerating or braking. This matters because:
- During acceleration, the rear squats and the front lifts. The EAS must ignore the front height rise — it’s not a real height change, it’s pitch.
- During braking, the front dives. Again, the EAS should not react with levelling corrections.
- On undulating roads, the pitch signal tells the EAS “this is road movement, not a real corner height change.”
Without a working longitudinal sensor, the EAS treats every pitch event as a height change. The compressor fires up. The levelling valves open. The suspension tries to correct something that doesn’t need correcting — and does it repeatedly, every time the road surface changes.
Where the Longitudinal Sensor Lives
On the Discovery 3, the longitudinal accelerometer is inside the EPB module (Electronic Parking Brake). Not in the RLM. Not in the ABS module. In the parking brake controller, mounted above the rear differential.
The EPB module broadcasts acceleration and brake force values onto the CAN bus. The RLM reads them and uses them to suppress false levelling events. If the EPB module is faulty, the RLM never gets the longitudinal data — and it reacts to every pitch as if the vehicle is changing height.
| Symptom | Cause |
|---|---|
| Compressor runs on flat roads | ECU sees phantom “corner collapsed” from height sensor wiper dead spot |
| Front levelling activates on undulations | No longitudinal sensor data to tell ECU “this is pitch, not height change” |
Height sensor b7=0x0D glitch at rest |
Sensor track wear at ride-height position (common D3 age issue) |
| Excessive brake dust / EPB squeal | EPB module failing — longitudinal sensor rots along with it |
The Fix: Replace the EPB Module
We sourced a used OEM EPB module and installed it on the rear differential. The module is a straightforward swap — three bolts, one electrical connector, and the parking brake cable attachment. No programming required (it self-calibrates on first use).
Immediately after replacement:
- Longitudinal acceleration values appeared on the CAN bus — real-time accel/decel data the RLM can now see.
- Brake force values appeared — the EPB module broadcasts braking force on deceleration, another signal the RLM uses.
- The phantom compressor events stopped — the RLM now has the data to distinguish pitch from height change.
- The car rides smoothly over undulating roads — no more random air suspension corrections.
The front-left height sensor glitch (b7=0x0D) was always present — it’s a worn resistive track. But with the longitudinal sensor now working, the RLM correctly ignores the glitch as “not physically possible” because the acceleration data contradicts it.
What We Learned (The Hard Way)
This investigation started with a simple question: “Why does my Discovery 3 compressor keep running?” It took us through:
- CAN bus reverse engineering — capturing 27 broadcast IDs, mapping every byte of air suspension data
- SDD VM extraction — downloading and dissecting the JLR dealer diagnostic tool
- Security cracking — reverse-engineering Ford’s KeyGenMkI LFSR from
SecAlg.dll - Hardware debugging — fixing the LilyGO ESP32 CAN TX transistors
- Tool building — writing a full Python UDS diagnostic stack with ISO-TP transport
- EXML decryption — breaking Triple DES encryption on 2,033 calibration files
- J2534 proxy development — building a MITM DLL to capture SDD’s exact protocol
- And finally: an EPB module replacement — the answer was in the parking brake.
The lesson: don’t just chase the numbers you can see. Chase the numbers that should be there and aren’t.
What’s Still Open
The investigation isn’t completely closed. Several threads remain:
- UDS diagnostic access to the RLM — our CAN ID scanner still hasn’t found the RLM’s diagnostic ID. It may be on MS-CAN (125kbps, pins 3+11) rather than HS-CAN, or use a CAN ID we haven’t tried yet.
- Gallery/reservoir pressure addresses —
0x04C1F6B0contains pressure data but byte mapping needs confirmation with a controlled access-to-offroad raise. - Steering angle left-turn validation — right turns confirmed on
0x17A9FFE0; left turns not yet tested. - Engine RPM scaling —
0x108CF1F0at idle ÷64 ≈ 800 RPM fits, but needs OBD-II PID 0C comparison for confirmation. - RLM calibration replay — we captured the calibration sequence and have the security keys. Safe replay was the next step.
But for the original problem that started this journey — the compressor running when it shouldn’t — that’s solved.
CAN ID Map (Complete, 28 Identified)
Here is the final map of all 27 continuously-broadcast CAN IDs on the Discovery 3 HS-CAN bus, plus the longitudinal sensor now confirmed from the EPB module:
Air Suspension (5)
| ID | DLC | Hz | Role |
|---|---|---|---|
0x12E9E6A0 |
8 | ~6 | Corner heights (potentiometer counts) |
0x17B80030 |
1 | ~11 | Compressor status (0x20=on) |
0x17CCE6A0 |
6 | ~3 | EAS mode (b3: 0x00=idle, 0x65=levelling) |
0x04C1F6B0 |
6 | ~26 | Pressure/valve activity |
0x17C404B0 |
7 | ~5 | Temperature/status |
Driving Dynamics (3)
| ID | DLC | Hz | Role |
|---|---|---|---|
0x1544F9F0 |
8 | ~3 | Wheel speeds (4 lanes) |
0x17A9FFE0 |
8 | ~5 | Steering angle / yaw rate |
0x108CF1F0 |
8 | ~3 | Engine RPM |
EPB Module — Longitudinal & Brake Data (newly confirmed)
| ID | DLC | Hz | Role |
|---|---|---|---|
| EPB longitudinal | — | — | Longitudinal acceleration (accel/decel) — fed to RLM for pitch compensation |
| EPB brake force | — | — | Braking force during deceleration — fed to RLM and ABS |
Engine / Transmission (4)
| ID | DLC | Hz | Role |
|---|---|---|---|
0x17B452B0 |
7 | ~53 | Engine/transmission status (highest frequency) |
0x17B1FFF0 |
8 | ~9 | Engine status flags |
0x17ADBF70 |
8 | ~9 | Transmission/shift status |
0x17D5FFF0 |
8 | ~2 | Engine temp or fuel rate |
Counters, Sensors, Keep-alive (15)
| ID | DLC | Hz | Role |
|---|---|---|---|
0x071C0AA0 |
6 | ~17 | Counter/CRC (b1=b3=b5 cycle 0–255) |
0x0001F1F0 |
8 | ~19 | Counter (b1 cycles full range) |
0x0BD5FDF0 |
7 | ~5 | Activity during EAS events |
0x17E49220 |
8 | ~1 | Odometer or fuel consumption |
0x17E80420 |
6 | <1 | Coolant temperature |
0x17D1FFF0 |
8 | <1 | Slow sensor (fuel/ambient) |
0x17F5FFF0 |
7 | <1 | Analog sensor, slow update |
0x17D80420 |
6 | ~2 | Unknown (b0/b2 linked) |
0x17DC0420 |
3 | ~1.5 | Heartbeat (00 00 00 or 00 00 08) |
0x17E012B0 |
2 | ~2 | Keep-alive (always 00 10) |
0x17EC0010 |
3 | <1 | Keep-alive (always 01 00 00) |
0x17F80020 |
4 | <1 | Keep-alive (always 00 00 00 00) |
0x1F01FFFF |
3 | <1 | Diagnostic (always 01 20 01) |
Tools & Code
All code from this series is open source on GitHub: github.com/jcian/discovery-3
Key tools built during this investigation:
d3can.py— CAN capture, analysis, event detection, signal vieweruds_rlm.py— Full UDS diagnostic tool (ISO-TP, security unlock, DID scanner)ford_security.py— Standalone Ford KeyGenMkI implementationrlm_calibration.py— Calibration harness (probe, parse, replay)d3can_signal_viewer.py— Browser-based CAN signal viewer- J2534 Pass-Thru proxy DLLs — capture SDD diagnostic sequences
Hardware Used
- LilyGO T-CAN485 — ESP32 with SN65HVD230 CAN transceiver (TX fixed via GPIO16/23)
- Custom firmware — serial-to-CAN bridge with command interface, 115200 baud
- OBD-II breakout — pins 6+14 for HS-CAN (500kbps), pins 3+11 for MS-CAN (125kbps)
- JLR SDD 130 VM — dealer diagnostic software extracted for analysis
- OEM EPB module — replacement parking brake module restoring longitudinal sensor data
Final Thoughts
What started as “why is my compressor running” became a ten-part deep dive into automotive reverse engineering. We learned CAN bus protocols, cracked Ford’s security algorithm, decompiled dealer diagnostic DLLs, built Python tools, and ultimately found the answer in an unexpected place — the electronic parking brake module.
The Discovery 3 is a network of ECUs. They talk to each other constantly. When one goes silent, the others don’t know — they just see the data they were depending on has stopped arriving. And they make their best guess. Sometimes that guess is wrong.
If you’re chasing a Discovery 3 air suspension gremlin and the height sensors check out, the compressor is healthy, and there are no leaks — look at the EPB module. That longitudinal sensor matters more than you’d think.
Thanks for following along with this series. The tools and findings are on GitHub. Use them, improve them, and share what you find.
Disclaimer: The information in this article is provided for educational and research purposes. Modifying vehicle ECU firmware or calibration data can affect safety, emissions compliance, and vehicle warranty. The EPB module replacement was performed on a private vehicle for diagnostic purposes. Always consult a qualified automotive technician before working on safety-critical systems including brakes and suspension.
Leave a Reply