DISCLAIMER: This library is meant to communicate with the vehicle's on-board diagnostic system. Improper configurations can cause unexpected communication failures within the vehicle. Therefore, it is recommended that only experts modify the library and always test in a safe location.
The user accepts all risks and responsibilities when modifying the firmware. KaiserEngineering, LLC and its affiliates accept no responsibility for damages or injury caused by misuse of the system.
C Library to communicate to a vehicle's on-board diagnostic (OBD) system.
These are the hardware peripherals the library will need to properly function. When choosing a microcontroller verify the CAN interface will have full control of the hardware configuration such as filters, headers, payload, etc. The 1ms timer can be assigned to the sysTick or a dedicated hardware timer. The accuracy of the timer is not critical, the timer is only used for the timeout function.
The OBDII_PACKET_MANAGER
struct is the core container for the device configuration and all of the real-time values. This struct will be passed for all function calls, thus allowing for multiple structs to be used in a single application.
The packet manager can be declared as seen below:
static OBDII_PACKET_MANAGER obdii; //Declare OBDII packet manager
The packet manager's OBDII_INIT
values should be set before calling any functions. This will define the static constants, such as HAL calls, timeouts and identification on the CAN bus.
Using the declared OBDII packet manager, assign the appropiate functions or variables to the init
struct.
obdii.init.transmit = ecu_tx; //Function call to transmit OBDII data to the vehicle
obdii.init.timeout = ECU_TIMEOUT; //Amount of time(ms) before lib_obdii will retry a transmission
obdii.init.arbitration_ID = 0x7E0; //Transmit ID on the CAN bus
obdii.init.IDE = OBDII_STD_IDE; //11-bit or 29-bit identifier
Now that the varaible are assinged, the OBDII library can be initialized:
/* Initialize the OBDII library */
OBDII_Initialize( &obdii );
Add error handling. (Future improvements)
As a way to reduce hardware timer usage, the lib_obdii library relys on a 1ms tick timer. This is mainly used for message timeouts, but can be used globably in the library for any time critical functions. OBDII_tick()
should be called every 1ms.
/* Called every 1ms */
OBDII_tick();
At this point the OBDII library is up and running. To begin a data stream, PIDs must be assigned.
We now have an OBDII packet manager that has all the hardware callbacks to interface with the vehicle's CAN bus network. The OBDII library will constantly see if any PIDs have been requested, and if so it will query the car until the PIDs are cleared.
To add a PID, OBDII_add_PID_request()
should be called. There are two parameters needed, the OBDII_PACKET_MANAGER
pointer and PID request pointer.
/* Declare and Engine RPM PID request*/
PID_DATA engine_rpm_req = { .pid = 0x0C, .mode = 0x01, .pid_unit = 0 };
/* Add Engine RPM PID request to the OBDII packet manager */
OBDII_add_PID_request( &obdii, &engine_rpm_req );
The function will either return OBDII_OK
or OBDII_MAX_PIDS_REACHED
, depending how many PIDs have been assigned. Note, that OBDII_MAX_PIDS_REACHED
will mean that the PID was NOT added.
OBDII_Service()
should be called in the main loop after the OBDII packet manager has been initialized. This function handles all of the data processing and packet handling.
/* Service the OBDII protocol manager */
OBDII_Service( &obdii );