Device::ELM327 - Methods for reading OBD data with an ELM327 module.
Version 0.11
This module provides a Perl interface to a device containing an Elm Electronics ELM327 OBD Interpreter and provides access to the following functions:
Read OBD parameters and extract individual values from results. Read OBD Trouble Codes and expand them to their full form. Reset OBD Trouble Codes. Read ELM327 parameters. Write and write the ELM327 data byte. Calibrate ELM327 Voltage. Switchable diagnostic trace and replay function for debugging.
The module is written entirely in Perl and works with both Linux and Windows. Depending on which operating system it is run on it uses either the Win32::SerialPort or Device::SerialPort module (which you'll need to install first) so it should work on any platform that supports one of them.
use Device::ELM327; my $obd = Device::ELM327->new(); # Read status information... $obd->Show("ELM identity"); $obd->Show("Vehicle Identification Number"); $obd->Show("Engine RPM"); $obd->ShowTroubleCodes(); undef $obd;
To open the device and have it search for an ELM module:
my $obd = Device::ELM327->new();
If you know the port name (e.g. 'COM5', '/dev/ttyUSB7' etc) it may be quicker to pass it into the function:
my $obd = Device::ELM327->new($port_name);
To override the default serial port settings (38400, no parity, 8 data bits, 1 stop bit, no handshaking), you can pass values with or instead of the port name:
my $port_details = "/dev/ttyUSB0:115200:none:8:1:none"; my $obd = Device::ELM327->new($port_details);
The port name may be left out:
my $port_details = "115200:none:8:1:none";
It is also ok to just define the port name and/or baud rate and use default values for parity, data bits, stop bits and handshake:
my $port_details = "/dev/ttyUSB0:115200";
or
my $port_details = "115200";
If you want extra debugging information, it can be enabled by setting $debug_level to a positive number in the range 1 to 3, with more information being displayed as the number increases:
my $obd = Device::ELM327->new($port_name, $debug_level);
A value of either undef or "" can be passed for the $port_name:
my $obd = Device::ELM327->new("", $debug_level);
The module can replay previously captured debugging information:
my $obd = Device_ELM327->new(undef, $debug_level, $replay_filename);
To produce a file containing replayable data simply set $debug_level to 1 or higher and pipe the output to a text file:
perl test.pl>test_output.txt
Returns 1 if the serial port and ELM module are working or 0 if no ELM device could be connected to.
$obd->PortOK();
Displays the list of values that can be read from the ELM/ECU.
$obd->ShowReadableValues();
When passed the name of an OBD value (e.g. "Engine RPM") in $value_name, it displays the address of the ECU which returned the value, the name of the value which was read or the name of one of many parameters returned followed by the value and the name of any unit associated with the value.
If an error occurred, a message will be displayed instead.
$obd->Show($value_name);
This function calls the 'Read' function.
When passed the name of an OBD value (e.g. "Engine RPM") in $value_name, it returns a reference to a structure containing a status flag and any responses:
my $response = $obd->Read($value_name); if ($response->{'status'} eq "ok") { foreach my $result (@{$response->{'results'}}) { print "$result->{'address'} - $result->{'name'}: $result->{'value'} $result->{'unit'}\n" } }
In the example above, $result->{'address'} contains the address of the ECU which returned the value, $result->{'name'} contains the name of the value which was read or the name of one of many parameters returned. $result->{'value'} and $result->{'unit'} contain the value and the name of any unit associated with the value.
Error conditions are indicated by a value of $response->{'status'} other than 'ok' and an expanded error message in $response->{'status_message'} (the default is 'No errors detected' when there is no error).
Error Meaning ok No errors detected Zero length response No data was returned by the ECU NO DATA A 'NO DATA' response was returned by the ELM STOPPED A 'STOPPED' response was returned by the ELM Port not ok The connection to the ELM module failed Negative response The vehicle returned a negative response Unsupported name The vehicle does not support this value Unrecognised name ELM327.pm does not recognise this value
Display any trouble codes on the console:
$obd->ShowTroubleCodes();
Clear any Trouble Codes and sensor data:
$obd->ClearTroubleCodes();
Note that clearing the sensor data will cause the vehicle to run on default values until it has recalibrated itself. This may affect performance and fuel economy.
The ISO specification also insists that any user interface which invokes this function should display an "are you sure?" message to the user before calling it.
Expand a trouble code (e.g. 4216) to the full ISO code (C0216)
This function is called by 'Read'.
$decoded_code = $obd->DecodeTroubleCode($code);
Changes the calibration value used by the ELM module. The value $Voltage is a string containing a fixed point value of the form: xx.xx, e.g "11.99", "12.01" etc.
$obd->CalibrateVoltage($Voltage);
The Voltage can be read by calling:
my $response = $obd->read("Input Voltage");
Resets the ELM module's Voltage calibration to the factory setting:
$obd->ResetVoltage();
Writes $byte_value to the ELM module's non-volatile storage area.
$obd->WriteStoredDataByte($byte_value);
The value of this byte can be read using:
$obd->Read("Stored data byte");
Send a command to the ELM, read any response and decode it if was an ECU command. AT command responses are placed in the $self->{'response'} array. Responses to ECU commands are written to the $self->{'results'} structure. On return a status of 0 indicates no errors.
This function is called by other module functions 'Read', 'ClearTroubleCodes' etc., but can be used to send commands that aren't otherwise supported.
$status = $obd->Command($command_string);
Returns a value from the last set of results from the ELM/ECU
$type can be one of the following: bool (1 bit), byte (8 bit), word (16 bit), dword (32 bit) or string. $number is the zero-based index into the array of results and takes the type into account such that $number=0 returns the first byte, word or dword and $number=1, returns the second. Booleans are treated the same as bytes and require individual bits to be extracted separately. For strings, $number is the offset of the start of the string.
$obd->GetResult($type, $number);
Write a command to the serial port unless replay is in progress.
This function is called by the 'Command' function.
$status = $obd->WriteCommand($command_string);
Read the ELM's response from the serial port and put each line into the $self->{'response'} array. Turn on debugging for a dump of the response array.
$status = $obd->ReadResponse();
Decode the ECU response (in the $self->{'response'} array) and write the result to the $self->{'results'} structure.
$status = $obd->DecodeResponse();
Get the results for command 06 on a CAN system.
This function is called by 'Read' and is not intended to be called by other functions.
$obd->GetResultsCommand06_CAN($results_reference);
Try to find an ELM module on a COM port. If $port_details contains the name of a port, start with that one and work upwards.
To override the default serial port settings (38400, no parity, 8 data bits, 1 stop bit, no handshaking), you can pass values in $port_details in the following format:
port_name:baud_rate:parity:data_bits:stop_bits:handshake
e.g.
$port_details = "/dev/ttyUSB0:115200:none:8:1:none";
$port_details = "115200:none:8:1:none";
$port_details = "/dev/ttyUSB0:115200"; or $port_details = "115200";
This function is called by 'new'.
$obd->OpenPort($port_details);
Set up the ELM module to return data in the required form.
This function is called by 'new' and should not be called again.
$obd->ConfigureDevice();
Query the ECU to find out which commands are supported and annotate the value entries in the 'get' structure with the 'available' flag set to 0 (not supported) or 1 (supported).
$obd->FindAvailableCommands();
This function is called by 'FindAvailableCommands' and should not be called by any other functions.
$obd->ProcessAvailableCommands($command);
Process a file containing debugging output and replay the commands through the module.
This function is called by 'new' and should not be called by other functions.
$obd->Replay($replay_filename);
Alister Perrott, <aperrott at cpan.org>
<aperrott at cpan.org>
Please report any bugs or feature requests to bug-device-elm327 at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Device-ELM327. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-device-elm327 at rt.cpan.org
Please also include a debug trace showing the error so that I can replay your vehicle data and see exactly what you're seeing. This can be done by setting $debug_level in the constructor to 1 and piping the output to a file. e.g. perl myOBD.pl&>trace.txt
You can find documentation for this module with the perldoc command.
perldoc Device::ELM327
You can also look for information at:
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Device-ELM327
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Device-ELM327
CPAN Ratings
http://cpanratings.perl.org/d/Device-ELM327
Search CPAN
http://search.cpan.org/dist/Device-ELM327/
My ELM327 page
http://gts-ltd.co.uk/ELM327.php
Many thanks to: The authors of Win32::SerialPort and Device::SerialPort. Kedar Warriner and Thomas Kaiser for their suggestions. George R Ahearn for sending sample SAE J1979 debug information. Larry Wall and all the other people who have worked on Perl. ELM Electronics for creating the ELM327 module. Everyone involved with CPAN.
Copyright 2012 Alister Perrott.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
To install Device::ELM327, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Device::ELM327
CPAN shell
perl -MCPAN -e shell install Device::ELM327
For more information on module installation, please visit the detailed CPAN module installation guide.