ObdClient class final

OBD-II (SAE J1979 / ISO 15765-4) client on any CanBus.

Requests are sent to the functional address; every ECU that answers within responseTimeout is collected (plus collectWindow after the first answer), and results are grouped by responding CAN ID. Multi-frame responses (VIN, DTC lists) are reassembled per ECU with flow control sent to that ECU's physical address. Requests run one at a time.

Reading is safe. Only clearDtcs changes vehicle state and needs allowWrites: true.

Connect in listen-only mode first to confirm the bitrate, or use autoDetect, which probes listen-only before it transmits.

final obd = ObdClient(bus);
final rpm = await obd.readPid(0x0C);
print(rpm.first); // Engine speed: 1726 rpm
await obd.close();

Constructors

ObdClient(CanBus bus, {ObdAddressing addressing = ObdAddressing.standard11Bit, Duration responseTimeout = const Duration(milliseconds: 1000), Duration collectWindow = const Duration(milliseconds: 100), Duration responsePendingTimeout = const Duration(milliseconds: 5000), IsoTpOptions isoTp = const IsoTpOptions(), bool allowWrites = false, int maxResponsePending = 20})
Creates a client and starts listening on bus.

Properties

addressing → ObdAddressing
11-bit or 29-bit addressing.
final
allowWrites → bool
Whether clearDtcs is allowed.
final
bus → CanBus
Bus the client runs on.
final
collectWindow → Duration
Extra time to collect answers from other ECUs after the first one.
final
hashCode → int
The hash code for this object.
no setterinherited
isClosed → bool
Whether close was called or the bus closed.
no setter
isoTp → IsoTpOptions
ISO-TP settings for multi-frame responses (padding, block size, N_Cr).
final
maxResponsePending → int
"Response pending" (NRC 0x78) answers accepted per request before the request ends; protects against an ECU that keeps answering 0x78.
final
responsePendingTimeout → Duration
Time to wait after an ECU reports "response pending" (NRC 0x78).
final
responseTimeout → Duration
Time to wait for the first response.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

clearDtcs() → Future<ObdEcuResponses<bool>>
Clears DTCs, freeze frames and readiness monitors (mode 04).
close() → Future<void>
Stops listening. Pending requests fail with CanBusClosedException.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
poll(List<int> pids, {Duration interval = const Duration(milliseconds: 500)}) → Stream<ObdPidSample>
Reads pids repeatedly, one request per PID, waiting interval between rounds. PIDs that no ECU answers are skipped in that round. Cancel the subscription to stop.
readCalibrationIds() → Future<ObdEcuResponses<List<String>>>
Calibration IDs (mode 09 PID 04), up to 16 characters each.
readEcuName() → Future<ObdEcuResponses<String>>
ECU name (mode 09 PID 0A), for example ECM-EngineControl.
readFreezeFrame(int pid, {int frame = 0}) → Future<ObdEcuResponses<ObdPidValue>>
Reads a PID from freeze frame frame (mode 02).
readPendingDtcs() → Future<ObdEcuResponses<List<Dtc>>>
Pending DTCs (detected in the current or last drive cycle), mode 07.
readPermanentDtcs() → Future<ObdEcuResponses<List<Dtc>>>
Permanent DTCs (cannot be cleared with mode 04), mode 0A.
readPid(int pid) → Future<ObdEcuResponses<ObdPidValue>>
Reads one mode 01 PID from every ECU that supports it.
readStoredDtcs() → Future<ObdEcuResponses<List<Dtc>>>
Stored (confirmed) DTCs, mode 03.
readVin() → Future<ObdEcuResponses<String>>
Vehicle identification number (mode 09 PID 02).
supportedPids() → Future<ObdEcuResponses<Set<int>>>
Supported mode 01 PIDs per ECU, walking the 0x00, 0x20, ... 0xC0 bitmaps while an ECU reports the next range as supported. Range PIDs themselves are omitted.
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Methods

autoDetect(Future<CanBus> openBus(CanBitrate bitrate, {required bool listenOnly}), {List<CanBitrate> bitrates = const [CanBitrate.k500, CanBitrate.k250], Duration listenWindow = const Duration(milliseconds: 300), Duration attemptTimeout = const Duration(milliseconds: 500), IsoTpOptions isoTp = const IsoTpOptions()}) → Future<ObdDetection?>
Tries 500 kbit/s and 250 kbit/s with 11-bit and 29-bit addressing and returns the first combination a vehicle answers on, or null.