# ECU Emulator Specification Документация для создания эмулятора ECU для тестирования Carpibord. ## Общие сведения - **CAN Bus Speed:** 500 kbps - **CAN ID Format:** 11-bit (standard) - **Протоколы:** OBD2 (ISO 15765-4) + UDS (ISO 14229) --- ## OBD2 Protocol (Mode 0x01) ### Формат запроса ``` CAN ID: 0x7DF (broadcast) или 0x7E0 (ECU direct) Data: [Length, Mode, PID, 0x00, 0x00, 0x00, 0x00, 0x00] Пример запроса RPM: 7DF [02 01 0C 00 00 00 00 00] │ │ │ │ │ └── PID 0x0C (RPM) │ └───── Mode 0x01 (Current Data) └──────── Length: 2 bytes ``` ### Формат ответа ``` CAN ID: 0x7E8 (ECU response) Data: [Length, Mode+0x40, PID, DataA, DataB, ...] Пример ответа RPM = 2000: 7E8 [04 41 0C 1F 40 00 00 00] │ │ │ │ │ │ │ │ └───┴── Data: (0x1F * 256 + 0x40) / 4 = 2000 RPM │ │ └──────── PID 0x0C │ └─────────── Mode 0x41 (response to 0x01) └────────────── Length: 4 bytes ``` --- ## OBD2 PIDs — Полная спецификация ### PID 0x00 — Supported PIDs [01-20] | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 00 00 00 00 00 00]` | | Response | `7E8 [06 41 00 XX XX XX XX 00]` | | Formula | Bitmask of supported PIDs | **Ответ для нашего набора PIDs:** ``` Поддерживаем: 0x04, 0x05, 0x0C, 0x0D, 0x0F, 0x10, 0x11 Bitmask: 0x18 3F 80 00 7E8 [06 41 00 18 3F 80 00 00] ``` ### PID 0x04 — Engine Load | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 04 00 00 00 00 00]` | | Response | `7E8 [03 41 04 XX 00 00 00 00]` | | Formula | `A * 100 / 255` (%) | | Min | 0% | | Max | 100% | | Bytes | 1 | **Примеры:** ``` Load = 0%: 7E8 [03 41 04 00 00 00 00 00] Load = 50%: 7E8 [03 41 04 80 00 00 00 00] (0x80 = 128 → 50.2%) Load = 100%: 7E8 [03 41 04 FF 00 00 00 00] ``` ### PID 0x05 — Coolant Temperature | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 05 00 00 00 00 00]` | | Response | `7E8 [03 41 05 XX 00 00 00 00]` | | Formula | `A - 40` (°C) | | Min | -40°C | | Max | 215°C | | Bytes | 1 | **Примеры:** ``` Temp = -40°C: 7E8 [03 41 05 00 00 00 00 00] Temp = 0°C: 7E8 [03 41 05 28 00 00 00 00] (0x28 = 40) Temp = 90°C: 7E8 [03 41 05 82 00 00 00 00] (0x82 = 130) Temp = 105°C: 7E8 [03 41 05 91 00 00 00 00] (0x91 = 145) ``` ### PID 0x0C — Engine RPM | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 0C 00 00 00 00 00]` | | Response | `7E8 [04 41 0C XX YY 00 00 00]` | | Formula | `(A * 256 + B) / 4` (RPM) | | Min | 0 RPM | | Max | 16383.75 RPM | | Bytes | 2 | **Примеры:** ``` RPM = 0: 7E8 [04 41 0C 00 00 00 00 00] RPM = 800: 7E8 [04 41 0C 0C 80 00 00 00] (0x0C80 = 3200, /4 = 800) RPM = 2000: 7E8 [04 41 0C 1F 40 00 00 00] (0x1F40 = 8000, /4 = 2000) RPM = 3500: 7E8 [04 41 0C 36 B0 00 00 00] (0x36B0 = 14000, /4 = 3500) RPM = 6000: 7E8 [04 41 0C 5D C0 00 00 00] (0x5DC0 = 24000, /4 = 6000) ``` **Формула кодирования:** `raw = RPM * 4`, затем `A = raw >> 8`, `B = raw & 0xFF` ### PID 0x0D — Vehicle Speed | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 0D 00 00 00 00 00]` | | Response | `7E8 [03 41 0D XX 00 00 00 00]` | | Formula | `A` (km/h) | | Min | 0 km/h | | Max | 255 km/h | | Bytes | 1 | **Примеры:** ``` Speed = 0: 7E8 [03 41 0D 00 00 00 00 00] Speed = 50: 7E8 [03 41 0D 32 00 00 00 00] Speed = 120: 7E8 [03 41 0D 78 00 00 00 00] Speed = 200: 7E8 [03 41 0D C8 00 00 00 00] ``` ### PID 0x0F — Intake Air Temperature | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 0F 00 00 00 00 00]` | | Response | `7E8 [03 41 0F XX 00 00 00 00]` | | Formula | `A - 40` (°C) | | Min | -40°C | | Max | 215°C | | Bytes | 1 | **Примеры:** ``` Temp = 25°C: 7E8 [03 41 0F 41 00 00 00 00] (0x41 = 65) Temp = 40°C: 7E8 [03 41 0F 50 00 00 00 00] (0x50 = 80) ``` ### PID 0x10 — MAF Air Flow Rate | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 10 00 00 00 00 00]` | | Response | `7E8 [04 41 10 XX YY 00 00 00]` | | Formula | `(A * 256 + B) / 100` (g/s) | | Min | 0 g/s | | Max | 655.35 g/s | | Bytes | 2 | **Примеры:** ``` MAF = 5 g/s: 7E8 [04 41 10 01 F4 00 00 00] (0x01F4 = 500, /100 = 5) MAF = 25 g/s: 7E8 [04 41 10 09 C4 00 00 00] (0x09C4 = 2500, /100 = 25) MAF = 100 g/s: 7E8 [04 41 10 27 10 00 00 00] (0x2710 = 10000, /100 = 100) ``` ### PID 0x11 — Throttle Position | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 11 00 00 00 00 00]` | | Response | `7E8 [03 41 11 XX 00 00 00 00]` | | Formula | `A * 100 / 255` (%) | | Min | 0% | | Max | 100% | | Bytes | 1 | **Примеры:** ``` Throttle = 0%: 7E8 [03 41 11 00 00 00 00 00] Throttle = 15%: 7E8 [03 41 11 26 00 00 00 00] (0x26 = 38 → 14.9%) Throttle = 50%: 7E8 [03 41 11 80 00 00 00 00] Throttle = 100%: 7E8 [03 41 11 FF 00 00 00 00] ``` ### PID 0x20 — Supported PIDs [21-40] | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 20 00 00 00 00 00]` | | Response | `7E8 [06 41 20 XX XX XX XX 00]` | **Ответ для поддержки 0x2F:** ``` 7E8 [06 41 20 00 00 00 01 00] ``` ### PID 0x2F — Fuel Tank Level | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 2F 00 00 00 00 00]` | | Response | `7E8 [03 41 2F XX 00 00 00 00]` | | Formula | `A * 100 / 255` (%) | | Min | 0% | | Max | 100% | | Bytes | 1 | **Примеры:** ``` Fuel = 25%: 7E8 [03 41 2F 40 00 00 00 00] Fuel = 50%: 7E8 [03 41 2F 80 00 00 00 00] Fuel = 75%: 7E8 [03 41 2F BF 00 00 00 00] ``` ### PID 0x40 — Supported PIDs [41-60] ``` 7E8 [06 41 40 00 00 00 01 00] (поддержка 0x5C) ``` ### PID 0x5C — Oil Temperature | Параметр | Значение | |----------|----------| | Request | `7DF [02 01 5C 00 00 00 00 00]` | | Response | `7E8 [03 41 5C XX 00 00 00 00]` | | Formula | `A - 40` (°C) | | Min | -40°C | | Max | 210°C | | Bytes | 1 | **Примеры:** ``` Oil Temp = 90°C: 7E8 [03 41 5C 82 00 00 00 00] (0x82 = 130) Oil Temp = 110°C: 7E8 [03 41 5C 96 00 00 00 00] (0x96 = 150) ``` --- ## UDS Protocol (Mode 0x22) ### Формат запроса ``` CAN ID: зависит от ECU (см. таблицу) Data: [03, 22, PID_H, PID_L, 55, 55, 55, 55] Пример запроса Boost (PID 0x202A) к Engine ECU: 7E0 [03 22 20 2A 55 55 55 55] │ │ │ │ │ │ └───┴── PID 0x202A │ └───────── Service 0x22 (Read Data By ID) └──────────── Length: 3 bytes ``` ### Формат ответа ``` CAN ID: response ID для ECU Data: [Length, 62, PID_H, PID_L, DataA, DataB, ...] Пример ответа Boost = 185 kPa: 7E8 [05 62 20 2A 07 3A 00 00] │ │ │ │ │ │ │ │ └───┴──┴───┴── PID + Data: 0x073A = 1850, *0.1 = 185.0 kPa │ └────────────── Service 0x62 (positive response) └───────────────── Length: 5 bytes ``` ### Negative Response Если PID не поддерживается: ``` 7E8 [03 7F 22 31 00 00 00 00] │ │ │ │ │ │ │ └── Error code 0x31 (Request Out of Range) │ │ └───── Service that failed (0x22) │ └──────── Negative response indicator (0x7F) └─────────── Length: 3 bytes ``` --- ## UDS PIDs — Engine ECU (0x7E0 → 0x7E8) ### PID 0x202A — Boost Pressure Actual | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 20 2A 55 55 55 55]` | | Response | `7E8 [05 62 20 2A XX YY 00 00]` | | Formula | `(A * 256 + B) * 0.1` (kPa) | | Min | 0 kPa | | Max | 400 kPa | | Bytes | 2 | **Примеры:** ``` Boost = 100 kPa (атм): 7E8 [05 62 20 2A 03 E8 00 00] (0x03E8 = 1000) Boost = 150 kPa: 7E8 [05 62 20 2A 05 DC 00 00] (0x05DC = 1500) Boost = 200 kPa: 7E8 [05 62 20 2A 07 D0 00 00] (0x07D0 = 2000) Boost = 250 kPa (1.5 bar): 7E8 [05 62 20 2A 09 C4 00 00] (0x09C4 = 2500) ``` ### PID 0x2029 — Boost Pressure Target | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 20 29 55 55 55 55]` | | Response | `7E8 [05 62 20 29 XX YY 00 00]` | | Formula | `(A * 256 + B) * 0.1` (kPa) | | Min | 0 kPa | | Max | 400 kPa | | Bytes | 2 | ### PID 0xF423 — Fuel Rail Pressure | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 F4 23 55 55 55 55]` | | Response | `7E8 [05 62 F4 23 XX YY 00 00]` | | Formula | `(A * 256 + B) * 10` (kPa) | | Min | 0 kPa | | Max | 25000 kPa (250 bar) | | Bytes | 2 | **Примеры:** ``` FRP = 5000 kPa (50 bar): 7E8 [05 62 F4 23 01 F4 00 00] (0x01F4 = 500) FRP = 15000 kPa (150 bar): 7E8 [05 62 F4 23 05 DC 00 00] (0x05DC = 1500) FRP = 20000 kPa (200 bar): 7E8 [05 62 F4 23 07 D0 00 00] (0x07D0 = 2000) ``` ### PID 0x10C0 — Lambda Actual | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 10 C0 55 55 55 55]` | | Response | `7E8 [05 62 10 C0 XX YY 00 00]` | | Formula | `(A * 256 + B) * 0.000977` (λ) | | Min | 0.5 λ | | Max | 2.0 λ | | Bytes | 2 | **Примеры:** ``` Lambda = 1.0 (stoich): 7E8 [05 62 10 C0 04 00 00 00] (0x0400 = 1024 → 1.000) Lambda = 0.8 (rich): 7E8 [05 62 10 C0 03 33 00 00] (0x0333 = 819 → 0.800) Lambda = 1.1 (lean): 7E8 [05 62 10 C0 04 66 00 00] (0x0466 = 1126 → 1.100) ``` **Формула кодирования:** `raw = lambda / 0.000977` ### PID 0x1456 — Lambda Target | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 14 56 55 55 55 55]` | | Response | `7E8 [05 62 14 56 XX YY 00 00]` | | Formula | `(A * 256 + B) * 0.000977` (λ) | ### PID 0x437C — Torque Actual | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 43 7C 55 55 55 55]` | | Response | `7E8 [05 62 43 7C XX YY 00 00]` | | Formula | `(A * 256 + B) * 0.1` (Nm) | | Min | 0 Nm | | Max | 500 Nm | | Bytes | 2 | **Примеры:** ``` Torque = 50 Nm: 7E8 [05 62 43 7C 01 F4 00 00] (0x01F4 = 500) Torque = 200 Nm: 7E8 [05 62 43 7C 07 D0 00 00] (0x07D0 = 2000) Torque = 350 Nm: 7E8 [05 62 43 7C 0D AC 00 00] (0x0DAC = 3500) ``` ### PID 0x39A2 — Wastegate Position Actual | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 39 A2 55 55 55 55]` | | Response | `7E8 [05 62 39 A2 XX YY 00 00]` | | Formula | `(A * 256 + B) * 0.01` (%) | | Min | 0% | | Max | 100% | | Bytes | 2 | **Примеры:** ``` WG = 0% (closed): 7E8 [05 62 39 A2 00 00 00 00] WG = 50%: 7E8 [05 62 39 A2 13 88 00 00] (0x1388 = 5000) WG = 100% (open): 7E8 [05 62 39 A2 27 10 00 00] (0x2710 = 10000) ``` ### PID 0x39A3 — Wastegate Position Target Аналогично 0x39A2, Request: `7E0 [03 22 39 A3 55 55 55 55]` ### PID 0x2004 — Ignition Timing | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 20 04 55 55 55 55]` | | Response | `7E8 [05 62 20 04 XX YY 00 00]` | | Formula | `signed(A * 256 + B) * 0.01` (°) | | Min | -10° | | Max | 50° | | Bytes | 2 (signed) | **Примеры:** ``` Timing = 0°: 7E8 [05 62 20 04 00 00 00 00] Timing = 10°: 7E8 [05 62 20 04 03 E8 00 00] (0x03E8 = 1000) Timing = 25°: 7E8 [05 62 20 04 09 C4 00 00] (0x09C4 = 2500) Timing = -5°: 7E8 [05 62 20 04 FE 0C 00 00] (0xFE0C = -500 signed) ``` **Формула кодирования (signed):** ```python raw = int(timing * 100) if raw < 0: raw = 0x10000 + raw # Two's complement A = (raw >> 8) & 0xFF B = raw & 0xFF ``` ### PID 0x200A-0x200D — Timing Correction Cylinders 1-4 | Параметр | Значение | |----------|----------| | Request | `7E0 [03 22 20 0A 55 55 55 55]` (Cyl 1) | | Response | `7E8 [05 62 20 0A XX YY 00 00]` | | Formula | `signed(A * 256 + B) * 0.01` (°) | | Min | -15° | | Max | 5° | | Bytes | 2 (signed) | **Примеры (Knock retard usually negative):** ``` Cyl1 TC = 0°: 7E8 [05 62 20 0A 00 00 00 00] Cyl1 TC = -2°: 7E8 [05 62 20 0A FF 38 00 00] (0xFF38 = -200 signed) Cyl1 TC = -5°: 7E8 [05 62 20 0A FE 0C 00 00] (0xFE0C = -500 signed) ``` --- ## UDS PIDs — Instrument Cluster (0x714 → 0x77E) ### PID 0x22D1 — RPM from Cluster | Параметр | Значение | |----------|----------| | Request | `714 [03 22 22 D1 55 55 55 55]` | | Response | `77E [05 62 22 D1 XX YY 00 00]` | | Formula | `(A * 256 + B) / 4` (RPM) | | Min | 0 RPM | | Max | 8000 RPM | | Bytes | 2 | **Примеры:** ``` RPM = 850: 77E [05 62 22 D1 0D 48 00 00] (0x0D48 = 3400, /4 = 850) RPM = 3000: 77E [05 62 22 D1 2E E0 00 00] (0x2EE0 = 12000, /4 = 3000) ``` ### PID 0x224D — Ambient Light Sensor | Параметр | Значение | |----------|----------| | Request | `714 [03 22 22 4D 55 55 55 55]` | | Response | `77E [04 62 22 4D XX 00 00 00]` | | Formula | `A` (0-255, 0=dark, 255=bright) | | Bytes | 1 | **Примеры:** ``` Night: 77E [04 62 22 4D 10 00 00 00] (0x10 = 16) Daytime: 77E [04 62 22 4D E0 00 00 00] (0xE0 = 224) ``` --- ## UDS PIDs — DSG Transmission (0x7E1 → 0x7E9) ### PID 0x3816 — Current Gear | Параметр | Значение | |----------|----------| | Request | `7E1 [03 22 38 16 55 55 55 55]` | | Response | `7E9 [04 62 38 16 XX 00 00 00]` | | Formula | Lookup table | | Bytes | 1 | **Gear mapping:** ``` 0x00 = Neutral (0) 0x0C = Reverse (-1) 0x02 = 1st gear 0x04 = 2nd gear 0x06 = 3rd gear 0x08 = 4th gear 0x0A = 5th gear 0x0E = 6th gear 0x10 = 7th gear ``` **Примеры:** ``` Neutral: 7E9 [04 62 38 16 00 00 00 00] Reverse: 7E9 [04 62 38 16 0C 00 00 00] 3rd gear: 7E9 [04 62 38 16 06 00 00 00] 6th gear: 7E9 [04 62 38 16 0E 00 00 00] ``` ### PID 0x3815 — Gear Selector Position (PRNDM) | Параметр | Значение | |----------|----------| | Request | `7E1 [03 22 38 15 55 55 55 55]` | | Response | `7E9 [04 62 38 15 XX 00 00 00]` | | Formula | Lookup table | | Bytes | 1 | **Mode mapping:** ``` 0x00 = P (Park) 0x01 = R (Reverse) 0x02 = N (Neutral) 0x03 = D (Drive) 0x04 = S (Sport) 0x05 = M (Manual) ``` **Примеры:** ``` Park: 7E9 [04 62 38 15 00 00 00 00] Drive: 7E9 [04 62 38 15 03 00 00 00] Sport: 7E9 [04 62 38 15 04 00 00 00] Manual: 7E9 [04 62 38 15 05 00 00 00] ``` ### PID 0x1940 — Transmission Oil Temperature | Параметр | Значение | |----------|----------| | Request | `7E1 [03 22 19 40 55 55 55 55]` | | Response | `7E9 [04 62 19 40 XX 00 00 00]` | | Formula | `A - 40` (°C) | | Min | -40°C | | Max | 150°C | | Bytes | 1 | **Примеры:** ``` Temp = 80°C: 7E9 [04 62 19 40 78 00 00 00] (0x78 = 120) Temp = 100°C: 7E9 [04 62 19 40 8C 00 00 00] (0x8C = 140) ``` --- ## Таблица быстрого референса ### OBD2 Request/Response Summary | PID | Request | Response Example | Value | |-----|---------|------------------|-------| | 0x04 | `7DF 02 01 04` | `7E8 03 41 04 80` | 50% load | | 0x05 | `7DF 02 01 05` | `7E8 03 41 05 82` | 90°C coolant | | 0x0C | `7DF 02 01 0C` | `7E8 04 41 0C 1F 40` | 2000 RPM | | 0x0D | `7DF 02 01 0D` | `7E8 03 41 0D 78` | 120 km/h | | 0x11 | `7DF 02 01 11` | `7E8 03 41 11 40` | 25% throttle | | 0x2F | `7DF 02 01 2F` | `7E8 03 41 2F 80` | 50% fuel | | 0x5C | `7DF 02 01 5C` | `7E8 03 41 5C 96` | 110°C oil | ### UDS Request/Response Summary | ECU | PID | Request | Response Example | Value | |-----|-----|---------|------------------|-------| | Engine | 0x202A | `7E0 03 22 20 2A` | `7E8 05 62 20 2A 07 D0` | 200 kPa boost | | Engine | 0x437C | `7E0 03 22 43 7C` | `7E8 05 62 43 7C 0D AC` | 350 Nm torque | | Engine | 0x10C0 | `7E0 03 22 10 C0` | `7E8 05 62 10 C0 04 00` | λ=1.0 | | Cluster | 0x22D1 | `714 03 22 22 D1` | `77E 05 62 22 D1 1F 40` | 2000 RPM | | DSG | 0x3816 | `7E1 03 22 38 16` | `7E9 04 62 38 16 06` | 3rd gear | | DSG | 0x3815 | `7E1 03 22 38 15` | `7E9 04 62 38 15 03` | Drive mode |