added first code for OBD2 via CAN and K-Line
This commit is contained in:
		| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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]); | ||||
| @@ -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. |                 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. | ||||
| @@ -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 <ESP8266WiFiMulti.h> | ||||
| @@ -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(); | ||||
|   | ||||
							
								
								
									
										84
									
								
								Software/src/obd2_can.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								Software/src/obd2_can.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| #include "obd2_can.h" | ||||
| #include <mcp_can.h> | ||||
| #include <SPI.h> | ||||
| #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; | ||||
| } | ||||
|  | ||||
							
								
								
									
										74
									
								
								Software/src/obd2_kline.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Software/src/obd2_kline.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user