GithubHelp home page GithubHelp logo

obd2-swift-lib's Introduction

OBD2 Swift

GitHub Release Swift Version GitHub Platforms GitHub license By

On-board diagnostics swift library.

Why do you need it?

OBD2?.. What?

OBD or On-board diagnostics is a vehicle's self-diagnostic and reporting capability. OBD systems give access to the status of the various vehicle subsystems. Simply saying, OBD-II is a sort of computer which monitors emissions, mileage, speed, and other useful data.

More details you can get here.

Ok. And what about this?

This is a library which can communicate with vehicles using OBD-II adapters. It is providing you with an opportunity for real-time vehicles diagnostics with several lines of code and without being nervous. The library will help you to connect with adapter and handle it's behaviour, like reconnect when something went wrong. And! You don't need to parse bytes response returned from adapter by yourself because OBD2 Swift will do it for your project.

Requirements

  • iOS 9.0+
  • Swift 3.0+
  • Xcode 8.0+
  • Mac OS X 10.0+

Features

  • Supporting next Modes with almost all their PIDs:
Mode Description
Mode 01(02) Sensors / Freeze Frame
Mode 03 Trouble Codes (DTC)
Mode 04 Reset Trouble Codes
Mode 09 Information
  • Real-time connection with OBD-II
  • OBD-II full described diagnostic sensors list
  • Observer of connection and other metrics
  • Several types of returning & requesting diagnostic response
  • Logger, which can save your logs into a file and share it

How to use?

Where to start?

First of all, create an OBD2 object for requesting vehicles metrics.

     let obd = OBD2()

Create a connection between your application and adapter.

โ— Remember that all callbacks return not in the main thread.

     obd.connect { [weak self] (success, error) in
             if let error = error {
                 print("OBD connection failed with \(error)")

             } else {
                 //perform something
             }
       }

Method connect would return you a response with an error if something went wrong and you can simply handle it, for example, show a message with reconnecting opportunity.

If all goes okay, you have a connection! ๐Ÿ˜Ž

Class OBD2 contain another methods for work with connection like pauseScan(), resumeScan() and stopScan() as well.

And what about getting metrics?

There is a simple way to get data from vehicle subsystems - to use requests. You can send it using request(_:) method of OBD2 object. Use struct Command for choosing what you want to request.

      obd.request(command: Command.Mode09.vin) { (descriptor) in
            let respStr = descriptor?.VIN()
            print(respStr ?? "No value")
        }

What if I want to get another response?

You can use request(_:) method with emun Custom: CommandType. It helps you to send and get data in digit and string format.

      obd.request(command: Command.Custom.digit(mode: 09, pid: 02)) { (descr) in
           if let response = descr?.response {
               print(response)
           } 
       }

Ok, but what about monitoring?

You can still use requests for doing this. There is a method request(repeat:) wich will send a request to OBD repeatedly.

     obd.request(repeat: Command.Mode01.pid(number: 12))

Where is a response?! ๐Ÿ˜ฑ

Response from this method will be returned to Observer. Choose Mode type and create an Observer object.

      let observer = Observer<Command.Mode01>()

Tell him to observe with specific PID number and enjoy responses. :]

      observer.observe(command: .pid(number: 12)) { (descriptor) in
          let respStr = descriptor?.shortDescription
          print("Observer : \(respStr)")
      }

โ— To bring Observer alive you must register it in ObserverQueue. It is needed for returning diagnostics responses.

    ObserverQueue.shared.register(observer: observer)

Don't forget to do unregister(_:) when you don't need Observer anymore.

How to stop it?

OBD2 object has method isRepeating(repeat:) wich takes Command as a parameter. Using it you can check if the specific command is repeating now and stop it.

       if obd.isRepeating(repeat: Command.Mode01.pid(number: 12)) {
           obd.stop(repeat: command)
       } 

Can I use observer for other requests?

Yep! Single request method can take Bool parameter notifyObservers wich is true by default. Using it you can manage which requests will return response not only in completion block but in observer block too.

Installation

Manually as Embedded Framework

  • Go to your project root git folder and clone OBD2 Swift as a git submodule by running the following command from the terminal.
$ git submodule add https://github.com/lemberg/obd2-swift-lib.git
  • Open obd2-swift-lib folder which was created. In the OBD2-Swift folder, you will found OBD2Swift.xcodeproj. Drag it into the Project Navigator of your project.

  • Select your project in the Xcode Navigation and then select your application target from the sidebar. After this, select the "General" tab and click on the + button under the "Embedded Binaries" section.

  • Select OBD2 Swift.framework from dialogue and that's all! ๐ŸŽ‰

Don't forget to do import OBD2Swift in classes where you want to use this framework

CocoaPods

To install it, simply add this line to your Podfile:

  pod "OBD2-Swift"

If you'll need, there is still a version written on Swift 3 named swift3.

Now you need to run pod update command from you project folder and that's it!

Author

Logo

License

OBD2 Swift is available under the MTI license. See the LICENSE file for more info.

obd2-swift-lib's People

Contributors

hellensoloviy avatar maxvitruk avatar overswift avatar sergiyloza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

obd2-swift-lib's Issues

Handling BUS INIT: ...ERROR

When I connect to the ELM327 device it sometimes gives me a bus init error like this BUS INIT: ...ERROR. This means I am connected to the device but the ECU will not accept commands. How do I handle this error state? The ignition is of course on.

Here is the full log

ELM327 v2.1
Write to OBD Optional("AT E0\r")
Wrote 6 bytes
Read 11 bytes
Read complete
AT E0
OK
Write to OBD Optional("AT I\r")
Wrote 5 bytes
Read 14 bytes
Read complete
ELM327 v2.1
Write to OBD Optional("01 00\r")
Wrote 6 bytes
Read 10 bytes
Read 1 bytes
Read 1 bytes
Read 1 bytes
Read 8 bytes
Read complete
BUS INIT: ...ERROR    <----------------------------------------
Set new pid group 0
Set new pid group 0
Write to OBD Optional("AT DP\r")
Wrote 6 bytes
Read 13 bytes
Read complete
ISO 9141-2
Set OBD protocol to Optional(OBD2.ScanProtocol.CAN29bit250KB)
------------------------------------
Successfully connected to OBD device
------------------------------------

Case "1D Oxygen sensors present" in Descriptor01 (calculateStringForData())

Method calculateStringForData(data:) in Descriptor01 class have some problems. Case 1D is returning an empty string.

    func calculateStringForData(data : Data) -> String? {
        switch pid {
        case 0x03:
            return calculateFuelSystemStatus(data)
        case 0x12:
            return calculateSecondaryAirStatus(data)
        case 0x13:
            return calculateOxygenSensorsPresent(data)
        case 0x1C:
            return calculateDesignRequirements(data)
        case 0x1D:
            return "" 
        case 0x1E:
            return calculateAuxiliaryInputStatus(data)
        default:
            return nil
        }
    }

As this article says

1D Oxygen sensors present (in 4 banks)

And it is almost like case 0x13, but there 4 banks instead of 2.
And I can see a not used method calculateOxygenSensorsPresentB() in Descriptor01. This method is very similar to calculateOxygenSensorsPresent() which used for case 0x13.

I recommend to use of to delete calculateOxygenSensorsPresentB() method, and fix case 0x1D.

AT commands always return NIL

Hi there, when I try to use an AT commando (like At.voltage), the Framework prints on the console the info, but looks like it doesn't store it on the DATA variable...

Set OBD protocol to Optional(OBD2.ScanProtocol.CAN29bit250KB)
Write to OBD Optional("AT RV\r")
Wrote 6 bytes
Read 10 bytes
Read complete
12.4V

Optional(OBD2.Response(timestamp: 2018-01-01 23:22:58 +0000, mode: OBD2.Mode.none, pid: 0, data: nil, rawData: [49, 50, 46, 52, 86, 13, 10, 0, 10, 62], strigDescriptor: nil))

Thanks...

Exception with demo app after AT DP\r

First of all, great work with the library!

I tried out the demo app, and when I press connect, it crashes after some time. The output from the the console says it connects and communicates, see debug output below:

Input stream opened
Output stream opened
isFinished true
isExecuting false
isFinished true
open operation completed without errors
Write to OBD Optional("AT WS\r")
Wrote 6 bytes
Read 16 bytes
Read complete


ELM327 v2.1
Write to OBD Optional("AT E0\r")
Wrote 6 bytes
Read 11 bytes
Read complete
AT E0
OK
Write to OBD Optional("AT I\r")
Wrote 5 bytes
Read 14 bytes
Read complete
ELM327 v2.1
Write to OBD Optional("01 00\r")
Wrote 6 bytes
Read 10 bytes
Read 1 bytes
Read 1 bytes
Read 1 bytes
Read 22 bytes
Read 2 bytes
Read complete
BUS INIT: ...OK
41 00 BE 3E B8 11 
Set new pid group 0
Set new pid group 0
Write to OBD Optional("AT DP\r")
Wrote 6 bytes
Read 13 bytes
Read complete
ISO 9141-2
(lldb) 

The breakpoint jumps to InitScanerOperation.swift:157 as shown in the screenshot below.

screenshot

Do you have any idea why it crashes? The debugger does not give much information.

/cheers

Connect Device ?

How to connect device using OBD II-swift-lib ? is it possible to connect without device ?

Issue installing the library

After cloning the repository, there is no OBD2Swift.xcodeproj in the OBD2-Swift folder.

How can I manually install the library?

OBD reconnect issue

Hi there,

Thanks so much for this awesome library, great work!

I think there is only one problem where the re-connection doesn't seem to work, every time after I done obd.disconnect() , I won't be able to connect back again unless unplugging the OBD dongle and put it back in.

By tracing the code found that the reconnect fail at InitScannerOperation where it return error "ELM error", I've tried different combination like pauseScan, stopScan, resumeScan doesn't seem to make any difference on this issue. Maybe I've missed something, could you help?

Thank you,
Jack Roderick

Is there a way to get raw data from request

Hi,
I am trying to get the list of available pids by requesting pid 0x00. However, there is no property of Mode01Descriptor or Response that provides the raw data. Is it possible to access raw data from a request using this library? If not, how can I access the list of available pids?

Thanks

let command = Command.Mode01.pid(number: 00)
obd.request(command: command) { [weak self] (descriptor) in
OperationQueue.main.addOperation {
if let response = descriptor?.response {
// Parse response
}
}
}

Custom comand. How to get string data from Descriptor or Response?

Hi all!

Thanks for a great OBD lib.
I just start investigate it and I have a question:

For example I want to get car temperature, using custom comand:

 obd.request(command: Command.Custom.digit(mode: 01, pid: 05)) { (descr) in
           if let response = descr?.response {
               print(response)
           } 
       }

In logs I recieve such data:

Write to OBD Optional("01 05\r")
Wrote 6 bytes
Read 10 bytes
Read 10 bytes
Read 2 bytes
Read complete
41 05 80
41 05 81

Using lib I receive descriptor:
from descriptor I can get Response.
What next steps???
How can I get such command : 41 05 80 ??

screen shot 2017-11-21 at 6 59 37 pm copy

desc?.gerResponse = nil

I can get only : desc.response
But : Response has interface:
public var strigDescriptor: String?
public static func ==(lhs: Response, rhs: Response) -> Bool
public var hasData: Bool { get }

Install Issues

Attempted the CocoaPods installation but had too many issues with the installation. Then focused on attempting to follow the embedded framework installation, this is where the issues started to become clear, in the main folder there is no 'OBD2Swift.xcodeproj' file however there was one with the same name in the Example folder which I decided to use and continue. I proceeded with the install instructions and went to add the 'OBD2 Swift.framework' to the embedded binaries but cannot find the file anywhere. I also attempted to open the example project and run it as is, but it still failed to have a working import.

'import OBD2_Swift'

This was the import written in the example file so I also tried to change it to 'OBD2Swift' as listed in the installation instructions, but it did not fix anything. Could someone please help attempt to fix the issue so I can use this framework in my product.

Blocked in .openingConnection when re-connecting OBD

Hi @MaxVitruk I encountered an issue about re-connecting OBD. Could you please help?

Issue:

It's OK to connect -> disconnect -> connect -> ... ->connect without any OBD request in between.
But if I trigger some repeated request, i.e. engine speed, then disconnect and connect, it will fail to re-connect and be blocked in .openingConnection state.

I did a little debugging, looks like OpenOBDConnectionOperation not executed when re-connect. Maybe the repeated requests still in the obdQueue, blocking OpenOBDConnectionOperation to be executed.

Steps to reproduce:

  1. Connect - OK
  2. Disconnect - OK
  3. Connect - OK
  4. Repeat requests 01 0C and 01 05 - OK
  5. Disconnect - OK
  6. Connect - Failed and blocked at .openingConnection state

Detailed logs:

-------> Connecting OBD
isExecuting true
-------> OBD current state: .openingConnection
Input stream opened
Output stream opened
isExecuting false
isFinished true
isFinished true
-------> OBD current state: .initializing
open operation completed without errors
Write to OBD Optional("AT WS\r")
Wrote 6 bytes
Read 16 bytes
Read complete


ELM327 v1.5
Write to OBD Optional("AT E0\r")
Wrote 6 bytes
Read 11 bytes
Read complete
AT E0
OK
Write to OBD Optional("AT I\r")
Wrote 5 bytes
Read 14 bytes
Read complete
ELM327 v1.5
Write to OBD Optional("01 00\r")
Wrote 6 bytes
Read 19 bytes
Read 2 bytes
Read complete
41 00 BE 1F A8 13 
Set new pid group 0
Set new pid group 0
Write to OBD Optional("AT DP\r")
Wrote 6 bytes
Read 27 bytes
Read complete
ISO 15765-4 (CAN 11/500)
Set OBD protocol to Optional(OBD2.ScanProtocol.CAN29bit250KB)
-------> OBD current state: .connected
-------> Connection success
-------> Disconnect OBD
-------> OBD current state: .none
-------> Connecting OBD
isExecuting true
-------> OBD current state: .openingConnection
Input stream opened
Output stream opened
isExecuting false
isFinished true
isFinished true
open operation completed without errors
Write to OBD Optional("AT WS\r")
-------> OBD current state: .initializing
Wrote 6 bytes
Read 16 bytes
Read complete


ELM327 v1.5
Write to OBD Optional("AT E0\r")
Wrote 6 bytes
Read 11 bytes
Read complete
AT E0
OK
Write to OBD Optional("AT I\r")
Wrote 5 bytes
Read 14 bytes
Read complete
ELM327 v1.5
Write to OBD Optional("01 00\r")
Wrote 6 bytes
Read 19 bytes
Read 2 bytes
Read complete
41 00 BE 1F A8 13 
Set new pid group 0
Set new pid group 0
Write to OBD Optional("AT DP\r")
Wrote 6 bytes
Read 27 bytes
Read complete
ISO 15765-4 (CAN 11/500)
Set OBD protocol to Optional(OBD2.ScanProtocol.CAN29bit250KB)
-------> OBD current state: .connected
-------> Connection success
Write to OBD Optional("01 0c\r")
Wrote 6 bytes
Read 13 bytes
Read 2 bytes
Read complete
41 0C 0A 34 
Request operation completed
Observer : Optional(OBD2.Mode01Descriptor)
Write to OBD Optional("01 05\r")
Wrote 6 bytes
Read 10 bytes
Read 2 bytes
Read complete
41 05 86 
Request operation completed
Write to OBD Optional("01 0c\r")
Wrote 6 bytes
Read 13 bytes
Read 2 bytes
Read complete
41 0C 0A 44 
Observer : Optional(OBD2.Mode01Descriptor)
Request operation completed
Write to OBD Optional("01 05\r")
Wrote 6 bytes
Read 10 bytes
Read 2 bytes
Read complete
41 05 86 
Request operation completed
Write to OBD Optional("01 0c\r")
Wrote 6 bytes
Read 13 bytes
-------> Disconnect OBD
-------> OBD current state: .none
-------> Connecting OBD
-------> OBD current state: .openingConnection

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.