New protocol handler alongside BMW I/K-Bus: - KLineObd2: 5-baud slow init, fast init (TiniPulse), request/response with half-duplex echo clearing, PID convenience wrapper - Obd2Pids.h: ~20 common PIDs with SAE J1979 decode helpers - obd2_scanner.cpp: polls RPM, speed, coolant, throttle, voltage Build config changes: - config.h: KLINE_* defaults (10400/8N1/MOD256/no idle detect) - platformio.ini: build_src_filter separates sketches, new [env:obd2-scanner] environment with KLINE_TX_INVERT=0
142 lines
5.4 KiB
C++
142 lines
5.4 KiB
C++
#pragma once
|
|
// OBD-II PID constants and decode helpers (SAE J1979)
|
|
// Covers the most common Mode 01 (current data) PIDs.
|
|
|
|
#include <Arduino.h>
|
|
|
|
namespace obd2 {
|
|
|
|
// --- Diagnostic modes ---
|
|
constexpr uint8_t MODE_CURRENT = 0x01; // current data
|
|
constexpr uint8_t MODE_FREEZE = 0x02; // freeze frame
|
|
constexpr uint8_t MODE_DTC = 0x03; // stored DTCs
|
|
constexpr uint8_t MODE_CLEAR_DTC = 0x04; // clear DTCs
|
|
constexpr uint8_t MODE_O2_TEST = 0x05; // O2 sensor monitoring
|
|
constexpr uint8_t MODE_TEST_RESULTS = 0x06; // on-board monitoring test results
|
|
constexpr uint8_t MODE_PENDING_DTC = 0x07; // pending DTCs
|
|
constexpr uint8_t MODE_CONTROL = 0x08; // control of on-board system
|
|
constexpr uint8_t MODE_VEHICLE_INFO = 0x09; // vehicle information (VIN, etc.)
|
|
constexpr uint8_t MODE_PERMANENT_DTC = 0x0A; // permanent DTCs
|
|
|
|
// --- Mode 01 PIDs ---
|
|
constexpr uint8_t PID_SUPPORTED_01_20 = 0x00; // supported PIDs [01-20]
|
|
constexpr uint8_t PID_DTC_STATUS = 0x01; // monitor status since DTCs cleared
|
|
constexpr uint8_t PID_FUEL_STATUS = 0x03; // fuel system status
|
|
constexpr uint8_t PID_ENGINE_LOAD = 0x04; // calculated engine load (%)
|
|
constexpr uint8_t PID_COOLANT_TEMP = 0x05; // engine coolant temperature (C)
|
|
constexpr uint8_t PID_SHORT_FUEL_TRIM_1 = 0x06; // short term fuel trim bank 1 (%)
|
|
constexpr uint8_t PID_LONG_FUEL_TRIM_1 = 0x07; // long term fuel trim bank 1 (%)
|
|
constexpr uint8_t PID_INTAKE_PRESSURE = 0x0B; // intake manifold pressure (kPa)
|
|
constexpr uint8_t PID_RPM = 0x0C; // engine RPM
|
|
constexpr uint8_t PID_SPEED = 0x0D; // vehicle speed (km/h)
|
|
constexpr uint8_t PID_TIMING_ADVANCE = 0x0E; // timing advance (degrees BTDC)
|
|
constexpr uint8_t PID_INTAKE_TEMP = 0x0F; // intake air temperature (C)
|
|
constexpr uint8_t PID_MAF_RATE = 0x10; // MAF air flow rate (g/s)
|
|
constexpr uint8_t PID_THROTTLE = 0x11; // throttle position (%)
|
|
constexpr uint8_t PID_OBD_STANDARD = 0x1C; // OBD standards compliance
|
|
constexpr uint8_t PID_RUN_TIME = 0x1F; // run time since engine start (s)
|
|
constexpr uint8_t PID_SUPPORTED_21_40 = 0x20; // supported PIDs [21-40]
|
|
constexpr uint8_t PID_FUEL_LEVEL = 0x2F; // fuel tank level input (%)
|
|
constexpr uint8_t PID_BARO_PRESSURE = 0x33; // barometric pressure (kPa)
|
|
constexpr uint8_t PID_SUPPORTED_41_60 = 0x40; // supported PIDs [41-60]
|
|
constexpr uint8_t PID_CONTROL_VOLTAGE = 0x42; // control module voltage (V)
|
|
constexpr uint8_t PID_FUEL_TYPE = 0x51; // fuel type
|
|
constexpr uint8_t PID_OIL_TEMP = 0x5C; // engine oil temperature (C)
|
|
constexpr uint8_t PID_FUEL_RATE = 0x5E; // engine fuel rate (L/h)
|
|
|
|
// --- K-line protocol constants ---
|
|
constexpr uint8_t SYNC_BYTE = 0x55; // ECU sync response
|
|
constexpr uint8_t DEFAULT_TARGET = 0x33; // ISO 9141 default ECU address
|
|
constexpr uint8_t TESTER_ADDR = 0xF1; // external test equipment
|
|
constexpr uint8_t FUNC_ADDR = 0x33; // functional addressing
|
|
|
|
// --- ISO 14230 (KWP2000) header formats ---
|
|
constexpr uint8_t KWP_FMT_NO_ADDR = 0x00; // no address info
|
|
constexpr uint8_t KWP_FMT_PHYS_ADDR = 0x80; // physical addressing
|
|
constexpr uint8_t KWP_FMT_FUNC_ADDR = 0xC0; // functional addressing
|
|
|
|
// --- Decode helpers ---
|
|
// All formulas from SAE J1979 / ISO 15031-5
|
|
|
|
// PID 0x04: Calculated engine load (0-100%)
|
|
inline float decodeEngineLoad(uint8_t a) {
|
|
return a * (100.0f / 255.0f);
|
|
}
|
|
|
|
// PID 0x05: Engine coolant temperature (-40 to 215 C)
|
|
inline int16_t decodeCoolantTemp(uint8_t a) {
|
|
return (int16_t)a - 40;
|
|
}
|
|
|
|
// PID 0x06/0x07: Short/long term fuel trim (-100 to 99.2%)
|
|
inline float decodeFuelTrim(uint8_t a) {
|
|
return (a / 1.28f) - 100.0f;
|
|
}
|
|
|
|
// PID 0x0B: Intake manifold pressure (0-255 kPa)
|
|
inline uint8_t decodeIntakePressure(uint8_t a) {
|
|
return a;
|
|
}
|
|
|
|
// PID 0x0C: Engine RPM (0-16383.75 RPM) — 2 bytes
|
|
inline float decodeRpm(uint8_t a, uint8_t b) {
|
|
return ((a * 256.0f) + b) / 4.0f;
|
|
}
|
|
|
|
// PID 0x0D: Vehicle speed (0-255 km/h)
|
|
inline uint8_t decodeSpeed(uint8_t a) {
|
|
return a;
|
|
}
|
|
|
|
// PID 0x0E: Timing advance (-64 to 63.5 degrees BTDC)
|
|
inline float decodeTimingAdvance(uint8_t a) {
|
|
return (a / 2.0f) - 64.0f;
|
|
}
|
|
|
|
// PID 0x0F: Intake air temperature (-40 to 215 C)
|
|
inline int16_t decodeIntakeTemp(uint8_t a) {
|
|
return (int16_t)a - 40;
|
|
}
|
|
|
|
// PID 0x10: MAF air flow rate (0-655.35 g/s) — 2 bytes
|
|
inline float decodeMafRate(uint8_t a, uint8_t b) {
|
|
return ((a * 256.0f) + b) / 100.0f;
|
|
}
|
|
|
|
// PID 0x11: Throttle position (0-100%)
|
|
inline float decodeThrottle(uint8_t a) {
|
|
return a * (100.0f / 255.0f);
|
|
}
|
|
|
|
// PID 0x1F: Run time since engine start (0-65535 s) — 2 bytes
|
|
inline uint16_t decodeRunTime(uint8_t a, uint8_t b) {
|
|
return (uint16_t)(a * 256) + b;
|
|
}
|
|
|
|
// PID 0x2F: Fuel tank level input (0-100%)
|
|
inline float decodeFuelLevel(uint8_t a) {
|
|
return a * (100.0f / 255.0f);
|
|
}
|
|
|
|
// PID 0x33: Barometric pressure (0-255 kPa)
|
|
inline uint8_t decodeBaroPressure(uint8_t a) {
|
|
return a;
|
|
}
|
|
|
|
// PID 0x42: Control module voltage (0-65.535 V) — 2 bytes
|
|
inline float decodeControlVoltage(uint8_t a, uint8_t b) {
|
|
return ((a * 256.0f) + b) / 1000.0f;
|
|
}
|
|
|
|
// PID 0x5C: Engine oil temperature (-40 to 210 C)
|
|
inline int16_t decodeOilTemp(uint8_t a) {
|
|
return (int16_t)a - 40;
|
|
}
|
|
|
|
// PID 0x5E: Engine fuel rate (0-3212.75 L/h) — 2 bytes
|
|
inline float decodeFuelRate(uint8_t a, uint8_t b) {
|
|
return ((a * 256.0f) + b) / 20.0f;
|
|
}
|
|
|
|
} // namespace obd2
|