Jump to content

Test-AC: Difference between revisions

From Teltonika Telematics Wiki
No edit summary
GTPGTM-11768 - draft
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
===Firmware versions===
==Introduction==


<table class="nd-othertables_2" style="width:100%; border-collapse: collapse;">
With a professional device lineup, telltale information (dashboard indicators) from heavy-duty vehicles can be read remotely to identify a variety of issues. New feature of Diagnostic Trouble Code (DTC) reading will help to narrow down the specific faults happening in vehicles.
<tr>
 
<th style="width:20%; vertical-align: middle; text-align: center;"> '''FIRMWARE VERSION''' </th>
With {{{model}}} you can read 2 types of DTC messages based on J1939 protocol:
<th style="width:20%; vertical-align: middle; text-align: center;"> '''RELEASE DATE''' </th>
 
<th style="width:60%; vertical-align: middle; text-align: center;"> '''CHANGES''' </th>
*DM1 – Communicates currently present faults
<tr style="text-align: center; vertical-align: middle;">
*DM2 – Reports stored faults
<td style="vertical-align: middle">''' 03.01.01.rev.15'''</td>
 
<td style="vertical-align: middle">2026.03.23</td>
{{{model}}} is able to read DM codes and pass them to the server in IO element. When active DM1 or DM2 messages appear on CAN line it is broadcasted very often – {{{model}}} device saves the codes into the internal memory and does not flood the server with irrelevant information – only new DTC codes are sent to the server.
<td style="text-align: left; vertical-align: top">
 
'''General Stability / Functionality'''
==Functionality Description==
*Improved internal device watchdog mechanisms to ensure more stable long-term operation.
 
*Fixed inconsistent generation of periodic records so they are now created according  to configuration.
This functionality is available from Firmware version '''03.01.02.rev.06''' or higher.
*Fixed the record counter IO so that it increments correctly when new records are created and does not reset unexpectedly in specific configurations.
 
*Fixed unnecessary daily activation of a specific event IO. The IO now triggers only on real events instead of once per day. 
For proper functionality, the device requires ignition to be active. Source of ignition and voltage level can be selected from '''System''' tab.
*Improved GNSS calculation algorithms for more stable, precise and faster coordinate updates.
 
*Fixed issues where idling events were not recorded even when idling detection was configured.
Ignition has to be active for at least 14 sec to start generating the DTC list. If ignition is turned off, the device will clean all DM1 and DM2 codes and functionality will not be working.
*Improved movement detection algorithms for more precise event recording. 
 
*Fixed duplicate or missing “Trip End” status records. 
[[File:DTC_Ignition.png]]
*Fixed DOUT1 behaviour in Geofence scenarios where a non-zero speed was required even when configuration did not require it.
 
*Fixed unnecessary immobilizer status change records. 
After the device is connected to the Configurator, there will be '''DM1 / DM2''' tab made available. There is a configurable DM1 / DM2 Data source parameter. This parameter selects the CAN source based on which device will parse DM data from. Based on selected data source, device will also call a request for DTCs.
*Fixed an issue where the immobilizer scenario could be bypassed under certain conditions and where immobilizer events were generated without values.
 
*Fixed incorrect behaviour where the immobilizer scenario was not enforced when no authorization list was configured.
'''Note:''' The functionality is completely separated from the FMS source.
*Improved logic for DOUT control in immobilizer scenarios so DOUT states are handled consistently, including across sleep/wake transitions. 
 
*Fixed mismatches between the device-calculated odometer and tachograph  odometer. 
[[File:DTC Data source selection.png]]
*Fixed issues where fuel data from certain liquid level sensors could be lost, causing incomplete fuel history.
 
*Improved total distance and trip distance counting for more accurate mileage  tracking. 
*NONE – Device will not use any CAN as data source
*Included multiple minor internal stability and bug-fix improvements that collectively improve overall system robustness, logging, and performance. 
*CAN1 – Device will use CAN1 as data source
*Fixed an issue where the device did not enter Deep Sleep mode properly.
*CAN2 – Device will use CAN2 as data source
'''Connectivity & Server Communication'''
*BOTH – Device will use CAN1 and CAN2 as data source
*Fixed an issue where the device did not establish a data connection if the APN field was left blank. 
 
*Improved modem and network handling, including better operator selection and reconnection behaviour, reducing unexpected data link issues. 
Bellow '''Data source''' parameters there is a list of configurable IOs
*Fixed behaviour where the device continuously contacted the NTP server when GNSS fix was unavailable. 
 
*Fixed an issue where incorrect NTP responses could lead to timestamps being set in the future.
[[File:DTC Configurable IOs.png]]
*Fixed a problem where the device could receive future timestamps when NITZ was used as the time synchronisation source. 
 
*Fixed an issue where the device did not send records to the configured duplicate server correctly. 
„DTC DM1“ and “DTC DM2“ shows the last DTC that has been detected. „Active DM1 List“ and „Active DM2 List“ provides a list of all active DTCs for a given source.
*Fixed failures to send records to the duplicate server in some TCP/UDP scenarios. 
 
*Fixed an issue where records were bundled into a single packet rather than being sent individually as expected. 
Example of generating DM1 / DM2 list: To register DM1 code, it is required to send a command using (pgn 0xFEFA). Device will first check if such DTC code exist in the system (MCUID and CAN Source has to be unique for each DTC). Otherwise, DTC will be rejected.
*Fixed delays in record transmission over UDP.
 
*Fixed issues where the device could disconnect from the server after executing certain GPRS or configuration commands. 
[[File:DTC Configurator outputs.png]]
*Fixed internal log download issues via over-the-air tools.
 
*Fixed a situation where over-the-air firmware update tasks could remain stuck in “Pending” or “Executing” state.
<span style="color:green;">9D000301:<span style="color:blue;">01:<span style="color:red;">01
*Fixed occasional failures of firmware updates performed via the configuration tool, reducing the chance of interrupted or failed local updates. 
*<span style="color:green;">9D000301</span> – DTC in hexadecimal format
*Fixed an issue where the device was not generating Iridium SBD records.
*<span style="color:blue;">01</span> – MCU source that reported the DTC
*Improved RS232 data sending to the Iridium module to ensure that SBD payloads are delivered reliably and without truncation.
*<span style="color:red;">01</span> – Device CAN source used (00 - CAN1, 01 - CAN2)
'''Bluetooth / BLE'''
 
*Fixed cases where the device generated unnecessary beacon records in stop mode.
<span style="color:green;">9D000302:<span style="color:blue;">02:<span style="color:red;">01
*Fixed issues where advanced beacon packet length information was not generated correctly in advanced beacon mode.
*<span style="color:green;">9D000302</span> – DTC in hexadecimal format
*Fixed incorrect reading of custom BLE parameter values when the data size was less than three bytes.
*<span style="color:blue;">02</span> – MCU source that reported the DTC
'''MQTT'''
*<span style="color:red;">01</span> – Device CAN source used (00 - CAN1, 01 - CAN2)
* Fixed incorrect packing of MQTT packets containing multiple JSON objects when sending to cloud platforms.  
 
* Fixed an issue where the device did not send data via MQTT to custom cloud endpoints in some configurations.
Based on configured „Priority“, „Event Only“ and „Operand“ device will add this parameter to record.
* Fixed behaviour where long RS232 messages were not sent correctly via MQTT, which could cause truncation or loss when transmitted as JSON. 
 
* Improved long-term stability of MQTT JSON operation, increasing reliability for continuous cloud integrations and complex payloads.
[[File:DTC Terminal logs.png]]
'''Tachograph, K-Line & Driver/Company Data'''
 
* Implemented separate internal instance IDs for tachograph IO elements and DDD file  downloading to avoid interference between live data and file download.
To remove one of the DTC from DM1 list, DM2 code (pgn 0xFEFB) is required. Device will check if the sent DTC code exists in the system (MCUID and CAN Source has to be unique for each DTC). If sent DTC does not exist in the system, it will be rejected.
* Fixed a problem where tachograph auto address selection did not work correctly. 
 
* Fixed an issue where the working tachograph address could change unexpectedly after firmware updates, causing DDD download failures. 
Based on previous example, sending DTC 9D000301 with MCUID 01 on CAN2, device remove this DTC from the system, as the result, this DTC is removed from „Active DM1 List“ and added to the „Active DM2 List“.
* Fixed errors where remote tachograph file download sessions could be interrupted or not start at all in certain conditions.
 
* Fixed behaviour where the tachograph company card number continued to be reported even after the card was removed.
[[File:DTC Configurator outputs 2.png]]
* Fixed an issue where the tachograph Driver Name field was missing or incomplete in driver information data.  
 
* Improved character encoding for tachograph Driver Name, including extended and Nordic letters.
Log example:
* Fixed an issue where no data was received over K-Line, preventing tachograph and diagnostic data reception.
 
* Improved K-Line detection and privacy mode handling, including explicit privacy status reporting where applicable. 
[[File:DTC Terminal logs 2.png]]
* Enhanced tachograph-related logging and error handling to make diagnostics clearer.
 
* Fixed transmission of vehicle and driver identification values (such as VIN, VRN and driver identification) so that accurate identification data is always sent.
That DTCs will be added to record and would be accessible on server. Data on server need to be converted from HEX to ASCII.
'''FMS / Manual CAN / CAN / Eco Driving & Vehicle Data'''
 
* Fixed missing or incorrect reading of specific FMS parameters, including version-specific parameter sets.
[[File:DTC Outputs from server.png]]
* Fixed fluctuating fuel levels when using FMS or CAN sources, improving fuel accuracy for both standard and EV FMS use cases.
 
* Fixed issues where FMS-based speed was not being used correctly as the selected speed source. 
'''39443030303330323A30323A30313B''' -> (after conversion from hex to ANSCII) '''9D000302:02:01''';
* Improved overall CAN stability so that tachograph CAN and FMS information is not lost due to CAN bus overflow.
 
* Fixed incomplete or malformed responses to commands that start or stop Manual CAN (MCAN) transmissions, ensuring clear responses and reliable remote control. 
'''39443030303330313A30313A30313B''' -> (after conversion from hex to ANSCII) '''9D000301:01:01''';
* Ensured that Manual CAN requests and commands are no longer executed when ignition is OFF.
 
'''New Features'''
==Functionality Block Diagram==
* NEW! Added support for storing and sending records from RAM memory. recommended for rapid data sending i.e. data saving every second etc. ([[FMC650 System settings#Records Saving/Sending Without TS|FMC650 System settings]])
Graphic representation of '''DM1''' and '''DM2''' functionality:
* NEW! Implemented a new feature called the “one minute rule” for tachograph driving state, reducing unnecessary state toggling and improving driving/rest detection accuracy.([[FMC650 LVCAN I/O,FMS IO and Tachograph data elements#Driver Working State Filters|FMC650 Driver Working State Filters]])
 
* NEW! Apache Thermograph ([[FMC650 Thermograph#Apache|FMC650 Thermograph]])
[[File:DTC Functionality blok diagram.png]]
* NEW! Trailer CAN functionality. ([[FMC650 TrailerCAN]])
 
* NEW! Implemented “scanevfms“ command for diagnosing electric trucks, providing targeted EV CAN diagnostics. ([[FMB scanevfms]])
 
* NEW! Implemented “can_info“ command that returns details of the CAN bus (baud rates, modes and other key parameters), aiding diagnostics. ([[FMB can_info]])
==DM1 Lamp Status and Flash Signals==
* NEW! Updated the “tachocheck“command to show more detailed information. ([[FMB tachocheck]])
 
'''Configuration, Parameters & Tools'''
The '''DM1 (Diagnostic Message 1)''' in the '''J1939''' protocol reports active '''Diagnostic Trouble Codes (DTCs)''' and controls vehicle warning indicators. It defines the behavior of the '''Malfunction Indicator Lamp (MIL)''' and other warning lamps, which can be off, on solid, or flashing, depending on the severity and priority of detected faults. Flashing typically signals a more urgent or severe condition, while a solid light indicates an active but less critical issue.
* Fixed an issue where a single setparam command could not change multiple parameters at once.
 
* Fixed behaviour where the odometer command always returned a GNSS-based odometer value regardless of the configured odometer source.
The first byte represents the status of four indicator lamps:
* Fixed cases where the device disconnected unnecessarily from the configurator.
 
* Fixed an issue where the SIM PIN was not remembered after soft or hard reset.
*'''PL (Protect Lamp)''' - DTC's indicate non-electronic subsystem issue.
</td>
*'''AWL(Amber Warning Light)''' - DTC's indicate a non-critical issue that does not warrant stopping the vehicle.
</tr>
 
*'''RSL(Red Stop Lamp)''' - DTC's indicate a critical issue that warrants stopping the vehicle immediately.  
 
*'''MIL(Malfunction Indicator Lamp)''' - At least one DTC indicates emissions related issue.
 
Each lamp is encoded using 2 bits, allowing four possible states: '''off, on, slow flash, and fast flash'''. This compact encoding means all lamp states are conveyed within a single byte, with each pair of bits mapped to a specific lamp in a fixed order. These lamp states directly inform the operator about the severity and urgency of active faults.
 
DM1 encodes warning lamp information in its first 2 bytes, combining both lamp status and flash behavior. Each lamp is represented by two 2-bit fields—one in byte 1 (status) and one in byte 2 (flash).  
 
To decode, split each byte into 2-bit segments and map each pair to its corresponding lamp. The final behavior is determined by combining status and flash (e.g., ON + fast flash = rapidly blinking warning).
 
==Global and Manufacturer SPN Codes==
 
===Global-Level SPN codes===
 
Standard codes are defined by the SAE J1939 standards and are recognized across all compliant vehicles and equipment. The SPNs for these codes fall within the range of '''1 to 24,324''' representing widely used parameters such as engine speed, coolant temperature, or oil pressure. FMI values are standardized, describing specific failure patterns such as high voltage, circuit open, or out-of-range conditions.
 
Because they are standardized, these codes are universally interpretable by any compliant diagnostic tool without requiring manufacturer-specific references.
 
===Manufacturer-Level SPN codes===
 
Manufacturer-level or proprietary codes are reserved for OEM-specific faults that are not defined in the J1939 standard. These allow manufacturers to monitor unique components, systems, or operational conditions that are specific to their equipment.
 
The SPNs for proprietary codes typically occupy the high end of the 19-bit field, ranging from '''516,096 to 524,287'''. FMI values may be standard or custom, but the meaning of the SPN is defined by the manufacturer. Accurate interpretation requires access to OEM documentation, as these codes are not universally defined or interpretable.
 
==DM1/DM2 Message Structure==
 
Each DM1/DM2 message is transmitted using the J1939 transport protocol when needed (multi-packet if the data exceeds 8 bytes), but can also fit within a single CAN frame when only one DTC is present. The message begins with a lamp status byte, followed by zero or more DTC entries, each occupying exactly 4 bytes.
 
 
 
Following the lamp status byte, the message contains one or more Diagnostic Trouble Codes (DTCs). Each DTC is encoded in a 4-byte structure that combines several fields into a compact binary format. The first 19 bits represent the Suspect Parameter Number (SPN), which identifies the specific parameter or component that is faulty. This value is split across the first three bytes in a non-linear way, requiring bit-level extraction rather than simple byte parsing.
 
The next 5 bits define the Failure Mode Identifier (FMI), which describes how the failure manifests (for example, data out of range, voltage too high, or signal erratic). Together, the SPN and FMI uniquely describe the nature of the fault.
 
After the FMI, a single bit is used for the SPN Conversion Method (CM). In modern systems, this bit is almost always set to 0, indicating the standard encoding method is used. A value of 1 indicates an alternative legacy encoding, which is rarely encountered but must still be handled correctly in robust implementations.
 
The final 7 bits of the 4-byte DTC structure represent the Occurrence Count (OC). This value indicates how many times the fault has been detected. It is typically capped at 127 and provides useful insight into whether a fault is intermittent or persistent.
 
When multiple DTCs are present, they are simply appended sequentially after the lamp status byte, each occupying 4 bytes. There is no explicit delimiter between DTCs; instead, the total message length determines how many are included. In multi-packet transmissions, this sequence continues seamlessly across transport protocol frames.
 
Practical Interpretation and DM1 vs DM2 Context
 
From an implementation perspective, decoding DM1 and DM2 messages requires careful bit extraction and reconstruction of the SPN, FMI, CM, and OC fields from each 4-byte DTC block. The lamp status byte must be interpreted separately before processing the DTC list.
 
The practical difference between DM1 and DM2 lies not in structure but in semantics. DM1 messages are typically broadcast periodically (for example, once per second) whenever active faults exist, making them essential for real-time monitoring and dashboards. In contrast, DM2 messages are only transmitted upon request and provide access to historical fault data that is no longer active but still stored in the ECU memory.
 
An important implementation detail is that DM1 messages may contain no DTCs, in which case only the lamp status byte is transmitted. This indicates that no active faults are present, and all lamps are typically off. However, the system must still correctly interpret this as a valid message rather than an error condition.
 
Another subtle but important aspect is that multiple ECUs on the same network can transmit their own DM1 messages independently. Each message is identified by its source address, meaning a complete diagnostic picture requires aggregating DM1 data across all nodes on the network.
 
In summary, the DM1/DM2 message structure is compact but highly information-dense. A single byte conveys overall system warning states, while each 4-byte DTC block encodes a complete fault description including what failed, how it failed, and how often it has occurred. Proper decoding requires precise bit-level handling, but once implemented, it provides a standardized and scalable way to monitor and diagnose vehicle systems across the entire J1939 network.

Latest revision as of 14:29, 26 March 2026

Introduction

With a professional device lineup, telltale information (dashboard indicators) from heavy-duty vehicles can be read remotely to identify a variety of issues. New feature of Diagnostic Trouble Code (DTC) reading will help to narrow down the specific faults happening in vehicles.

With {{{model}}} you can read 2 types of DTC messages based on J1939 protocol:

  • DM1 – Communicates currently present faults
  • DM2 – Reports stored faults

{{{model}}} is able to read DM codes and pass them to the server in IO element. When active DM1 or DM2 messages appear on CAN line it is broadcasted very often – {{{model}}} device saves the codes into the internal memory and does not flood the server with irrelevant information – only new DTC codes are sent to the server.

Functionality Description

This functionality is available from Firmware version 03.01.02.rev.06 or higher.

For proper functionality, the device requires ignition to be active. Source of ignition and voltage level can be selected from System tab.

Ignition has to be active for at least 14 sec to start generating the DTC list. If ignition is turned off, the device will clean all DM1 and DM2 codes and functionality will not be working.

After the device is connected to the Configurator, there will be DM1 / DM2 tab made available. There is a configurable DM1 / DM2 Data source parameter. This parameter selects the CAN source based on which device will parse DM data from. Based on selected data source, device will also call a request for DTCs.

Note: The functionality is completely separated from the FMS source.

  • NONE – Device will not use any CAN as data source
  • CAN1 – Device will use CAN1 as data source
  • CAN2 – Device will use CAN2 as data source
  • BOTH – Device will use CAN1 and CAN2 as data source

Bellow Data source parameters there is a list of configurable IOs

„DTC DM1“ and “DTC DM2“ shows the last DTC that has been detected. „Active DM1 List“ and „Active DM2 List“ provides a list of all active DTCs for a given source.

Example of generating DM1 / DM2 list: To register DM1 code, it is required to send a command using (pgn 0xFEFA). Device will first check if such DTC code exist in the system (MCUID and CAN Source has to be unique for each DTC). Otherwise, DTC will be rejected.

9D000301:01:01

  • 9D000301 – DTC in hexadecimal format
  • 01 – MCU source that reported the DTC
  • 01 – Device CAN source used (00 - CAN1, 01 - CAN2)

9D000302:02:01

  • 9D000302 – DTC in hexadecimal format
  • 02 – MCU source that reported the DTC
  • 01 – Device CAN source used (00 - CAN1, 01 - CAN2)

Based on configured „Priority“, „Event Only“ and „Operand“ device will add this parameter to record.

To remove one of the DTC from DM1 list, DM2 code (pgn 0xFEFB) is required. Device will check if the sent DTC code exists in the system (MCUID and CAN Source has to be unique for each DTC). If sent DTC does not exist in the system, it will be rejected.

Based on previous example, sending DTC 9D000301 with MCUID 01 on CAN2, device remove this DTC from the system, as the result, this DTC is removed from „Active DM1 List“ and added to the „Active DM2 List“.

Log example:

That DTCs will be added to record and would be accessible on server. Data on server need to be converted from HEX to ASCII.

39443030303330323A30323A30313B -> (after conversion from hex to ANSCII) 9D000302:02:01;

39443030303330313A30313A30313B -> (after conversion from hex to ANSCII) 9D000301:01:01;

Functionality Block Diagram

Graphic representation of DM1 and DM2 functionality:


DM1 Lamp Status and Flash Signals

The DM1 (Diagnostic Message 1) in the J1939 protocol reports active Diagnostic Trouble Codes (DTCs) and controls vehicle warning indicators. It defines the behavior of the Malfunction Indicator Lamp (MIL) and other warning lamps, which can be off, on solid, or flashing, depending on the severity and priority of detected faults. Flashing typically signals a more urgent or severe condition, while a solid light indicates an active but less critical issue.

The first byte represents the status of four indicator lamps:

  • PL (Protect Lamp) - DTC's indicate non-electronic subsystem issue.
  • AWL(Amber Warning Light) - DTC's indicate a non-critical issue that does not warrant stopping the vehicle.
  • RSL(Red Stop Lamp) - DTC's indicate a critical issue that warrants stopping the vehicle immediately.
  • MIL(Malfunction Indicator Lamp) - At least one DTC indicates emissions related issue.

Each lamp is encoded using 2 bits, allowing four possible states: off, on, slow flash, and fast flash. This compact encoding means all lamp states are conveyed within a single byte, with each pair of bits mapped to a specific lamp in a fixed order. These lamp states directly inform the operator about the severity and urgency of active faults.

DM1 encodes warning lamp information in its first 2 bytes, combining both lamp status and flash behavior. Each lamp is represented by two 2-bit fields—one in byte 1 (status) and one in byte 2 (flash).

To decode, split each byte into 2-bit segments and map each pair to its corresponding lamp. The final behavior is determined by combining status and flash (e.g., ON + fast flash = rapidly blinking warning).

Global and Manufacturer SPN Codes

Global-Level SPN codes

Standard codes are defined by the SAE J1939 standards and are recognized across all compliant vehicles and equipment. The SPNs for these codes fall within the range of 1 to 24,324 representing widely used parameters such as engine speed, coolant temperature, or oil pressure. FMI values are standardized, describing specific failure patterns such as high voltage, circuit open, or out-of-range conditions.

Because they are standardized, these codes are universally interpretable by any compliant diagnostic tool without requiring manufacturer-specific references.

Manufacturer-Level SPN codes

Manufacturer-level or proprietary codes are reserved for OEM-specific faults that are not defined in the J1939 standard. These allow manufacturers to monitor unique components, systems, or operational conditions that are specific to their equipment.

The SPNs for proprietary codes typically occupy the high end of the 19-bit field, ranging from 516,096 to 524,287. FMI values may be standard or custom, but the meaning of the SPN is defined by the manufacturer. Accurate interpretation requires access to OEM documentation, as these codes are not universally defined or interpretable.

DM1/DM2 Message Structure

Each DM1/DM2 message is transmitted using the J1939 transport protocol when needed (multi-packet if the data exceeds 8 bytes), but can also fit within a single CAN frame when only one DTC is present. The message begins with a lamp status byte, followed by zero or more DTC entries, each occupying exactly 4 bytes.


Following the lamp status byte, the message contains one or more Diagnostic Trouble Codes (DTCs). Each DTC is encoded in a 4-byte structure that combines several fields into a compact binary format. The first 19 bits represent the Suspect Parameter Number (SPN), which identifies the specific parameter or component that is faulty. This value is split across the first three bytes in a non-linear way, requiring bit-level extraction rather than simple byte parsing.

The next 5 bits define the Failure Mode Identifier (FMI), which describes how the failure manifests (for example, data out of range, voltage too high, or signal erratic). Together, the SPN and FMI uniquely describe the nature of the fault.

After the FMI, a single bit is used for the SPN Conversion Method (CM). In modern systems, this bit is almost always set to 0, indicating the standard encoding method is used. A value of 1 indicates an alternative legacy encoding, which is rarely encountered but must still be handled correctly in robust implementations.

The final 7 bits of the 4-byte DTC structure represent the Occurrence Count (OC). This value indicates how many times the fault has been detected. It is typically capped at 127 and provides useful insight into whether a fault is intermittent or persistent.

When multiple DTCs are present, they are simply appended sequentially after the lamp status byte, each occupying 4 bytes. There is no explicit delimiter between DTCs; instead, the total message length determines how many are included. In multi-packet transmissions, this sequence continues seamlessly across transport protocol frames.

Practical Interpretation and DM1 vs DM2 Context

From an implementation perspective, decoding DM1 and DM2 messages requires careful bit extraction and reconstruction of the SPN, FMI, CM, and OC fields from each 4-byte DTC block. The lamp status byte must be interpreted separately before processing the DTC list.

The practical difference between DM1 and DM2 lies not in structure but in semantics. DM1 messages are typically broadcast periodically (for example, once per second) whenever active faults exist, making them essential for real-time monitoring and dashboards. In contrast, DM2 messages are only transmitted upon request and provide access to historical fault data that is no longer active but still stored in the ECU memory.

An important implementation detail is that DM1 messages may contain no DTCs, in which case only the lamp status byte is transmitted. This indicates that no active faults are present, and all lamps are typically off. However, the system must still correctly interpret this as a valid message rather than an error condition.

Another subtle but important aspect is that multiple ECUs on the same network can transmit their own DM1 messages independently. Each message is identified by its source address, meaning a complete diagnostic picture requires aggregating DM1 data across all nodes on the network.

In summary, the DM1/DM2 message structure is compact but highly information-dense. A single byte conveys overall system warning states, while each 4-byte DTC block encodes a complete fault description including what failed, how it failed, and how often it has occurred. Proper decoding requires precise bit-level handling, but once implemented, it provides a standardized and scalable way to monitor and diagnose vehicle systems across the entire J1939 network.