Это простая, но мощная библиотека для легкого взаимодействия вашего Arduino со сканером ELM327 OBD-II. С помощью этой библиотеки вы можете запрашивать любые PID, поддерживаемые OBD-II, для сбора самых разных данных об автомобиле (например, скорость, обороты в минуту, температура двигателя и т. д.). Кроме того, вы можете использовать ELMduino для просмотра и очистки кодов неисправностей вашего автомобиля — больше не нужно заходить в AutoZone!
Установите ELMduino с помощью диспетчера библиотек Arduino IDE (найдите «ELMduino.h»)
Если у вас возникли трудности с подключением/поддержанием соединения с вашим ELM327, попробуйте использовать скорость 38400 бод вместо 115200. Если у вас все еще есть проблемы, попробуйте все другие возможные скорости. Наконец, если вы используете BluetoothSerial на ESP32, попробуйте использовать MAC-адрес ELM327 вместо имени устройства «OBDII» и удалите сопряженные устройства, используя этот эскиз.
Библиотека неблокирующая. Это означает, что когда вы запрашиваете PID, например, myELM327.rpm()
, код не ждет ответа, который блокирует выполнение другого вашего кода в основном цикле. С ELMDuino ваш основной цикл может продолжать выполнять другие задачи. Чтобы это работало, вам необходимо неоднократно вызывать функцию запроса PID и проверять состояние неблокируемого приема ( myELM327.nb_rx_state
), пока оно не станет равным ELM_SUCCESS
. Если статус не ELM_SUCCESS
, библиотека все еще может ожидать получения ответа. На это указывает значение myELM327.nb_rx_state
равное ELM_GETTING_MSG
. Если статус не равен ни одному из этих значений (ELM_SUCCESS или ELM_GETTING_MSG), это указывает на то, что произошла ошибка. Вы можете вызвать myELM327.printError()
чтобы проверить, в чем проблема. См. простой пример ниже, в котором запрашивается скорость двигателя в об/мин.
Для ясности: не пытайтесь запрашивать более одного PID одновременно. Прежде чем начинать следующий, вам необходимо дождаться завершения текущего запроса PID.
# include " ELMduino.h "
# define ELM_PORT Serial1
const bool DEBUG = true ;
const int TIMEOUT = 2000 ;
const bool HALT_ON_FAIL = false ;
ELM327 myELM327;
typedef enum { ENG_RPM,
SPEED } obd_pid_states;
obd_pid_states obd_state = ENG_RPM;
float rpm = 0 ;
float mph = 0 ;
void setup ()
{
Serial. begin ( 115200 );
ELM_PORT. begin ( 115200 );
Serial. println ( " Attempting to connect to ELM327... " );
if (!myELM327. begin (ELM_PORT, DEBUG, TIMEOUT))
{
Serial. println ( " Couldn't connect to OBD scanner " );
if (HALT_ON_FAIL)
while ( 1 );
}
Serial. println ( " Connected to ELM327 " );
}
void loop ()
{
switch (obd_state)
{
case ENG_RPM:
{
rpm = myELM327. rpm ();
if (myELM327. nb_rx_state == ELM_SUCCESS)
{
Serial. print ( " rpm: " );
Serial. println (rpm);
obd_state = SPEED;
}
else if (myELM327. nb_rx_state != ELM_GETTING_MSG)
{
myELM327. printError ();
obd_state = SPEED;
}
break ;
}
case SPEED:
{
mph = myELM327. mph ();
if (myELM327. nb_rx_state == ELM_SUCCESS)
{
Serial. print ( " mph: " );
Serial. println (mph);
obd_state = ENG_RPM;
}
else if (myELM327. nb_rx_state != ELM_GETTING_MSG)
{
myELM327. printError ();
obd_state = ENG_RPM;
}
break ;
}
}
}
bool begin (Stream& stream, const bool & debug = false , const uint16_t & timeout = 1000 , const char & protocol = ' 0 ' , const uint16_t & payloadLen = 40 , const byte& dataTimeout = 0 );
bool initializeELM ( const char & protocol = ' 0 ' , const byte& dataTimeout = 0 );
void flushInputBuff ();
uint64_t findResponse ();
void queryPID ( const uint8_t & service, const uint16_t & pid, const uint8_t & num_responses = 1 );
void queryPID ( char queryStr[]);
float processPID ( const uint8_t & service, const uint16_t & pid, const uint8_t & num_responses, const uint8_t & numExpectedBytes, const float & scaleFactor = 1 , const float & bias = 0 );
void sendCommand ( const char *cmd);
int8_t sendCommand_Blocking ( const char *cmd);
int8_t get_response ();
bool timeout ();
float conditionResponse ( const uint8_t & numExpectedBytes, const float & scaleFactor = 1 , const float & bias = 0 );
float batteryVoltage ( void );
int8_t get_vin_blocking ( char vin[]);
bool resetDTC ();
void currentDTCCodes ( const bool & isBlocking = true );
uint32_t supportedPIDs_1_20 ();
uint32_t monitorStatus ();
uint16_t freezeDTC ();
uint16_t fuelSystemStatus ();
float engineLoad ();
float engineCoolantTemp ();
float shortTermFuelTrimBank_1 ();
float longTermFuelTrimBank_1 ();
float shortTermFuelTrimBank_2 ();
float longTermFuelTrimBank_2 ();
float fuelPressure ();
uint8_t manifoldPressure ();
float rpm ();
int32_t kph ();
float mph ();
float timingAdvance ();
float intakeAirTemp ();
float mafRate ();
float throttle ();
uint8_t commandedSecAirStatus ();
uint8_t oxygenSensorsPresent_2banks ();
uint8_t obdStandards ();
uint8_t oxygenSensorsPresent_4banks ();
bool auxInputStatus ();
uint16_t runTime ();
uint32_t supportedPIDs_21_40 ();
uint16_t distTravelWithMIL ();
float fuelRailPressure ();
float fuelRailGuagePressure ();
float commandedEGR ();
float egrError ();
float commandedEvapPurge ();
float fuelLevel ();
uint8_t warmUpsSinceCodesCleared ();
uint16_t distSinceCodesCleared ();
float evapSysVapPressure ();
uint8_t absBaroPressure ();
float catTempB1S1 ();
float catTempB2S1 ();
float catTempB1S2 ();
float catTempB2S2 ();
uint32_t supportedPIDs_41_60 ();
uint32_t monitorDriveCycleStatus ();
float ctrlModVoltage ();
float absLoad ();
float commandedAirFuelRatio ();
float relativeThrottle ();
float ambientAirTemp ();
float absThrottlePosB ();
float absThrottlePosC ();
float absThrottlePosD ();
float absThrottlePosE ();
float absThrottlePosF ();
float commandedThrottleActuator ();
uint16_t timeRunWithMIL ();
uint16_t timeSinceCodesCleared ();
float maxMafRate ();
uint8_t fuelType ();
float ethanolPercent ();
float absEvapSysVapPressure ();
float evapSysVapPressure2 ();
float absFuelRailPressure ();
float relativePedalPos ();
float hybridBatLife ();
float oilTemp ();
float fuelInjectTiming ();
float fuelRate ();
uint8_t emissionRqmts ();
uint32_t supportedPIDs_61_80 ();
float demandedTorque ();
float torque ();
uint16_t referenceTorque ();
uint16_t auxSupported ();
void printError ();
const char AUTOMATIC = ' 0 ' ;
const char SAE_J1850_PWM_41_KBAUD = ' 1 ' ;
const char SAE_J1850_PWM_10_KBAUD = ' 2 ' ;
const char ISO_9141_5_BAUD_INIT = ' 3 ' ;
const char ISO_14230_5_BAUD_INIT = ' 4 ' ;
const char ISO_14230_FAST_INIT = ' 5 ' ;
const char ISO_15765_11_BIT_500_KBAUD = ' 6 ' ;
const char ISO_15765_29_BIT_500_KBAUD = ' 7 ' ;
const char ISO_15765_11_BIT_250_KBAUD = ' 8 ' ;
const char ISO_15765_29_BIT_250_KBAUD = ' 9 ' ;
const char SAE_J1939_29_BIT_250_KBAUD = ' A ' ;
const char USER_1_CAN = ' B ' ;
const char USER_2_CAN = ' C ' ;
const uint8_t SUPPORTED_PIDS_1_20 = 0 ; // 0x00 - bit encoded
const uint8_t MONITOR_STATUS_SINCE_DTC_CLEARED = 1 ; // 0x01 - bit encoded
const uint8_t FREEZE_DTC = 2 ; // 0x02 -
const uint8_t FUEL_SYSTEM_STATUS = 3 ; // 0x03 - bit encoded
const uint8_t ENGINE_LOAD = 4 ; // 0x04 - %
const uint8_t ENGINE_COOLANT_TEMP = 5 ; // 0x05 - °C
const uint8_t SHORT_TERM_FUEL_TRIM_BANK_1 = 6 ; // 0x06 - %
const uint8_t LONG_TERM_FUEL_TRIM_BANK_1 = 7 ; // 0x07 - %
const uint8_t SHORT_TERM_FUEL_TRIM_BANK_2 = 8 ; // 0x08 - %
const uint8_t LONG_TERM_FUEL_TRIM_BANK_2 = 9 ; // 0x09 - %
const uint8_t FUEL_PRESSURE = 10 ; // 0x0A - kPa
const uint8_t INTAKE_MANIFOLD_ABS_PRESSURE = 11 ; // 0x0B - kPa
const uint8_t ENGINE_RPM = 12 ; // 0x0C - rpm
const uint8_t VEHICLE_SPEED = 13 ; // 0x0D - km/h
const uint8_t TIMING_ADVANCE = 14 ; // 0x0E - ° before TDC
const uint8_t INTAKE_AIR_TEMP = 15 ; // 0x0F - °C
const uint8_t MAF_FLOW_RATE = 16 ; // 0x10 - g/s
const uint8_t THROTTLE_POSITION = 17 ; // 0x11 - %
const uint8_t COMMANDED_SECONDARY_AIR_STATUS = 18 ; // 0x12 - bit encoded
const uint8_t OXYGEN_SENSORS_PRESENT_2_BANKS = 19 ; // 0x13 - bit encoded
const uint8_t OXYGEN_SENSOR_1_A = 20 ; // 0x14 - V %
const uint8_t OXYGEN_SENSOR_2_A = 21 ; // 0x15 - V %
const uint8_t OXYGEN_SENSOR_3_A = 22 ; // 0x16 - V %
const uint8_t OXYGEN_SENSOR_4_A = 23 ; // 0x17 - V %
const uint8_t OXYGEN_SENSOR_5_A = 24 ; // 0x18 - V %
const uint8_t OXYGEN_SENSOR_6_A = 25 ; // 0x19 - V %
const uint8_t OXYGEN_SENSOR_7_A = 26 ; // 0x1A - V %
const uint8_t OXYGEN_SENSOR_8_A = 27 ; // 0x1B - V %
const uint8_t OBD_STANDARDS = 28 ; // 0x1C - bit encoded
const uint8_t OXYGEN_SENSORS_PRESENT_4_BANKS = 29 ; // 0x1D - bit encoded
const uint8_t AUX_INPUT_STATUS = 30 ; // 0x1E - bit encoded
const uint8_t RUN_TIME_SINCE_ENGINE_START = 31 ; // 0x1F - sec
const uint8_t SUPPORTED_PIDS_21_40 = 32 ; // 0x20 - bit encoded
const uint8_t DISTANCE_TRAVELED_WITH_MIL_ON = 33 ; // 0x21 - km
const uint8_t FUEL_RAIL_PRESSURE = 34 ; // 0x22 - kPa
const uint8_t FUEL_RAIL_GUAGE_PRESSURE = 35 ; // 0x23 - kPa
const uint8_t OXYGEN_SENSOR_1_B = 36 ; // 0x24 - ratio V
const uint8_t OXYGEN_SENSOR_2_B = 37 ; // 0x25 - ratio V
const uint8_t OXYGEN_SENSOR_3_B = 38 ; // 0x26 - ratio V
const uint8_t OXYGEN_SENSOR_4_B = 39 ; // 0x27 - ratio V
const uint8_t OXYGEN_SENSOR_5_B = 40 ; // 0x28 - ratio V
const uint8_t OXYGEN_SENSOR_6_B = 41 ; // 0x29 - ratio V
const uint8_t OXYGEN_SENSOR_7_B = 42 ; // 0x2A - ratio V
const uint8_t OXYGEN_SENSOR_8_B = 43 ; // 0x2B - ratio V
const uint8_t COMMANDED_EGR = 44 ; // 0x2C - %
const uint8_t EGR_ERROR = 45 ; // 0x2D - %
const uint8_t COMMANDED_EVAPORATIVE_PURGE = 46 ; // 0x2E - %
const uint8_t FUEL_TANK_LEVEL_INPUT = 47 ; // 0x2F - %
const uint8_t WARM_UPS_SINCE_CODES_CLEARED = 48 ; // 0x30 - count
const uint8_t DIST_TRAV_SINCE_CODES_CLEARED = 49 ; // 0x31 - km
const uint8_t EVAP_SYSTEM_VAPOR_PRESSURE = 50 ; // 0x32 - Pa
const uint8_t ABS_BAROMETRIC_PRESSURE = 51 ; // 0x33 - kPa
const uint8_t OXYGEN_SENSOR_1_C = 52 ; // 0x34 - ratio mA
const uint8_t OXYGEN_SENSOR_2_C = 53 ; // 0x35 - ratio mA
const uint8_t OXYGEN_SENSOR_3_C = 54 ; // 0x36 - ratio mA
const uint8_t OXYGEN_SENSOR_4_C = 55 ; // 0x37 - ratio mA
const uint8_t OXYGEN_SENSOR_5_C = 56 ; // 0x38 - ratio mA
const uint8_t OXYGEN_SENSOR_6_C = 57 ; // 0x39 - ratio mA
const uint8_t OXYGEN_SENSOR_7_C = 58 ; // 0x3A - ratio mA
const uint8_t OXYGEN_SENSOR_8_C = 59 ; // 0x3B - ratio mA
const uint8_t CATALYST_TEMP_BANK_1_SENSOR_1 = 60 ; // 0x3C - °C
const uint8_t CATALYST_TEMP_BANK_2_SENSOR_1 = 61 ; // 0x3D - °C
const uint8_t CATALYST_TEMP_BANK_1_SENSOR_2 = 62 ; // 0x3E - °C
const uint8_t CATALYST_TEMP_BANK_2_SENSOR_2 = 63 ; // 0x3F - °C
const uint8_t SUPPORTED_PIDS_41_60 = 64 ; // 0x40 - bit encoded
const uint8_t MONITOR_STATUS_THIS_DRIVE_CYCLE = 65 ; // 0x41 - bit encoded
const uint8_t CONTROL_MODULE_VOLTAGE = 66 ; // 0x42 - V
const uint8_t ABS_LOAD_VALUE = 67 ; // 0x43 - %
const uint8_t FUEL_AIR_COMMANDED_EQUIV_RATIO = 68 ; // 0x44 - ratio
const uint8_t RELATIVE_THROTTLE_POSITION = 69 ; // 0x45 - %
const uint8_t AMBIENT_AIR_TEMP = 70 ; // 0x46 - °C
const uint8_t ABS_THROTTLE_POSITION_B = 71 ; // 0x47 - %
const uint8_t ABS_THROTTLE_POSITION_C = 72 ; // 0x48 - %
const uint8_t ACCELERATOR_PEDAL_POSITION_D = 73 ; // 0x49 - %
const uint8_t ACCELERATOR_PEDAL_POSITION_E = 74 ; // 0x4A - %
const uint8_t ACCELERATOR_PEDAL_POSITION_F = 75 ; // 0x4B - %
const uint8_t COMMANDED_THROTTLE_ACTUATOR = 76 ; // 0x4C - %
const uint8_t TIME_RUN_WITH_MIL_ON = 77 ; // 0x4D - min
const uint8_t TIME_SINCE_CODES_CLEARED = 78 ; // 0x4E - min
const uint8_t MAX_VALUES_EQUIV_V_I_PRESSURE = 79 ; // 0x4F - ratio V mA kPa
const uint8_t MAX_MAF_RATE = 80 ; // 0x50 - g/s
const uint8_t FUEL_TYPE = 81 ; // 0x51 - ref table
const uint8_t ETHANOL_FUEL_PERCENT = 82 ; // 0x52 - %
const uint8_t ABS_EVAP_SYS_VAPOR_PRESSURE = 83 ; // 0x53 - kPa
const uint8_t EVAP_SYS_VAPOR_PRESSURE = 84 ; // 0x54 - Pa
const uint8_t SHORT_TERM_SEC_OXY_SENS_TRIM_1_3 = 85 ; // 0x55 - %
const uint8_t LONG_TERM_SEC_OXY_SENS_TRIM_1_3 = 86 ; // 0x56 - %
const uint8_t SHORT_TERM_SEC_OXY_SENS_TRIM_2_4 = 87 ; // 0x57 - %
const uint8_t LONG_TERM_SEC_OXY_SENS_TRIM_2_4 = 88 ; // 0x58 - %
const uint8_t FUEL_RAIL_ABS_PRESSURE = 89 ; // 0x59 - kPa
const uint8_t RELATIVE_ACCELERATOR_PEDAL_POS = 90 ; // 0x5A - %
const uint8_t HYBRID_BATTERY_REMAINING_LIFE = 91 ; // 0x5B - %
const uint8_t ENGINE_OIL_TEMP = 92 ; // 0x5C - °C
const uint8_t FUEL_INJECTION_TIMING = 93 ; // 0x5D - °
const uint8_t ENGINE_FUEL_RATE = 94 ; // 0x5E - L/h
const uint8_t EMISSION_REQUIREMENTS = 95 ; // 0x5F - bit encoded
const uint8_t SUPPORTED_PIDS_61_80 = 96 ; // 0x60 - bit encoded
const uint8_t DEMANDED_ENGINE_PERCENT_TORQUE = 97 ; // 0x61 - %
const uint8_t ACTUAL_ENGINE_TORQUE = 98 ; // 0x62 - %
const uint8_t ENGINE_REFERENCE_TORQUE = 99 ; // 0x63 - Nm
const uint8_t ENGINE_PERCENT_TORQUE_DATA = 100 ; // 0x64 - %
const uint8_t AUX_INPUT_OUTPUT_SUPPORTED = 101 ; // 0x65 - bit encoded
(https://www.sparkfun.com/datasheets/Widgets/ELM327_AT_Commands.pdf)
const char * const DISP_DEVICE_DESCRIPT = " AT @1 " ; // General
const char * const DISP_DEVICE_ID = " AT @2 " ; // General
const char * const STORE_DEVICE_ID = " AT @3 %s " ; // General
const char * const REPEAT_LAST_COMMAND = " AT r " ; // General
const char * const ALLOW_LONG_MESSAGES = " AT AL " ; // General
const char * const AUTOMATIC_RECEIVE = " AT AR " ; // OBD
const char * const ADAPTIVE_TIMING_OFF = " AT AT0 " ; // OBD
const char * const ADAPTIVE_TIMING_AUTO_1 = " AT AT1 " ; // OBD
const char * const ADAPTIVE_TIMING_AUTO_2 = " AT AT2 " ; // OBD
const char * const DUMP_BUFFER = " AT BD " ; // OBD
const char * const BYPASS_INIT_SEQUENCE = " AT BI " ; // OBD
const char * const TRY_BAUD_DIVISOR = " AT BRD %s " ; // General
const char * const SET_HANDSHAKE_TIMEOUT = " AT BRT %s " ; // General
const char * const CAN_AUTO_FORMAT_OFF = " AT CAF0 " ; // CAN
const char * const CAN_AUTO_FORMAT_ON = " AT CAF1 " ; // CAN
const char * const CAN_EXTENDED_ADDRESS_OFF = " AT CEA " ; // CAN
const char * const USE_CAN_EXTENDED_ADDRESS = " AT CEA %s " ; // CAN
const char * const SET_ID_FILTER = " AT CF %s " ; // CAN
const char * const CAN_FLOW_CONTROL_OFF = " AT CFC0 " ; // CAN
const char * const CAN_FLOW_CONTROL_ON = " AT CFC1 " ;