From 1ee326fd57f8b995acd7e82f326b7a7263c3d5c6 Mon Sep 17 00:00:00 2001 From: Marcel Peterkau Date: Sun, 4 May 2025 12:03:19 +0200 Subject: [PATCH] added first code for OBD2 via CAN and K-Line --- Software/data_src/static/dtc_table.json | 29 ++++++++- Software/include/can.h | 1 - Software/include/common.h | 4 +- Software/include/dtc_defs.h | 18 ++++-- Software/include/obd2_can.h | 10 +++ Software/include/obd2_kline.h | 10 +++ Software/src/can.cpp | 25 +++----- Software/src/common.cpp | 13 ++-- Software/src/dtc_defs.txt | 41 ++++++------ Software/src/main.cpp | 21 ++++--- Software/src/obd2_can.cpp | 84 +++++++++++++++++++++++++ Software/src/obd2_kline.cpp | 74 ++++++++++++++++++++++ 12 files changed, 277 insertions(+), 53 deletions(-) create mode 100644 Software/include/obd2_can.h create mode 100644 Software/include/obd2_kline.h create mode 100644 Software/src/obd2_can.cpp create mode 100644 Software/src/obd2_kline.cpp diff --git a/Software/data_src/static/dtc_table.json b/Software/data_src/static/dtc_table.json index a1c9ecd..10298da 100644 --- a/Software/data_src/static/dtc_table.json +++ b/Software/data_src/static/dtc_table.json @@ -1,6 +1,6 @@ { - "codegenerator_checksum": "23dff82a4745f67041012080b05ec367c2dd44c6bb02974143b227ba49682b6f", - "timestamp": "2024-01-10 19:06:30", + "codegenerator_checksum": "15e9152fb712bc6ed7c3353a05b1b54dc697f3e489a6e1ff42b7e57f0fa094d4", + "timestamp": "2025-05-04 12:01:55", "dtc_table_data": [ { "num": 0, @@ -89,6 +89,31 @@ }, { "num": 17, + "title": "OBD2-KLine Timeout", + "description": "Die Anfrage über OBD2-KLine konnte nicht gesendet werden. Prüfen Sie den K-Line-Treiber (z. B. L9637D) und die Verkabelung." + }, + { + "num": 18, + "title": "OBD2-CAN Timeout", + "description": "Die Anfrage an das Steuergerät über OBD2-CAN konnte nicht gesendet werden. Prüfen Sie die Verbindung zum CAN-Modul und die OBD2-Konfiguration." + }, + { + "num": 19, + "title": "Keine OBD2-CAN Antwort", + "description": "Es wurde innerhalb der erwarteten Zeit keine Antwort vom Steuergerät über OBD2-CAN empfangen. Prüfen Sie, ob das Fahrzeug OBD2 unterstützt und die Verbindung korrekt ist." + }, + { + "num": 20, + "title": "Keine OBD2-KLine Antwort", + "description": "Es wurde innerhalb der erwarteten Zeit keine Antwort über OBD2-KLine empfangen. Prüfen Sie die Verbindung zum Steuergerät und die Protokollkompatibilität." + }, + { + "num": 21, + "title": "OBD2-KLine Antwort ungültig", + "description": "Das empfangene Frame war unvollständig oder entsprach nicht dem erwarteten OBD2-Format. Möglicherweise inkompatibles Steuergerät." + }, + { + "num": 22, "title": "Last Error", "description": "Last Error" } diff --git a/Software/include/can.h b/Software/include/can.h index 9b4dd3a..1c19d8f 100644 --- a/Software/include/can.h +++ b/Software/include/can.h @@ -32,7 +32,6 @@ struct can_frame // Function prototypes void Init_CAN(); -void CAN_Process(); uint32_t Process_CAN_WheelSpeed(); #endif diff --git a/Software/include/common.h b/Software/include/common.h index 7e5a378..ad92162 100644 --- a/Software/include/common.h +++ b/Software/include/common.h @@ -85,7 +85,9 @@ typedef enum SpeedSource_e #endif SOURCE_IMPULSE, SOURCE_GPS, - SOURCE_CAN + SOURCE_CAN, + SOURCE_OBD2_KLINE, + SOURCE_OBD2_CAN } SpeedSource_t; // String representation of SpeedSource enum diff --git a/Software/include/dtc_defs.h b/Software/include/dtc_defs.h index 8baa29e..fa512a9 100644 --- a/Software/include/dtc_defs.h +++ b/Software/include/dtc_defs.h @@ -7,10 +7,10 @@ * It includes enums for DTC active status, severity levels, and specific DTC codes. * The file also defines an array of DTC definitions and a timestamp indicating the generation time. * - * @note This file is auto-generated by a script on 2024-01-10 18:37:05. + * @note This file is auto-generated by a script on 2025-05-04 12:01:55. * * @author Marcel Peterkau - * @date 10.01.2024 + * @date 04.05.2025 */ #ifndef DTC_DEFS_H @@ -57,7 +57,12 @@ typedef struct { #define DTC_FAKE_DTC_INFO 14 #define DTC_FAKE_DTC_WARN 15 #define DTC_FAKE_DTC_CRIT 16 -#define DTC_LAST_DTC 17 +#define DTC_OBD2_KLINE_TIMEOUT 17 +#define DTC_OBD2_CAN_TIMEOUT 18 +#define DTC_OBD2_CAN_NO_RESPONSE 19 +#define DTC_OBD2_KLINE_NO_RESPONSE 20 +#define DTC_OBD2_KLINE_BAD_FRAME 21 +#define DTC_LAST_DTC 22 const DTC_t dtc_definitions[] = { { DTC_NO_DTC , DTC_NONE }, // No Error @@ -77,9 +82,14 @@ const DTC_t dtc_definitions[] = { { DTC_FAKE_DTC_INFO , DTC_INFO }, // Ein Dummy-DTC der Schwere "Info" für Debugging-Zwecke { DTC_FAKE_DTC_WARN , DTC_WARN }, // Ein Dummy-DTC der Schwere "Warnung" für Debugging-Zwecke { DTC_FAKE_DTC_CRIT , DTC_CRITICAL }, // Ein Dummy-DTC der Schwere "Kritisch" für Debugging-Zwecke + { DTC_OBD2_KLINE_TIMEOUT , DTC_CRITICAL }, // Die Anfrage über OBD2-KLine konnte nicht gesendet werden. Prüfen Sie den K-Line-Treiber (z. B. L9637D) und die Verkabelung. + { DTC_OBD2_CAN_TIMEOUT , DTC_CRITICAL }, // Die Anfrage an das Steuergerät über OBD2-CAN konnte nicht gesendet werden. Prüfen Sie die Verbindung zum CAN-Modul und die OBD2-Konfiguration. + { DTC_OBD2_CAN_NO_RESPONSE , DTC_WARN }, // Es wurde innerhalb der erwarteten Zeit keine Antwort vom Steuergerät über OBD2-CAN empfangen. Prüfen Sie, ob das Fahrzeug OBD2 unterstützt und die Verbindung korrekt ist. + { DTC_OBD2_KLINE_NO_RESPONSE , DTC_WARN }, // Es wurde innerhalb der erwarteten Zeit keine Antwort über OBD2-KLine empfangen. Prüfen Sie die Verbindung zum Steuergerät und die Protokollkompatibilität. + { DTC_OBD2_KLINE_BAD_FRAME , DTC_WARN }, // Das empfangene Frame war unvollständig oder entsprach nicht dem erwarteten OBD2-Format. Möglicherweise inkompatibles Steuergerät. { DTC_LAST_DTC , DTC_NONE } // Last Error }; #endif // DTC_DEFS_H -// CODEGENERATOR_CHECKSUM: 23dff82a4745f67041012080b05ec367c2dd44c6bb02974143b227ba49682b6f \ No newline at end of file +// CODEGENERATOR_CHECKSUM: 15e9152fb712bc6ed7c3353a05b1b54dc697f3e489a6e1ff42b7e57f0fa094d4 \ No newline at end of file diff --git a/Software/include/obd2_can.h b/Software/include/obd2_can.h new file mode 100644 index 0000000..9075fbf --- /dev/null +++ b/Software/include/obd2_can.h @@ -0,0 +1,10 @@ +#ifndef _OBD2_CAN_H_ +#define _OBD2_CAN_H_ + +#include + +// === Funktionen === +void Init_OBD2_CAN(); +uint32_t Process_OBD2_CAN_Speed(); + +#endif diff --git a/Software/include/obd2_kline.h b/Software/include/obd2_kline.h new file mode 100644 index 0000000..39036f9 --- /dev/null +++ b/Software/include/obd2_kline.h @@ -0,0 +1,10 @@ +#ifndef _OBD2_KLINE_H_ +#define _OBD2_KLINE_H_ + +#include + +// === Funktionen === +void Init_OBD2_KLine(Stream &serial); // Übergib z.B. SoftwareSerial oder Serial1 +uint32_t Process_OBD2_KLine_Speed(); // liefert mm seit letztem Aufruf + +#endif diff --git a/Software/src/can.cpp b/Software/src/can.cpp index 68278a1..fed9947 100644 --- a/Software/src/can.cpp +++ b/Software/src/can.cpp @@ -49,21 +49,6 @@ void Init_CAN() CAN0.setMode(MCP_NORMAL); } -/** - * @brief Processes CAN messages and sends a CAN debug message periodically. - * - * This function processes CAN messages and sends a CAN debug message periodically based on a time interval. - */ -void CAN_Process() -{ - static uint32_t previousMillis = 0; - - if (millis() - previousMillis >= 100) - { - sendCANDebugMessage(); - previousMillis = millis(); - } -} /** * @brief Processes CAN messages to determine the wheel speed based on the configured CAN source. * @@ -115,6 +100,16 @@ uint32_t Process_CAN_WheelSpeed() MaintainDTC(DTC_NO_CAN_SIGNAL, (millis() > lastRecTimestamp + 10000 ? true : false)); } +#ifdef CAN_DEBUG_MESSAGE + static uint32_t previousMillis = 0; + + if (millis() - previousMillis >= 1000) + { + sendCANDebugMessage(); + previousMillis = millis(); + } +#endif + return milimeters_to_add; } diff --git a/Software/src/common.cpp b/Software/src/common.cpp index 52b4cf4..6ffa341 100644 --- a/Software/src/common.cpp +++ b/Software/src/common.cpp @@ -7,8 +7,10 @@ const char *SpeedSourceString[] = { #endif "Impuls", "GPS", - "CAN-Bus" - }; + "CAN-Bus", + "OBD2 (K-Line)", + "OBD2 (CAN)", +}; const size_t SpeedSourceString_Elements = sizeof(SpeedSourceString) / sizeof(SpeedSourceString[0]); @@ -19,14 +21,15 @@ const char *GPSBaudRateString[] = { "19200", "38400", "57600", - "115200" - }; + "115200", +}; const size_t GPSBaudRateString_Elements = sizeof(GPSBaudRateString) / sizeof(GPSBaudRateString[0]); // String representation of CANSource enum const char *CANSourceString[] = { "KTM 890 Adventure R (2021)", - "KTM 1290 Superduke R (2023)"}; + "KTM 1290 Superduke R (2023)", +}; const size_t CANSourceString_Elements = sizeof(CANSourceString) / sizeof(CANSourceString[0]); \ No newline at end of file diff --git a/Software/src/dtc_defs.txt b/Software/src/dtc_defs.txt index 8702d78..0fe83ef 100644 --- a/Software/src/dtc_defs.txt +++ b/Software/src/dtc_defs.txt @@ -1,18 +1,23 @@ -# No. | DTC-Constant | Severity | Title | Description -#-----|------------------------------|---------------|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------- - 1; DTC_TANK_EMPTY; DTC_CRITICAL; Ölvorrat leer; Ölvorrat ist komplett leer. Den Ölvorrat auffüllen und im Menu 'Wartung' zurück setzen - 2; DTC_TANK_LOW; DTC_WARN; Ölvorrat niedrig; Ölvorrat ist unter der Warnschwelle. Den Ölvorrat demnächst auffüllen und im Menu 'Wartung' zurück setzen - 3; DTC_NO_EEPROM_FOUND; DTC_CRITICAL; kein EEPROM erkannt; Es wurde kein EEPROM gefunden. Dies lässt einen Hardware-Defekt vermuten. - 4; DTC_EEPROM_CFG_BAD; DTC_CRITICAL; EEPROM CFG Checksumme; Die Checksumme der Config-Partition des EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'CFG' im Menu 'Wartung' zurück - 5; DTC_EEPROM_PDS_BAD; DTC_CRITICAL; EEPROM PDS Checksumme; Die Checksumme der Betriebsdaten-Partition des EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'PDS' im Menu 'Wartung' zurück - 6; DTC_EEPROM_PDSADRESS_BAD; DTC_CRITICAL; EEPROM PDS Adresse; Die Adresse der Betriebsdaten-Partition im EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'PDS' im Menu 'Wartung' zurück - 7; DTC_EEPROM_VERSION_BAD; DTC_CRITICAL; EEPROM Version falsch; Die Layout-Version des EEPROM stimmt nicht mit der Firmware-Version überein. Setzen sie den EEPROM-Bereich 'CFG' im Menu 'Wartung' zurück - 8; DTC_FLASHFS_ERROR; DTC_CRITICAL; Flashspeicher Fehler; Der Flashspeicher konnte nicht initialisiert werden. Aktualisieren sie Flash & Firmware - 9; DTC_FLASHFS_VERSION_ERROR; DTC_CRITICAL; Flashversion falsch; Die Version des Flashspeicher stimmt nicht mit der Firmware-Version überein. Aktualisieren sie den Flash mit der passenden Update-Datei - 10; DTC_NO_GPS_SERIAL; DTC_CRITICAL; Keine GPS-Verbindung; Es wurde kein GPS-Signal über die serielle Schnittstelle empfangen, Prüfen sie die Verbindung und das GPS-Modul - 11; DTC_CAN_TRANSCEIVER_FAILED; DTC_CRITICAL; CAN-Transceiver Error; Es konnte keine Verbindung zum CAN-Transceiver hergestellt werden. Prüfen Sie die Hardware auf Defekte - 12; DTC_NO_CAN_SIGNAL; DTC_WARN; Keine CAN-Verbindung; Es konnte kein CAN-Signal empfangen werden. Prüfen sie die Verbindung und die Einstellungen - 13; DTC_EEPROM_CFG_SANITY; DTC_WARN; Config-Validierung; Ein oder mehrer Einstellungswerte sind ausserhalb plausibler Werte. Prüfen Sie Ihre Einstellungen - 14; DTC_FAKE_DTC_INFO; DTC_INFO; Dummy-DTC Info; Ein Dummy-DTC der Schwere "Info" für Debugging-Zwecke - 15; DTC_FAKE_DTC_WARN; DTC_WARN; Dummy-DTC Warnung; Ein Dummy-DTC der Schwere "Warnung" für Debugging-Zwecke - 16; DTC_FAKE_DTC_CRIT; DTC_CRITICAL; Dummy-DTC Kritisch; Ein Dummy-DTC der Schwere "Kritisch" für Debugging-Zwecke \ No newline at end of file +# No. | DTC-Constant | Severity | Title | Description +#-----|------------------------------|---------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------- + 1; DTC_TANK_EMPTY; DTC_CRITICAL; Ölvorrat leer; Ölvorrat ist komplett leer. Den Ölvorrat auffüllen und im Menu 'Wartung' zurück setzen + 2; DTC_TANK_LOW; DTC_WARN; Ölvorrat niedrig; Ölvorrat ist unter der Warnschwelle. Den Ölvorrat demnächst auffüllen und im Menu 'Wartung' zurück setzen + 3; DTC_NO_EEPROM_FOUND; DTC_CRITICAL; kein EEPROM erkannt; Es wurde kein EEPROM gefunden. Dies lässt einen Hardware-Defekt vermuten. + 4; DTC_EEPROM_CFG_BAD; DTC_CRITICAL; EEPROM CFG Checksumme; Die Checksumme der Config-Partition des EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'CFG' im Menu 'Wartung' zurück + 5; DTC_EEPROM_PDS_BAD; DTC_CRITICAL; EEPROM PDS Checksumme; Die Checksumme der Betriebsdaten-Partition des EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'PDS' im Menu 'Wartung' zurück + 6; DTC_EEPROM_PDSADRESS_BAD; DTC_CRITICAL; EEPROM PDS Adresse; Die Adresse der Betriebsdaten-Partition im EEPROM ist ungültig. Setzen sie den EEPROM-Bereich 'PDS' im Menu 'Wartung' zurück + 7; DTC_EEPROM_VERSION_BAD; DTC_CRITICAL; EEPROM Version falsch; Die Layout-Version des EEPROM stimmt nicht mit der Firmware-Version überein. Setzen sie den EEPROM-Bereich 'CFG' im Menu 'Wartung' zurück + 8; DTC_FLASHFS_ERROR; DTC_CRITICAL; Flashspeicher Fehler; Der Flashspeicher konnte nicht initialisiert werden. Aktualisieren sie Flash & Firmware + 9; DTC_FLASHFS_VERSION_ERROR; DTC_CRITICAL; Flashversion falsch; Die Version des Flashspeicher stimmt nicht mit der Firmware-Version überein. Aktualisieren sie den Flash mit der passenden Update-Datei + 10; DTC_NO_GPS_SERIAL; DTC_CRITICAL; Keine GPS-Verbindung; Es wurde kein GPS-Signal über die serielle Schnittstelle empfangen, Prüfen sie die Verbindung und das GPS-Modul + 11; DTC_CAN_TRANSCEIVER_FAILED; DTC_CRITICAL; CAN-Transceiver Error; Es konnte keine Verbindung zum CAN-Transceiver hergestellt werden. Prüfen Sie die Hardware auf Defekte + 12; DTC_NO_CAN_SIGNAL; DTC_WARN; Keine CAN-Verbindung; Es konnte kein CAN-Signal empfangen werden. Prüfen sie die Verbindung und die Einstellungen + 13; DTC_EEPROM_CFG_SANITY; DTC_WARN; Config-Validierung; Ein oder mehrer Einstellungswerte sind ausserhalb plausibler Werte. Prüfen Sie Ihre Einstellungen + 14; DTC_FAKE_DTC_INFO; DTC_INFO; Dummy-DTC Info; Ein Dummy-DTC der Schwere "Info" für Debugging-Zwecke + 15; DTC_FAKE_DTC_WARN; DTC_WARN; Dummy-DTC Warnung; Ein Dummy-DTC der Schwere "Warnung" für Debugging-Zwecke + 16; DTC_FAKE_DTC_CRIT; DTC_CRITICAL; Dummy-DTC Kritisch; Ein Dummy-DTC der Schwere "Kritisch" für Debugging-Zwecke + 17; DTC_OBD2_KLINE_TIMEOUT; DTC_CRITICAL; OBD2-KLine Timeout; Die Anfrage über OBD2-KLine konnte nicht gesendet werden. Prüfen Sie den K-Line-Treiber (z. B. L9637D) und die Verkabelung. + 18; DTC_OBD2_CAN_TIMEOUT; DTC_CRITICAL; OBD2-CAN Timeout; Die Anfrage an das Steuergerät über OBD2-CAN konnte nicht gesendet werden. Prüfen Sie die Verbindung zum CAN-Modul und die OBD2-Konfiguration. + 19; DTC_OBD2_CAN_NO_RESPONSE; DTC_WARN; Keine OBD2-CAN Antwort; Es wurde innerhalb der erwarteten Zeit keine Antwort vom Steuergerät über OBD2-CAN empfangen. Prüfen Sie, ob das Fahrzeug OBD2 unterstützt und die Verbindung korrekt ist. + 20; DTC_OBD2_KLINE_NO_RESPONSE; DTC_WARN; Keine OBD2-KLine Antwort; Es wurde innerhalb der erwarteten Zeit keine Antwort über OBD2-KLine empfangen. Prüfen Sie die Verbindung zum Steuergerät und die Protokollkompatibilität. + 21; DTC_OBD2_KLINE_BAD_FRAME; DTC_WARN; OBD2-KLine Antwort ungültig; Das empfangene Frame war unvollständig oder entsprach nicht dem erwarteten OBD2-Format. Möglicherweise inkompatibles Steuergerät. \ No newline at end of file diff --git a/Software/src/main.cpp b/Software/src/main.cpp index 3ca2145..06bc5d0 100644 --- a/Software/src/main.cpp +++ b/Software/src/main.cpp @@ -37,6 +37,8 @@ #include "gps.h" #include "dtc.h" #include "led_colors.h" +#include "obd2_kline.h" +#include "obd2_can.h" #ifdef FEATURE_ENABLE_WIFI_CLIENT #include @@ -154,6 +156,16 @@ void setup() wheelSpeedcapture = &Process_Impulse_WheelSpeed; Serial.print("\nPulse-Input Init done"); break; + case SOURCE_OBD2_KLINE: + Init_OBD2_KLine(Serial); + wheelSpeedcapture = &Process_OBD2_KLine_Speed; + Serial.print("\nOBD2-KLine-Init done"); + break; + case SOURCE_OBD2_CAN: + Init_OBD2_CAN(); + wheelSpeedcapture = &Process_OBD2_CAN_Speed; + Serial.print("\nOBD2-CAN-Init done"); + break; default: break; } @@ -227,19 +239,14 @@ void setup() void loop() { // Run lubrication application with the calculated wheel distance - RunLubeApp(wheelSpeedcapture()); + if (wheelSpeedcapture != nullptr) + RunLubeApp(wheelSpeedcapture()); #ifdef FEATURE_ENABLE_OLED // Update OLED display if enabled Display_Process(); #endif - // Process CAN messages if the speed source is not impulse - if (LubeConfig.SpeedSource != SOURCE_IMPULSE) - { - CAN_Process(); - } - // Process button input, manage LED behavior, perform EEPROM tasks, handle webserver operations, // process Diagnostic Trouble Codes (DTC), and manage debugging Button_Process(); diff --git a/Software/src/obd2_can.cpp b/Software/src/obd2_can.cpp new file mode 100644 index 0000000..adacd4f --- /dev/null +++ b/Software/src/obd2_can.cpp @@ -0,0 +1,84 @@ +#include "obd2_can.h" +#include +#include +#include "common.h" +#include "globals.h" +#include "dtc.h" +#include "debugger.h" + +// === Setup: MCP2515 CS-Pin definieren === +#define OBD2_CAN_CS_PIN 10 +#define OBD2_OBD_REQUEST_ID 0x7DF +#define OBD2_OBD_RESPONSE_ID 0x7E8 + +MCP_CAN OBD_CAN(OBD2_CAN_CS_PIN); + +static uint32_t lastQueryTime = 0; +static uint32_t lastRecvTime = 0; +static uint32_t lastSpeedMMperSec = 0; + +#define OBD2_QUERY_INTERVAL 500 // alle 500ms + +void Init_OBD2_CAN() +{ + if (OBD_CAN.begin(MCP_STD, CAN_500KBPS, MCP_16MHZ) != CAN_OK) + { + Serial.println("OBD2 CAN Init FAILED!"); + return; + } + + OBD_CAN.setMode(MCP_NORMAL); + delay(100); + Serial.println("OBD2 CAN Init OK"); +} + +uint32_t Process_OBD2_CAN_Speed() +{ + if (millis() - lastQueryTime < OBD2_QUERY_INTERVAL) + return 0; + + lastQueryTime = millis(); + + // Anfrage: 01 0D → Geschwindigkeit + byte obdRequest[8] = {0x02, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00}; + byte sendStat = OBD_CAN.sendMsgBuf(OBD2_OBD_REQUEST_ID, 0, 8, obdRequest); + + if (sendStat != CAN_OK) + { + MaintainDTC(DTC_OBD2_CAN_TIMEOUT, true); + Debug_pushMessage("OBD2_CAN: send failed (%d)\n", sendStat); + return 0; + } + + unsigned long rxId; + byte len = 0; + byte rxBuf[8]; + uint32_t timeout = millis() + 100; + + while (millis() < timeout) + { + if (OBD_CAN.checkReceive() == CAN_MSGAVAIL) + { + OBD_CAN.readMsgBuf(&rxId, &len, rxBuf); + if ((rxId & 0xFFF8) == OBD2_OBD_RESPONSE_ID && rxBuf[1] == 0x0D) + { + MaintainDTC(DTC_OBD2_CAN_NO_RESPONSE, false); // alles ok + + uint8_t speed_kmh = rxBuf[3]; + uint32_t speed_mm_per_sec = (uint32_t)speed_kmh * 1000000 / 3600; + uint32_t dt = millis() - lastRecvTime; + lastRecvTime = millis(); + lastSpeedMMperSec = speed_mm_per_sec; + + Debug_pushMessage("OBD2_CAN: %d km/h (%lu mm/s)\n", speed_kmh, speed_mm_per_sec); + return (speed_mm_per_sec * dt) / 1000; + } + } + } + + // Keine Antwort erhalten + MaintainDTC(DTC_OBD2_CAN_NO_RESPONSE, true); + Debug_pushMessage("OBD2_CAN: no response within timeout\n"); + return 0; +} + diff --git a/Software/src/obd2_kline.cpp b/Software/src/obd2_kline.cpp new file mode 100644 index 0000000..5917aab --- /dev/null +++ b/Software/src/obd2_kline.cpp @@ -0,0 +1,74 @@ +#include "obd2_kline.h" + +// === Konstante für Anfrageintervalle === +#define OBD2_QUERY_INTERVAL 500 // alle 500 ms neue Anfrage + +// === Private Variablen === +static Stream *klineSerial = nullptr; +static uint32_t lastQueryTime = 0; +static uint32_t lastRecvTime = 0; +static uint32_t lastSpeedMMperSec = 0; + +// === Slow Init nach ISO9141-2 === +void OBD2_KLine_SlowInit() +{ + pinMode(1, OUTPUT); // TXD-Pin (z.B. D1) + digitalWrite(1, HIGH); + delay(3000); + + digitalWrite(1, LOW); + delay(200); // 200ms + digitalWrite(1, HIGH); + delay(400); // 400ms + digitalWrite(1, LOW); + delay(400); // 400ms + digitalWrite(1, HIGH); + delay(200); // 200ms + + // zurück auf Serialbetrieb + pinMode(1, INPUT); + delay(300); +} + +// === Initialisierung === +void Init_OBD2_KLine(Stream &serial) +{ + klineSerial = &serial; + OBD2_KLine_SlowInit(); + delay(100); + + // Sende 01 0D (Vehicle Speed) + byte speedRequest[] = {0x68, 0x6A, 0xF1, 0x01, 0x0D}; // OBD2 PID-Request + klineSerial->write(speedRequest, sizeof(speedRequest)); +} + +// === Geschwindigkeit abfragen === +uint32_t Process_OBD2_KLine_Speed() +{ + if (!klineSerial || (millis() - lastQueryTime < OBD2_QUERY_INTERVAL)) return 0; + + byte req[] = {0x68, 0x6A, 0xF1, 0x01, 0x0D}; + klineSerial->write(req, sizeof(req)); + lastQueryTime = millis(); + + uint8_t buf[16]; + size_t len = klineSerial->readBytes(buf, sizeof(buf)); + for (size_t i = 0; i < len - 2; ++i) + { + if (buf[i] == 0x48 && buf[i + 1] == 0x6B && buf[i + 2] == 0x10) + { + if (buf[i + 3] == 0x41 && buf[i + 4] == 0x0D) + { + uint8_t speed_kmh = buf[i + 5]; + uint32_t speed_mm_per_sec = (uint32_t)speed_kmh * 1000000 / 3600; + uint32_t dt = millis() - lastRecvTime; + lastRecvTime = millis(); + lastSpeedMMperSec = speed_mm_per_sec; + + return (speed_mm_per_sec * dt) / 1000; + } + } + } + + return 0; +}