All Projects → rzetterberg → elmobd

rzetterberg / elmobd

Licence: MIT license
A Go library for talking to cars over OBD-II

Programming Languages

go
31211 projects - #10 most used programming language
python
139335 projects - #7 most used programming language
Gherkin
971 projects
Nix
1067 projects

Projects that are alternatives of or similar to elmobd

awesome-automotive-can-id
🚜 unpretentious attempt to collect CAN IDs and payloads for various car brands/models in one place.
Stars: ✭ 104 (-25.18%)
Mutual labels:  automotive, obd2
iso15765-canbus
Implementation of ISO15765-2 in C
Stars: ✭ 36 (-74.1%)
Mutual labels:  automotive, obd2
ecu-simulator
OBD-II ECU Simulator
Stars: ✭ 24 (-82.73%)
Mutual labels:  obd2, obd-ii
QtDigitalInstrumentCluster
Qt OBD II Digital Instrument Cluster
Stars: ✭ 37 (-73.38%)
Mutual labels:  automotive, obd2
obdii
The repo contains the Python code developed for the Connected Car OSS work
Stars: ✭ 18 (-87.05%)
Mutual labels:  obd2
strados
Transform OBD2 data from your car into human readable data
Stars: ✭ 27 (-80.58%)
Mutual labels:  obd2
TractorHacking.github.io
Tractor Hacking GHPages
Stars: ✭ 34 (-75.54%)
Mutual labels:  automotive
carloop
Carloop OBDII reader
Stars: ✭ 21 (-84.89%)
Mutual labels:  obd2
piObdDashboard
WIP Dashboard application that collects and displays realtime car telemetry information such as speed, rpm, throttle, etc using a raspberry pi. A short clip of it running can be found here: https://www.youtube.com/watch?v=rTwZY9AT3mg&ab_channel=BrianChan
Stars: ✭ 33 (-76.26%)
Mutual labels:  obd2
vehicle signal manager
Vehicle Signal Manager to read, transform, and emit VSS signals based on configurable rules.
Stars: ✭ 12 (-91.37%)
Mutual labels:  automotive
Asap2
Asap2 parser.
Stars: ✭ 27 (-80.58%)
Mutual labels:  automotive
Firmware Over The Air
graduation project of ITI, flashing a new firmware over the air for automotive industry
Stars: ✭ 18 (-87.05%)
Mutual labels:  automotive
ldfparser
LIN Description File parser written in Python
Stars: ✭ 30 (-78.42%)
Mutual labels:  automotive
evDash
EV dashboard - software for small dev boards connected to the car via obd2 BLE4 or CAN bus.
Stars: ✭ 83 (-40.29%)
Mutual labels:  obd2
ELMduino
Arduino OBD-II Bluetooth Scanner Interface Library for Car Hacking Projects
Stars: ✭ 274 (+97.12%)
Mutual labels:  obd2
dreyeve
[TPAMI 2018] Predicting the Driver’s Focus of Attention: the DR(eye)VE Project. A deep neural network learnt to reproduce the human driver focus of attention (FoA) in a variety of real-world driving scenarios.
Stars: ✭ 88 (-36.69%)
Mutual labels:  automotive
multicycles
Multicycles.org aggregates on one map, more than 200 share vehicles like bikes, scooters, mopeds and cars. Demo APP for the Data Flow API, see https://flow.fluctuo.com
Stars: ✭ 84 (-39.57%)
Mutual labels:  cars
audiowagon
AudioWagon will play audio files from an attached USB flash drive in cars equipped with Android Automotive OS
Stars: ✭ 23 (-83.45%)
Mutual labels:  automotive
pyobd
pyOBDII remake - better than ever!
Stars: ✭ 115 (-17.27%)
Mutual labels:  obd2
BMWConnectedAnalysis
No description or website provided.
Stars: ✭ 24 (-82.73%)
Mutual labels:  automotive

README

https://img.shields.io/badge/status-active-green.svg https://travis-ci.org/rzetterberg/elmobd.svg?branch=master https://goreportcard.com/badge/github.com/rzetterberg/elmobd?status.svg https://godoc.org/github.com/rzetterberg/elmobd?status.svg

Version
0.8.0

Go library for communicating with cars OBD-II system using ELM327 based USB-devices.

To make this library as good as possible - feedback, bug reports and feature requests are very welcome in the GitHub issues of this project.

How it works

There are more than 10 different OBD-II signal protocol variations used by the various cars that exist. To avoid having to handle all the details of these protocols the ELM327 exists. The ELM327 acts a facade between the computer and the car. You talk to the ELM327 using a simple text based protocol similar to the Hayes command set and the ELM327 takes care of the communication details of the car.

docs/assets/overview-diagram.png

As shown in the diagram above this library connects to a serial device of the operating system. The library is not concerned with what is connected to that serial device, whether it’s a bluetooth USB-dongle with a ELM327 at the other end or a ELM327 connected directly via an USB-cable.

Communicating with the ELM327 is similar to communicating with a web server. You make a request and wait for a response. However, in this context we are calling a command and waiting for one or more responses.

This library is designed to be used in a way that resembles the way you physically use the device. You have a type called Device that represents a ELM327 device connected to the computer. This Device then has a function called RunCommand that sends a command to the actual device and then waits for a response.

This library aims to be as type safe as possible, which means that you don’t deal with raw text commands, instead you have different command types.

All command types need to implement the OBDCommand interface to be able to be run on the device. Since there are A LOT of OBD commands, you can easily extend this library, by just implementing the OBDCommand interface of your commands.

Let’s start by looking at some example of how you use the library.

Example usage

Note: these examples are performed on Linux. If you are using another platform there should be minimal changes, but they are not documented yet. Go ahead and put a 👍 on issue #11 if you think this should be prioritized.

First of all, you need to plug in your ELM327 device into your computer and get the path to the device. You can plugin the device and check dmesg, this is what I get on my computer:

$ dmesg | tail
[359720.858480] usb 6-2: Manufacturer: FTDI
[359720.858482] usb 6-2: SerialNumber: A503GJEX
[359720.897717] usbcore: registered new interface driver usbserial
[359720.897733] usbcore: registered new interface driver usbserial_generic
[359720.897748] usbserial: USB Serial support registered for generic
[359720.901755] usbcore: registered new interface driver ftdi_sio
[359720.901767] usbserial: USB Serial support registered for FTDI USB Serial Device
[359720.901839] ftdi_sio 6-2:1.0: FTDI USB Serial Device converter detected
[359720.901913] usb 6-2: Detected FT232RL
[359720.904481] usb 6-2: FTDI USB Serial Device converter now attached to ttyUSB0

Now that I know that the device is available at /dev/ttyUSB0 I can use the library to connect to the device and check the ELM327 version of the device:

example1.go

package main

import (
	"flag"
	"fmt"
	"github.com/rzetterberg/elmobd"
)

func main() {
	serialPath := flag.String(
		"serial",
		"/dev/ttyUSB0",
		"Path to the serial device to use",
	)

	flag.Parse()

	dev, err := elmobd.NewTestDevice(*serialPath, false)

	if err != nil {
		fmt.Println("Failed to create new device", err)
		return
	}

	version, err := dev.GetVersion()

	if err != nil {
		fmt.Println("Failed to get version", err)
		return
	}

	fmt.Println("Device has version", version)
}

Note: These examples uses the function NewTestDevice, which uses a mocked ELM327 device. To use a real ELM327 device, you instead use NewDevice. The reason why a mocked device is used is because the examples should be runnable without using a real device.

$ go run example.go
Device has version OBDII by [email protected]

The next step is to run some OBD commands on the device. For this we need to plug in the ELM327 into our car and turn on the ignition.

Like mentioned before you use the function RunCommand that accepts a OBDCommand to run. A OBDCommand has 3 responsibilities:

  • Tell the ELM327 what command to run
  • Store the value
  • Convert the value to a common format

So you start out by creating a new OBDCommand that does not contain a value. You then take that OBDCommand and call the RunCommand function with it. RunCommand will then return the OBDCommand with the value from the car.

Let’s try this out by checking the RPM of the engine. There is a OBDCommand for that defined in the library already, called EngineRPM. We start by creating a new EngineRPM that we call RunCommand with:

example2.go

package main

import (
	"flag"
	"fmt"
	"github.com/rzetterberg/elmobd"
)

func main() {
	serialPath := flag.String(
		"serial",
		"/dev/ttyUSB0",
		"Path to the serial device to use",
	)

	flag.Parse()

	dev, err := elmobd.NewTestDevice(*serialPath, false)

	if err != nil {
		fmt.Println("Failed to create new device", err)
		return
	}

	rpm, err := dev.RunOBDCommand(elmobd.NewEngineRPM())

	if err != nil {
		fmt.Println("Failed to get rpm", err)
		return
	}

	fmt.Printf("Engine spins at %s RPMs\n", rpm.ValueAsLit())
}

There are more than 180 different OBD commands, and cars have different support for these commands. So to avoid sending OBD commands to the car that it does not support we can check what commands the car support:

example3.go

package main

import (
	"flag"
	"fmt"
	"github.com/rzetterberg/elmobd"
)

func main() {
	serialPath := flag.String(
		"serial",
		"/dev/ttyUSB0",
		"Path to the serial device to use",
	)

	flag.Parse()

	dev, err := elmobd.NewTestDevice(*serialPath, false)

	if err != nil {
		fmt.Println("Failed to create new device", err)
		return
	}

	supported, err := dev.CheckSupportedCommands()

	if err != nil {
		fmt.Println("Failed to check supported commands", err)
		return
	}

	rpm := elmobd.NewEngineRPM()

	if supported.IsSupported(rpm) {
		fmt.Println("The car supports checking RPM")
	} else {
		fmt.Println("The car does NOT supports checking RPM")
	}
}

The supported here is a SupportedCommands which is a special type that stores the raw lookup table and exposes two helper functions that reads this table:

IsSupported
Check if given command is supported
FilterSupported
Filters out supported commands from given list

For simplicity there’s a function called GetSensorCommands which gives you a list of all the commands defined in the library. You can use this list of commands and filter out what commands are supported on by car:

example4.go

package main

import (
	"flag"
	"fmt"
	"github.com/rzetterberg/elmobd"
)

func main() {
	serialPath := flag.String(
		"serial",
		"/dev/ttyUSB0",
		"Path to the serial device to use",
	)

	flag.Parse()

	dev, err := elmobd.NewTestDevice(*serialPath, false)

	if err != nil {
		fmt.Println("Failed to create new device", err)
		return
	}

	supported, err := dev.CheckSupportedCommands()

	if err != nil {
		fmt.Println("Failed to check supported commands", err)
		return
	}

	allCommands := elmobd.GetSensorCommands()
	carCommands := supported.FilterSupported(allCommands)

	fmt.Printf("%d of %d commands supported:\n", len(carCommands), len(allCommands))

	for _, cmd := range carCommands {
		fmt.Printf("- %s supported\n", cmd.Key())
	}
}

Besides checking sensor values, you can also check whether the MIL is on and if there are any DTCs:

example5.go

package main

import (
	"flag"
	"fmt"
	"github.com/rzetterberg/elmobd"
)

func main() {
	serialPath := flag.String(
		"serial",
		"/dev/ttyUSB0",
		"Path to the serial device to use",
	)

	flag.Parse()

	dev, err := elmobd.NewTestDevice(*serialPath, false)

	if err != nil {
		fmt.Println("Failed to create new device", err)
		return
	}

	cmd, err := dev.RunOBDCommand(elmobd.NewMonitorStatus())

	if err != nil {
		fmt.Println("Failed to get monitor status", err)
		return
	}

        status := cmd.(*elmobd.MonitorStatus)

	fmt.Printf("MIL is on: %t, DTCamount: %d\n", status.MilActive, status.DtcAmount)
}

Please see the godocs for a more detailed explanation of the library and it’s structure.

Features

  • [X] Reading sensor data
  • [ ] Reading trouble codes
  • [ ] Resetting Check Engine Light
  • [ ] Reading freezed sensor data

Roadmap

The project uses quarterly milestones to plan upcoming changes. The current quarter will focus on implementing new features. To see the details of what will be done see the milestone 2018 Q3.

Changes of the library are tracked in the CHANGELOG.

Compability

Platforms

The library has been built and tested on the following platforms:

Operating systemGo version
Linux 4.9.25 x86_641.9

Cars

The library has been used successfully on the following cars:

CarLibrary versionTester
Lexus IS200 Manual 20040.3.0@rzetterberg
Ford Ka 20110.5.0@Enrico204
Ford Transit Automat 20190.6.0@mikspec
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].