Improving ECU Connection Speed with an ELM327 Microcontroller
ELM327 Introduction
An ELM327 microcontroller can be viewed as a translation device for communicating with the onboard computer of a vehicle. The microcontroller can be interacted with over a number of different mediums like Bluetooth, Wi-Fi or USB etc. Different vehicles use different protocols, and therefore the ELM327 microcontroller allows you to use a single interface to interact with multiple vehicle communication protocols behind the scenes using a single command set.
The ELM327 microcontroller supports number of protocols as outlined by ELM Electronics:
- SAE J1850 PWM
- SAE J1850 VPW
- ISO 9141-2
- ISO 14230-4 KWP (5 baud init, 10.4 kbit/s)
- ISO 14230-4 KWP (fast init, 10.4 kbit/s)
- ISO 15765-4 CAN (11 bit ID, 500 kbit/s)
- ISO 15765-4 CAN (29 bit ID, 500 kbit/s)
- ISO 15765-4 CAN (11 bit ID, 250 kbit/s)
- ISO 15765-4 CAN (29 bit ID, 250 kbit/s)
- SAE J1939 (250kbit/s)
- SAE J1939 (500kbit/s)
In this article, the ISO 9141-2 protocol was used for testing.
Connection Speed Overview
When looking to query a large number of parameters at once or simply query a small number of parameters at minimal time intervals, there are a number of steps you can take to increase the performance of the connections between an ELM 327 microcontroller and your vehicles ECU (Engine Control Unit).
Although the connection speed can be greatly impacted by the vehicle processing time itself, or the quality of the onboard diagnostics device used, there are a number of ways to make the connection more efficient and make the ECU responses easier to parse and process in end applications.
It is assumed that you are using a v2.1 ELM 327 microcontroller or newer in this post. If you are using an older ELM 327 microcontroller, then it’s recommended to use one that is running v2.1 or higher where improved speed can be seen as outlined by ELM Electronics.
You can find out what version your ELM 327 is by running the AT Z command and the version number will be returned in the response.
> AT Z ELM327 v2.1
Note, if this command returns v1.5, then this is a non-genuine clone device and will likely run at a slower rate. ELM Electronics never made a version 1.5.
1) Removing Request Information in ECU Responses
By default, the responses from the ECU includes the request query prepended to the response payload. Turning off echoes can decrease response size.
Echoes can be turned off by sending the E0 parameter.
> AT E0 // turn off echo
Example:
> 01 0C // request engine rpm 010C 48 6B 11 41 0C 00 00 11 > AT E0 // turn off echo OK > 01 0C // request engine rpm 48 6B 11 41 0C 00 00 11
2) Removing Linefeeds in ECU Responses
When linefeeds are enabled, a new line is added after each carriage return when the response is returned.
The default status for the linefeeds value is dictated by the voltage at pin 7. When this pin is at a high voltage level, linefeeds will be turned on by default. Otherwise, it will be turned off and no new line will be added in the responses. Usually there is a high voltage on pin 7 by default on most onboard diagnostic devices.
Linefeeds Pin 7
The increase in payload size due to the carriage return only slows down the connection. One useful reason to use linefeeds is for debugging using a terminal to make the responses easier to read, however for consumption in applications, it often makes it easier to parse when linefeeds are turned off.
Linefeeds can be turned off by sending the L0 parameter.
> AT L0 // turn off linefeeds
3) Removing Headers in ECU Responses
When responses are returned from the ECU, additional header information may be returned along with the data payload for the the request parameter. If header information is not of interest, these can be turned off to reduce message length which in turn enhances performance.
Headers can be turned off by sending the H0 parameter.
> AT H0 // turn off headers
Example:
> 01 0C // request engine rpm 48 6B 11 41 0C 00 00 11 > AT H0 // turn off headers OK > 01 0C // request engine rpm 41 0C 00 00 11
4) Removing Spaces in ECU Responses
By default, when responses are returned from the ECU, there is a space inserted between every 2 bytes to make the response more human readable.
By removing the spaces in the response, the response payload size will be reduced, increasing speed. This generally makes it easier to consume for application use, but may make it more difficult for terminal debugging.
Spaces in responses can be turned off by sending the S0 parameter.
> AT S0 // turn off spaces
Example:
> 01 0C // request engine rpm 41 0C 00 00 11 > AT S0 // turn off spaces OK > 01 0C // request engine rpm 410C000011
Using the above commands, we have already reduced the response message size dramatically. This makes a big difference when querying every few milliseconds.
010C 48 6B 11 41 0C 00 00 11 // initial length of 28 characters 410C000011 // new length of 10 characters
5) Adaptive Timing
If you are running using an ELM327 microcontroller that is version 1.2 or higher, you can utilize something known as adaptive timing. The adaptive timing will adjust the timeout time dynamically based on the response times from the ECU.
There are 3 different settings with adaptive timing:
- Off
- Normal
- Aggressive
By default, the ‘Normal’ mode is used for the adaptive timing.
If you’d like to disable adaptive timing, so you can manually set your own timeouts, you can do so using the AT 0 command.
> AT AT 0 OK
Similarly, to turn on aggressive mode, you can do so using the AT 2 command. In most cases, it’s recommended to use the default adaptive timing mode, however you can experiment with the more aggressive mode to see if there are any performance improvements without causing the buffer to be overloaded.
> AT AT 2 OK
You can return to the default mode by issuing the AT 1 command.
> AT AT 1 OK
6) Known Response Size
One of the lesser known ways to increase connection speed is to define the expected response length in the outgoing request to the ECU. If you know what the response size is going to be, you can notify the ELM327 microcontroller of this information so it’s not waiting around for more data to be received until the timeout finally occurs (as defined by adaptive timing or a user provided timeout length).
You can define the expected response size using a single hexadecimal digit at the end of your request. For instance, the timing advance parameter ID has a payload of 1 byte in size, so we simply append the hex value 1 to the end of the request.
> 01 0E // Request Timing advance > 01 0E 1 // Request Timing advance and return when 1 line of data is received
Similarly, with parameter ID’s that return larger payloads such as MAF air flow rate, we simply set the expected response size in the same way:
> 01 0E // Request MAF air flow rate > 01 0E 2 // Request MAF air flow rate and return when 2 lines of data are received.
Conclusion
To summarize, there are 3 main approaches to improving connection speed:
- Reducing response size by trimming the payload of headers, echoes, spaces and request information.
- Limiting the number of parameter ID’s being queried at the same time to improve refresh rate of specific parameters.
- Using adaptive timing (or manual timeouts) along with setting expected response sizes to minimize the full timeout length.
Thanks, very useful!
good article