Table of Contents
OBD-II diagnostics
What you can and cannot get from the OBD-II socket on the U5, worked out by probing it with a cheap USB-CAN adapter and cross-checking against the head unit's own readouts. Short version: you can read a great deal, but you cannot write anything without the manufacturer's secret key. See CAN bus for how this port differs from the internal buses.
The port is a query-only diagnostic gateway
- OBD-II pin 6 = CAN-H, pin 14 = CAN-L (ground on 4/5, permanent 12 V on 16). This is the only CAN pair on the connector — no second bus, no automotive Ethernet / DoIP.
- Passive listening is silent at every bitrate — nothing is broadcast here.
- Active requests are answered at 500 kbit/s, 11-bit (ISO 15765-4). 29-bit and other bitrates stay silent.
- The port sits on a dedicated diagnostic CAN that dead-ends at the central gateway. The gateway bridges the car's separate internal buses — powertrain, chassis, body/comfort, infotainment, telematics — and routes each request to the target ECU. So you can reach every ECU through it, but the connector never carries the live internal broadcasts. You can poll; you cannot sniff here. This is a genuine central-gateway firewall.
Generic OBD-II — any scan tool
Standard emissions services work, addressed functionally to 0x7DF (responses on 0x7E8):
- Mode 09 — VIN (
09 02) and calibration IDs. - Mode 03 / 07 / 0A — stored / pending / permanent DTCs.
- Mode 01 — live PIDs. The primary powertrain endpoint (0x7E0) reports a supported-PID bitmask of
BF FB FF F7and, usefully on an EV, PID 0x5B (“hybrid/EV battery remaining charge”). - Mode 04 — clear emissions DTCs (see Clearing fault codes below).
As on any EV, generic OBD exposes little — VIN, generic fault codes, a couple of values (mostly 0 while parked). Everything interesting — real SoC, pack voltage, cell data — lives in the manufacturer UDS layer below.
The ECU map (UDS)
The gateway routes UDS requests to the internal ECUs. Enumerate them gently with a single
functional TesterPresent (3E 00 → 0x7DF): it changes nothing, yet every reachable ECU answers
from its own ID. On the U5 this finds 24 ECUs. Response ID = request ID + 8 (e.g. 0x701 → 0x709).
| Request ID | Notes |
|---|---|
| 0x7E0 | Generic-OBD powertrain endpoint. Answers Mode-01 but rejects all UDS (serviceNotSupported). |
| 0x7E1 | Battery management system — pack voltage / current / SoC / cell data live here (below). |
| 0x7E2, 0x7E3 | Powertrain pair (consecutive part numbers) — motor/charge electronics. |
| 0x700–0x707, 0x710–0x713, 0x720–0x727, 0x730–0x736, 0x7AC | Body / chassis / comfort controllers (BCM, HVAC, ESP, EPS, airbag, steering, cluster, seats, tailgate, TPMS, …). |
The internal ECUs reachable this way are the usual EV set: BMS, VCU, motor controller, on-board charger, gear selector (powertrain); BCM, A/C module, PTC/compressor, seat heaters, tailgate, low-speed warning (body); ESP, EPS, iBooster, airbag, steering-angle sensor, cameras/radars (chassis); head unit, instrument cluster (infotainment); T-Box (telematics). Exact address↔module mapping is only confirmed for 0x7E0/0x7E1; the rest is inferred from the data and address block.
Reading data (non-destructive)
In the default session (no session change) you can typically:
- 0x19 ReadDTCInformation — stored fault codes, decoded (
19 02 FF= report by status mask). - 0x22 ReadDataByIdentifier — read data by 16-bit DID.
The identification block (DIDs 0xF180–0xF1FF) returns, on most ECUs: a part number in an
8619xxxxx scheme, a supplier code (CS-000xxx), a programming date, and the VIN (0xF190).
Example from one ECU: part 861923101B, supplier CS-000029, programmed 2021-11-10. Sweeping
these across all 24 ECUs builds a full part-number / build map of the car — no public Aiways ECU list
exists otherwise.
The BMS (0x7E1) carries a live measurement block around DIDs 0x8800–0x887F — roughly
120 aggregate battery values: pack voltage, current, cell voltages, SoC, temperatures, and status
words. This is where the numbers the head unit does not expose (cell min/max, temperatures,
state-of-health) should live.
⚠ Do not disturb the car while it is used
A broad scan — sweeping many ECU addresses and forcing an extended session (10 03) — makes
ECUs stop their normal CAN broadcasts. The instrument cluster then flags the “missing” modules with
warning icons, and a downstream display can freeze on a substituted value (we saw the
outside-temperature reading stick). It is read-only and reverts once probing stops, but:
- Never run a broad/aggressive scan while driving — an ECU dropping off the bus mid-drive is unsafe.
- Prefer the gentle method: functional discovery + default-session reads only (0x19 / 0x22), no session control. A single-ECU default-session read does not disturb the dash.
The fault codes you will see
The last two hex digits of a DTC are the standardised failure-type byte: …88 = CAN Bus Off, …87 = missing message / timeout, …82/83 = rolling-counter / checksum. So a `U…87` / `U…88` code means “lost communication”, not a real hardware event.
A consequence: any bus or power interruption — including an aggressive scan — makes many modules log “lost communication” against each other at once. After a heavy scan expect a long list of U-codes (and contiguous B-/C-code ranges); these are artifacts, self-clearing over clean drive cycles. The codes worth attention are the powertrain P-codes, which point at real sensor / HV faults. Read them all with 0x19 first, then judge.
Battery management fault codes
Manufacturer-specific codes (second character `1`, e.g. P110C00) turn out to be properly documented and genuinely EV-relevant — HV contactor voltage checks, BMS current-sensor faults, CAN gateway message timeouts, crash/airbag signalling. None of them are combustion-engine leftovers. The following battery-management codes have been identified and confirmed:
| Code | Meaning |
|---|---|
P112868 | CAN collision (crash) signal fault |
U11FA87 | Gateway message 0x2BB timeout |
U11FB87 | Gateway message 0x2DF timeout |
U11FC87 | Gateway message 0x3AA timeout |
U11FD87 | Gateway message 0x050 timeout |
U11FE87 | Gateway message 0x2F1 timeout |
U11FF87 | Gateway message 0x195 timeout |
U120087 | Gateway message 0x37F timeout |
U120187 | Gateway message 0x28C timeout |
U120287 | Gateway message 0x17D timeout |
U002888 | CAN bus disabled (bus off ≥3 s while awake) |
U00BA88 | DC fast-charge CAN bus disabled |
U10BA87 | DC fast-charge message timeout (charge controller) |
U112182 | Airbag ECU crash-message counter fault |
U112183 | Airbag ECU crash-message checksum fault |
U011187 | Communication loss with the BMS (message 0x2C7 missing 10 s) |
P110364 | Main-relay downstream voltage plausibility fault |
P110386 | Main-relay voltage invalid |
P11021C | Battery voltage out of allowable range |
P11081C | Internal current sensor (CAB) supply voltage faulty |
P110A1C | Internal current sensor (LEM) supply voltage faulty |
P110C00 | 12 V supply shuts down abnormally |
P11011D | Shunt current out of allowable range |
P110162 | Shunt current signal plausibility check failed |
P110164 | Shunt current sensor self-learn fault |
P110167 | Shunt current sensor fault |
P110192 | Current measurement fault in two circuits |
P110711 | Internal current sensor (Iem) shorted to ground |
P110712 | Internal current sensor (Iem) shorted to supply |
P110264 | Battery signal plausibility check failed |
P110286 | Invalid battery voltage signal |
P110464 | DC fast-charge relay downstream voltage plausibility fault |
P110486 | DC charging voltage invalid |
P11B467 | DC fast-charge voltage fault |
P11051D | Hall current sensor reading out of range |
P110562 | Hall current signal plausibility check failed |
P110564 | Hall current sensor self-learn fault |
P110567 | Defective Hall current sensor |
P110592 | Deviation between bus current from different sensors too large |
P110609 | Internal current sensor (CAB) fault |
P11061C | Internal current sensor (CAB) supply voltage faulty |
P110692 | Interior current sensor (CAB) fault after BMS self-test |
P115B92 | Simultaneous failure of two current-circuit sensors |
U11F487 | Internal current sensor (CAB) message timeout |
Every code here clears automatically if absent for 40 drive cycles, or via a diagnostic tool. The standard repair escalation is: cross-check codes on other modules → inspect harness/connector → check HV harness insulation resistance (target >1.5 MΩ, ≥120 MΩ for the PTC heater, at 500 V DC) → replace the battery pack assembly as a unit — there is no component-level BMS board repair path.
By contrast, the generic/SAE codes (second character `0`, e.g. the P02C1/P01C1 seen during live scans above) sit in ranges the standard defines for combustion-engine subsystems — P02xx is nominally “fuel injector circuit,” meaningless on this car. The ECU reporting them self-identifies over Mode 09 as HPCM-HybridPtCtrl (“Hybrid Powertrain Control Module”) — a real hint its diagnostic software is inherited from a hybrid/ICE platform, with some legacy generic checks never fully pruned for the pure-EV variant. Treat unexplained generic P0-range codes with suspicion; the manufacturer-specific P1xx range is the trustworthy one.
Charging-system codes have also turned up, though only as bare identifiers so far (no definitions found yet): P120019, P120119, P122000, P122100, P128A19, P128B98, P12A500. If anyone can pin down what these mean, please add it here.
Coverage note: a systematic search turned up fault-code documentation only for the battery-management codes above and this bare charging-system list — nothing yet for ESP, parking brake, brake booster, steering, HVAC, or body-electrics modules. If your car throws a code in one of those areas, this wiki doesn't have it documented — please add whatever you find.
Decoding the raw values
There is no public scaling for the manufacturer DIDs, so raw values are decoded by correlation — read a DID while you know the true value from another source (the head unit's decoded readout is ideal), and find the field + scale that match. A field is only trustworthy once you can make it move: switch a big HV load (A/C compressor) on and off and watch which fields track.
Confirmed on the BMS (0x7E1) this way:
- Pack voltage = DID
0x8871(raw = volts; read 407 vs head-unit 406.9 V). - Pack current = DID
0x887b(rises with load; identified by the A/C on/off test).
State-of-charge and the 12 V system voltage have plausible candidates but are not yet nailed —
near-constant signals need the car in different states (a drive, a charge) before their field and
scale can be confirmed. The decoded numbers sanity-check against the known pack spec (≈268–417 V
range, 24 modules, cell 2.8–4.35 V), so e.g. a 0x882d reading of ≈4.01 V is a real cell
voltage. A logger that records reference values and DIDs together across normal driving is the clean way
to finish the map.
Clearing fault codes
Clearing DTCs is the one “write” normally allowed without Security Access (it is needed for repair):
- Generic — Mode 04 (
ClearDiagnosticInformation): send04to 0x7DF / 0x7E0. Clears emissions DTCs and freeze frames. - Manufacturer — UDS service 0x14: send
14 FF FF FF(“clear all groups”) to a specific ECU (e.g. 0x7E1). Clears that module's stored DTCs, usually in the default session.
Notes: clearing masks real faults (good and bad alike) — read the codes first. Permanent DTCs cannot be cleared by a tool; the ECU clears them itself after its readiness monitors pass. A 12 V battery disconnect resets volatile display state but does not clear stored DTCs (non-volatile) — for that you need a clear command.
Waking the car
Diagnostic requests on this port wake the gateway and addressed ECUs for diagnostics (that is how a scan tool works on a parked car). That is a diagnostic wake only — it does not power up the HV system, close the main contactors, or start climate. Those are actuation functions behind Security Access.
What is locked — and the one interesting exception
Everything that changes or actuates — writing configuration (0x2E), actuator tests (0x2F), routines (0x31), ECU reset (0x11), flashing (0x34/0x36/0x37) — sits behind Security Access (0x27). The gateway answers a seed request, but the key algorithm is an OEM secret that is not public for this car. So in practice OBD-II here is read-only: fault codes and data yes, control no.
The interesting exception: a dealer tool activates functions like HV power-up or preconditioning via a security-gated routine (0x31) over this same diagnostic CAN. So the diagnostic port is not architecturally a dead end for control — with the correct Security-Access key, remote preconditioning could in principle be commanded straight over OBD-II, no internal-bus tap required. The key is the missing piece (see roadmap).
It is all standard
Under the hood this is plain UDS (ISO 14229) over ISO-TP (ISO 15765-2) on 500 k / 11-bit CAN — nothing proprietary at the wire level. That means standard open tools work: a small ISO-TP + UDS client in Python, or off-the-shelf car-diagnostic tools, will talk to this car. What is not open is the data dictionary (which DID means what, with what scaling) and the Security-Access key — both live in the manufacturer's diagnostic database.
Wiring & tools
A CANable-class USB-CAN adapter (gs_usb) on 500 k / 11-bit, driven from Python (raw frames + a small ISO-TP layer for multi-frame UDS).
- Wire CAN-H → OBD pin 6, CAN-L → OBD pin 14, ground to pin 4/5. Getting this wrong looks exactly like a dead bus.
- Adapter DIPs: Boot OFF (run), R120 OFF (the OBD-II bus is already terminated 2×120 Ω). A DIP change only takes effect after a full unplug/replug.
- Confirm wiring by watching the adapter's TX and RX LEDs blink during an active probe.