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."); } diff --git a/src/OBD2_KLine.cpp b/src/OBD2_KLine.cpp index 3303735..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); @@ -160,7 +159,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 +178,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++) { @@ -807,7 +830,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); @@ -955,4 +978,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;