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.
Standard emissions services work, addressed functionally to 0x7DF (responses on 0x7E8):
09 02) and calibration IDs.BF FB FF F7 and, usefully on an EV, PID 0x5B (“hybrid/EV battery remaining charge”).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 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.
In the default session (no session change) you can typically:
19 02 FF = report by status mask).
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.
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:
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.
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.
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:
0x8871 (raw = volts; read 407 vs head-unit 406.9 V).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 DTCs is the one “write” normally allowed without Security Access (it is needed for repair):
ClearDiagnosticInformation): send 04 to 0x7DF / 0x7E0. Clears emissions DTCs and freeze frames.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.
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.
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).
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.
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).