diff --git a/README.md b/README.md index 3553b0c..06338e7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,521 @@ -# Model make +# Land Rover LR4 (L319) — Signal Reference +OBDb signalset for the 2016 Land Rover LR4 / Discovery 4 — 3.0L supercharged +V6 (AJ126), ZF 8HP70, full-time 4WD with locking rear differential and +electronic air suspension. + +Signals here were confirmed against ~13M logged request/response pairs from +this vehicle (VIN `SALAK2V62GA832217`). Anything still named `*_RAW` responds +on the bus but hasn't been decoded yet. + +--- + +## Modules + +Thirteen modules answer on this truck. Six have never been mined — they +reject unknown DIDs with a negative response rather than staying silent, +which is how we know they're there. Requests go to `hdr`, replies come back +from `rax`. + +| Request | Response | Module | +|---|---|---| +| `7E0` | `7E8` | Engine (ECM) | +| `7E1` | `7E9` | Transmission (TCM) | +| `716` | `71E` | Unmined | +| `726` | `72E` | Unmined — returns the VIN | +| `732` | `73A` | Gear selector | +| `734` | `73C` | Unmined | +| `737` | `73F` | Unmined | +| `760` | `768` | Unmined | +| `761` | `769` | Body / instrument | +| `792` | `79A` | Unidentified — answers `2A3x` | +| `795` | `79D` | Rear differential | +| `797` | `79F` | Unmined | +| `7D3` | `7DB` | Air suspension (EAS) | + +Two addressing quirks are worth knowing: + +**Per-ECU DID offsets.** The engine's proprietary DIDs sit `+0x300` from +their base (`00F2` → `03F2`), while the transmission and differential use +`+0x1000` (`0E69` → `1E69`). A DID that returns "out of range" is often just +sitting at the other offset. + +**`22F4xx` aliases.** Any standard OBD PID `01XX` is also readable as +`22F4XX` — `010C` (RPM) is the same data as `22F40C`. This matters because +Pelican handles standard PIDs internally, so a signalset entry for `012F` +never surfaces in the app. The `F4xx` alias arrives as a custom signal and +shows up normally. Most of this file uses that trick. + +--- + +## Engine + +| Signal | Address | Notes | +|---|---|---| +| Engine Speed | `7E0` `22F40C` | | +| Calculated Load | `7E0` `22F404` | Percent of available torque at current RPM | +| Absolute Load | `7E0` `22F443` | Percent of *peak possible* airflow — exceeds 100% under boost | +| Coolant Temp | `7E0` `22F405` | Thermostat opens ~88°C; normal running 90–105°C | +| Manifold Pressure | `7E0` `22F40B` | **Absolute**, not gauge. See boost calculation below | +| Barometric Pressure | `7E0` `22F433` | ~101 kPa at sea level, drops with altitude | +| Altitude | `7E0` `22F433` | Barometric converted to feet by lookup table | +| Intake Air Temp | `7E0` `22F40F` | Before the supercharger | +| Charge Air Temp | `7E0` `220520` | **After** the supercharger and intercooler | +| Timing Advance | `7E0` `22F40E` | Degrees before top dead centre | +| Throttle Position | `7E0` `22F411` | Actual plate position | +| Commanded Throttle | `7E0` `22F44C` | What the ECU asked for | +| Accelerator Pedal D / E | `7E0` `22F449` / `22F44A` | Two sensors in one pedal | +| Mass Air Flow | `7E0` `22F410` | Grams of air per second | +| Equivalence Ratio | `7E0` `22F444` | Commanded lambda | +| O2 Lambda B1S1 | `7E0` `22F434` | Measured lambda | +| O2 Sensor Voltage | `7E0` `22F434` | Second half of the same response | +| Catalyst Temp B1S1 / B2S1 | `7E0` `22F43C` / `22F43D` | One per bank | +| Oil Temp | `7E0` `2203F3` | Land Rover's own sensor | +| Oil Temp (SAE) | `7E0` `22F45C` | Standard PID, same physical sensor | +| Oil Level | `7E0` `2203E6` | Millimetres in the sump | +| Oil Volume | `7E0` `2203F2` | | + +### Lambda + +Lambda expresses air-fuel ratio relative to perfect combustion (14.7:1 for +gasoline). + +- **1.00** — stoichiometric, the cruise target +- **below 1.00** — rich, extra fuel +- **above 1.00** — lean, extra air + +Under boost the ECU deliberately commands rich (~0.85) because extra fuel +cools the charge and suppresses knock. A value of 2.00 means deceleration +fuel cut — injectors fully off while coasting, sensor reading pure air. + +--- + +## Fuel + +| Signal | Address | Notes | +|---|---|---| +| Fuel Level | `7E0` `22F42F` | | +| Fuel Rail Pressure | `7E0` `22033E` | Proprietary; ~60 bar idle, 130+ under load | +| Fuel Rail Pressure (SAE) | `7E0` `22F423` | Standard PID, same rail | +| Short Term Fuel Trim B1 | `7E0` `22F406` | Immediate correction, swings constantly | +| Long Term Fuel Trim B1 | `7E0` `22F407` | Learned correction, drifts slowly | + +--- + +## Drivetrain + +| Signal | Address | Notes | +|---|---|---| +| Gear Selector | `732` `22D928` | 0 Park · 1 Reverse · 2 Neutral · 3 Drive · 7 Sport | +| Gearbox Temp | `7E1` `221E69` | ZF 8HP70 sump | +| Locking Diff Oil Temp | `795` `221E8A` | | + +--- + +## Suspension + +All four corners report gauge pressure in the air spring. + +| Signal | Address | +|---|---| +| Pressure Front Left / Right | `7D3` `223B04` / `223B03` | +| Pressure Rear Left / Right | `7D3` `223B06` / `223B05` | +| Height Offset | `7D3` `222B12` | Signed, millimetres from nominal | +| Compressor Activity | `7D3` `223B07` | ~110 at rest, over 1,300 while the truck raises | +| Ride Height Mode | `7D3` `223B3C` | 1 normal, 2 raised — both confirmed | +| Height Sensor Front / Rear | `7D3` `223B71` / `223B72` | **Inverted** — falls as the truck rises | +| Module Voltage | `7D3` `22D11A` | Should mirror battery voltage | + +Normal standing pressures are roughly 40 psi per corner at normal ride +height, rising with load and with raised height modes. + +--- + +## Reading signals together + +Individual numbers are useful. Pairs are where the diagnostics live. + +### Boost — Manifold Pressure minus Barometric Pressure + +The LR4 reports manifold pressure as *absolute*, so at idle it reads well +below atmospheric and looks wrong. Subtract barometric and you get true +boost: + +``` +boost = Manifold Pressure − Barometric Pressure +``` + +Negative is vacuum (closed throttle, coasting). Zero is atmospheric. Positive +is supercharger boost. Because barometric is a live reading, this stays +correct as you gain or lose altitude. + +### Heat-limited power — Charge Air Temp with Timing Advance + +Charge air temp is the truck's honest report of whether the intercooler is +keeping up. Watch it with timing advance: + +| Charge air temp | Timing advance | Meaning | +|---|---|---| +| Near ambient | Normal | Healthy, full power available | +| Climbing | Retarding | ECU pulling timing to prevent knock — power is fading | +| High, stable after stopping | — | Heat soak; recovers once moving | + +Timing retarding *without* a temperature rise points at fuel quality or knock +sensor activity instead. + +### Fueling health — Commanded vs Measured Lambda + +Equivalence Ratio is the target, O2 Lambda is reality. They should track +closely. A persistent gap means fueling isn't achieving its target — failing +sensor, vacuum leak, or fuel delivery shortfall. + +### Total fuel correction — Short Term plus Long Term Trim + +Add them. Their sum is how far off the base fuel map the engine is running. + +| Sum | Meaning | +|---|---| +| Within ±5% | Normal | +| Around +20% at warm idle | Adding fuel to compensate — vacuum leak or lazy MAF | +| Persistently negative | Running rich — leaking injector or high fuel pressure | + +Short term swinging while long term stays near zero is normal closed-loop +operation. Long term drifting away from zero is the engine *learning* a +problem, which is the one to act on. + +### Sensor cross-checks + +Several values are measured twice by independent paths. Agreement validates +both; disagreement localises the fault. + +| Pair | Should agree within | +|---|---| +| Oil Temp vs Oil Temp (SAE) | A few degrees | +| Fuel Rail Pressure vs SAE equivalent | Similar magnitude at steady idle | +| Accelerator Pedal D vs E | A percent or two — they're redundant by design | + +Pedal D and E disagreeing is significant: the ECU compares them itself and +will enter limp mode if they diverge. + +### Bank imbalance — Catalyst Temp B1 vs B2 + +The two banks should run within ~30°C of each other. A persistent split means +one bank is working harder — a misfire, an injector, or an O2 sensor on the +cooler side. + +### Load distribution — the four suspension pressures + +Front and rear pairs should be near-symmetrical left to right. A single +corner reading consistently low is either a load imbalance or an air spring +losing pressure. Compare against Height Offset: if pressure is low but height +is nominal, the system is compensating for a slow leak. + +### Warm-up sequence — Coolant, Oil, Gearbox + +These heat at different rates, and the order tells you about circulation. +Coolant reaches operating temperature first, oil follows several minutes +later, gearbox last. Oil temp lagging far behind coolant on a long drive +suggests restricted flow. Gearbox temperature climbing above normal while +towing is the signal to back off. + +### Airflow sanity — MAF against RPM and Load + +At idle, roughly 3–8 g/s. Under full boost, ten times that or more. MAF +staying flat while load and RPM climb means the sensor is under-reporting — +which the fuel trims will then try to correct, showing up as a rising +positive trim. + +--- + +## Computed signals + +The signalset defines eight synthetic signals. Each is a **ratio between two +readings that should hold a known value**, which makes them suited to a +display: you learn the normal number once, and anything else is a signal. + +| Signal | Ratio | Normal | Meaning when it moves | +|---|---|---|---| +| Boost Pressure Ratio | MAP / Barometric | 1.0 idle, up to ~1.8 | Above 1.0 is supercharger boost, self-correcting for altitude | +| Lambda Tracking | Measured / Commanded lambda | 1.0 | Fuelling isn't hitting its target — sensor, leak, or delivery | +| Bank Balance | Cat temp B1 / B2 | 1.0 | One bank working harder — misfire or injector on the low side | +| Pedal Agreement | Pedal D / Pedal E | 1.0 | Redundant pedal sensors disagreeing; the ECU limps if they diverge | +| Throttle Tracking | Actual / Commanded throttle | 1.0 | Plate not following orders — sticky or carbonned throttle body | +| Rail Pressure Crosscheck | Proprietary / SAE rail pressure | steady | Drift means one sensor path is wrong | +| Suspension Balance Front | Front left / right pressure | 1.0 | A corner losing air, before the dash warns | +| Suspension Balance Rear | Rear left / right pressure | 1.0 | Same, rear axle | + +Six of the eight sit at **1.0 when healthy**, so a single glance covers +fuelling, ignition balance, pedal and throttle integrity, and air springs. + +Boost Pressure Ratio is the exception and the one to watch for fun: it's the +closest thing to a boost gauge this vehicle exposes. The schema's only +operation is division, so true gauge boost (`MAP − Barometric`) isn't +expressible as a synthetic — but the ratio carries the same information and +needs no altitude correction. + +--- + +## Altitude and mountain driving + +### Reading altitude + +There's no altitude signal, but **Barometric Pressure is one** — air thins +predictably with height. Read `22F433` directly: + +| Altitude | Barometric | In psi | +|---|---|---| +| Sea level | 101 kPa | 14.7 | +| 2,000 ft | 94 kPa | 13.7 | +| 4,000 ft | 88 kPa | 12.7 | +| 6,000 ft | 81 kPa | 11.8 | +| 8,000 ft | 75 kPa | 10.9 | +| 10,000 ft | 70 kPa | 10.1 | +| 12,000 ft | 64 kPa | 9.3 | + +Roughly 1 kPa per 300 ft near sea level, stretching to about 340 ft +per kPa above 8,000 ft. Weather shifts it a few kPa, so treat +it as approximate unless you calibrate against a known elevation. + +### Measured on this truck + +From the September 2025 mountain trip, barometric pressure ranged **65–76 kPa, +median 70** — roughly 7,800 to 11,800 ft, spending most of its time near +10,000. Those runs give real baselines to compare against: + +| Signal | Mountains, Sept 2025 | Notes | +|---|---|---| +| Charge Air Temp | 6–81°C, median 47 | Wide swing with grade and airflow | +| Gearbox Temp | 8–85°C, median 64 | Never troubling | +| Diff Temp | 0–60°C, median 35 | Cooler than a hot-weather lowland drive | +| Coolant Temp | up to 103°C | Normal ceiling on sustained climbs | +| Mass Air Flow | peak 216 g/s | Full-load airflow | + +Worth noting the differential ran *hotter* on flat August driving (median +71°C) than in the mountains (35°C). Ambient temperature matters more to it +than terrain does. + +### Fuel trim climbs with altitude + +Long term fuel trim tracks altitude clearly across ~76,000 logged samples: + +| Barometric | Altitude | Median LTFT | +|---|---|---| +| 100 kPa | ~400 ft | +8.6% | +| 80 kPa | ~6,400 ft | +7.8% | +| 75 kPa | ~7,900 ft | +12.5% | +| 70 kPa | ~9,400 ft | +14.1% | +| 65 kPa | ~10,900 ft | +14.8% | + +Altitude adding fuel trim is expected — the mass air flow sensor tends to +under-report in thin air and the ECU compensates. **The part worth watching +is the low-altitude baseline of around +8%.** A healthy engine sits within +±5%, so there's a mild lean condition present before altitude adds anything, +and the two stack: near +15% at 11,000 ft is approaching where a lean code +would set. + +Most likely cause on this engine is a small unmetered air leak — the +supercharged V6 has a lot of intake plumbing and hose joints. Not urgent, but +if the truck ever feels flat at altitude, this is the reason to look at +first. + +### What altitude does to the engine + +A naturally aspirated engine loses about 3% power per 1,000 ft. Yours loses +much less, because the supercharger is a fixed-displacement blower geared to +the crank — it keeps stuffing the same volume in regardless of ambient +pressure. What you'll see instead: + +- **Boost Pressure Ratio holds steady.** It's normalised against barometric, + so it reads the same at 10,000 ft as at sea level. That's the point of + using the ratio rather than raw manifold pressure. +- **Mass Air Flow drops** at the same throttle and RPM. Thinner air, less + mass, less fuel, less power — the loss the blower can't fully erase. +- **Fuel trims may drift positive** as the ECU adapts. Mild drift climbing a + long pass is normal, not a fault. + +### What to watch climbing + +Sustained high load is the hardest thing you'll ask of the truck. + +| Signal | Watch for | +|---|---| +| Charge Air Temp | Climbing on a long pull, with Timing Advance retarding — the ECU protecting itself, and where your power goes | +| Gearbox Temp | The one that matters. Sustained climbing in a low gear heats the ZF fast | +| Coolant Temp | Should stay near 100°C. Rising past that on a grade means the cooling system is at its limit | +| Absolute Load | Pinned near 100% for long stretches means you're asking for everything available | + +### What to watch descending + +Engine braking sends heat somewhere different. + +- **Lambda goes to 2.00** on a closed-throttle descent. That's deceleration + fuel cut, working exactly as intended — you're using no fuel at all. +- **Gearbox Temp still climbs** in a low gear, even off-throttle. +- **Coolant Temp can rise** on a long descent despite low load, because + airflow is low and the engine is being driven by the wheels. + +--- + +## Off-road + +### Air suspension + +The four corner pressures are the most useful thing you have off-road. On +uneven ground the truck articulates, and pressures diverge as weight shifts. + +- **Suspension Balance Front / Rear** — the two synthetic ratios. At 1.0 the + axle is evenly loaded. Away from 1.0, weight has moved to one side. +- A corner going very low while its opposite goes high means that wheel is + unloading — the first hint of lifting a wheel. +- **Height Offset** shows where you are relative to normal ride height. + +Back on pavement both balance ratios should settle at 1.0. If one doesn't, +you've either shifted your load or picked up a slow leak. + +### Watch on the trail + +| Signal | Why | +|---|---| +| Gearbox Temp | Low-range crawling generates heat with almost no airflow. The number to respect | +| Locking Diff Oil Temp | Same reason, and it climbs fast when the diff is locked and working | +| Coolant Temp | Low speed means low airflow; the fan is doing the work alone | +| Suspension Balance | Articulation and weight transfer, live | +| Gear Selector | Confirms what the transmission thinks it's in | + +Ride Height, Ride Height Front/Rear and Drive Mode are in the signalset as +untested probes — the addresses come from a Jaguar EAS that shares this +module's pressure DIDs, so they have a good chance of working. If Drive Mode +returns a value, note what it reads in each Terrain Response setting and the +numbers can be mapped to names. + +### Before you go + +Air suspension raises the truck at low speed and drops it as you speed up. If +you're crawling and it lowers unexpectedly, watch Height Offset and the +corner pressures — an EAS fault normally means the truck sits down, which +matters a lot more with rocks under it than in a parking lot. + +--- + +## Undecoded + +These respond on the bus but their meaning isn't established. They're in the +signalset so their values get logged during normal driving, which is how the +formulas eventually get worked out. + +| Address | Signals | +|---|---| +| `792` / `79A` | `2A32`–`2A3A` — eight live values, none resembling tire pressures | +| `795` / `79D` | `1E89` | +| `7E1` / `7E9` | `1E68`, `1E6A` — neighbours of the gearbox temp | +| `761` / `769` | `197C`, `D11C` | +| `7D3` / `7DB` | `3B00`, `3B01`, `3B02`, `3B08`, `3B0B` — `3B02` answers four single-byte values that look like one per corner | + +**Tire pressures remain unsolved, but they exist.** Module `751` returns no +data to any request, and nothing found so far resembles four tire pressures. +The decisive clue is the spare: this truck warns when the *spare* is low, and a +spare does not rotate — so there is no wheel-speed difference to infer it from. +That rules out an indirect system and means real pressure sensors are fitted and +reporting to some module. Six modules answer negative responses but have never +been mined — `716`, `726`, `734`, `737`, `760`, `797` — and each is now probed +with the Jaguar tire-pressure DID as a locator. A positive response from any of +them finds the module. + +### Air suspension notes + +`3B71` and `3B72` track the height sensors, and they read **inverted** — the +number falls as the truck rises. Observed: 115/115 at normal height, 93/101 +raised. Treat a falling value as the truck going up. + +`3B3C` is the height mode and increments upward: mode 1 was normal and mode 2 +was raised, both confirmed. The map also labels 0 as Access and 3 as Extended on +the assumption the ordering continues — neither has been observed yet, so +correct them if they read wrong. + +The two balance ratios respond to cargo, not just faults. With the load area +full, front balance read 0.99 and rear read 0.92 — the rear axle carrying more +on one side. Check the ratios unloaded before reading a low number as a leak. + +--- + +## Polling + +The adapter sustains about **13 request/response round trips per second**, +measured across many hours of logging. That is the ELM327's ceiling, not the +CAN bus — 13 requests per second is negligible against 500 kbit/s, and +diagnostic identifiers in the `7xx` range are low priority by CAN arbitration, +so they yield to powertrain traffic automatically. Service `22` is read-only. +Polling cannot harm anything; it can only compete with itself. + +**`freq` is a minimum interval in seconds, not a rate.** Pelican documents it as +the maximum frequency at which a command may be sent, expressed in seconds, so +a *smaller* number polls *harder*. There is no priority field anywhere in the +v3 format — command count and `freq` are the only levers. + +The budget in this file: + +| Interval | Commands | Contents | +|---|---|---| +| 1s | 4 | Manifold pressure, barometric, engine speed, vehicle speed | +| 3s | 8 | Throttle, pedals, timing, lambda, load | +| 5s | 12 | Temperatures, fuel trims, mass air flow | +| 10s | 16 | Air suspension | +| 30s | 8 | Fuel level, battery, catalyst temperatures | +| 120s | 14 | Undecoded probes | +| 600s | 3 | Odometer, oil level, oil volume | + +That totals about 11 requests per second of demand against roughly 11 available +once protocol overhead is removed. The four one-second commands exist so the +boost calculation stays responsive. + +**Two known inefficiencies**, neither fixable from a signalset: + +Requests carry no expected-response count. The ELM327 datasheet documents that +appending a digit (`22F405 1`) lets the adapter return the instant it has that +many responses instead of waiting out the full timeout, and shows it nearly +doubling throughput. No request in this vehicle's history uses it. + +Sparse headers cost triple. Reading one value from a module means `ATSH`, then +a receive filter, then the read — three round trips for one number. The engine +module amortises this well at 0.12 setup commands per read; a header carrying a +single command pays 2.0. + +Multi-DID requests would help most — a single frame holds seven payload bytes, +enough for `22` plus three identifiers — but the schema caps `cmd` at one +identifier, so the format cannot express it. + +--- + +## Terminal probing + +Sidecar's terminal is the fastest way to test a DID. + +``` +ATSH 7E0 set request address +ATCRA 7E8 set response filter +22F42F read a DID +ATAR restore automatic addressing +``` + +**Always finish with `ATAR`.** A left-over `ATCRA` filter blocks replies from +every other module, which makes the whole app look broken. + +Reading a reply — `7E8 04 62 F42F EC` is address, length, positive response, +echoed DID, then data. `7E8 03 7F 22 31` is a negative response: the DID +doesn't exist here. `NO DATA` means nothing answered at all. + +### Safety + +Service `22` is read-only by definition and cannot change vehicle state. It +is safe to send anything at it. + +Service `10 03` (extended diagnostic session) does change ECU state. It's a +standard service that auto-reverts after a few seconds, but run it parked — +some modules reduce normal messaging while an extended session is open. + +Avoid entirely unless you know exactly what you're doing: `2F` (actuator +control), `31` (routine control), `2E` (write), `11` (ECU reset), `14` (clear +codes), `27` (security access). On this vehicle `2F` and `31` sent to the +suspension module can physically raise or lower the truck, and `14` erases +emissions readiness monitors, which means failing inspection until a full +drive cycle completes. diff --git a/signalsets/v3/default.json b/signalsets/v3/default.json index 7176ccf..a92747c 100644 --- a/signalsets/v3/default.json +++ b/signalsets/v3/default.json @@ -1,4 +1,308 @@ { "commands": [ - +{ "hdr": "732", "cmd": {"22": "D928"}, "freq": 5, + "signals": [ + {"id": "LR4_GEAR_SELECTOR", "path": "Transmission", "name": "Gear Selector", "fmt": {"len": 8, "map": { + "0": { "description": "Park", "value": "Park" }, + "1": { "description": "Reverse", "value": "Reverse" }, + "2": { "description": "Neutral", "value": "Neutral" }, + "3": { "description": "Drive", "value": "Drive" }, + "7": { "description": "Sport", "value": "Sport" } + }} + } + ]}, +{ "hdr": "761", "rax": "769", "cmd": {"22": "197C"}, "freq": 30, + "signals": [ + {"id": "LR4_197C_RAW", "path": "ECU", "fmt": { "len": 16, "max": 65535, "nullmin": 0, "unit": "scalar" }, "name": "197C Raw"} + ]}, +{ "hdr": "761", "rax": "769", "cmd": {"22": "D11C"}, "freq": 30, + "signals": [ + {"id": "LR4_D11C_RAW", "path": "ECU", "fmt": { "len": 8, "max": 255, "nullmin": 0, "unit": "scalar" }, "name": "D11C Raw"} + ]}, +{ "hdr": "792", "rax": "79A", "cmd": {"22": "2A36"}, "freq": 30, + "signals": [ + {"id": "LR4_2A36_RAW", "path": "Tires", "fmt": { "len": 24, "max": 16777215, "nullmin": 0, "unit": "scalar" }, "name": "2A36 Distance Counter"} + ]}, +{ "hdr": "795", "cmd": {"22": "1E8A"}, "freq": 5, + "signals": [ + {"id": "LR4_REAR_DIFF_TEMP", "path": "Drivetrain", "fmt": { "len": 8, "max": 150, "min": -40, "add": -40, "unit": "celsius" }, "name": "Locking Diff Oil Temp"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "2B12"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_2B12", "path": "Suspension", "fmt": { "len": 16, "max": 32767, "min": -32768, "sign": true, "unit": "millimeters" }, "name": "Suspension Height Offset"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B02"}, "freq": 30, + "signals": [ + {"id": "LR4_3B02_B0", "path": "Suspension", "fmt": { "len": 8, "max": 255, "unit": "scalar" }, "name": "3B02 Byte 1"}, + {"id": "LR4_3B02_B1", "path": "Suspension", "fmt": {"bix": 8, "len": 8, "max": 255, "unit": "scalar" }, "name": "3B02 Byte 2"}, + {"id": "LR4_3B02_B2", "path": "Suspension", "fmt": {"bix": 16, "len": 8, "max": 255, "unit": "scalar" }, "name": "3B02 Byte 3"}, + {"id": "LR4_3B02_B3", "path": "Suspension", "fmt": {"bix": 24, "len": 8, "max": 255, "unit": "scalar" }, "name": "3B02 Byte 4"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B03"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_PRES_FR", "path": "Suspension", "fmt": {"bix": 8, "len": 8, "max": 51, "div": 5, "nullmin": 0, "unit": "psi" }, "name": "Suspension Pressure Front Right"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B04"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_PRES_FL", "path": "Suspension", "fmt": {"bix": 8, "len": 8, "max": 51, "div": 5, "nullmin": 0, "unit": "psi" }, "name": "Suspension Pressure Front Left"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B05"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_PRES_RR", "path": "Suspension", "fmt": {"bix": 8, "len": 8, "max": 51, "div": 5, "nullmin": 0, "unit": "psi" }, "name": "Suspension Pressure Rear Right"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B06"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_PRES_RL", "path": "Suspension", "fmt": {"bix": 8, "len": 8, "max": 51, "div": 5, "nullmin": 0, "unit": "psi" }, "name": "Suspension Pressure Rear Left"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B07"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_COMPRESSOR", "path": "Suspension", "fmt": { "len": 16, "max": 65535, "nullmin": 0, "unit": "scalar" }, "name": "Compressor Activity"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B0B"}, "freq": 30, + "signals": [ + {"id": "LR4_3B0B_RAW", "path": "Suspension", "fmt": { "len": 16, "max": 65535, "nullmin": 0, "unit": "scalar" }, "name": "3B0B Raw"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B3C"}, "freq": 10, + "signals": [ + {"id": "LR4_RIDE_HEIGHT", "path": "Suspension", "name": "Ride Height Mode", "fmt": {"len": 8, "map": { + "0": { "description": "Access", "value": "Access" }, + "1": { "description": "Normal", "value": "Normal" }, + "2": { "description": "Off-Road", "value": "Off-Road" }, + "3": { "description": "Extended", "value": "Extended" } + }} + } + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B4D"}, "freq": 10, + "signals": [ + {"id": "LR4_DRIVE_MODE", "path": "Suspension", "fmt": { "len": 8, "max": 255, "nullmin": 0, "unit": "scalar" }, "name": "Drive Mode"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B71"}, "freq": 10, + "signals": [ + {"id": "LR4_RIDE_HEIGHT_FRONT", "path": "Suspension", "fmt": { "len": 8, "max": 255, "nullmin": 0, "unit": "scalar" }, "name": "Height Sensor Front (inverted)"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "3B72"}, "freq": 10, + "signals": [ + {"id": "LR4_RIDE_HEIGHT_REAR", "path": "Suspension", "fmt": { "len": 8, "max": 255, "nullmin": 0, "unit": "scalar" }, "name": "Height Sensor Rear (inverted)"} + ]}, +{ "hdr": "7D3", "rax": "7DB", "cmd": {"22": "D11A"}, "freq": 10, + "signals": [ + {"id": "LR4_SUSPENSION_SUPPLY_V", "path": "Suspension", "fmt": { "len": 8, "max": 40.8, "mul": 16, "div": 100, "unit": "volts" }, "name": "Suspension Module Voltage"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "033E"}, "freq": 5, + "signals": [ + {"id": "LR4_FUEL_RAIL_P", "path": "Fuel", "fmt": { "len": 16, "max": 30000, "unit": "kilopascal" }, "name": "Fuel Rail Pressure"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "03E6"}, "freq": 600, + "signals": [ + {"id": "LR4_MEASURED_OIL_LEVEL", "path": "Engine", "fmt": { "len": 8, "max": 255, "unit": "millimeters" }, "name": "Oil Level"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "03F2"}, "freq": 600, + "signals": [ + {"id": "LR4_ENGINE_OIL_VOLUME_GAL", "path": "Engine", "fmt": { "len": 8, "max": 6.74, "mul": 0.0264172, "unit": "gallons" }, "name": "Oil Volume"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "03F3"}, "freq": 5, + "signals": [ + {"id": "LR4_ENGINE_OIL_TEMP", "path": "Engine", "fmt": { "len": 8, "max": 120, "min": -40, "add": -40, "unit": "celsius" }, "name": "Oil Temp", "suggestedMetric": "engineOilTemperature"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "0520"}, "freq": 5, + "signals": [ + {"id": "LR4_CHARGE_AIR_TEMP", "path": "Engine", "fmt": { "len": 8, "max": 215, "min": -40, "add": -40, "unit": "celsius" }, "name": "Charge Air Temp"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "DD01"}, "freq": 600, + "signals": [ + {"id": "LR4_ODOMETER", "path": "Trips", "fmt": { "len": 24, "max": 16777215, "nullmin": 0, "unit": "kilometers" }, "name": "Odometer", "suggestedMetric": "odometer"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F404"}, "freq": 3, + "signals": [ + {"id": "LR4_LOAD_CALC", "path": "Engine", "fmt": { "len": 8, "max": 100, "mul": 100, "div": 255, "unit": "percent" }, "name": "Calculated Load", "suggestedMetric": "engineLoad"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F405"}, "freq": 5, + "signals": [ + {"id": "LR4_COOLANT_TEMP", "path": "Engine", "fmt": { "len": 8, "max": 215, "min": -40, "add": -40, "unit": "celsius" }, "name": "Coolant Temp", "suggestedMetric": "engineCoolantTemperature"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F406"}, "freq": 5, + "signals": [ + {"id": "LR4_SHRTFT1", "path": "Fuel", "fmt": { "len": 8, "max": 99.2, "min": -100, "mul": 100, "div": 128, "add": -100, "unit": "percent" }, "name": "Short Term Fuel Trim B1", "suggestedMetric": "shortTermFuelTrim"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F407"}, "freq": 5, + "signals": [ + {"id": "LR4_LONGFT1", "path": "Fuel", "fmt": { "len": 8, "max": 99.2, "min": -100, "mul": 100, "div": 128, "add": -100, "unit": "percent" }, "name": "Long Term Fuel Trim B1"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F40B"}, "freq": 1, + "signals": [ + {"id": "LR4_MAP", "path": "Engine", "fmt": { "len": 8, "max": 255, "unit": "kilopascal" }, "name": "Manifold Pressure"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F40C"}, "freq": 1, + "signals": [ + {"id": "LR4_RPM", "path": "Engine", "fmt": { "len": 16, "max": 16383.75, "div": 4, "unit": "rpm" }, "name": "Engine Speed", "suggestedMetric": "engineSpeed"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F40D"}, "freq": 1, + "signals": [ + {"id": "LR4_SPEED", "path": "Movement", "fmt": { "len": 8, "max": 255, "unit": "kilometersPerHour" }, "name": "Vehicle Speed", "suggestedMetric": "speed"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F40E"}, "freq": 3, + "signals": [ + {"id": "LR4_SPARK_ADV", "path": "Engine", "fmt": { "len": 8, "max": 63.5, "min": -64, "div": 2, "add": -64, "unit": "degrees" }, "name": "Timing Advance"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F40F"}, "freq": 30, + "signals": [ + {"id": "LR4_IAT", "path": "Engine", "fmt": { "len": 8, "max": 215, "min": -40, "add": -40, "unit": "celsius" }, "name": "Intake Air Temp"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F410"}, "freq": 5, + "signals": [ + {"id": "LR4_MAF", "path": "Engine", "fmt": { "len": 16, "max": 655.35, "div": 100, "unit": "gramsPerSecond" }, "name": "Mass Air Flow", "suggestedMetric": "massAirFlow"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F411"}, "freq": 3, + "signals": [ + {"id": "LR4_THROTTLE_POS", "path": "Engine", "fmt": { "len": 8, "max": 100, "mul": 100, "div": 255, "unit": "percent" }, "name": "Throttle Position", "suggestedMetric": "throttlePosition"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F423"}, "freq": 5, + "signals": [ + {"id": "LR4_FUEL_RAIL_P_GAUGE", "path": "Fuel", "fmt": { "len": 16, "max": 655350, "mul": 10, "unit": "kilopascal" }, "name": "Fuel Rail Pressure (SAE)"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F42F"}, "freq": 30, + "signals": [ + {"id": "LR4_FUEL_LEVEL", "path": "Fuel", "fmt": { "len": 8, "max": 100, "mul": 100, "div": 255, "unit": "percent" }, "name": "Fuel Level", "suggestedMetric": "fuelTankLevel"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F431"}, "freq": 30, + "signals": [ + {"id": "LR4_DIST_SINCE_CLR", "path": "Trips", "fmt": { "len": 16, "max": 65535, "nullmin": 0, "unit": "kilometers" }, "name": "Distance Since Codes Cleared", "suggestedMetric": "distanceSinceDTCsCleared"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F433"}, "freq": 1, + "signals": [ + {"id": "LR4_BARO", "path": "Engine", "fmt": { "len": 8, "max": 255, "unit": "kilopascal" }, "name": "Barometric Pressure"}, + {"id": "LR4_ALTITUDE", "path": "Movement", "name": "Altitude", "fmt": {"len": 8, "map": { + "55": { "description": "15,955 ft", "value": "15,955 ft" }, + "56": { "description": "15,511 ft", "value": "15,511 ft" }, + "57": { "description": "15,073 ft", "value": "15,073 ft" }, + "58": { "description": "14,641 ft", "value": "14,641 ft" }, + "59": { "description": "14,215 ft", "value": "14,215 ft" }, + "60": { "description": "13,795 ft", "value": "13,795 ft" }, + "61": { "description": "13,380 ft", "value": "13,380 ft" }, + "62": { "description": "12,971 ft", "value": "12,971 ft" }, + "63": { "description": "12,568 ft", "value": "12,568 ft" }, + "64": { "description": "12,169 ft", "value": "12,169 ft" }, + "65": { "description": "11,776 ft", "value": "11,776 ft" }, + "66": { "description": "11,387 ft", "value": "11,387 ft" }, + "67": { "description": "11,003 ft", "value": "11,003 ft" }, + "68": { "description": "10,624 ft", "value": "10,624 ft" }, + "69": { "description": "10,249 ft", "value": "10,249 ft" }, + "70": { "description": "9,878 ft", "value": "9,878 ft" }, + "71": { "description": "9,512 ft", "value": "9,512 ft" }, + "72": { "description": "9,150 ft", "value": "9,150 ft" }, + "73": { "description": "8,792 ft", "value": "8,792 ft" }, + "74": { "description": "8,438 ft", "value": "8,438 ft" }, + "75": { "description": "8,088 ft", "value": "8,088 ft" }, + "76": { "description": "7,742 ft", "value": "7,742 ft" }, + "77": { "description": "7,399 ft", "value": "7,399 ft" }, + "78": { "description": "7,060 ft", "value": "7,060 ft" }, + "79": { "description": "6,724 ft", "value": "6,724 ft" }, + "80": { "description": "6,392 ft", "value": "6,392 ft" }, + "81": { "description": "6,063 ft", "value": "6,063 ft" }, + "82": { "description": "5,737 ft", "value": "5,737 ft" }, + "83": { "description": "5,415 ft", "value": "5,415 ft" }, + "84": { "description": "5,095 ft", "value": "5,095 ft" }, + "85": { "description": "4,779 ft", "value": "4,779 ft" }, + "86": { "description": "4,466 ft", "value": "4,466 ft" }, + "87": { "description": "4,156 ft", "value": "4,156 ft" }, + "88": { "description": "3,848 ft", "value": "3,848 ft" }, + "89": { "description": "3,544 ft", "value": "3,544 ft" }, + "90": { "description": "3,242 ft", "value": "3,242 ft" }, + "91": { "description": "2,943 ft", "value": "2,943 ft" }, + "92": { "description": "2,646 ft", "value": "2,646 ft" }, + "93": { "description": "2,352 ft", "value": "2,352 ft" }, + "94": { "description": "2,061 ft", "value": "2,061 ft" }, + "95": { "description": "1,772 ft", "value": "1,772 ft" }, + "96": { "description": "1,486 ft", "value": "1,486 ft" }, + "97": { "description": "1,202 ft", "value": "1,202 ft" }, + "98": { "description": "920 ft", "value": "920 ft" }, + "99": { "description": "641 ft", "value": "641 ft" }, + "100": { "description": "364 ft", "value": "364 ft" }, + "101": { "description": "sea level", "value": "sea level" }, + "102": { "description": "sea level", "value": "sea level" }, + "103": { "description": "sea level", "value": "sea level" }, + "104": { "description": "sea level", "value": "sea level" }, + "105": { "description": "sea level", "value": "sea level" } + }} + } + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F434"}, "freq": 3, + "signals": [ + {"id": "LR4_O2_LAMBDA", "path": "Engine", "fmt": { "len": 16, "max": 2, "div": 32768, "nullmin": 0, "unit": "scalar" }, "name": "O2 Lambda B1S1", "suggestedMetric": "o2Lambda"}, + {"id": "LR4_O2_VOLTAGE", "path": "Engine", "fmt": {"bix": 16, "len": 16, "max": 7.999, "div": 8192, "unit": "volts" }, "name": "O2 Sensor Voltage"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F43C"}, "freq": 30, + "signals": [ + {"id": "LR4_CAT_TEMP_B1", "path": "Engine", "fmt": { "len": 16, "max": 6513.5, "min": -40, "div": 10, "add": -40, "unit": "celsius" }, "name": "Catalyst Temp B1S1"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F43D"}, "freq": 30, + "signals": [ + {"id": "LR4_CAT_TEMP_B2", "path": "Engine", "fmt": { "len": 16, "max": 6513.5, "min": -40, "div": 10, "add": -40, "unit": "celsius" }, "name": "Catalyst Temp B2S1"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F442"}, "freq": 30, + "signals": [ + {"id": "LR4_BAT_V", "path": "Battery", "fmt": { "len": 16, "max": 65.535, "div": 1000, "unit": "volts" }, "name": "Battery Voltage", "suggestedMetric": "starterBatteryVoltage"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F443"}, "freq": 3, + "signals": [ + {"id": "LR4_LOAD_ABS", "path": "Engine", "fmt": { "len": 16, "max": 25700, "mul": 100, "div": 255, "unit": "percent" }, "name": "Absolute Load", "suggestedMetric": "absoluteEngineLoad"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F444"}, "freq": 3, + "signals": [ + {"id": "LR4_EQ_RATIO", "path": "Engine", "fmt": { "len": 16, "max": 2, "div": 32768, "unit": "scalar" }, "name": "Equivalence Ratio", "suggestedMetric": "commandedLambda"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F446"}, "freq": 30, + "signals": [ + {"id": "LR4_AMBIENT_TEMP", "path": "Climate", "fmt": { "len": 8, "max": 215, "min": -40, "add": -40, "unit": "celsius" }, "name": "Ambient Air Temp"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F449"}, "freq": 3, + "signals": [ + {"id": "LR4_PEDAL_D", "path": "Engine", "fmt": { "len": 8, "max": 100, "mul": 100, "div": 255, "unit": "percent" }, "name": "Accelerator Pedal D"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F44A"}, "freq": 3, + "signals": [ + {"id": "LR4_PEDAL_E", "path": "Engine", "fmt": { "len": 8, "max": 100, "mul": 100, "div": 255, "unit": "percent" }, "name": "Accelerator Pedal E"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F44C"}, "freq": 30, + "signals": [ + {"id": "LR4_THROTTLE_CMD", "path": "Engine", "fmt": { "len": 8, "max": 100, "mul": 100, "div": 255, "unit": "percent" }, "name": "Commanded Throttle"} + ]}, +{ "hdr": "7E0", "rax": "7E8", "cmd": {"22": "F45C"}, "freq": 5, + "signals": [ + {"id": "LR4_OIL_TEMP_SAE", "path": "Engine", "fmt": { "len": 8, "max": 215, "min": -40, "add": -40, "unit": "celsius" }, "name": "Oil Temp (SAE)"} + ]}, +{ "hdr": "7E1", "rax": "7E9", "cmd": {"22": "1E68"}, "freq": 30, + "signals": [ + {"id": "LR4_1E68_RAW", "path": "Transmission", "fmt": { "len": 8, "max": 255, "nullmin": 0, "unit": "scalar" }, "name": "1E68 Raw (varies most)"} + ]}, +{ "hdr": "7E1", "rax": "7E9", "cmd": {"22": "1E69"}, "freq": 5, + "signals": [ + {"id": "LR4_GEARBOX_OIL_TEMP", "path": "Drivetrain", "fmt": { "len": 8, "max": 120, "min": -40, "add": -40, "unit": "celsius" }, "name": "Gearbox Temp", "suggestedMetric": "transmissionFluidTemperature"} + ]} +], +"synthetics": [ + { "id": "LR4_BANK_BALANCE", "path": "Engine", "name": "Bank Balance", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_CAT_TEMP_B1", "b": "LR4_CAT_TEMP_B2" + }}, + { "id": "LR4_BOOST_RATIO", "path": "Engine", "name": "Boost Pressure Ratio", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_MAP", "b": "LR4_BARO" + }}, + { "id": "LR4_LAMBDA_TRACKING", "path": "Engine", "name": "Lambda Tracking", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_O2_LAMBDA", "b": "LR4_EQ_RATIO" + }}, + { "id": "LR4_PEDAL_AGREEMENT", "path": "Engine", "name": "Pedal Agreement", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_PEDAL_D", "b": "LR4_PEDAL_E" + }}, + { "id": "LR4_RAIL_CROSSCHECK", "path": "Fuel", "name": "Rail Pressure Crosscheck", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_FUEL_RAIL_P", "b": "LR4_FUEL_RAIL_P_GAUGE" + }}, + { "id": "LR4_SUSPENSION_BALANCE_F", "path": "Suspension", "name": "Suspension Balance Front", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_SUSPENSION_PRES_FL", "b": "LR4_SUSPENSION_PRES_FR" + }}, + { "id": "LR4_SUSPENSION_BALANCE_R", "path": "Suspension", "name": "Suspension Balance Rear", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_SUSPENSION_PRES_RL", "b": "LR4_SUSPENSION_PRES_RR" + }}, + { "id": "LR4_THROTTLE_TRACKING", "path": "Engine", "name": "Throttle Tracking", "max": 3, "unit": "scalar", "formula": { + "op": "ratio", "a": "LR4_THROTTLE_POS", "b": "LR4_THROTTLE_CMD" + }} ] }