CXDTC Command — ECU Fault Codes (DTC)
Reads the diagnostic trouble codes reported by the vehicle’s computer: the same ones a workshop scan tool shows, delivered over the device’s normal protocol.
- Trucks and machinery (J1939): SPN, FMI, reporting ECU, occurrence count and dashboard lamps.
- Light vehicles (OBD2): the full standard code —
P0301,P0420,P0087— and the reporting ECU.
Available in the 1.09.27 firmware series, which at the time of publishing this page is a
T (pre-release) version: delivered via FOTA on request, not part of the latest stable release.
Within the series: T1 adds J1939, T5 the signals, EVAL functions and the token, T6 the
report generator entry and T9 OBD2 support. With a T earlier than 9 the device does not read
OBD2 faults. Always confirm the installed T with >QVR<.
What is it for?
| Use case | Description |
|---|---|
| 🔧 Predictive maintenance | Know which fault the vehicle has without taking it to the workshop |
| 🚨 Immediate alert | Automatic report as soon as a new fault appears |
| 📋 Remote diagnostics | Query the list of active faults at any time |
| ⚙️ Local rules | Trigger actions in the vehicle (output, buzzer, SMS) without going through the server |
| 📊 Simple integration | Every report is a full snapshot: the platform never rebuilds state |
Compatibility
Rinho Zero IoT has no CAN transceiver: on that model these commands answer
NA. To read vehicle faults use Spider IoT or Smart IoT.
The protocol configured in CXCAN
must match the vehicle: J1939 on trucks, OBDII on light vehicles. If it does not match, the
module always reports zero faults.
Configuration — SCXDTC / QCXDTC
SCXDTC[en][,agesec[,busclr[,autorpt[,destination]]]]
QCXDTC
RCXDTC[en],[agesec],[busclr],[autorpt],[destination]| Parameter | Description | Default |
|---|---|---|
en | 0 = disabled, 1 = enabled | 0 |
agesec | Seconds without seeing a code before clearing it (1-60) | 3 |
busclr | Reserved for clearing faults on the vehicle | 0 |
autorpt | 0/1 — automatic report on new fault or resolution | 0 |
destination | Where the automatic report goes | GP |
Fields are positional and optional from left to right: >SCXDTC1< enables reading and leaves the
rest untouched, while >SCXDTC1,3,0,1,GP< sets them all. An invalid field rejects the whole command
without persisting anything.
Automatic report destinations
| Token | Channel |
|---|---|
GP | Main GPRS (default) |
WI | Main WiFi |
BT | Bluetooth |
TR | Serial port |
BGP / BWI | Backup GPRS / WiFi |
BACK | Smart backup |
LOG | Internal datalog — retrieved later with >QDL+< |
ALL | All active channels |
To validate the integration, start with LOG: the report is stored in the device and reviewed all at
once at the end of the trip with >QDL+<, without depending on the server being up.
The busclr field is reserved: it is accepted and stored, but does not yet trigger fault
clearing on the vehicle (DM11 on J1939 / Mode 04 on OBD2). Leave it at 0.
Query — QDTC
QDTC
RDTC[n][;<source>:<ecu>:<code>:<fmi>:<occurrences>;…]| Response | Meaning |
|---|---|
RDTC0 | Reading the bus, no active faults |
RDTC2;J:00:100:1:4;J:00:1761:1:12 | Two active faults (truck) |
RDTC1;O:00:P0301:0:0 | One active fault (light vehicle) |
RDTCNA | Reading is disabled (en=0) |
On OBD2 the module polls the ECU every 30 seconds: after enabling, wait one cycle before trusting a zero response. On J1939 reading is immediate, because the ECU broadcasts the DM1 on its own.
Clearing — CDTC
CDTC → RDTC OKClears the list stored in the device. If the vehicle keeps reporting the fault, it reappears on
the next cycle — which is the correct behaviour: CDTC clears the device’s record, it does not
turn off the vehicle’s fault.
List format
J:00:100:1:4
│ │ │ │ └─ occurrence count
│ │ │ └─── FMI: how it fails
│ │ └─────── SPN: which component fails
│ └────────── reporting ECU (hex)
└──────────── source: J = J1939 · O = OBD2| Source | Code | FMI | Occurrences |
|---|---|---|---|
J (J1939) | Numeric SPN (100, 1761) | 0-31 | 0-127 |
O (OBD2) | Standard code (P0301, U0100) | always 0 | always 0 |
FMI and occurrence count are J1939-specific fields: the OBD2 protocol does not transmit them, which
is why they are zero. The leading letter of an OBD2 code indicates the system: P powertrain,
C chassis, B body, U network.
FMI — the fault type (J1939)
| FMI | Meaning |
|---|---|
| 0 / 1 | Value above / below normal range |
| 2 | Erratic or intermittent data |
| 3 / 4 | Short to power / short to ground |
| 5 / 6 | Open circuit / over-current |
| 7 | Mechanical system not responding |
| 12 | Component damaged |
| 31 | Condition exists, no further detail |
The distinction matters: fuel pressure with FMI 1 is genuinely low pressure (filter, pump); with FMI 5 it is an open circuit (disconnected sensor or cut wire).
Automatic report
With autorpt=1 the device emits a DF report
when a new fault appears and when all of them clear:
>RDF00020826143512;2;J:00:100:1:4;J:00:1761:1:12< // two active faults
>RDF00020826150233;0< // resolution: none leftDate and time are those of the moment the fault occurred, not of transmission: if the vehicle was out of coverage, the report waits in the queue and reports when it actually happened once signal returns.
It can also be requested on demand, like any other report:
>QDF< // direct response over the asking channel
>GDF00H< // queues the report to the configured destinationRule signals
Faults are event engine triggers, combinable with any other signal:
| Signal | Activates when |
|---|---|
DTC00 | There is at least one active fault |
DTC01 | A new fault appeared |
DTC02 | A dashboard lamp is on (J1939 only) |
DTC03 | All faults were cleared |
>SRL05E;TRG=DTC01+;ACC={GDF00H}< // new fault → report to server
>SRL07E;TRG=DTC02+;ACC={SSSXP0011}< // lamp on → output in the cabinEVAL functions
| Function | Returns |
|---|---|
DTCN() | Number of active faults |
DTC(n) | The DTC0n sub-signal (DTC(0) = any fault, DTC(2) = lamp on) |
DTCH(spn) | 1 if that SPN is active — J1939 only |
Template token
'DTC' inserts the full fault list into a user report
(UC) or a dynamic action
(DA):
>SUC00 faults:'DTC'<Limits
| Limit | Value |
|---|---|
| Simultaneous faults in the table | 32 |
| Faults per frame | ~15 (the reported count is always the real one; the list is truncated) |
Faults in the 'DTC' token | ~7 (128-byte buffer) |
| OBD2 polling period | 30 s (backs off to 5 min if no ECU answers for 5 cycles) |
| Minimum interval between automatic reports | 10 s |
| Memory with reading enabled | 768 bytes (nothing is allocated with en=0) |
Not available yet: clearing faults on the vehicle (busclr), stored or pending faults
(DM2 / Mode 07), dashboard lamps on OBD2, and DTCH() over OBD2 codes.
Bus load: on J1939 the module is listen-only and transmits nothing. On OBD2 it issues one Mode 03 request every 30 seconds, the same request a diagnostic scan tool makes.
Full example
>QCXCAN< // 1. check the protocol (J1939 or OBDII)
>SCXDTC1,3,0,1,GP< // 2. enable with automatic report to the server
>QCXDTC< // → RCXDTC1,3,0,1,GP
>QDTC< // 3. current status
// → RDTC1;O:00:P0301:0:0 (Chevrolet Tracker with a cylinder 1 misfire)See Also
- DF Report - Fault report format
- Reading ECU faults - Step-by-step application note
- CXCAN Command - Bus protocol selection
- ECU Command - Engine telemetry
- Trigger list - Event engine signals