From bf59c1896cbdab1dd361cb43ca38be9a9c02a2d6 Mon Sep 17 00:00:00 2001 From: Muksin Muksin <75759731+muki01@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:52:35 +0200 Subject: [PATCH 1/5] Added cheksum setter --- src/OBD2_KLine.cpp | 4 ++++ src/OBD2_KLine.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/OBD2_KLine.cpp b/src/OBD2_KLine.cpp index 3303735..81380bc 100644 --- a/src/OBD2_KLine.cpp +++ b/src/OBD2_KLine.cpp @@ -955,4 +955,8 @@ void OBD2_KLine::setISO14230Header(uint8_t h1, uint8_t h2, uint8_t h3) { void OBD2_KLine::setLengthMode(bool inHeader) { useLengthInHeader = inHeader; +} + +void OBD2_KLine::setChecksumType(uint8_t checksum) { + checksumType = checksum; } \ No newline at end of file diff --git a/src/OBD2_KLine.h b/src/OBD2_KLine.h index d5b4d74..7e8b8a1 100644 --- a/src/OBD2_KLine.h +++ b/src/OBD2_KLine.h @@ -101,6 +101,7 @@ class OBD2_KLine { void setISO9141Header(uint8_t h1, uint8_t h2, uint8_t h3); void setISO14230Header(uint8_t h1, uint8_t h2, uint8_t h3); void setLengthMode(bool inHeader); + void setChecksumType(uint8_t checksumType); private: SerialType* _serial; @@ -113,6 +114,7 @@ class OBD2_KLine { uint8_t header_ISO9141[3] = {0x68, 0x6A, 0xF1}; uint8_t header_ISO14230_Fast[3] = {0xC0, 0x33, 0xF1}; bool useLengthInHeader = true; + uint8_t checksumType = 2; // 0: NONE, 1: XOR, 2: Modulo256, 3: Two's Complement uint8_t resultBuffer[160] = {0}; uint8_t unreceivedDataCount = 0; From b56babb7be9015a3561c06d8dab7d1f6622f359f Mon Sep 17 00:00:00 2001 From: Muksin Muksin <75759731+muki01@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:54:45 +0200 Subject: [PATCH 2/5] Added checksums to writeData function --- src/OBD2_KLine.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/OBD2_KLine.cpp b/src/OBD2_KLine.cpp index 81380bc..4817410 100644 --- a/src/OBD2_KLine.cpp +++ b/src/OBD2_KLine.cpp @@ -160,7 +160,8 @@ void OBD2_KLine::writeRawData(const uint8_t* dataArray, uint8_t length, uint8_t void OBD2_KLine::writeData(const uint8_t* data, uint8_t dataLength) { uint8_t headerLength = 3; uint8_t actualLengthByteCount = useLengthInHeader ? 0 : 1; - uint8_t fullDataLength = headerLength + actualLengthByteCount + dataLength + 1; // +1 for checksum + uint8_t checksumLength = (checksumType == 0) ? 0 : 1; + uint8_t fullDataLength = headerLength + actualLengthByteCount + dataLength + checksumLength; // +1 for checksum uint8_t message[fullDataLength]; if (connectedProtocol == "ISO9141") { @@ -178,7 +179,30 @@ void OBD2_KLine::writeData(const uint8_t* data, uint8_t dataLength) { uint8_t dataStartOffset = headerLength + actualLengthByteCount; memcpy(&message[dataStartOffset], data, dataLength); - message[fullDataLength - 1] = checksum8_Modulo256(message, fullDataLength - 1); + // Compute checksum if enabled + if (checksumType != 0) { + uint8_t checksum = 0; + + switch (checksumType) { + case 1: + checksum = checksum8_XOR(message, fullDataLength - 1); + break; + + case 2: + checksum = checksum8_Modulo256(message, fullDataLength - 1); + break; + + case 3: + checksum = checksum8_TwosComplement(message, fullDataLength - 1); + break; + + default: + checksum = 0; + break; + } + + message[fullDataLength - 1] = checksum; + } debugPrint(F("\n➡️ Sending Data: ")); for (size_t i = 0; i < fullDataLength; i++) { From f34ee4af6de18ca6b75bd7172988a11ea109b2c6 Mon Sep 17 00:00:00 2001 From: Muksin Muksin <75759731+muki01@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:37:19 +0200 Subject: [PATCH 3/5] Fixed parity bit --- src/OBD2_KLine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OBD2_KLine.cpp b/src/OBD2_KLine.cpp index 4817410..7482911 100644 --- a/src/OBD2_KLine.cpp +++ b/src/OBD2_KLine.cpp @@ -831,7 +831,7 @@ void OBD2_KLine::send5baud(uint8_t data) { for (int i = 1; i <= 7; i++) { if (bits[i]) ones++; } - bits[8] = (ones % 2 == 0) ? 1 : 0; // parity bit + bits[8] = (ones % 2 == 0) ? 0 : 1; // parity bit debugPrint(F("➡️ 5 Baud Init for Module 0x")); debugPrintHex(data); From bee03c639473ad5f1ed4bca6ae22b787f74d7174 Mon Sep 17 00:00:00 2001 From: Muksin Muksin <75759731+muki01@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:37:41 +0200 Subject: [PATCH 4/5] Remove unnecessary delay after KW2 write in trySlowInit --- src/OBD2_KLine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OBD2_KLine.cpp b/src/OBD2_KLine.cpp index 7482911..ddd7cdf 100644 --- a/src/OBD2_KLine.cpp +++ b/src/OBD2_KLine.cpp @@ -64,7 +64,6 @@ bool OBD2_KLine::trySlowInit() { debugPrintln(F("Writing inverted KW2")); _serial->write(~resultBuffer[2]); - delay(_byteWriteInterval); clearEcho(1); setInterByteTimeout(60); From 196b34a3a59e7c24419974600245bfbfc627dc9d Mon Sep 17 00:00:00 2001 From: Muksin Muksin <75759731+muki01@users.noreply.github.com> Date: Tue, 27 Jan 2026 20:38:41 +0200 Subject: [PATCH 5/5] Add KLine.setChecksumType(2) to example sketches --- examples/Car Specific/Honda/Honda.ino | 1 + examples/Car Specific/Opel/Opel.ino | 1 + examples/OBD2 Standard/ClearDTC/ClearDTC.ino | 1 + examples/OBD2 Standard/GetFreezeFrame/GetFreezeFrame.ino | 1 + examples/OBD2 Standard/GetLiveData/GetLiveData.ino | 1 + examples/OBD2 Standard/GetSupportedPIDs/GetSupportedPIDs.ino | 1 + examples/OBD2 Standard/GetVehicleInfo/GetVehicleInfo.ino | 1 + examples/OBD2 Standard/ReadDTC/ReadDTC.ino | 1 + examples/OBD2 Standard/Sniffer/Sniffer.ino | 1 + 9 files changed, 9 insertions(+) diff --git a/examples/Car Specific/Honda/Honda.ino b/examples/Car Specific/Honda/Honda.ino index 77603b2..12165c1 100644 --- a/examples/Car Specific/Honda/Honda.ino +++ b/examples/Car Specific/Honda/Honda.ino @@ -24,6 +24,7 @@ void setup() { //KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. //KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. //KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + //KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("Honda Code."); } diff --git a/examples/Car Specific/Opel/Opel.ino b/examples/Car Specific/Opel/Opel.ino index 3afaa80..7c062d0 100644 --- a/examples/Car Specific/Opel/Opel.ino +++ b/examples/Car Specific/Opel/Opel.ino @@ -27,6 +27,7 @@ void setup() { //KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0x80, 0x11, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. //KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("Opel Code."); } diff --git a/examples/OBD2 Standard/ClearDTC/ClearDTC.ino b/examples/OBD2 Standard/ClearDTC/ClearDTC.ino index 931e895..f48fda2 100644 --- a/examples/OBD2 Standard/ClearDTC/ClearDTC.ino +++ b/examples/OBD2 Standard/ClearDTC/ClearDTC.ino @@ -24,6 +24,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); } diff --git a/examples/OBD2 Standard/GetFreezeFrame/GetFreezeFrame.ino b/examples/OBD2 Standard/GetFreezeFrame/GetFreezeFrame.ino index 823f673..a622c6a 100644 --- a/examples/OBD2 Standard/GetFreezeFrame/GetFreezeFrame.ino +++ b/examples/OBD2 Standard/GetFreezeFrame/GetFreezeFrame.ino @@ -24,6 +24,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); } diff --git a/examples/OBD2 Standard/GetLiveData/GetLiveData.ino b/examples/OBD2 Standard/GetLiveData/GetLiveData.ino index e6737e3..07fdf3f 100644 --- a/examples/OBD2 Standard/GetLiveData/GetLiveData.ino +++ b/examples/OBD2 Standard/GetLiveData/GetLiveData.ino @@ -24,6 +24,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); } diff --git a/examples/OBD2 Standard/GetSupportedPIDs/GetSupportedPIDs.ino b/examples/OBD2 Standard/GetSupportedPIDs/GetSupportedPIDs.ino index 663673e..12faddf 100644 --- a/examples/OBD2 Standard/GetSupportedPIDs/GetSupportedPIDs.ino +++ b/examples/OBD2 Standard/GetSupportedPIDs/GetSupportedPIDs.ino @@ -24,6 +24,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); } diff --git a/examples/OBD2 Standard/GetVehicleInfo/GetVehicleInfo.ino b/examples/OBD2 Standard/GetVehicleInfo/GetVehicleInfo.ino index 82194de..82a3775 100644 --- a/examples/OBD2 Standard/GetVehicleInfo/GetVehicleInfo.ino +++ b/examples/OBD2 Standard/GetVehicleInfo/GetVehicleInfo.ino @@ -24,6 +24,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); } diff --git a/examples/OBD2 Standard/ReadDTC/ReadDTC.ino b/examples/OBD2 Standard/ReadDTC/ReadDTC.ino index 9a8df41..6476b51 100644 --- a/examples/OBD2 Standard/ReadDTC/ReadDTC.ino +++ b/examples/OBD2 Standard/ReadDTC/ReadDTC.ino @@ -24,6 +24,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); } diff --git a/examples/OBD2 Standard/Sniffer/Sniffer.ino b/examples/OBD2 Standard/Sniffer/Sniffer.ino index e51f8c8..34c4ff1 100644 --- a/examples/OBD2 Standard/Sniffer/Sniffer.ino +++ b/examples/OBD2 Standard/Sniffer/Sniffer.ino @@ -23,6 +23,7 @@ void setup() { KLine.setISO9141Header(0x68, 0x6A, 0xF1); // Optional: Configures the 3-byte header (Priority, Receiver, Transmitter) for ISO9141. KLine.setISO14230Header(0xC0, 0x33, 0xF1); // Optional: Configures the 3-byte header (Format, Receiver, Transmitter) for KWP2000. KLine.setLengthMode(true); // Optional: Defines if data length is embedded in the header or sent as a separate byte. + KLine.setChecksumType(2); // Optional: Selects checksum method (0: None, 1: XOR, 2: Modulo 256, 3: Two's Complement). Serial.println("OBD2 Starting."); }