ELM327 Reads Volvo 850 Mileage

Surprise!  An ELM327 cable can read the Volvo 850 vehicle mileage, the Service Reminder counters, their counter limits that determine when the Service light illuminates, and it can read some other data maintained by the Instrument Panel (otherwise known as the Instrument Cluster, or the COMBI).

Introduction

The contention that the ELM327 can read the Volvo 850 mileage and the Service Reminder counters / limits contradicted the conventional wisdom at Matthew's Volvo site and all other Volvo forums that I had seen as late as 2013-04-30 (when this page was created).

To help you test if you can read your Volvo 850's mileage with an ELM327, I've included: a list of the hardware and software requirements, some links to help in getting the ELM327 setup properly, and, most importantly, the AT commands and KWPD3B0 (request-generating) commands that need to be sent to the ELM327, the responses which were generated on my 1997 Volvo 850 T5, and detailed explanations of those responses.

Note:
The COMBI will sometimes be referred to as ECU 51 on this page. (A list of other Volvo 850 ECUs' hexadecimal #s is available here).

Requirements

The following were used to read the data shown on this page:

  • 1997 Volvo 850 T5 OBDII port.

    It's known that the method shown on this page has worked for at least one Volvo in each of the following categories:

    It's not yet known if the method shown on this current page works for these Volvos:

    • any USA 1996-1997 Volvo 850 with Yazaki cluster,
    • any USA late-1995 Volvo 850 with an OBDII port, or
    • any non-USA 1995+ Volvo 850 with Yazaki cluster.

    The method probably works for most all the USA 1996-1997 850 that have a VDO cluster.  It might work for some of the USA 1995 850 with an OBDII port (though this USA 1995 850 NA wagon w/ Motronic 4.3, manufactured 1995-03, could not read the mileage, but it could perform OBDII emission diagnostics).  Furthermore, the method on this page probably works for some of the non-USA 1995+ 850 that have an OBDII port (though those non-USA cars probably will not be able to perform much, if any, OBDII emission diagnostics).

    Note:
    I don't recall anyone reporting that they have used the instructions on this page to successfully read the vehicle mileage from a 1996-1997 850 that has a Yazaki cluster.  It might be that the '96-'97 850's Yazaki cluster can not communicate via the KWPD3B0 protocol.
    Warning:
    This page does *not* work for 1998 S70/V70/C70/XC70 !

    Some of the 00-padded (KWPD3B0-oriented) commands on this page are known to not work for the 1998 V70 & XC70 models. Consequently, a separate, but similar, page has been created which contains some extra details and should work equally well both for the 1996-1997 850 and the 1998 S70/V70/C70/XC70.

    If you have a 1998 S70 / V70 / C70 / XC70, or if you simply want to use the same set of instructions for all the 1996-1998 Volvo 850 / S70 / V70 / C70 / XC70, then click here.
  • ~$18 ELM327 clone cable (v1.4 or higher).

    My guess is that many ELM327 (v1.2 or higher) based devices will now work -- especially those that are based on the real (non-clone) ELM327 chip from Elm Electronics -- since (as of 2019-07-20) the commands on this page now use ATSR 13 as the preferred alternative to ATRA 13.

    ScanTool.net OBDLink SX (USB), OBDLink LX (Bluetooth), OBDLink MX (Bluetooth), and OBDLink MX+ (Bluetooth for Windows/Android/iOS) devices -- with the latest firmware -- are also known to work quite well.  As long as they have the latest firmware, (with respect to 850 communication) they appear to operate like ELM327 v1.4 or higher, even though they respond to ATI as "ELM327 v1.3a".

    See ATTA, ATSR (or ATRA), and ATSI below for some other notes relating to ELM327 versions >= v1.2 and < v1.4.

  • Free, downloadable Silicon Labs CP210x VCP driver for use with ELM327 USB cable.

    I've used CP210x_VCP_Win_XP_S2K3_Vista_7.exe (version v6.5.3) on WinXP, and I've used CP210x_VCP_Windows.zip (version v6.6.1) on both WinXP and Win7.

    See Setup -- where "STEP 1" is mentioned -- for links to download the latest Silicon Labs CP210x VCP drivers for Windows, Linux, Mac, etc.

    You may need to use different driver(s), eg, FTDI, Prolific, etc. That Setup page may help in locating them.

Hints:
If you don't have the above items, you'll have to improvise.

***IMPORTANT***
For example, the answer provided to the Volvo 850 OBDII FAQ question "How to detect fake ELM327 devices that can not talk KWPD3B0?" may help to avoid buying an ultra-cheap ELM327 device which can not read the '96-'97 Volvo 850 mileage, and which can not perform other KWPD3B0 communication!

You can also check these hints for using mikeri's milageread (on Windows) or applagapp's "ELM327 Identifier" app (on Android) to verify your ELM327 tool's ability to communicate via the Volvo special KWPD3B0 protocol.

Everything after this section assumes: a) that you already have the ELM327 operational enough to successfully perform an ISO9141-2 style Slow Init connection, and b) that you have a terminal emulator setup properly. If you already know your ELM327 can perform an ISO9141-2 connect with your Volvo 850, and you already know a terminal emulator is setup properly, then you can skip to the next section on Read COMBI data.

Otherwise, now is the time to first explore one or more of the following resources before trying to connect and read the vehicle mileage:

The first thing to get operational is your ability to talk to the ELM327. A serial terminal emulator can be used to do this. Terminal emulators work both with the USA Volvo 850s that have OBDII emission diagnostics and with the European Volvo 850s that do not provide OBDII emission diagnostics. You can use the terminal emulator links included here to find a suitable one.

Note:
For some ELM327-compatible devices, you can even perform this initial connection test to the ELM327 without the ELM327 being connected to the car.  That's the case for ELM327-compatibles that use a USB serial interface.

Using a terminal emulator, issue the following five (5) ELM327 commands, each on a separate line: ATZ, ATL1, ATE1, ATI, ATIIA 51.

Once you:

  • get the ELM327 to respond to each of the 5 commands (ATZ, ATL1, ATE1, ATI, ATIIA 51),
  • have the ATE1 respond with OK, and
  • have the ATI respond with "ELM327 v1.2" or a higher version, eg, "ELM327 v1.2a", "ELM327 v1.3", "ELM327 v1.3a", "ELM327 v1.4", "ELM327 v1.4b", "ELM327 v1.5", "ELM327 v2.0", "ELM327 v2.1", "ELM327 v2.2", "ELM327 v2.3", etc,

then:

  1. you've at least got your ELM327 talking with your smart phone / tablet / laptop / etc.

If the "ATIIA 51" command responded exactly the same as the "ATI" command, then you can not use the instructions on this page to retrieve the mileage, since your ELM327 device is incapable of communicating with the Volvo special KWPD3B0 protocol necessary to read the vehicle mileage and to further communicate with the COMBI, SRS, ABS, etc.  This page will be of no use to you while using a KWPD3B0-incapable pseudo-ELM327 !!!

Warning:
Some purported ELM327 devices are incapable of KWPD3B0 communication!!!

See the Volvo 850 OBDII FAQ question "How to detect fake ELM327 devices that can not talk KWPD3B0?" to help avoid buying a device which can not read the '96-'97 Volvo 850 mileage, and which can not perform other KWPD3B0 communication.

However, if the "ATIIA 51" command responded with "OK", then:

  1. you've verified that the most important ELM327 command necessary to communicate with a Volvo 850 using the KWPD3B0 protocol does indeed work.  Most likely it'll be OK to continue further on this page and attempt to communicate with the COMBI.  [To perform a more complete check, see the FAQ question mentioned in the Warning above or see this.]

Once you get the ATZ, ATL1, ATE1, ATI, and ATIIA 51 working, if you have an 850 which can not handle OBDII emission diagnostics (eg, a European Volvo 850 with an ECM which does not handle OBDII emission diagnostics), then jump to the next section on Read COMBI data.

If you have not yet connected via any OBDII diagnostic software and you have a USA 850 which has an J1962 OBDII port, you can still check if the ISO9141-2 style Slow Init connection can be established before jumping to the next section. Just use the terminal emulator to issue these 6 commands to the ELM327: ATZ, ATL1, ATE1, 0100, 0100, 03 -- each on a separate line.  Check if the 0100, 0101, and 03 OBDII commands and their responses appear similar to the following example when there were 0 emission diagnostic DTCs and the headers/checksums display was turned off:

>0100
41 00 80 00 00 00
41 00 BE 1D B0 00
 
>0101
41 01 00 04 00 00
41 01 00 07 E5 00
>03
NO DATA

or similar to the following example for a vehicle that also had a Secondary Air system and which had 5 misfire oriented DTCs: P1310, P0304, P0303, P0305, and P0300, as well as the Check Engine Light (CEL) on.  The 0100 command's 4100 response is shown both without and with headers (and checksums).

>0100
41 00 80 00 00 00
41 00 BE 1D F0 00
>ATH1
OK
>0100
48 6B 1F 41 00 80 00 00 00 93
48 6B 17 41 00 BE 1D F0 00 D6
>0101
48 6B 1F 41 01 00 04 00 00 18
48 6B 17 41 01 85 07 ED ED 72
>03
48 6B 17 43 13 10 03 04 03 03 3D
48 6B 17 43 03 05 03 00 00 00 18

If that is not the case -- ie, you can not initialize successfully (eg, you get "BUS INIT...ERROR" responses), and/or you can not get the 0100, 0101, and 03 commands to generate responses that are formatted somewhat similar to one of the above examples (where responses to 0100 and 0101 begin with 41 or 48), and if you know your car has OBDII emission diagnostic capability -- then you might need to:

a) reseat your ELM327 connector into the car's J1962 OBDII port,
b) review your ELM327 driver setup,
c) turn on your ignition,
d) do some more web research, and/or
e) ask some questions in the MVS 850... forum or some other Volvo forum.

Or you could always just continue to the next section and see what happens.

Read COMBI data

ELM327 commands to read 850 mileage

A list follows of the commands to read the 850 mileage (using B90300). It is what you would use immediately after plugging in all the cables (or after your ELM327 seemed to lock up or otherwise seem to be unresponsive or behaving unexpectedly).

>ATZ
>ATL1
>ATE1
>ATSP 3            (might be necessary to establish ISO 9141-2 as default)
>ATH1
>ATAL
>ATKW0
>ATSR 13           <<< Remember to use this or "ATRA 13"! <<<
>ATIIA 51
>ATWM 82 51 13 A1
>ATSI              (optional)
>ATSH 84 51 13
>B90300

Another, even shorter, way involves: stopping any existing communication via ATPC [the ECUs will stop communicating in a little over 5 seconds], performing a less involved init sequence, then reading the mileage.  This shorter sequence (shown below) is oftentimes all that's necessary when the ATZ thru ATSI sequence above has already been used to successfully establish communication with one of the ECUs via the keyword D3 B0 protocol (as is done when reading each ECU's DTCs, etc. in succession).

>ATPC
>ATIIA 51
>ATWM 82 51 13 A1
>ATSI              (optional)
>ATSH 84 51 13
>B90300

ELM327 commands to read 850 ECU 51 DTCs and B9xx data

A more extended list follows of the minimum to read the 850 ECU 51 DTCs (using AE0100) and all ECU 51 B9 data (using B9xx00). Keep in mind the same as above applies to this list also -- ie, ATPC can replace the ATZ thru ATSR 13 commands if all 8 of those commands had been successfully issued previously and are still in effect.

>ATZ
>ATL1
>ATE1
>ATSP 3            (might be necessary to establish ISO 9141-2 as default)
>ATH1
>ATAL
>ATKW0
>ATSR 13           <<< Remember to use this or "ATRA 13"! <<<
>ATIIA 51
>ATWM 82 51 13 A1
>ATSI              (optional)
>ATSH 84 51 13
>AE0100
>B90100
>B90300
>B90400
>B90500
>B90600
>B90700
>B90800
>B90900
>B90A00
>B90B00
>B90C00
>B90D00
>B90E00
>B9F000

ELM327 850 ECU 51 commands & responses example (with links)

Details of all that just-displayed 850 example's listed commands and their responses are now described (with extra ATI, ATDP, ATBD, ATKW, and ATPC commands thrown in for good measure):

Hint:
The following detailed example -- involving 00-padded KWPD3B0 commands AE0100 and B9xx00 -- is applicable to the 850 (but *not* to the SVC70).  To see a more general 850 example that can be used with either 1996-1997 850 or 1997-1998 S70/V70/C70/XC70, click this.

>ATZ
ELM327 v1.5

>ATL1
OK

>ATE1
OK

>ATI
ELM327 v1.5

>ATSP 3
OK

>ATDP
ISO 9141-2

>ATH1
OK

>ATAL
OK

>ATKW0
OK

>ATSR 13        <<< Remember to use this or "ATRA 13"! <<<
OK

>ATIIA 51
OK

>ATWM 82 51 13 A1
OK

>ATSI
BUS INIT: ...OK

>ATBD           (if issued < 2.5 sec after "...OK" finished, will respond as...)
06 51 55 D3 B0 4F AE 51 13 A1 8F 09 02

>ATBD           (if issued > 4.5 sec after 1st ATBD response, will respond as...)
05 82 51 13 A1 87 09 81 13 A1 8F 09 02
>------ This looks like a good ISO9141-2 style slow initialization,
        where the ELM327 interprets the entire exchange as the
        following 6 byte message:

        * proper ECU:       51    (sent by ELM327 at 5 baud)
        * proper sync byte: 55    (sent by ECU 51 at 10400 baud)
        * proper keywords:  D3 B0 (   "       "        "       )
        * B0 complement:    4F    (sent by ELM327 at 10400 baud)
        * 51 complement:    AE    (sent by ECU 51 at 10400 baud)

>------ followed several seconds later by a "82 51 13 A1 87" keepalive
        request sent by ELM327 as tester 13 to ECU 51.

>------ NOTE: For ScanTool.net OBDLink SX/LX/MX/MX+ devices,
        it's useless to use ATBD commands, since they always respond:
        00 00 00 00 00 00 00 00 00 00 00 00 00.
>ATKW           (optional)
1:D3 2:B0

>ATSH 84 51 13
OK

>AE0100
84 13 51 EE 01 05 DC

>B90100
84 13 51 F9 01 A4 86

>B90300
85 13 51 F9 03 34 30 49

>B90400
85 13 51 F9 04 24 19 23

>B90500
84 13 51 F9 05 10 F6

>B90600
85 13 51 F9 06 E3 3A 05

>B90700
85 13 51 F9 07 A0 05 8E

>B90800
85 13 51 F9 08 75 0D 6C

>B90900
85 13 51 F9 09 F4 01 E0

>B90A00
85 13 51 F9 0A 22 00 0E

>B90B00
84 13 51 F9 0B FF EB

>B90C00
86 13 51 F9 0C 4B 6E 78 20

>B90D00
84 13 51 F9 0D 00 EE

>B90E00
84 13 51 F9 0E C3 B2

>B9F000
92 13 51 F9 F0 00 09 44 23 78 30 30 32 09 44 22 07 30 30 31 60
>------ ECU 51 B9 data recorded at: 2013-04-20 19:32.

 ------ B903 = 34 30, ie, 3034 hex = 12340, which implies mileage of
        12340 * 10 = 123400.  This is 123400 - 121820 = 1580 miles (2543 km)
        since the last reading on 2013-01-18.

 ------ Changes from last ECU 51 B9 readings on 2013-01-18 09:48 are:
            B903 -- (3034 - 2F96) hex = 9E hex = +158, implies 1580 miles (2543 km).
            B906 -- (3AE3 - 3971) hex = 172 hex = +370, implies 92 days 12 hours.
            B908 -- (0D75 - 0D19) hex = 5C hex = +92 engine hours.
        B903 matches well with actual values.
        B906 matches extremely well with actual values.
        B908 is plausible.
>ATPC
OK

Hint:
The above detailed example -- involving 00-padded KWPD3B0 commands AE0100 and B9xx00 -- is applicable to the 850 (but *not* to the S70/V70).  To see a more general 850 example that can be used with either 1996-1997 850 or 1997-1998 S70/V70/C70/XC70, click this.

Interpret 850 COMBI data

We'll go down through each of the commands and responses in the just-shown, detailed 850 (00-padded) COMBI commands/responses example, paying particular attention to each of the B9xx data values (returned in the F9xx response), and explaining what I've been able to infer about them.  In the process, we'll see:

  • the typical way to setup the ELM327 to communicate via the Volvo keyword D3 B0 protocol (KWPD3B0),

  • the COMBI's DTCs,

  • the mileage (which does not include any mileage "lost" when the ABS module was failing),

  • the Service Reminder counters and limits, and

  • possible interpretations of the remaining B9xx data.

Explain ELM327 Setup for Keyword D3 B0 Protocol (KWPD3B0)

ATZ, ATL1, and ATE1

The first 3 commands are ATZ, ATL1, and ATE1 to reinitialize the ELM327, to turn on linefeeds, and to turn on echo. The ATZ output that identifies the ELM327 version will get garbled until the ATL1 is issued. So don't be surprised.

Note:
I didn't display the ATZ output and ATL1 output above as it actually appears on the Hyperterminal display.  If you want to see that, refer to the Volvo 850 OBDII FAQ question: How do I read emission diagnostics DTCs by manually issued commands to the ELM327?, in its Steps 1-6.

Hint #1:
ATL1 and ATE1 work well for me with Hyperterminal or with volvo850diag / Realterm v2.0.0.70.  However, some terminal emulators or programs work better with ATL0 and/or ATE0.  For example, STNterm works better with ATE0.  Experiment to see what works best for your situation, then adapt the ATL1 and ATE1 commands in the command list so that your resultant display looks like the ELM327 AT commands, KWPD3B0 commands, and their responses shown on this page.

Hint #2:
After the ELM327 is initialized with ATZ and ATL1, then subsequent KWPD3B0 inits during the same debugging session can often suffice with ATPC, which does a Protocol Close to cease any existing communication channels between the ELM327 and the Volvo. The ELM327 parameters seem to retain their values after an ATPC, so this ATPC "lesser" init is much more convenient with any subsequent inits of either that same ECU or any of the other ECUs that communicate via KWPD3B0.

The timing window in which the ATPC "lesser" init works to reestablish KWPD3B0 communication vanishes completely when: a) an ATZ is issued to reestablish OBDII emission diagnostics, or b) an ATZ, ATD, or ATWS is issued for any other reason, or c) a power failure occurs, or d) certain ELM327 ERRnn errors occur, etc. When the ATPC "lesser" inits consistently fail to reestablish KWPD3B0 communication when you think that they should work, then you need to fallback to the full ATZ init.

ATI, ATSP, and ATDP (all usually optional)

The ATI simply documents the ELM327 version if you couldn't see it properly from the ATZ command.

The ATSP 3 (or ATSP 3A or ATSP A3) command will establish ISO 9141-2 as the default protocol. If the 'A' is included before or after the '3', then the default protocol will be set to AUTO, ISO 9141-2, and the ELM327 will fallback to "AUTO" if the attempt to connect via "ISO 9141-2" fails. It is probably wise to issue ATSP 3 at least once when you first start using your ELM327 device. Afterwards, because the ELM327 is good at remembering what protocol connected successfully, it may only be necessary to issue the ATSP command after you have used the ELM327 to connect to a vehicle which uses a different protocol than "ISO 9141-2".

The ATDP command documents the current protocol. During a lot of my testing, the protocol was forced to be ISO 9141-2, so that there was no confusion whatsoever which protocol was being used. However, things seem to also work well if the protocol is set to AUTO, ISO 9141-2. The ATDP command is included here simply to remind you that -- if the value is not either "ISO 9141-2" or "AUTO, ISO 9141-2", then things might not work as described here, and you'll likely need to issue ATSP 3 (or ATSP 3A).

Some other values for ATDP work partially, if they include AUTO, but I don't recommend use of any of them for the '96-'97 850, since they don't work anywhere near as well as the "ISO 9141-2" or "AUTO, ISO 9141-2" mentioned in the previous 2 paragraphs.

ATH1

The ATH1 turns on headers/checksum display. I very strongly suggest displaying the headers when using non-emissions diagnostics communication between the ELM327 and the Volvo 850. There's several important things that you can not see if you don't display the headers. Consequently, the documentation on this site will almost always include those headers and checksums (at least for the non-emissions diagnostics using the Volvo special KWPD3B0 protocol).

ATAL

The ATAL command relaxes the testing for message lengths. Normal OBDII protocols restrict the number of data bytes to 7. In other words, in those protocols up to 7 bytes are allowed after the header and before the checksum. When ATAL is used, the ELM327 will allow up to 8 data bytes when sending and an unlimited number of data bytes when receiving. Use of ATAL is necessary for viewing a wide variety of responses sent back from the Volvo 850 using the Volvo keyword D3 B0 protocol (KWPD3B0). For the '96-'97 850, I strongly suggest always using ATAL when doing KWPD3B0-based diagnostics, and recommend never using ATAL when doing standard OBDII emissions diagnostics.

ATKW0

The ATKW0 command disables the keyword checking when performing the ISO 9141-2 protocol initiation. This is necessary when using the Volvo keyword D3 B0 protocol for non-emissions diagnostics, since the ELM327 knows nothing about those Volvo special keywords: D3 B0. They are not part of any standard (that the ELM327 knows about).

ATTA 13   <<< No longer included in command lists on this page! <<<

The ATTA 13 command changes the tester address. A tester address of 13 has successfully been used with all the 850 ECUs mentioned in the Volvo 850 keyword D3 B0 protocol ECU list (including the Immobilizer). Tester address 13 is the one used by Vol-FCR, and it's the same one used by both rkam and Brick-Diag.

Update for ELM327 v1.2 thru v1.3a owners:        <<< Updated 2019-07-20! <<<
Analysis and extensive testing suggests use of ATTA 13 (or its ATPP 06 alternative) is very likely superfluous for owners of those earlier ELM327 devices.

On 2016-11-14, Adam Goldman enlightened me:

"I think the ATTA command to the ELM is not necessary...

Since the settings made by ATTA end up being overridden anyway with ATSH and ATWM, you can skip the ATTA and do only ATSH, ATWM and ATSR/ATRA. This would probably be of most interest to those on ELM v1.2/1.3 where ATPP to set the tester address would thus be unnecessary."

My testing of skipping ATTA 13 and only doing ATSR (or ATRA), ATWM, and ATSH reveals his contention is true.

In volvo850diag v0.9 -- to simplify instructions so they are applicable to all ELM327 compatible devices from ELM327 v1.2 onwards -- both the ATTA 13 command (and its cumbersome ATPP 06 alternative) were eliminated entirely, and ATSR 13 became the default way that volvo850diag sets the Receive Address.

Likewise, on 2019-07-20 the ATTA 13 command was permanently deleted from the command lists on this page.

However, the ATTA 13 section has been retained for historical purposes and because there are links to it.

ATSR 13 (or ATRA 13)       <<< Updated 2019-07-20! <<<

The ATSR 13 (or ATRA 13) command manually sets the receive address, thereby turning off the ELM327's AR (Automatically set the Receive address) mode. This is a very important, essential command which forces the ELM327 to only accept responses addressed to 13.

The ATSR 13 (or ATRA 13) command is only used by KWPD3B0 communication, eg, to the Volvo's COMBI, ABS, SRS, Automatic Transmission, Power Seats, Motronic 4.4, etc. It should definitely not be used for OBDII emission diagnostics. When the ATZ is issued preceding OBDII emission diagnostics, it will erase the effect of ATSR 13 (or ATRA 13) and revert the ELM327 back to AR mode, as if an ATAR command had been issued.

History:
I only discovered ATRA 13 in late 2013-10, a year after discovering how to perform KWPD3B0 communication via the ELM327. So there's examples here and there on the web that don't display this in the command list.  But rest assured, KWPD3B0 communication works much better when using ATRA 13 (or ATSR 13) -- especially while scanning ABS (ECU 01) and AW 50-42 (ECU 6E) with ELM327 clone devices.

Important Mandatory Requirement for ELM327 v1.2 and v1.2a owners:
If your ELM327 does not have the ATRA command because it is a v1.2 or v1.2a, then you **must** use "ATSR 13" instead of "ATRA 13".  ATRA and ATSR are synonymous commands.

ATTA 13 and ATRA 13 have been replaced with the single ATSR 13 command:
On 2019-07-20, this page was changed to list ATSR 13 (instead of ATRA 13) as the preferred command to set the Selective Receive Address, since ATSR 13 applies to a larger set of ELM327 chips.  At the same time, the ATTA 13 command was eliminated from the command lists.

ATIIA 51

The ATIIA 51 command sets the Slow Init address to 51 (to override the default of 33 which the ISO 9141-2 spec requires for the OBDII emission diagnostics).

Warning:
The proper response to an ATIIA 51 command is: OK.

If the ATIIA 51 command does not respond with OK -- eg, if the ATIIA 51 command responds the same as the ATI command -- then you have an old or fake ELM327 which can not  perform KWPD3B0 communication !!!

ATWM 82 51 13 A1

The ATWM 82 51 13 A1 command overrides the default settings for the Wakeup Message (aka "periodic idle", aka "Keepalive", aka "watchdog message"). The message sent will be "82 51 13 A1 cs", where "cs" is the automatically generated checksum.

These Wakeup (Keepalive) messages are by default sent every 3 seconds, but you can change that with the ATSW command. For example ATSW CC changes the interval to roughly 4 seconds.

I've experimented with the ATWM message and discovered you can use ATWM 83 51 13 A1 00 or ATWM 84 51 13 A1 00 00 to accomplish the same "periodic idle" purpose for 1996-1997 Volvo 850. But I don't suggest doing that, unless you are forced to for some reason. Those longer formats do not work with the 1998 V70, XC70, etc.

ATSI (optional)

The ATSI command will manually start a Slow Initialization.

Originally, I thought it might be safer to begin the ISO 9141-2 Slow Initialization manually, rather than having the initialization automatically triggered when the first data request is sent, since:

  • the Volvo keyword D3 B0 communication dictates that each ECU will inherently have a different header, and
  • the ATSH command is the only way to specify those unique headers, and
  • there are incongruities implied in paragraph 3 of the SH xx yy zz description in the ELM327 data sheet.

However, as the following note explains, it is possible to bypass this command successfully.

Note for ELM327 v1.2 or v1.3 owners (and anyone wanting to bypass the ATSI):
If your ELM327 doesn't have the ATSI command because it is a v1.2 or v1.3, then you ought to be able to simply delete the ATSI command, the two optional ATBD commands, and the optional ATKW command from the procedures and follow the remainder of the procedures as is. That would effectively issue the ATSH command for the initial post-initialization command before initialization is performed. You'll just have to experiment with having a sufficient delay both before and after the first command which will cause the implicit Slow Init in order to get the "non-ATSI" approach to work consistently.  That approach is used with the "Read All DTCs", "Quick Scan All ECUs", "Full Scan All ECUs", "My Extra Scans", and ECU xx "Read DTCs" buttons in volvo850diag, and it works very successfully.  I wouldn't worry about any possible "incongruities" just mentioned.

In fact, bypassing the ATSI command is now my preferred approach. I just let the ELM327 perform the Slow Init when it thinks that it should.

Because ATSI and the following ATBD and ATKW commands sometimes can come in handy for debugging connection problems, they are still listed here for completeness.

2 ATBD commands after ATSI (optional)

The two ATBD commands and the ATKW command which follow the ATSI are all three optional.

The 1st ATBD command is issued immediately after seeing the "BUS INIT: ...OK" response from the ATSI command, so that it can capture the "51 55 D3 B0 4F AE" sequence. The main thing I look for is the ECU address, 51 in this case, and the D3 B0 keyword bytes. But this is actually a standard ISO 9141-2 initialization response, other than the keywords used aren't mentioned in any ISO literature.

The 2nd ATBD command is issued about 4-5 seconds later, after the first Wakeup Message (ie, Keepalive) has been sent. The ATBD buffer should then contain: a 1-byte length of the immediately following Wakeup Message and checksum, the Wakeup Message specified by the ATWM command, the automatically generated checksum, and several bytes of garbage.

Neither ATBD command should be issued if you're using a ScanTool.net OBDLink device, since those devices just respond with a meaningless string of 00s. For OBDLink devices, you have to use the ATKW command to verify the keywords are D3 B0.

The "------" comments were added by me then later edited to be more readable. That's the standard way that I document what I'm doing while using the ELM327. Of course, you do not need to enter the comments when you're duplicating the sequences.

Those "------" comments are a good introductory explanation of the ISO9141-2 init sequence.

ATKW (optional)

The ATKW command clearly shows the keywords. It is optional and is useful when you want to check the keywords, yet: a) the ATBD command (after an ATSI) was issued too late and didn't show the D3 B0 keywords, or b) the ELM327 compatible device -- eg, OBDLink SX, OBDLink LX, OBDLink MX, OBDLink MX+, etc -- does not have a useful ATBD command.

ATSH 84 51 13

The ATSH 84 51 13 command sets up the proper header for KWPD3B0 requests that will have 3 bytes sandwiched after the header and before the checksum.  The way to interpret this header (and all other Volvo keyword D3 B0 protocol request headers that I've seen used in 850 ECUs) is:

  • 1st byte = length = # of request's bytes after the header, including the 1 checksum byte.
    • The high 2 bits of that 1st byte should be masked out to determine the length.
    • The high 2 bits should be 10 binary, which means the ECU address is a "physical" ECU address, not a "functional" ECU address.
  • 2nd byte = (physical) ECU address.  Should be same as value specified by ATIIA command.
  • 3rd byte = tester address. Should be same as value specified by ATSR or ATRA commands.

84 is equivalent to 4 bytes, so when using this "84 51 13" header, 3 bytes of data must always be specified by the user (when sending the KWPD3B0 command to the ELM327).  The "ATSH 84 51 13" command must precede KWPD3B0 commands that consist of 6 hex digits -- eg, AE0100, B90300, B9F000, A50701.

The "ATSH 83 51 13" command must precede KWPD3B0 commands that consist of 4 hex digits, ie, those that involve 2 bytes (between header and checksum).

The "ATSH 82 51 13" command must precede KWPD3B0 commands that consist of 2 hex digits, ie, those that involve 1 byte (between header and checksum).

The "ATSH 87 51 13" command must precede KWPD3B0 commands that consist of 12 hex digits, ie, those that involve 6 bytes (between header and checksum).

You get the idea.

Once a header is manually setup via an ATSH command, it remains in effect until another ATSH is issued, or the ELM327 is reset (via ATZ, ATD, ATWS, or power down).

Interpret ELM327 850 ECU 51 Read DTCs Command

AE0100

The AE0100 command is one convenient way to retrieve the ECU 51 DTCs from 850s using the ELM327 (*even if* ATSR 13 or ATRA 13 is not used). The use of the 3-byte AE0100 somehow triggers the Volvo 850 ECU 51 and/or the ELM327 to communicate in a manner where the ELM327 can automatically tie the AE0100 command with its response and obviate the need to use a subsequent ATBD command to see the response (or part of the response).

Warning:
The AE0100 command does *not* work for all 1996-1997 850 ECUs !
For example, AE0100 can not be used to read the DTCs for an 850's ABS or AW 50-42.

Hint:
However, the (non-00-padded) AE01 command *does* work for all '96-'97 850's KWPD3B0-conversant ECUs, *and* it works for all '97-'98 S70/V70/C70/XC70's KWPD3B0-conversant ECUs.

If you want to learn a more consistent way to read DTCs on the '96-'98 850/S70/V70/C70/XC70, then you might want to review the more general purpose AE01 section (and use its page instead).

The AE0100 command actually generates a KWPD3B0 request represented by "84 51 13 AE 01 00 cs", where "cs" is the automatically generated checksum.  As you can see the "84 51 13" is the header that we specified with the ATSH command, and the "AE 01 00" is the AE0100 command that we just specified.

The "84 13 51 EE 01 05 DC" response to the AE0100 command (in our example above) is interpreted as follows:

  • 1st byte = 84 indicates two things:
    • higher order 2 bits = 10 binary indicates 3rd byte is ECU's physical address, and
    • lower order 6 bits = length (in bytes) after header = 84 & 3F (ie, hex 84 bitwise ANDed with hex 3F) = 4 bytes = 3 (post-header, pre-checksum) bytes + 1 checksum byte.
  • 2nd byte = destination address = 13 = tester address.
  • 3rd byte = source address = 51 = ECU address.
  • 4th byte = EE = positive ack of AE in request's 4th byte (ie, the request's "function" byte)
                 = AE | 40 (ie, hex AE bitwise ORed with positive ack indicator of hex 40).
  • 5th byte = 01 = echo of request's 5th byte (ie, the request's "subfunction" byte).
  • 6th byte = DTC #1 = 05 -> CI-113 -- Low Fuel / Fuel Level signal interrupted.
  • 7th byte = checksum = DC for this particular message.

However, if our response to the AE0100 command had been "83 13 51 EE 01 D6", then we would have interpreted it as:

  • 1st byte = 83 -> 3 bytes = 2 (post-header, pre-checksum) bytes + 1 checksum byte.
  • 2nd byte = destination address = 13 = tester address.
  • 3rd byte = source address = 51 = (physical) ECU address.
  • 4th byte = EE = positive ack of AE in request's 4th byte (ie, the request's "function" byte), thereby acking the AE0100 command (and satisfying the AE0100 request).
  • 5th byte = 01 = echo of request's 5th byte (ie, the request's "subfunction" byte).
  • 6th byte = checksum = D6 for this particular message.

And what does that mean? You guessed it -- ECU 51 (COMBI) has 0 DTCs!
There's 0 DTCs after the EE 01 and before the checksum.

Interpret ELM327 850 ECU 51 B9xx Data

B9xx00 Overview

The B9xx00 commands retrieve what's considered the COMBI data that encompasses the vehicle mileage, the counters and limits associated with illuminating the Service light (to remind about getting the oil changed), and miscellaneous other parameters.

Each ECU 51 B9xx00 command actually generates a KWPD3B0 request represented by "84 51 13 B9 xx 00 cs", where "xx" = 01, 03, 04, ..., 0D, 0E, or F0, and where "cs" is the automatically generated checksum.  As you can see the "84 51 13" is the header that we specified with the ATSH command, and the "B9 xx 00" comes from the B9xx00 command sent to the ELM327.

Their F9xx positive ack responses all have similar patterns:

  • 1st byte = 84, 85, 86, or 92 implies length = 4, 5, 6, or 18 (decimal) bytes = 3, 4, 5, or 17 bytes (after the header and before the checksum) + 1 checksum byte.
  • 2nd byte = destination address = 13 = tester address.
  • 3rd byte = source address = 51 = (physical) ECU address.
  • 4th byte = F9 = positive ack of B9 in request's 4th byte (ie, the request's "function" byte)
                 = B9 | 40 (ie, hex B9 bitwise ORed with positive ack indicator of hex 40).
  • 5th byte = 01, 03-0E, F0 = echo of request's 5th byte (ie, request's "subfunction" byte)
                 = the "xx" of the "84 51 13 B9 xx 00 cs" request which is being positively acked
                 = the "xx" of the originating B9xx00 command.
  • 6th thru last-1 bytes = command specific values (see below).
  • last byte = checksum.

Each of the specific B9xx00 command descriptions below will only focus on their responses' 6th thru last-1 bytes.

To get a rough preview of my present understanding of the COMBI's B9 values, check out jonesrh's ECU 51 B9 Meaning of Values raw notes, and consider leaving the raw notes open while reading the rest of this page.  Sometimes those notes contain more info than this page.

B90100

The B90100 command retrieves the 1 byte: A4 (hex) = 164 (decimal):

>B90100
84 13 51 F9 01 A4 86 

This value has never changed for me. At first I thought it might be the "Ländercode" (ie, Country Code) which is displayed on the Brick-Diag Kombi-Parameter screen. If so, then 164 = USA. However, several other USA 850 owners have submitted a different value for this: 24 (hex) = 36 (decimal), so my original Country Code guess may be incorrect.

Some examples are included in the more generic "ELM327 Reads Volvo 850 and SVC70 Mileage" page's B901 section.

B90300 - Vehicle Mileage

The B90300 command retrieves 2 bytes which represent the vehicle mileage.  The lower order byte consistently increments once every 10 miles (~16.1 km), *IF* your ABS is sending the speed signal correctly. The ABS can actually be faulty for other reasons, but if it consistently delivers a valid speed signal, then this B903 value will increment (very close to or exactly) once every 10 miles.

Note:
The B903 value does not include any mileage that has been "lost" due to the ABS failing to supply the speed signal to the Instrument Panel.  And, of course, it may not be anything close to the true vehicle mileage if the original, factory installed Instrument Panel has been replaced.

New understanding of B903 value -- COMBI B903 increments every 10.0 mi (16.09344 km).
That applies to all cars worldwide -- regardless of country, regardless of how the COMBI displays speed or mileage, and regardless of how the Trip Computer (if present) displays mileage.  Click here for details.

As you recall the B90300 command and its response were:

>B90300
85 13 51 F9 03 34 30 49 

The way to calculate the mileage from the 2 bytes in the B90300 request's F903 response are as follows:

  1. Get the two bytes after the "F9 03" and before the checksum. In our example, that is "34 30". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 3034 hex.

  3. Convert the hex to decimal, then multiply by 10.  In our case we have: 3034 hex = 12340 decimal, and 12340 * 10 = 123400. That represents 123400 miles.

  4. Convert to kilometers by multiplying by 1.609344 km/mile.  In our case we have: 123400 miles * 1.609344 km/mile = 198593 km.

So 123400 miles (198593 km) is the Vehicle Mileage (minus any lost mileage).

If you have some reasonable idea of the mileage "lost" due to ABS failure, then you can add that to the above figure. For example, in my case, I've kept meticulous records of precisely how many gallons of gas have been added to my car since I bought it. I can also come up with what I think is an "accurate enough for my purposes" Average MPG, since I had periodically calculated that off and on when I went from near empty to near full tanks of gas. After multiplying the Average MPG and the # of gallons, I concluded 10100 was a good estimate of my lost miles. So in our example, adding 123400 + 10100 = 133500 should be a good estimate of the vehicle mileage when planning for maintenance purposes, and for informing anyone that might buy the car eventually.

Mileage Calculation Hint #1:
To save some time in doing the mileage calculation, I've included a page which can do the calculation for you: Volvo 850 V70 keyword D3 B0 protocol interpreter. You can even paste the contents of an entire ELM327 diagnostic session into the interpreter's Paste Volvo 850/SVC70 communication here box and see what the interpreter can glean from the session.

I think you'll find it useful.

But remember the complete response -- with headers and checksum -- must be included for (almost all) responses from ECU 51 and the other ECUs, and the responses must be left-aligned (almost always), else the interpreter will not be able to parse those ECUs' responses.

Mileage Calculation Hint #2:
Alternatively, you might try using the Google Sheets Volvo 850 Mileage Converter (that I think was developed by the author of the Reading Mileage from a 1997 Volvo 850R blog at potatofi.com). 

You change the values in "Block 6" and "Block 7" to match those bytes in the ECU 51 F903 response, then observe the miles and km in the "Block 6" column on the purple colored lines 7 and 8.

B90400 - Mileage at Service Light Reset

The B90400 command retrieves 2 bytes which represent the vehicle mileage at last Service Light Reset.  Its units are 10 miles (~16.1 km), just like those for the response to B90300.

As you recall the B90400 command and its response were:

>B90400
85 13 51 F9 04 24 19 23 

The way to calculate the mileage from the 2 bytes in the B90400 request's F904 response is similar to the way it is done for the B903/F903 mileage:

  1. Get the two bytes after the "F9 04" and before the checksum. In our example, that is "24 19". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 1924 hex.

  3. Convert the hex to decimal, then multiply by 10.  In our case we have: 1924 hex = 6436 decimal, and 6436 * 10 = 64360. That represents 64360 miles.

  4. Convert to kilometers by multiplying by 1.609344 km/mile.  In our case we have: 64360 miles * 1.609344 km/mile = 103577 km.

So 64360 miles (103577 km) is the Vehicle Mileage (minus any lost mileage) when the last Service Light Reset was performed.

Jump to the next section on B90500 to see how the COMBI uses the B904 Mileage at (last) Service Light Reset when evaluating if the Service light should be illuminated.

The previous remainder of this section -- which contained specifics of my car which helped show a Service Light Reset had been performed over 10 years in the past, and helped show my car probably still had the original cluster -- have been deleted from this page.  If you're interested in those nitty gritty details, click here.

B90500 - Service Reminder Interval in Kilometers / 500

The B90500 command retrieves 1 byte which is (as of 2015-12-28) thought to always equal:

  • Max Kilometers / 500 before Service light illuminates.

The B905 value is thought to always be in km/500 (for all cars worldwide), regardless whether the instrument panel displays mileage as miles or km).

As you recall the example's B90500 command and response were:

>B90500
84 13 51 F9 05 10 F6 

The way to calculate the Service Reminder Interval in Kilometers from the 1 byte in the B90500 request's F905 response is:

  1. Get the one byte after the "F9 05" and before the checksum. In our example, that is "10". Remember that's a hex value.

  2. Convert the hex to decimal, then multiply by 500.  In our case we have: 10 hex = 16 decimal, and 16 * 500 = 8000.

    So 8000 is the Service Reminder Interval in Kilometers.

Taking that a step further, we can calculate the Service Reminder Interval in Miles:

  1. Divide the result in step 2 by the exact value 1.609344.

    In our case the result is: 8000 / 1.609344 = 4971.

    So 4971 is the Service Reminder Interval in Miles.

    [Alternatively, you could have multipled the result in step 2 by the "close enough" approximation 0.6213712.  For example, 8000 km * 0.6213712 km/mile = 4971 miles.]

My 1997 Volvo 850 Owner's Manual says on p2:5 concerning the Service reminder indicator intervals:

"This light will come on at 10,000 mile (16,000 km) intervals*, after 750 hours of driving or after 12 months, whichever occurs first...
* Turbo-charged model intervals: 5,000 miles (8,000 km), 500 hours of driving or after 12 months, whichever occurs first."

The way the COMBI evaluates the Mileage since Last Service Light Reset and compares to its corresponding limit is thought to be: simply compare the Mileage since Last Service Reset virtual counter (ie, B903 - B904) vs. the Service Reminder Interval limit (B905), after applying appropriate multipliers -- a) regardless what the "lost mileage" value in B90A is, and b) regardless if the instrument cluster (and/or Trip Computer if any) displays mileage as miles or km, and c) using the observation that B905 is a multiple of 500 km...

Illuminate the Service light when:
  1. (B903 - B904) * 10 miles >= B905 * (500 / 1.609344) miles

or:
  1. (B903 - B904) * 16.09344 km >= B905 * 500 km

where:
  • B903 is thought to increment every 10.0 mile = 16.09344 km (precisely).

  • B905 = Multiple of 500 km when SRI Mileage Limit is triggered.

  • The SERVICE light apparently works independently of any "lost mileage" that might be recorded one way or another in B90A.

It's a very simple, straightforward comparison.

This approach uses one single SRI Mileage comparison formula for all '96-'97 850 worldwide.  Its Comparison #1 form is more useful if you measure in miles. Its Comparison #2 form is more useful if you measure in kilometers. Both forms are identical in predicting / detecting when the SERVICE light comes on.  That box does a good (though not perfect, within-a-few-miles) job of predicting when the SERVICE light is illuminated.

Hint:
The way to use an ELM327 compatible device to manually reprogram this Service Reminder Interval Mileage limit is to use the ECU 51 B805xx command.  For example, B80520 reprograms the Mileage limit to 16000 km when issued as:

>ATSH 84 51 13
>B805 20

[That's a correction to the "32000 km" published on this page up through mid 2016-02.]

Alternatively, to reprogram this Service Reminder Interval Mileage limit with a pushbutton GUI, download volvo850diag.zip, follow its setup instructions, then use volvo850diag's "Select SERVICE Reminder Indicator (SRI) limit(s)" pulldown and "Reprogram SRI limit(s)" button.

For more details on reprogramming the 850's Service Reminder Interval Mileage limit, see this post at MVS, and search for all references to "B805" in that post (but keep in mind that post displays the B805 = 20 hex SRI Mileage limit inaccurately as "~20000 mi or 32000 km" when it should actually say "16000 km (9942 mi) [roughly 10000 miles]").

B90600 - 1/4 Days since Service Light Reset

The B90600 command retrieves 2 bytes which mean the exact # of 6 hour periods since last Service Light Reset.

As you recall the example's B90600 command and response were:

>B90600
85 13 51 F9 06 E3 3A 05 

The way to calculate the 1/4 Days since Service Light Reset from the 2 bytes in the B90600 request's F906 response is:

  1. Get the two bytes after the "F9 06" and before the checksum. In our example, that is "E3 3A". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 3AE3 hex.

  3. Convert the hex to decimal. In our case we have: 3AE3 hex = 15075 decimal.

So there's been 15075 * 1/4 days = 3768.75 days since the last Service Light Reset.

The example's B9xx data was recorded 2013-04-20 19:32. The car's CarFax shows the last "Oil and filter changed" service on 2002-12-26. Assuming there are 365.25 days per year, 3768.75 days / 365.25 = 10.318 years. Roughly speaking that should be about 10 years + 4 months - ~1 week in the past. The 2002-12-26 date is within a day of that calculation.  Amazing!

You could also do the backtracking by counting exactly how many days occurred in each month and year until you exhaust your 1/4 day counter. The results should be very close to the same.

B90700 - Service Reminder Interval in 1/4 Days

The B90700 command retrieves 2 bytes which equal the Service Reminder Interval in exact # of 6 hour periods.

If you divide this value by 4, you'll get the precise # of calendar days since Last Service Light Reset (accurate to within 1/4 day) at which time the Service light will illuminate again due to this calendar time interval having transpired.

Most software will display this interval in Months, where it is (inaccurately, but close enough) assumed that each month has 30 days.

The example's B90700 command and response were:

>B90700
85 13 51 F9 07 A0 05 8E 

The way to calculate the Service Reminder Interval in 1/4 Days from the 2 bytes in the B90700 request's F907 response is:

  1. Get the two bytes after the "F9 07" and before the checksum. In our example, that is "A0 05". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 05A0 hex.

  3. Convert the hex to decimal. In our case we have: 05A0 hex = 1440 decimal.

Since the 1440 can be factored into 12 * 30 * 4, and can plausibly be interpreted as:

  • 12 = the default # for Service Reminder Interval in Months,
  • 30 = the rough approximation for # days/month,
  •  4 = the # of 6-hour intervals/day,

it is probably true that if the Service light were to illuminate due to the 12 month interval transpiring, it would actually do so 5-6 days early each year (since the 1440 6-hour periods equates to 360 days instead of the typical year's 365 days or the leap year's 366 days).

The way the COMBI evaluates the 1/4 Days since Last Service Light Reset counter vs. its corresponding limit is simply...

If B906 >= B907, then illuminate the Service light.

Note that once again, the design principle of conceptual integrity seems to have kicked in. Both B906 and B907 have to do with the number of 1/4 days, so they are grouped together.

Hint:
The way to use an ELM327 compatible device to manually reprogram this Service Reminder Interval 1/4 Days limit is to use the ECU 51 B807xxyy command.  For example, B807400B reprograms the 1/4 Days limit to 2880 (ie, ~2 years) when issued as:

>ATSH 85 51 13
>B807 400B

Alternatively, to reprogram this Service Reminder Interval 1/4 Days limit with a pushbutton GUI, download volvo850diag.zip, follow its setup instructions, then use volvo850diag's "Select SERVICE Reminder Indicator (SRI) limit(s)" pulldown and "Reprogram SRI limit(s)" button.

For more details on reprogramming the Service Reminder Interval "1/4 Days" limit (which is sometimes called the "Months" limit, since most software displays it in months), see this post at MVS, and search for all references to "B807xxyy" and "B807400B" in the thread that contains that post.

B90800 - Engine Hours since Service Light Reset

The B90800 command retrieves 2 bytes which equal Engine Hours since Service Light Reset.

I kept an accurate record of "engine on" minutes over a several week period and can attest that this B908 data reflects Engine Hours, plus or minus an hour or two, when measured over a period of several days to several weeks. Further testing just before and just after an SRI Reset reveals those hours are indeed Engine Hours since Service Light Reset. That's consistent with the fact that "Engine Hours since Service Light Reset" is one of the parameters which can trigger the Service light to be illuminated (according to the Volvo 850 Owner's Manual).

The example's B90800 command and response were:

>B90800
85 13 51 F9 08 75 0D 6C 

The way to calculate Engine Hours since Service Light Reset from the 2 bytes in the B90800 request's F908 response is:

  1. Get the two bytes after the "F9 08" and before the checksum. In our example, that is "75 0D". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 0D75 hex.

  3. Convert the hex to decimal. In our case we have: 0D75 hex = 3445 decimal.

So there's been 3445 "engine on" hours since the last Service Light Reset.

B90900 - Service Reminder Interval for Engine Hours

The B90900 command retrieves 2 bytes which equal the Service Reminder Interval for Engine Hours. On my car, this value had always equaled 500 (until I experimented with reprogramming it).

The example's B90900 command and response were:

>B90900
85 13 51 F9 09 F4 01 E0 

The way to calculate Service Reminder Interval in Engine Hours from the 2 bytes in the B90900 request's F909 response is:

  1. Get the two bytes after the "F9 09" and before the checksum. In our example, that is "F4 01". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 01F4 hex.

  3. Convert the hex to decimal. In our case we have: 01F4 hex = 500 decimal.

So 500 hours is the Service Reminder Interval Engine Hours limit.

The Volvo 850 Owner's Manual says, per the Service reminder indicator intervals quote listed in the B90500 section, that a Turbo's Service Reminder Interval is 500 hours of "driving". The Brick-Diag "Kombi-Service" screen snapshot says "Motorbetrieb (h)", ie, Engine Operation Hours, can be 1000, 750, or 500. So I'm guessing that the "driving" comment in the Volvo Owner's Manual really means Engine Hours. It probably just means the hours the engine is turned on, and therefore even includes the engine hours when you sit idling for very long periods of time.

The way the COMBI evaluates the Engine Hours since Service Light Reset counter vs. its corresponding limit is simply...

If B908 >= B909, then illuminate the Service light.

Note that once again, the design principle of conceptual integrity has kicked in. Both B908 and B909 deal with the same subject, Engine Hours, so they are grouped together.

Hint:
The way to use an ELM327 compatible device to manually reprogram this Service Reminder Interval Engine Hours limit is to use the ECU 51 B809xxyy command.  For example, B809E803 reprograms the Engine Hours limit to 1000 hours when issued as:

>ATSH 85 51 13
>B809 E803

Alternatively, to reprogram this Service Reminder Interval Engine Hours limit with a pushbutton GUI, download volvo850diag.zip, follow its setup instructions, then use volvo850diag's "Select SERVICE Reminder Indicator (SRI) limit(s)" pulldown and "Reprogram SRI limit(s)" button.

For more details on reprogramming the Service Reminder Interval "Engine Hours" limit, see this post at MVS, and search for all references to "B809xxyy" and "B809E803" in the thread that contains that post.

B90A00 - Engine Hours VSS Missing / Estimated "Lost" Mileage

The B90A00 command retrieves 2 bytes which are believed to be what Brick-Diag Free v0.0.6.6, the Volvo Scan Tool (VST), and the OTP Volvo 850 Service Manuals DVD calls "Manipulation".

The OTP Volvo 850 Service Manuals DVD (OTP-TP-51956) document "Combined Instrument, VDO 850 1996-" (TP-3801032), says on p28, p150, p151, and p153 -- all 4 pages merged together -- that the "Manipulation of speedometer" parameter indicates in hours how long the Vehicle Speed Signal (VSS) to the COMBI has been disabled while the car was being driven.  Apparently, the "RPM > 1500 rpm, Engine Coolant > 50 C (122 F)" constraint (mentioned on p95 for the "CI-221 Vehicle Speed Signal Missing" DTC) must be satisfied before the Manipulation hours is incremented.

The Volvo 850 VDO cluster's "Manipulation hours" is further believed to indirectly approximate -- one way or another -- the "lost" mileage from when the ABS module was not supplying the Vehicle Speed Sensor (VSS) signal.

The example's B90A00 command and response were:

>B90A00
85 13 51 F9 0A 22 00 0E 

The way to calculate a value from the 2 bytes in the B90A00 request's F90A response is:

  1. Get the two bytes after the "F9 0A" and before the checksum. In our example, that is "22 00". Remember those are hex values.

  2. Swap those two bytes. In our example, that becomes 0022 hex.

  3. Convert the hex to decimal. In our case we have: 0022 hex = 34 decimal.

If your B90A value (returned in the F90A response) = 0, then you can skip the remainder of this B90A00 section, and jump directly to B90B00.

But if your B90A value is >= 1, you might want to read further...

Note:
Most "lost mileage" calculations included in prior versions of this page have been removed, since they were erroneous.

To be honest, the correct way to estimate lost mileage from B90A is not really understood!  This section merely mentions two guesses (along with a couple of links for a more detailed explanation and to explore some alternative ideas).

  1. Approach #1 - B90A-derived hours * Avg MPH or Avg Km/h

    The only way I can think of to calculate "lost" mileage from "Manipulation" hours is to multiply the hours derived from B90A by an estimated Average MPH or Average KmPH that applied during the hours that VSS was missing.

    • B90A in decimal hours * Avg MPH
    or:
    • B90A in decimal hours * Avg Km/h

    In my Volvo 850 T5 case, this "B90A hours * Avg MPH" approach failed miserably to estimate the "lost" mileage.  So I explored alternative approaches...

  2. Approach #2 - B90A * 500 km

    The idea that best explains my 850's estimated 10100 miles of "lost" mileage is to assume B90A, after converting to decimal, must be multiplied by 500 km (ie, the same units as B905).  Surprisingly enough, this calculation agrees with my 10100 miles "lost" mileage estimate -- to within 5% !!!  The formula might be stated:

    • B90A in decimal * 500 "lost" km
    or:
    • B90A in decimal * (500 / 1.609344) "lost" miles

I've never seen ECU 51 B90A increment while the ABS module sends a valid speed signal. The only time I've seen the (1st byte of the) B90A data increment is while a faulty ABS was being used that did not supply a consistent speed signal. It incremented once during the 9-day period, from the time I started measuring B90A data until shortly before I replaced the ABS with another one which did supply a proper speed signal.

Ideas for further exploration:
For more details on the two approaches listed above, see the B90A section on the correlary, more general purpose page which handles the '96-'98 850/S70/V70/C70/XC70 together.

For some details on alternative ways to interpret B90A, see item 0A in jonesrh's ECU 51 B9 Meaning of Values raw notes

B90B00

The B90B00 command retrieves 1 byte which is speculated to be a binary flag, like On/Off or Yes/No.

The example's B90B00 command and response were:

>B90B00
84 13 51 F9 0B FF EB 

The way to calculate something meaningful from the 1 byte in the B90B00 request's F90B response is:

  1. Get the one byte after the "F9 0B" and before the checksum. In our example, that is "FF".

  2. Convert the hex to decimal or something else. In our case we have: FF hex = either 255 decimal (if unsigned), or -1 (if signed), or Yes, On, Enabled (if it is a binary flag, with probably 00 hex equating to No, Off, Disabled).

I haven't yet been able to come to a certain conclusion about this B90B data.

At one time I thought B90B was a "Boost Pressure Gauge exists" flag, ie, what is probably the "Ladedruck-Anzeige" on the Brick-Diag Kombi-Parameter screen. My car does have a Turbo gauge in the dash, which is what the Volvo 850 Owner's Manual calls "Boost pressure gauge". It is located between the Fuel Gauge and the Coolant Temperature gauge, but positioned a little higher than those two gauges. The manual states that the Turbo gauge is only for certain turbo-charged models. So its plausible that a flag needs to be maintained by the COMBI computer to remember whether this gauge exists or not.

Since tzanis has a Canada '97 850 GLT which does have B90B = FF, yet his car does not have a Turbo Boost gauge, that blows my "B90B = Boost Pressure Gauge exists" hypothesis out of the water.  Back to brainstorming another explanation for B90B.

Again, some other Volvo owners will need to report this info, either with FF or other values for B90B, and they'll need to also report whether they do or don't have the Turbo gauge as shown on the Volvo 850 Owner's Manual p2:2, have VDO vs. Yazaki clusters, and what are the min and max of the tachometer's red range, etc. That way we can develop a clearer understanding of what B90B (and/or some of the other ECU 51 B9xx data) really is.

Got any ideas? Or got any better explanations?

B90C00

The B90C00 command retrieves 3 bytes which might represent 3 different temperatures.

The example's B90C00 command and response were:

>B90C00
86 13 51 F9 0C 4B 6E 78 20 

There are several possible ways to calculate something meaningful from the 3 bytes in the B90C00 request's F90C response are.  They are explained in detail at B90C.  On the present page we will: a) bypass most of the details included on that more general page which treats B90C info for both 850 and S70/V70/XC70, and b) only mention the one single, simple way that XantheFIN introduced to me -- interpret the B90C data as directly representing Celsius temperatures:

  1. Get the three bytes after the "F9 0B" and before the checksum. In our example, that is "4B 6E 78".

  2. Convert them each individually from hex to decimal. That yields 75, 110, 120.

  3. Assume those directly represent 3 temperatures in Celsius -- 75 C, 110 C, 120 C -- that are possibly used in the algorithm to control the Instrument Panel's Temp gauge.

  4. If desired, convert the Celsius to Fahrenheit using the formula (C * 9/5) + 32 = F.

This is a plausible temperature interpretation, since the values are thought to align fairly well with the temperatures when the Temp needle "almost reaches horizontal", "begins to rise above horizontal", and "reaches (at, near, or in the) red zone".

In our example, the three bytes yield:

  • 4B hex =  75 ->  75 C =  167 F.
  • 6E hex = 110 -> 110 C = 230 F.
  • 78 hex = 120 -> 120 C = 248 F.

The first of those temperatures corresponds to my 850 Temp Gauge's needle being slightly below horizontal -- about a 10-15 degree angle below horizontal.  It is speculated that the 2nd and 3rd temps corresponds approximately to the temp at which the Temp needle begins rising above horizontal, and the temp at which the needle reaches the red zone, respectively.  I have not tested that speculation about the 2nd and 3rd (supposed) temp values meaning.  But it does agree with the OTP Volvo 850 DVD documents that say the normal operating temp is 80 C to 105 C.  So you might expect that the Temp Gauge needle begins to rise above horizontal relatively soon after rising above the 105 C top of the normal operating range.  It's plausible that 110 C is when the rise starts.

But I'm still not convinced this is the correct interpretation, since the OTP Volvo 850 DVD seems to have nothing that suggests temperature setpoints are a parameter which can be read.

Got any ideas? Or got any better explanations? If B90C is not temperatures, what is it?

B90D00 - Fuel Level Adjustment (disabled in 850 cars)

The B90D00 command retrieves 1 byte. Its meaning is not known for certain, but probably it is simply a placeholder for the Fuel Level Adjustment available on '98 S70/V70/etc.

The example's B90D00 command and response were:

>B90D00
84 13 51 F9 0D 00 EE 

The way to calculate something meaningful from the 1 byte in the B90D00 request's F90D response is:

  1. Get the one byte after the "F9 0D" and before the checksum. In our example, that is "00".

  2. Convert the hex to decimal or something else. In our case we have: 00 hex = either 0 decimal, or No, Off, Disabled, Not Encountered (if it is a binary flag, with probably FF hex equating to Yes, On, Enabled, Encountered).

I toyed with several ideas to explain this B90D data, and have finally come to the conclusion that its value always equaling 00 for the 850 cars simply means that the 850 cars do *not* allow any Fuel Level Adjustment.

For more details on how 850 (and SVC70) ECU 51 B90D is (as of 2017-05-16) interpreted as Fuel Level Adjustment (or lack thereof), see B90D. Also, see item 0D in jonesrh's ECU 51 B9 Meaning of Values raw notes.  But keep in mind that it's still not certain that 850 ECU 51 B90D wasn't used for some other purpose besides simply being a dormant Fuel Level Adjustment function that wasn't implemented until the SVC70.

B90E00 - Tire Size

The B90E command retrieves 1 byte which seems be an encoding of Tire Size.

The example's B90E00 command and response were:

>B90E00
84 13 51 F9 0E C3 B2 

The way to calculate the Tire Size encoding from the 1 byte in the B90E00 request's F90E response is:

  1. Get the 1 byte after the "F9 0E" and before the checksum. In our example, that is "C3".

  2. Convert the hex to decimal. In our case we have: C3 hex = 195 decimal.

Since "Reifen", ie, tire (size), is listed on the Brick-Diag Kombi-Parameter screen, and since 185, 195, and 205 were three tire widths mentioned in the Wheels and tires section on p5:2 and p5:3 of the Volvo 850 Owner's Manual, you might think that it's safe to conclude that B90E is the Tire Width (in mm).

However, several Volvo owners have submitted values to kwpd3b0_interpreter.html which don't look anything like a tire width in mm. And all 3 tire values: Section Width, Aspect Ratio, and Wheel Diameter -- ie, the 195, 60, 15 of 195/60R15, the 205, 55, 16 of 205/55R16, etc -- have to be used to determine the distance traveled per revolution, not just one of the 3 values.  [For some details on those two situations, see the more generic "ELM327 Reads Volvo 850 and SVC70 Mileage" page's B90E section, or see jonesrh's ECU 51 B9 Meaning of Values raw notes item 0E.]

The various Tire Size encoding(s) detailed in the 2 links just listed are still not yet fully understood.

Anybody know how they precisely relate to tire circumference?

Or anybody know how they precisely relate to the Section Width, Aspect Ratio, and Wheel Diameter?

B9F000 - Hardware & Software Versions

The B9F000 command retrieves 15 bytes which contain the Hardware and Software versions and revisions of the ECU. What I am calling the Hardware version and Software version appears to me to be a Volvo part number, ie, a 7-digit number beginning with 9.  Vol-FCR calls them "Module Id" and "Software Code", respectively.

The example's ECU 51 (COMBI) B9F000 command and response were:

>B9F000
92 13 51 F9 F0 00 09 44 23 78 30 30 32 09 44 22 07 30 30 31 60 

The way to parse the 15 bytes of data in the B9F000 request's F9F0 response is:

  1. Get the 15 bytes after the "F9 F0" and before the checksum. In our example, that is:

           00 09 44 23 78 30 30 32 09 44 22 07 30 30 31

  2. I don't know what the first 00 byte is, unless it is part of the next field.

  3. The subsequent "09 44 23 78" is strung together as "09442378" and is probably a Volvo part number for the ECU hardware. Normally this number is stamped on the outside of the ECU's container.

  4. The subsequent "30 30 32" is a 3-character ASCII string. In our case, it equals "002". This is the hardware revision #.

  5. The subsequent "09 44 22 07" is strung together as "09442207" and is probably a Volvo part number for the ECU's software. I believe this number is also stamped on the outside of the ECU's container.

  6. The subsequent "30 30 31" is a 3-character ASCII string. In our example here, it equals "001". This is the software revision #.

ATPC - Protocol Close

The ATPC performs a Protocol Close to cease any existing communication channels between the ELM327 and the Volvo. This is the easiest way to stop the ELM327 from sending any more automatic A1 (Keepalive) messages.

Issuing the ATPC (almost) negates the need to send an A0 (Stop Communication) message (like Vol-FCR and Brick-Diag Free v0.0.6.6 do). The A0 is superior in that it will immediately cause the ECU to terminate the connection. Whereas the ATPC will simply cause the ELM327 to stop sending the Keepalive messages, so it may take as much as 5+ seconds for the comm link to actually be severed by the ECU, depending on when the last Keepalive had been sent by the ELM327.

The ELM327 parameters seem to retain their values after an ATPC, so that any immediately subsequent init (of either this same ECU or any of the other ECUs that communicate via KWPD3B0) only have to use the proper ECU-specific ATIIA and ATWM commands before either:

  1. issuing an ATSI command to explicitly perform the ISO9141-2 Slow Init, then following that with the appropriate ECU-specific, next-KWPD3B0-request-specific ATSH command before issuing other KWPD3B0 (request generating) commands; or

  2. issuing the proper ATSH command and a KWPD3B0 (request generating) command (eg, AE0100 or B90300 or B9F000) to implicitly trigger the ISO9141-2 Slow Init, before issuing other KWPD3B0 (request generating) commands.

References

Here's some useful external references:

Here's two useful internal references with some info that's not documented anywhere else:

  • Volvo 850 OBDII FAQ.
    Got a question?  Maybe its answered here.  It's worth a quick review.

  • ELM327 Commands to Scan a Volvo 850.
    This contains elm327_volvo_850_scan_all.txt, a very extensive list of the ELM327 commands to do a thorough scan of the Volvo 850 -- much more thorough than the COMBI oriented list on this page. It's certainly thorough enough for most DIYers purposes. The commands are listed in the typical order that I would type (or send) them. This is also well worth a quick review, or maybe even a very long study!

    Once you've generated an ELM327 log from all or portions of this command list along with the Volvo 850's responses, you can paste the contents of that log into the KWPD3B0 interpreter's Paste Volvo 850/SVC70 communication here box, then press the Interpret button, to glean some of what the log recorded.

Here's a tool to help you semi-automatically scan the Volvo 850:

  • volvo850diag.zip, ie, volvo850diag to be run on your "local" machine.
    The "local" version of volvo850diag uses an ELM327, Realterm (v2.0.0.70 only), Internet Explorer (IE8 on WinXP, IE11 on Win7/Win8.1/Win10), and Javascript to communicate with a '96-'97 Volvo 850. The contents of its automatically generated log can also be pasted into the Volvo 850 V70 keyword D3 B0 protocol interpreter to make some sense out of the hex mumbo-jumbo.

Here's links to info on 2 programs that can both read the 850 mileage and automatically display it:

See Volvo 850 Diagnostic Links for additional reference links.


This page is copyright © 2013-2021, Richard H. Jones. All rights reserved.

Page's last update was on 2021-06-07.