• Stars
    star
    617
  • Rank 72,724 (Top 2 %)
  • Language
    C
  • License
    BSD 3-Clause "New...
  • Created almost 11 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Unified Diagnostics Service (UDS) and OBD-II (On Board Diagnostics for Vehicles) C Library

Unified Diagnostic Services (UDS) Support Library in C

This is a platform agnostic C library that implements the Unified Diagnostics Services protocol for automotive electronics. UDS is documented in ISO 14229 and is the underpinning for the more well-known On-board Diagnostics (OBD) standard. The library currently supports UDS running over CAN (ISO 15765-4), which uses the ISO-TP (ISO 15765-2) protocol for message framing.

This library doesn't assume anything about the source of your diagnostic message requests or underlying interface to the CAN bus. It uses dependency injection to give you complete control.

Usage

First, create some shim functions to let this library use your lower level system:

// required, this must send a single CAN message with the given arbitration
// ID (i.e. the CAN message ID) and data. The size will never be more than 8
// bytes.
bool send_can(const uint32_t arbitration_id, const uint8_t* data,
        const uint8_t size) {
    ...
}

// optional, provide to receive debugging log messages
void debug(const char* format, ...) {
    ...
}


// not used in the current version
void set_timer(uint16_t time_ms, void (*callback)) {
    ...
}

With your shims in place, create a DiagnosticShims object to pass them around:

DiagnosticShims shims = diagnostic_init_shims(debug, send_can, set_timer);

With your shims in hand, send a simple PID request to the standard broadcast address, 0x7df (we use the constant OBD2_FUNCTIONAL_BROADCAST_ID here):

// Optional: This is your callback that will be called the response to your
// diagnostic request is received.
void response_received_handler(const DiagnosticResponse* response) {
    // You received a response! Do something with it.
}

DiagnosticRequestHandle handle = diagnostic_request_pid(&shims,
        DIAGNOSTIC_STANDARD_PID, // this is a standard PID request, not an extended or enhanced one
        OBD2_FUNCTIONAL_BROADCAST_ID, // the request is going out to the broadcast arbitration ID
        0x2, // we want PID 0x2
        response_received_handler); // our callback (optional, use NULL if you don't have one)

if(handle.completed) {
    if(!handle.success) {
        // something happened and it already failed - possibly we aren't
        // able to send CAN messages
        return;
    } else {
        // this should never occur right away - you need to receive a fresh
        // CAN message first
    }
} else {
    while(true) {
        // Continue to read from CAN, passing off each message to the handle.
        // This will return a 'completed' DiagnosticResponse when the when
        // the request is completely sent and the response is received
        // (which may take more than 1 CAN frames)
        DiagnosticResponse response = diagnostic_receive_can_frame(&shims,
            &handle, can_message_id, can_data, sizeof(can_data));

        if(response.completed && handle.completed) {
            if(handle.success) {
              if(response.success) {
                  // The request was sent successfully, the response was
                  // received successfully, and it was a positive response - we
                  // got back some data!
              } else {
                  // The request was sent successfully, the response was
                  // received successfully, BUT it was a negative response
                  // from the other node.
                  printf("This is the error code: %d", response.negative_response_code);
              }
            } else {
                // Some other fatal error ocurred - we weren't able to send
                // the request or receive the response. The CAN connection
                // may be down.
            }
        }
    }
}

Requests for other modes

If you want to do more besides PID requests on mode 0x1 and 0x22, there's a lower level API you can use. Here's how to make a mode 3 request to get DTCs.

DiagnosticRequest request = {
    arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
    mode: OBD2_MODE_EMISSIONS_DTC_REQUEST
};
DiagnosticRequestHandle handle = diagnostic_request(&SHIMS, &request, NULL);

if(handle.completed) {
    if(!handle.success) {
        // something happened and it already failed - possibly we aren't
        // able to send CAN messages
        return;
    } else {
        // this should never occur right away - you need to receive a fresh
        // CAN message first
    }
} else {
    while(true) {
        // Continue to read from CAN, passing off each message to the handle.
        // This will return a 'completed' DiagnosticResponse when the when
        // the request is completely sent and the response is received
        // (which may take more than 1 CAN frames)
        DiagnosticResponse response = diagnostic_receive_can_frame(&shims,
            &handle, can_message_id, can_data, sizeof(can_data));

        if(response.completed && handle.completed) {
            if(handle.success) {
              if(response.success) {
                  // The request was sent successfully, the response was
                  // received successfully, and it was a positive response - we
                  // got back some data!
                  printf("The DTCs are: ");
                  for(int i = 0; i < response.payload_length; i++) {
                    printf("0x%x ", response.payload[i]);
                  }
              } else {
                  // The request was sent successfully, the response was
                  // received successfully, BUT it was a negative response
                  // from the other node.
                  printf("This is the error code: %d", response.negative_response_code);
              }
            } else {
                // Some other fatal error ocurred - we weren't able to send
                // the request or receive the response. The CAN connection
                // may be down.
            }
        }
    }
}

Dependencies

This library requires 2 dependencies:

Testing

The library includes a test suite that uses the check C unit test library.

$ make test

You can also see the test coverage if you have lcov installed and the BROWSER environment variable set to your choice of web browsers:

$ BROWSER=google-chrome-stable make coverage

OBD-II Basics

TODO diagram out a request, response and error response

  • store the request arb id, mode, pid, and payload locally
  • send a can message
  • get all new can messages passed to it
  • Check the incoming can message to see if it matches one of the standard ECU response IDs, or our arb ID + 0x8
  • if it matches, parse the diagnostic response and call the callback

Future Notes

you're going to request a few PIDs over and over again at some frequency you're going to request DTCs once and read the response you're going to clear DTCs once

we need another layer on top of that to handle the repeated requests.

Authors

Chris Peplin [email protected]

License

Copyright (c) 2013 Ford Motor Company

Licensed under the BSD license.

More Repositories

1

android-webcam

Android library to access a USB webcam feed
C
323
star
2

isotp-c

An implementation of the ISO-TP (ISO15765-2) CAN protocol in C
C
289
star
3

openxc-android

Android library for accessing vehicle data from an OpenXC vehicle interface
Java
230
star
4

vi-firmware

OpenXC-compatible firmware for PIC32 and LPC1768
C++
194
star
5

openxc-python

OpenXC Python library
Python
109
star
6

openxc-message-format

Specification for the OpenXC JSON message format
C
97
star
7

bitfield-c

Bit array parsing and encoding utility library in C
C
85
star
8

AT-commander

A C library to control a device via UART that responds to an AT command set (like an RN-42)
C
75
star
9

openxc-vehicle-simulator

Python
62
star
10

openxcplatform.com

Static website for openxcplatform.com
HTML
40
star
11

reference-vi

Open Source Hardware Schematics for OpenXC Vehicle Interface
HTML
38
star
12

bluetooth-audio-passthrough

Open source schematics for Bluetooth audio passthrough
21
star
13

nxpUSBlib

Fork of NXP's USB library for all LPC microcontrollers, with bug fixes
C
20
star
14

emhashmap

This library is an implementation of a hash map in C that maps integers to void pointers
C
20
star
15

web-logging-example

Example OpenXC web application in Python for vehicle data logging
Python
17
star
16

diagnostic-tool

OpenXC Android Tool for Sending OBD-II Requests to a Vehicle Interface
Java
16
star
17

rearview-camera

Rearview camera implemented as an Android app with OpenXC
Java
16
star
18

openxc-starter

OpenXC "hello world."
Java
15
star
19

openxc-ios-framework

OpenXC iOS framework for use with the C5 BLE device. Also see the openxc-ios-app-demo.
Swift
14
star
20

trace-analyzer

JavaScript visualization of OpenXC vehicle data traces
JavaScript
12
star
21

nxp-cdl

Fork with slight modifications to NXP's Common Driver Library, for LPCxxxx Microcontrollers
C
12
star
22

nightvision

Video-based object detection for forward collision warnings with OpenXC
Java
9
star
23

emqueue

An implementation of a queue in C that can support arbirtary element types.
C
9
star
24

arduino-transfer-benchmarking

Benchmarking USB and FTDI transfer rates on Arduino-compatible microcontrollers
C
8
star
25

openxc-ios-library

OpenXC iOS framework for use with the C5 BLE device. Example contains the OpenXC demonstration app that use all of the features of the OpenXC Framework.
Swift
8
star
26

nonstandard-android-measurements

Non-standard OpenXC Measurement and Unit types for Android
Java
7
star
27

emlist

A simple linked list in C for embedded applications
C
7
star
28

openxc-ios-app-demo

OpenXC demonstration app that use all of the features of the openxc-ios-framework. This can be a starting app for any OpenXC iOS application that wishes to use the C5 BLE device.
HTML
6
star
29

OpenXCAccessory

Contents of OpenXCAccessory directory on V2X and Modem devices
Python
6
star
30

shiftknob-android

Android application to control the OpenXC-enabled Haptic Shift Knob
Java
6
star
31

mpg

Java
5
star
32

openxc-c

C library to access data from an OpenXC vehicle interface
C
5
star
33

shiftknob-3Ddesign

3D design sources for the OpenXC-enabled Haptic Shift Knob
Perl
5
star
34

simple-hud

Firmware and Java connector for a Bluetooth-connected OpenXC module
Java
4
star
35

chipkit-vehicle-interface

Assembly instructions for a chipKIT-based OpenXC Vehicle Interface
CSS
3
star
36

smart-wiper

Java
3
star
37

openxc-data-tools

Python tools for OpenXC data analysis and visualization
Python
3
star
38

vi-windows-driver

Windows driver for USB OpenXC Vehicle Interface
3
star
39

rain

Android application to provide rain detection information to Weather Underground
Java
3
star
40

shiftknob-firmware

Embedded (Arduino) firmware for OpenXC-enabled Haptic Shift Knob
Arduino
2
star
41

MLA

Microchip Library Access for use on OpenXC vi-firmware
C
2
star
42

SimCrashDetection

Crash detection library for app testing purposes, triggers an event when crash is detected (currently crude algorithm)
Java
2
star
43

validation-android

Validation app used to verify signals from VI
Java
2
star
44

pixel-openxc-android

A smart brake light prototype using the pixelart board(http://ledpixelart.com/) utilizing the OpenXC platform (http://openxcplatform.com)
Java
2
star
45

shiftknob-hardware

Electrical schematics for the OpenXC-enabled Haptic Shift Knob
Ruby
1
star
46

EV_Coach_public

Continuation of the Ford EV Coach Efficiency Application Trainer
Java
1
star
47

SignalMonitor

Application to send all OpenXC signals only when a monitored signal crosses a designated threshold
1
star
48

nxp-bsp

Fork with slight modifications to NXP's Board Support Package, for LPCxxxx Microcontrollers
C
1
star
49

io-accessory

Open source schematics for a generic I/O extension for the OpenXC platform
1
star