OBD or On Board Diagnostics and OBD-II is a standard for communicating and reading data from a car, its standard across most modern cars and the likelihood is you have a connector in your car which you can read all sorts of data about the car such as RPM, Speed, Temperature and a million other things you wouldn't guess a car was monitoring.
Update - I've taken this prototype to the next stage and used the OBD data to overlay mph, rpm, temperature and throttle position over video taken with the camera board.
I got hold of a USB to OBD2 interface cable for about £10. Pick one up from amazon.com or amazon.co.uk.
I then took a fork of salgar's software from his github repository, https://github.com/roflson/pyobd, as the basis for my program. salgar's software is a fork from a project called pyobd, https://github.com/peterh/pyobd, which is a GUI based application for reading OBD-II data.
I used this as the basis for a program which would connect through OBD-II interface, 'ask' the car which sensors it supported and then read the data sensors in a loop every 0.5 second and write them to the screen.
I see this as step one in a project to log data about a car for other uses.
Download and run
You can download the code direct from github, https://github.com/martinohanlon/pyobd, so open a terminal and follow the instructions:
sudo apt-get install python-serial
sudo apt-get install git-core
cd ~
git clone https://github.com/martinohanlon/pyobd
cd pyobd
python obd_capture.py
sudo apt-get install git-core
cd ~
git clone https://github.com/martinohanlon/pyobd
cd pyobd
python obd_capture.py
:O That is so cool! Maybe you can control the car with Raspberry Pi!
ReplyDeleteThat'll take a lot more work! I'll put it on the list tho.
DeleteImagine what people could do with Raspberry Pi-powered cars... Heck, why not houses?? Snap of your fingers, you house lights up. xD
DeleteThere are loads of raspberry pi home automation projects, just google it.
DeleteIt works for volkswagen's car too?
ReplyDeleteLook interesant!!
I'm also intrested, because vag group use a can bus obd... I have a seat ibiza...
DeleteThe reader I got says it supports any OBD-II standard including CAN. Exactly the same setup works on a BMW 3 Series.
DeleteIt works well for Skoda so obviously VW
DeleteI've managed to communicate with JLR cars with a raspberry Pi and SPI connected can analysis board. No GUI on it as such but has the ability to listen and broadcast CAN packets.
ReplyDeletethere is a similar project on going at http://awards.xee.com; main difference being the iPhone notification!
ReplyDeleteI have a Bluetooth adapter that I currently connect with my Nexus 4 and the "Torque" app- If I was to add a Bluetooth adapter to my Pi would it be able to see and connect in the same way?
ReplyDeleteWith one of these: http://learn.adafruit.com/adafruit-ultimate-gps-on-the-raspberry-pi it looks like I'd be able to get the same functionatlity as the torque/Android combination I currently use right?
I dont know much about Torque, but if the bluetooth adapter appears as a serial device, then I dont see a reason why it wouldnt work.
DeleteHi Edge
DeleteDid you manage to get this working? I have been doing some testing today and I can pair my pi with a bluetooth dongle to my phone but torque is unable to find the obd2 through the pi. There are obd2 adaptors with bluetooth built in on ebay but I would like to do some messing around with the data on the pi as well as through torque which would be more for quick diagnostics.
Another question,can you show us an example of the output?
ReplyDeleteI want to modify the script for redirecting the output also to a file, and it would be great if it will be in some kind of csv format...
If you download the repository from github and look at salgar's original program obd_recorder.py, that is exactly what this does - writes the out of a limited number of sensors to a csv file. I've got other plans, getting data out was just my first step.
DeleteHey Martin, great program man! (and to be fair, thanks to those who did work before you) I tried this python script previously on my mac, before realizing that it would be impossible (at least for me) to get it running because of sandboxing. Now I have a pi and a small screen installed in my car, and I can monitor rpm continuously. My next step will be to build a nice gui to give me a sweet revcounter, as my care doesn't have one, and then I'll be soo happy :D
Deletevery cool! i'll try it...
ReplyDeletecould i do this with a arduino uno? or beaglebone black ?
ReplyDeleteNo idea, but probably.
DeleteHi, i'm getting this error:
ReplyDeleteFile "/home/pi/pyobd/obd_io.py", line 25, in
import serial
ImportError: No module named serial
There are some other module to install?
Yes, you need to install pyserial. Google it.
DeleteIll update the post in a while with some instructions.
Solved with sudo apt-get install python-serial
DeleteHowever is not working, it only read 2 data from the car, and i don't know what they are.
i'm not sure if it's the software or the car (Seat Ibiza), i will try with a windows pc.
When you say 2 data, do you mean it only picks up 2 sensors? Could you paste the log, so I could have a look?
DeleteWOW amazing project! i was looking to do this someway! i was wondering can you use this to extract error codes from the car or does this only show RPM, temperature etc?
ReplyDeleteYes, its just a question of sending different commands through the obd interface to the car. Check out the obd2 page on Wikipedia there's a good summary of the commands.
ReplyDeleteHey Martin I just had a go at this using my pi and obd2 and testing via putty from in the house whilst the car ran outside. The script was running fine picking up sensors but then hit this error. I assume there is some invalid code coming out?
ReplyDeletesupported sensor index = 21 o212
supported sensor index = 28 obd_standard
supported sensor index = 31 engine_time
supported sensor index = 32 engine_mil_time
boguscode?7F 12
Traceback (most recent call last):
File "obd_capture.py", line 86, in
o.capture_data()
File "obd_capture.py", line 68, in capture_data
(name, value, unit) = self.port.sensor(sensorIndex)
File "/home/pi/pyobd/obd_io.py", line 226, in sensor
r = self.get_sensor_value(sensor)
File "/home/pi/pyobd/obd_io.py", line 215, in get_sensor_value
data = sensor.value(data)
File "/home/pi/pyobd/obd_sensors.py", line 58, in sec_to_min
code = hex_to_int(code)
File "/home/pi/pyobd/obd_sensors.py", line 26, in hex_to_int
i = eval("0x" + str, {}, {})
File "", line 1
0x
^
SyntaxError: invalid token
or a code which the pyobd program is not setup to understanding. Time for some debugging maybe!
DeleteAwesome! Do you know of any hardware to interface directly with a car/bike? Like read rpm from the reverse coil? Or is that what the obd 2 is? I'm thinking of older cars without an onboard computer.
ReplyDeleteOBD 2 can do this, but for older cars / bikes which dont support it you are going to need something different. I've never had the need to look for one, but Im sure such a sensor exists.
DeleteMartin, excellent write-up. Have tried this but get the error detailed below, would you know why..? Thanks.
ReplyDeleteError:
Opening interface (serial port)
Interface successfully /dev/ttyUSB0 opened
Connecting to ECU...
atz response:ELM327 v1.5
ate0 response:ate0OK
0100 response:CAN ERROR
Connected to /dev/ttyUSB0
Traceback (most recent call last):
File "obd_capture.py", line 86, in
o.capture_data()
File "obd_capture.py", line 39, in capture_data
self.supp = self.port.sensor(0)[1]
File "/home/pi/pyobd/obd_io.py", line 226, in sensor
r = self.get_sensor_value(sensor)
File "/home/pi/pyobd/obd_io.py", line 215, in get_sensor_value
data = sensor.value(data)
File "/home/pi/pyobd/obd_sensors.py", line 109, in hex_to_bitstring
v = eval("0x%s" % i)
File "", line 1
0xR
^
SyntaxError: invalid token
You seem to be getting a response from the request to ask OBD what sensors are being supported that cant be converted from hex to a bitstring (e.g. 0x1A to 0010101010101).
DeleteIf you want to and see if you can move forward, modify the code to remove the stuff which finds the supported and unsupported sensors and hard code the supported sensor list. e.g. supportedSensorList = ["rpm", "speed", "temp"].
Hi, I got the same error
Deleteate0 response:ate0OK
0100 response:CAN ERROR
File "", line 1
0xRROR
^
SyntaxError: invalid token
I tried change supportedSensorList but still not working. Any help? Thanks.
I keep getting the same error. It breaks because of the result "CAN ERROR". I can't seem to find what this error means.
DeleteI have added a simple
if data == "CAN ERROR":
return "CANERROR"
to get_sensor_value() in obd_io.py which stops the script from breaking. After that it just shows the time but no sensor values. Any idea what the problem could be?
Sorry guys. I can only guess that car manufacturers implementation of the OBD2 standard isn't always 'standard'!
DeleteThis was really simple to follow, great stuff. However I've got a similar problem to the one above I'm afraid. Do I need to manually configure the supportedSensorList as well or might this be something else.
ReplyDelete['/dev/ttyUSB0']
Opening interface (serial port)
Interface successfully /dev/ttyUSB0 opened
Connecting to ECU...
atz response:atzELM327 v1.5
ate0 response:ate0OK
0100 response:41 00 98 18 80 01 41 00 98 3B 80 19
Connected to /dev/ttyUSB0
Traceback (most recent call last):
File "obd_capture.py", line 86, in
o.capture_data()
File "obd_capture.py", line 49, in capture_data
self.unsupportedSensorList.append([i+1, obd_sensors.SENSORS[i+1]])
IndexError: list index out of range
Its difficult to be sure, but I think you are getting an error due to OBD reporting more sensors than the exist in the pyobd SENSORS list. You could also hardcode the sensors to monitor and do away with this bit of code, or change it to handle the error.
DeleteI was having this same issue! The first thing I did was print out the size of the entire sensorlist and a counter to see where it was stopping using:
Deleteprint(len(self.supp))
This showed me that it was stopping at index 33 of self.supp. yet for some reason its length would print out as 80. I just changed the loop to run from 0 till 32(length of the sensor[] in obd_sensors.py and everything is perfect.
'for i in range(0, 32):' instead of 'for i in range(0, len(self.supp)):'
If anyone can explain this I would love to know! Good Luck!
I see, I suspect what is happening is that your car is returning the string of zero's and one's representing the supported sensors but it is padding it with whitespaces up to the maximum, which presumably is 80.
Deletean you read the error codes too if so how?
ReplyDeleteI dont read the error codes in this example, but I think you can, the obd_io class in obd_io.py has a method called get_dtc() which looks like it should return the Diagnostic Trouble Codes (DTC). Have a go let me know how you get on. There is also a class called pcodes in obd2_codes.py which provides a dictionary of codes and descriptions.
Deleteok thanks
DeleteGM has it's own special unicorn blood codes that the guys at Autozone can never read with their code readers any chance someone with this setup has a GM?
ReplyDelete'05 Saturn Vue here...
I am curious to know if I can add sensors to be supported. Since the list of sensors is written out in obd_sensors.py like this: ' Sensor("rpm" , " Engine RPM", "010C1", rpm ,"" )'
ReplyDeleteHow would I find this information for other sensors? For example if my car had a sensor for bumper temperature, would I be able to add it? How?
Have a read of http://en.wikipedia.org/wiki/OBD-II_PIDs it describes all the sensors (parameter ids) which are in the standard, although they may not all be supported by a car.
ReplyDeleteThere are also non standard pids which tend to be proprietary to each manufacturer and there is usually very limited information about them, however i beleive that even they are readable by the same hardware its just whether you can find out how and how to interpret the result
Thanks! ^_^
DeleteDId you get any 'NameError: name 'DATAERROR' is not defined' problems when you were testing this out?
ReplyDeleteNo sorry i didnt see that error, have you got any more info? When does the error occur, could you cut and paste the whole error message?
DeleteI'm afraid I don't have the full error handy (though sometimes DATAERROR would be followed by some numbers, like DATAERROR410303 for instance). The error seemed to originate from def get_sensor_value on line 215, I suppose the script can't handle whatever my car (2001 Mustang GT) is returning, what do you think?
DeleteHi Martin,
ReplyDeleteI'm excited to use this code. I never wanted a UI anyway I just want to log to a file and mine it later. I'm getting an SSL error when I try to clone the git repo:
error: SSL: certificate subject name (*.opendns.com) does not match target host name 'github.con' while accessing https://github.con/martinohanlon/pyobd/info/refs
fatal: HTTP request failed
ideas? Thanks,
--Mike
github.coN rather than github.coM looks kind of suspicious, is this just a typo or have you copied the url incorrectly?
DeleteI have the same OBD II reader except its the bluetooth version, I am having no luck connecting it. I have paired it and set it as a serial device. When I run the program all I am getting is "Not connected". Any tips ...?
ReplyDeleteOther than checking the simple stuff like making sure you have got the right serial device, no not really, i have tried to do this with a bluebooth device.
DeleteI have made quite a few modifications to the project you made available such as support and interpretation of more sensors, this was a very fun project. But there is one thing that I cannot seem to get; How do I tell the make/model of the vehicle via OBDII?
ReplyDeleteSo far I have not been able to find any documentation regarding this feature. It must be possible. Any suggestions?
This would be greatly helpful so that I could create a database of vehicles and their drivers based on make/model/VIN.
DeleteAccording to wikipedia, you should be able to get VIN using Mode $09:
Deletehttp://en.wikipedia.org/wiki/On-board_diagnostics#OBD-II
Mode $09 is used to retrieve vehicle information. Among others, the following information is available:
- VIN (Vehicle Identification Number): Vehicle ID
Would you mind sharing your code?
Thank you! I will share my code as soon as my project is wrapped up.
DeleteHi Martin,
ReplyDeleteI'm getting this error, do you know how it can be fixer ? :
pi@raspberrypi ~/pyobd $ python obd_capture.py
Traceback (most recent call last):
File "obd_capture.py", line 81, in
o.connect()
File "obd_capture.py", line 18, in connect
portnames = scanSerial()
File "/home/pi/pyobd/obd_utils.py", line 9, in scanSerial
s = serial.Serial(i)
File "/usr/local/lib/python2.7/dist-packages/serial/serialutil.py", line 282, in __init__
self.open()
File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 289, in open
self.fd = os.open(self.portstr, os.O_RDWR|os.O_NOCTTY|os.O_NONBLOCK)
OSError: [Errno 2] No such file or directory: '/dev/ttyS0'
Thanks a lot
Your getting the error because the serial port ttyS0 isnt setup properly.. Why is a totally different question!
DeleteHey I'm having the same issue and struggling to fix it, any ideas?
DeleteIf you're having problems with the Serial port setup I would recommend following this link on Debian's forums. It really helps to explain the process and utilization of the correct commands for setting up and linking the USB to any Serial port you would like to use. http://forums.debian.net/viewtopic.php?f=16&t=61943
DeleteHi, love your OBDII project. I have really only just stumbled across the PI . such a wonderful creation, man if only we had this back when I was at college, instead of messing about with duff circuits & stuff that would take 90% of time to get functioning and 10% of the lesson to do some simple task.
ReplyDeleteI wondered with your Pi OBDII reader , given that it has a Lan port, - would it be possible to have it connected via a smartphone to the web and then write the obd readings at intervals while you are driving the car on the track into a SQL table on the web. which then could be viewed by someone logged on to the SQL table (and wizzy interface) (on their laptop or phone at the side of the track) That would be interesting.
It certainly sounds possible.
DeleteAwesome btw I am planing to have a sound activation in the system .. am not sure where to start , unlock the car .. do u think it is plausible?
ReplyDeleteIt certainly sounds plausible to unlock the car, providing you can hook into the unlock mechanism. I suspect on older cars, this will be much easier than modern. So in summary, it probably depends on the car.
DeleteHi Martin, can you please help me with my connection. When I try to record the data i get the following error. Can you please help me.
ReplyDeleteOpening interface (serial port)
Interface successfully /dev/ttyUSB0 opened
Connecting to ECU...
Got nothing
Got nothing
Got nothing
Got nothing
Got nothing
atz response:atz
Got nothing
Got nothing
Got nothing
Got nothing
Got nothing
ate0 response:ate0
Got nothing
Got nothing
Got nothing
Got nothing
Got nothing
0100 response:0100
Traceback (most recent call last):
File "obd_capture.py", line 81, in
o.connect()
File "obd_capture.py", line 29, in connect
print "Connected to "+self.port.port.name
AttributeError: 'Serial' object has no attribute 'name'
Regards from Munich...
Its not an error I have seen before... Have you got the latest version of software, particularly pySerial? You could just comment out that line and see if it continues, its only a debug line to show which serial port you are connected too.
DeleteHi Martin,
ReplyDeleteThis project is awesome! I have just set it up in my car and the OBDII USB is all talking, but all I get is a running datestamp without the data. Looking at your write-up on the video overlay I can see your example csv file matches mine minus the data! Is it possible my car isn't talking or that I don't have the right pid codes? I'd expect to see something more that just datestamps, jibberish even?
Help much appreciated! Your work is awesome!
I wonder if the program is running but the OBD-II interface isnt returning any sensors on the supported sensors PID.
DeleteIf you look at the obd_capture.py program, there is a line which says:
print "supported sensor index = " + str(supportedSensor[0]) + " " + str(supportedSensor[1].shortname)
Does this print anything?
Cheers for the reply Martin, no that doesn't appear. The output is this:
Delete['/dev/ttyUSB0']
Opening interface (serial port)
Interface successfully /dev/ttyUSB0 opened
Connecting to ECU...
atz response:atzELM327 v1.5
ate0 response:ate00K
0100 response:NO DATA
Connected to /dev/ttyUSB0
11:25:9.14550
[date stamps continue thereafter]
I'm guessing the atz and ate response are showing the ECU is talking in a basic sense, but the 0100 response is what's throwing things off?
Any help very welcome!
I just wanted to say thank you for taking time to share your knowledge here.
ReplyDeleteThe project is great and very imaginative.
I've been looking to do the same with my car but didn't think the software would be available for my RPi B+.
All I want to do is read off the CAN bus for the speed of vehicle date and then also use the Pi to display the speed onto a 8 segment LED matrix (in effect a word length).
Now that I can see a way of doing it, by adapting your code I will give it a go soon.
Once again, many grateful thanks for your work.
M.
I am doing research about the HHO gas produced via water electrolysis. This is for increase mileage and cut emissions. But to accomplish this one needs to manipulate the signals form MAP, IAT, lambda O2, coolant, etc... Now i am doing all this just with potentiometers. Also i use a PWD to control amps to the cell. It would be very neat to integrate all this in just one Pi !!
ReplyDeleteWill this work on a Wi-Fi OBD reciever too?
ReplyDeleteNo idea! Whats the interface to the Wifi OBD receiver?
DeleteI've got an ElM 327 Wifi unit and I chose it over a bluetooth one due to the higher transfer speeds but it's really becoming an issue due to there being little to no support for me :(
DeleteI have this one: http://www.amazon.co.uk/Stoga-Wirless-scanner-Diagnostic-Scanner/dp/B00WERYISW/ref=sr_1_4?ie=UTF8&qid=1452254119&sr=8-4&keywords=wifi+obd
This is the one I used, a cheap wired usb module. http://www.amazon.co.uk/ELM327-USB-Interface-Diagnostic-Scanner/dp/B00IWLLX1Y/ref=sr_1_4?ie=UTF8&qid=1452255036&sr=8-4&keywords=usb+obd2+cable
DeleteHi Martin,
ReplyDeleteCan you help me with the error that i've encountered here.
Error is -:
madan@madan:~/pyobd$ python obd_capture.py
Traceback (most recent call last):
File "obd_capture.py", line 3, in
import obd_io
File "/home/madan/pyobd/obd_io.py", line 270
for i in range(0, ((dtcNumber+2)/3)):
^
SyntaxError: invalid syntax