ELM327 Reads Volvo 850 and SVC70 Mileage

Surprise!  An ELM327 tool can read the 1996-1997 Volvo 850 vehicle mileage, the 1997-1998 S70/V70/C70/XC70 vehicle mileage, the Service Reminder counters and counter limits that determine when the Service light illuminates, and it can read some other data maintained by the Instrument Panel (aka, Instrument Cluster, or COMBI).

Introduction

The contention that an ELM327-compatible device can read the '96-'98 Volvo 850 / S70 / V70 / C70 / XC70 mileage and 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.  This page intends to show you how to use an ELM327 to read the Vehicle Mileage from your instrument cluster (if your instrument cluster supports that capability).

It will be most helpful to '96-'97 850 owners with broken odometers (on VDO clusters).  But the same approach can be used to read the Vehicle Mileage from a '97-'98 S70/V70/C70/XC70 (Yazaki) instrument cluster.

To help you test if you can read your Volvo's mileage with an ELM327-compatible tool, I've included: a list of the hardware and software requirements, some links pointing you in the right direction to get the ELM327 setup properly, and, most importantly, the ELM327-destined AT commands and KWPD3B0 (request-generating) commands that need to be sent to the ELM327 (in order to generate the car-destined KWPD3B0 requests), typical responses which have been generated on my 1997 Volvo 850 T5 and my 1998 Volvo S70 GLT (or on other 1996-1998 850, S70, V70, or XC70), and detailed explanations of those responses.

Skip the details.  Show me a quick, easy-to-understand example!

If you don't have time to read through this page in its entirety and you already have your ELM327 setup properly, check out one (or more) of these 3 possible shortcut solutions:

  • xiaotec "850 OBD-II" Android app, <<< Recommended 96-98 850 / S70 scanning app!

  • milageread.exe (on Windows), or milageread.py (whereever Python is installed), or

  • item 2a in this post within gmh's MVS thread: "I read my 97 850R mileage with ELM327 and an Android phone".  That post's item 2a lists some ELM327 commands that can read the Vehicle Mileage from some '96-'97 Volvo 850 Instrument Clusters and some '97-'98 S70/V70/C70/XC70 Instrument Clusters.

However, if you need more detailed instructions and explanations, then continue...

Requirements

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

  1. OBDII port (of 1997 Volvo 850 T5, 1998 Volvo S70 GLT, etc).

    The OBDII port is sometimes referred to as the Diagnostic/Data Link Connector (DLC) or as the J1962 connector.

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

    • USA 1997 Volvo 850R (see this thread) and 850 T5 (see this current page),
    • USA 1997 Volvo 850 non-turbo,
    • USA 1996 Volvo 850 turbo and 850R,
    • USA 1996 Volvo 850 non-turbo,
    • non-USA 1995+ Volvo 850 with the OBDII port,
    • USA 1998 S70 GLT (mine -- again, see this current page),
    • USA 1998 V70 and XC70 (see Mike91 and esl_97_850_T5's seven (7) posts exchange at brickboard.com starting with Mike91's 2013-10-27 post, switching the view to FLAT or THREADED EXPANDED or PRINT ALL, ending with Mike91's 2013-11-07 post, where there's a history of us discovering some of the info which eventually made its way onto this current page), and
    • non-USA 1997 Volvo S70 / V70 / C70 / XC70 with the OBDII port.

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

    • any USA 1996-1997 Volvo 850 with Yazaki cluster,
    • any USA late-1995 Volvo 850 with an OBDII port,
    • any non-USA 1995+ Volvo 850 with Yazaki cluster,
    • any non-USA 1998 S70 / V70 / C70 / XC70 [probably works at least sometimes], or
    • any early-1999 S70 / V70 / C70 / XC70.

    My guess is that the mileage reading probably works for most all USA and non-USA Volvo 850 that have an OBDII port (ie, a J1962 DLC connector) and were 1995-1997 models, if they have a VDO cluster. I'd also venture a guess that the mileage reading probably works for most USA and non-USA Volvo S70 / V70 / C70 / XC70 that have an OBDII port (ie, a J1962 DLC connector) and were 1996-1998 models (except for some non-USA 1998 S70 / V70 / C70 / XC70 that might use a newer protocol).

    The OBDII emission diagnostics probably works for all the USA 1996-1998 850 / S70/V70/C70/XC70, but might only work for some of the USA 1995 850 that have an OBDII port. Furthermore, the non-USA 1995+ 850 / S70 / V70 / C70 / XC70 that have an OBDII port probably will not be able to perform much, if any, OBDII emission diagnostics [unless their ECM (Motronic 4.4, Motronic 4.3, etc) has been replaced or reflashed with USA-style OBDII emission diagnostic capabilities]. But even if those non-USA cars can not do any substantive OBDII emission diagnostics, they oftentimes will be able to read the mileage -- at least on 850 VDO clusters and S70/V70/XC70 Yazaki clusters.

    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.
    Note:
    This page works equally well with 850 as well as S70 / V70 / C70 / XC70.

    This page is a better reference for reading the 850 / S70 / V70 / C70 / XC70 mileage & COMBI data compared to the corresponding 850-specific page.

    But if you have a Volvo 850 and insist on using the 00-padded B9xx00 (and AExx00) commands for 1996-1997 Volvo 850 mileage and COMBI reading, somewhat similar to how they were originally published on this site, then click here.  Be aware that those instructions only work for the 850, that the 850-specific page was retained more for historical reasons than anything, and it is less likely to be updated compared to this present, more general purpose, more information rich, 850 / 70-series page.
    An interesting USA 1995 Volvo 850 NA w/ Motronic 4.3 case:
    Click here to see an interesting case of a USA 1995 850, manufactured in 1995-03, that allowed OBDII scanning via its in-the-car OBDII port and an ELM327 tool, but would not allow mileage reading via that OBDII port and an ELM327 tool.  In fact, it would not allow any KWPD3B0 communication via that OBDII port -- at least, not the style of KWPD3B0 communication used by the USA '96-'97 850.  The COMBI, ABS, and SRS diagnostics required using the under-the-hood OBDI box.  Whereas, engine diagnostics could be performed from either the OBDII port (to see P0172) or the OBDI box (to see 2-3-2).

    I wonder if most all 1995 850 that had both OBDI box and OBDII port behave similarly -- OBDII emission diagnostics work, but KWPD3B0 diagnostics do not work (or at least, the KWPD3B0 diagnostics do not work as fully in the USA '95 850 as they do for the USA '96-'97 850)?

    For such a 1995 850, the mileage might be readable via the OBDI box.
  2. ~$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/SVC70 communication) they appear to operate like ELM327 v1.4 or higher, even though they respond to ATI as "ELM327 v1.3a".

    I personally have successfully used the following 5 tools:

    Each of those 5 tools have their own strengths.  All of them are capable of performing the instructions on this page.  [The first 4 are very capable.  The BAFX is capable; it is adequate; but I don't recommend it due to my experience with more-than-I-care-to-deal-with Bluetooth communication errors.]

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

    If your claimed ELM327-compatible device does *not* respond with an "OK" response to each of the following 5 commands, then it can *not* be used to read the vehicle mileage (and it probably can *not* be used for any KWPD3B0 communication):

    ATSP 3
    ATKW0
    ATIIA 51
    ATWM 82 51 13 A1
    ATSH 83 51 13

    Furthermore, if your claimed ELM327-compatible device responds to any of these commands with a question mark (?), then it may be a waste of your time to try using this site's info to communicate with your 1996-1998 Volvo 850/S70/V70/XC70:

    ATH1
    ATAL
    ATPPS
    ATSR 13
    ATSW CC
    ATST 2C
    ATAT 0

    So check with your device's vendor **before** purchasing a purported ELM327-compatible device to ensure that each command in those lists is handled like a real ELM327 (v1.2 or higher) compatible device would handle them.

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

    Hints for after-purchase checks:
    1. milageread can be used to automatically detect KWPD3B0 incapable devices!

    Versions of mikeri's milageread which identify themselves as 2017-09-23 (or newer) when "milageread -h" or "milageread.py -h" is issued will automatically show you if any commands necessary for KWPD3B0 communication do **not** work in your purported ELM327-compatible device (when you run milageread to read the mileage).

    2. applagapp's "ELM327 Identifier" Android app can also be used to detect KWPD3B0 incapable devices!
    See this to locate the app on Google Play, this for my brief introduction to the app, and this for an explanation on how to use the "ELM327 Identifier" app to detect if an ELM327 is KWPD3B0-capable.

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

    The answer to the Volvo 850 OBDII FAQ question "What version of the ELM327 is required to communicate with 1996-1998 Volvo 850/S70/V70/C70/XC70 cars?" may also help if you have an ELM327-compatible whose version is >= v1.2 and < v1.4.

    The bottom line is that any true ELM327-compatible tool from v1.2 (and higher) can probably be used to retrieve the vehicle mileage using the commands shown on this page (as of 2019-07-20) -- as long as a KWPD3B0 connection can be successfully established with ECU 51 (COMBI).

  3. 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.

    Note for USB and serial ELM327 tools:
    Your ELM327 device might not use the Silicon Labs chip.  You may need driver(s) from other vendors.  For example, the ScanTool.net OBDLink SX USB cable uses FTDI drivers, and some ELM327 devices use Prolific drivers.  That Setup page is intended to help in locating the drivers for several common chips used by vendors of ELM327-compatible diagnostic tools.

    Note for Bluetooth ELM327 tools:
    The Bluetooth ELM327 devices usually do not require extra driver downloads, since the Bluetooth drivers are normally built into the operating system's Bluetooth stack.  [For details, search Wikipedia for "Bluetooth stack" and notice which stacks support the SPP profile.]

  4. Free OBD Now Terminal app (for Android).
    Free Bluetooth USB WIFI Terminal app (for Android).
    Free ScanTool.net STNterm terminal emulator (for WinXP / Win7 / Win8.1 / Win10).
    Free Realterm v2.0.0.70 terminal emulator (for WinXP / Win7 / Win8 / Win8.1 / Win10) --
           [or its several years older Realterm v2.0.0.70 (unsigned) equivalent].
    Free Hyperterminal terminal emulator (comes with WinXP) -- [what I used originally].
    Free PuTTY terminal emulator (on Linux, Windows).
    US$1.99 xiaotec "850 OBD-II" app (for Android) -- [built-in ELM327 terminal emulator
           included with this low priced '96-'98 850/S70/V70/C70 scanning software].

    Probably any good terminal emulator would work.

    For your initial connects on Windows using USB, serial, or Bluetooth ELM327 devices, I recommend STNterm [search for "stnterm" on that page].  STNterm is simple and requires no setup other than selecting the port and baud rate. It is adequate for issuing single commands one at a time. It's definitely my first choice on Windows when testing a new ELM327 tool.

    For your initial connects on Android using Bluetooth ELM327 devices, I recommend either of these 3 apps: "OBD Now Terminal", "Bluetooth USB WIFI Terminal", or "850 OBD-II".  You pair your ELM327 Bluetooth device with Android, run one of those apps, connect, then issue single commands one at a time. On the "850 OBD-II" app (V1.1.0 or later), the ELM327 terminal emulator is reached via its "Service" button (see instructions).

    If you plan on issuing more than just a few ELM327 AT commands, OBDII (request generating) commands, and KWPD3B0 (request generating) commands, or if you plan on issuing them often, and if you're running MS Windows, then downloading and installing Realterm is a good idea.  If you install Realterm v2.0.0.70 -- (not Realterm v3.0.0.xx nor v3.0.1.xx) -- you'll also be able to eventually use volvo850diag (described here) which is expressly designed to communicate with the 1996-1998 Volvo 850 and S70/V70/C70/XC70 and minimize your need to remember any of the necessary commands.

    If on Windows you don't like STNterm, Realterm, Hyperterminal, and PuTTY, then you might try TeraTerm on Vista / Win7 / Win8 / (and presumably Win10).

    If those aren't a good fit for you, check out the four Elm Electronics, Hyperterminal equivalent on Win8, and Wikipedia links included here for terminal emulators on various platforms: MacOS8 thru MacOSX, Win95 thru Win8, WinCE, Palm, etc.

    Hint for Android users:
    On Android, you might try one of these simple apps:

    • OBD Now Terminal app.

      It has a pleasant GUI that scrolls easily to see previous commands and responses.  And it comes preconfigured with a timestamped log file! "OBD Now Terminal" is most usable after issuing ATZ, then ATE0.

    • Bluetooth USB WIFI Terminal app.

      This also has a pleasant GUI that scrolls easily to see previous commands and responses.  It can also create a log file.  This app (by "Timers n Savers") works better than the previously recommended ElmBasic (which seems to no longer be available).  "Bluetooth USB WIFI Terminal" is usable after clicking both "CR" and "LF", then issuing ATZ, ATL1, and ATE0.

      But "Bluetooth USB WIFI Terminal" is most usable: a) after loading a command list (in their format) that begins with lines for ATZ, ATL1, ATE0, then includes 1 line for each of the commands you want to use; b) then clicking "Send Direct" and "LF", but leaving "CR" unchecked; c) then clicking any of the desired commands from the command list, scrolling to the next command, then repeating step c) until you're finished scanning.  It's not scripting, but at least use of the command lists eliminates most typing.

    Both of those apps are free and are adequate for issuing single commands one at a time.

    Note:
    Previously on this page, I had noted:

    "Even though some of the OBDII diagnostics software programs suggested by ELM327 vendors do provide the capability to interactively send requests (like our KWPD3B0 requests) after the connection with the car has been established, there is no OBDII diagnostics software program that I'm aware of that allows complete control of the ELM327 setup before an ISO9141-2 style connect is established.

    Consequently, this page requires the use of a terminal emulator to issue precisely what ELM327 commands and KWPD3B0 requests will work to retrieve the mileage."

    That's not entirely true.

    After experimenting with OBDwiz and TouchScan, I've been able to adapt some of the volvo850diag scripts to work with (some older versions of) OBDwiz / TouchScan and have been able to read the mileage. OBDwiz was tested with a ScanTool.net OBDLink SX. TouchScan Demo was tested with both the OBDLink SX and an ELM327 v1.5 USB clone.  Some of the steps involved have been documented in the \scripts\touchscan_obdwiz\readme*.txt file extracted from volvo850diag.zip.

    Just thought I should correct the above quote to say:

    At least 2 existing OBDII diagnostics software programs -- (some older versions of) OBDwiz and its sister TouchScan -- *have* been used to read the raw mileage data in the response to ECU 51 B903.

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

The required setup to read the Volvo vehicle mileage basically involves the following general steps (not necessarily in the order listed):

  • Prepare by exploring the following resources:

  • Install any drivers needed by your ELM327 tool.

  • Make necessary configuration changes for your type of ELM327 device.

  • For USB and DB9 serial devices, plug in the ELM327 to your phone / tablet / laptop / etc.
    For Bluetooth devices, pair the Bluetooth device with your computer.
    For wireless devices, perform the wireless equivalent of Bluetooth pairing.

  • Download and/or install an appropriate terminal emulator, if its not already provided on your smart phone / tablet / laptop / etc that's driving your ELM327 device.

  • Check for successful communication to the ELM327 device by using the terminal emulator to send the ELM327 command sequence -- ATZ, ATL1, ATE1, ATI, ATIIA 51 (where each of those 5 commands are entered on a separate line) -- while observing each of their responses.

    Note:
    For ELM327-compatible devices that connect via USB, you can even perform this initial communication test with the ELM327 (on the desktop) **before** doing the next step (in the car).

  • Plug in the ELM327 device to your car's OBDII port, ensuring it is plugged in firmly.

  • Turn ignition to pos II.

  • If you have a car which was required to handle OBDII emission diagnostics (eg, the USA '96-'97 Volvo 850), then use a vendor suggested OBDII software program to perform some OBDII diagnostics. Sometimes those programs are very useful in helping debug initial communication problems, such as mismatched speed settings, etc. Some commonly used OBDII diagnostic programs are: OBDwiz, TouchScan, Torque, etc. If that software can connect, then display any OBDII DTCs, Coolant Temp, RPM, Speed, Fuel Trims, etc, then the ISO9141-2 connection has definitely succeeded.

Everything after this Requirements 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 / S70 / V70 / C70 / XC70, and you already know a terminal emulator is setup properly, then you can skip to the next section to Read COMBI data.

Otherwise, using the above "required setup" bulleted list as a guide, the first order of business is to establish communication with the ELM327.  A serial terminal emulator can be used to do that. Terminal emulators work both with the USA cars that have OBDII emission diagnostics and with the European cars that did not provide OBDII emission diagnostics during the 1995-1998 time frame.

Some terminal emulators that have been used to retrieve the vehicle mileage from a 1996-1998 Volvo 850, S70, V70, etc. COMBI include:

Also, you should be able to use some of those included in:

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 these 5 commands -- ATZ, ATL1, ATE1, ATI, ATIIA 51 -- with something besides '?',
  • 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, AW 50-42 (if available), Power Seats (if available), etc.  This page will be of no use to you while using a KWPD3B0-incapable pseudo-ELM327 !!!

Hint:
Click here for help in detecting and dealing with a "partial" ELM327 device which does not respond to ATIIA 51 with an OK.

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 / S70 / V70 / C70 / XC70 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, you can a) relatively quickly test the ELM327 commands listed in the Warning above, and/or b) spend some more time and review the answer to the FAQ question mentioned in that Warning, since that FAQ answer goes into much more detail.]

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

If you have not yet connected via any OBDII diagnostic software and you have a USA 1995-1999 850 / S70 / V70 / C70 / XC70, you can still check if the ISO9141-2 style Slow Init connection can be established. Just use the terminal emulator to issue these 4 commands to the ELM327: ATZ, ATL1, ATE1, 0100 -- each on a separate line.  Check if the 0100 OBDII command and its response(s) appear similar to the following example when the headers/checksums display was disabled:

>0100
41 00 80 00 00 00
41 00 BE 1D B0 00

or similar to the following example for a vehicle that also had a Secondary Air system, and had headers/checksums display enabled.

>0100
48 6B 1F 41 00 80 00 00 00 93
48 6B 17 41 00 BE 1D F0 00 D6

If that is not the case -- ie, you can not initialize successfully (eg, you get "BUS INIT...ERROR" or "UNABLE TO CONNECT" responses), and/or you can not get the 0100 command to generate responses that are formatted somewhat similar to one of the above examples (where responses to 0100 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) repeat something in the above bulleted "required setup" list,
c) turn on your ignition,
d) do some more web research, and/or
e) ask some questions in the MVS 850, S70, V70... forum or some other Volvo forum.

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

Note:
In the remainder of this page, the COMBI will sometimes be referred to as ECU 51.  (A list of several of the other 1996-1998 Volvo 850 / S70 / V70 / C70 / XC70 ECUs' hexadecimal #s is available here).

Read COMBI data

ELM327 commands to read mileage

A list follows of the commands to read the mileage (using B903). 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 83 51 13
>B903

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 -- and there have not been any intervening resets (via ATZ, ATD, ATWS, power failure, or disconnecting the ELM327 from the car's OBDII port) after the KWPD3B0-specific setup just shown above.

>ATPC
>ATIIA 51
>ATWM 82 51 13 A1
>ATSI              (optional)
>ATSH 83 51 13
>B903

ELM327 commands to read ECU 51 DTCs and B9xx data

A more extended list follows of the minimum to read the ECU 51 DTCs and all ECU 51 B9 data. 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 83 51 13
>AE01
>B901
>B903
>B904
>B905
>B906
>B907
>B908
>B909
>B90A
>B90B
>B90C
>B90D
>B90E
>B9F0

And here are some extra B9xx commands that have been seen strictly on S70/V70.

>B9F1              (observed on '97 V70 TDI, my '98 S70 GLT, and other SVC70)
>B902              (on my '98 S70 GLT, and some other SVC70)
>B90F              (on my '98 S70 GLT, and some other SVC70)
>B910              (on my '98 S70 GLT, and some other SVC70)
>B912              (on my '98 S70 GLT, and some other SVC70)
>B913              (on my '98 S70 GLT, and some other SVC70)
>B914              (on my '98 S70 GLT, and some other SVC70)
>B915              (on my '98 S70 GLT, and some other SVC70)

ELM327 ECU 51 commands & responses examples (with links)

The following are two (2) examples of all the above commands and their responses:

Details of all the listed commands and their responses -- including the recently discovered S70/V70 specific B9xx commands/responses -- are now described (with extra ATI, ATDP, ATBD, ATKW, and ATPC commands thrown in for good measure).

Just click on each command's link to see that command's/response's detailed description.

850 example (with links)

This is an example of a '97 850 T5 having its COMBI DTCs and B9xx data being scanned with an ELM327 v1.5 clone USB cable.


>ATZ
ELM327 v1.5

>ATL1               (usually ATL1, but some terminal emulators require ATL0)
OK

>ATE1               (usually ATE1, but some terminal emulators require ATE0)
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               (optional)
BUS INIT: ...OK

>ATBD               (optional)
06 51 55 D3 B0 4F AE 51 13 A1 8F 09 02

>ATBD               (optional)
05 82 51 13 A1 87 09 81 13 A1 8F 09 02
>------ The first ATBD shows 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)

        You only see this ATBD response **if** the ATBD is issued
        within < 3 seconds after the "...OK" is finished.

>------ The 2nd ATBD shows a "82 51 13 A1 87" keepalive request
        sent by ELM327 as tester 13 to ECU 51.  The first one
        is usually sent 3-4 seconds after the "...OK", then the
        keepalive request is resent by the ELM327 every 3-4 seconds
        thereafter.

>------ 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 83 51 13
OK

>AE01
84 13 51 EE 01 05 DC

>B901
84 13 51 F9 01 A4 86

>B903
85 13 51 F9 03 34 30 49

>B904
85 13 51 F9 04 24 19 23

>B905
84 13 51 F9 05 10 F6

>B906
85 13 51 F9 06 E3 3A 05

>B907
85 13 51 F9 07 A0 05 8E

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

>B909
85 13 51 F9 09 F4 01 E0

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

>B90B
84 13 51 F9 0B FF EB

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

>B90D
84 13 51 F9 0D 00 EE

>B90E
84 13 51 F9 0E C3 B2

>B9F0
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


S70 example (with links)

This is an example of a '98 S70 GLT having its COMBI DTCs and B9xx data being scanned with a ScanTool.net OBDLink LX BT (Bluetooth) device.

In this example the ATSI, double ATBD, and ATKW commands are not used -- for the simple reason that they are seldom needed after the initial attempts to connect the ELM327 device to the COMBI, and because the ATBD commands are useless with the ScanTool.net OBDLink devices (that are based on the STNxxxx chips).  Also, in this example two (2) STxx commands -- STI and STDI -- are used which help to identify more clearly what kind of ELM327-compatible device this is.

Notice how the "BUS INIT: ...OK" occurs after the first command which causes the Slow Init -- ie, the AE01 -- not after the ATSI as in the 850 example above.

Also, notice there are two "7E B9 23" responses -- one for B909 and one for B9F0 -- which are simply temporary "Request in progress" informational messages that inform the ELM327 to continue waiting for the final response, instead of giving up and declaring NO DATA.  They are entirely benign (and just a nuisance to deal with).  It is common to see 1 or more of these "7E xx 23" messages during scanning of some S70/V70/C70/XC70 ECUs, but those messages are never (or almost never) seen on the 850.


>ATZ
ELM327 v1.3a

>ATL1               (usually ATL1, but some terminal emulators require ATL0)
OK

>ATE1               (usually ATE1, but some terminal emulators require ATE0)
OK

>STI                (optional)
STN1155 v3.4.1
>STDI               (optional)
OBDLink LX BT r1.2

>ATI
ELM327 v1.3a

>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

>ATSH 83 51 13
OK

>AE01
BUS INIT: ...OK
83 13 51 EE 01 D6

>B901
84 13 51 F9 01 B4 96

>B903
85 13 51 F9 03 83 4D B5

>B904
85 13 51 F9 04 B0 2D C3

>B905
84 13 51 F9 05 10 F6

>B906
85 13 51 F9 06 7D 44 A9

>B907
85 13 51 F9 07 A0 05 8E

>B908
85 13 51 F9 08 84 0B 79

>B909
84 13 51 7E B9 23 42
85 13 51 F9 09 F4 01 E0

>B90A
85 13 51 F9 0A 05 00 F1

>B90B
84 13 51 F9 0B FF EB

>B90C
86 13 51 F9 0C 52 73 7E 32

>B90D
84 13 51 F9 0D 05 F3

>B90E
84 13 51 F9 0E 0F FE

>B9F0
84 13 51 7E B9 23 42
92 13 51 F9 F0 00 09 14 89 30 20 20 41 09 16 81 33 20 32 33 8E

>B9F1
8A 13 51 F9 F1 19 96 06 03 08 00 00 98

>B902
84 13 51 F9 02 01 E4

>B90F
84 13 51 F9 0F 00 F0

>B910
84 13 51 F9 10 80 71

>B912
84 13 51 F9 12 32 25

>B913
84 13 51 F9 13 32 26

>B914
85 13 51 F9 14 0A 0F 0F

>B915
84 13 51 F9 15 00 F6

>ATPC
OK

This S70 example is a composite example. The B903-B909 data is from one of the very first readings when I bought the car -- before the Reset SRI (ie, turn off SERVICE light) and before the reprogramming of the SRI limits to values more to my liking.  During the 3+ years that I owned my '98 S70 GLT, the B901 and B90A-B90E and B9F0-B9F1 data always remained constant.  Also, the SVC70-specific B902 and B90F-B910 and B912-B915 data remained constant during the 2+ years that I was aware of those S70/V70/C70/XC70-specific items' existence.

Interpret COMBI data

We'll go down through each of the commands and responses in the just listed examples, 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.

The explanations for the commands/responses below are generalized to explain both 850 cases and (some of the) S70/V70/C70/XC70 cases.

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.

But keep in mind that the Volvo may take over 5 seconds before it realizes the protocol session has been terminated.

The timing window in which the ATPC "lesser" init works to reestablish KWPD3B0 communication vanishes completely:
  • when an ATZ is issued to reestablish OBDII emission diagnostics,
  • when an ATZ, ATD, or ATWS is issued for any other reason,
  • when a power failure occurs, or
  • when 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.

STI and STDI (optional)

The STI is the first of two (2) ST commands to help identify the ScanTool.net OBDLink devices more clearly.  It identifies the chip type and its firmware version.  In our case, the chip type = "STN1155" (which is what an OBDLink LX BT uses) and the firmware version = "v3.4.1".

The STDI is the second of two (2) ST commands to help identify the ScanTool.net OBDLink devices more clearly.  It identifies the device model and its hardware revision level.  In our case, the device model = "OBDLink LX BT" and the hardware revision level = "r1.2".

These ST commands (and all other ST commands) are only useful with ScanTool.net devices, eg, OBDLink SX USB, OBDLink LX BT, OBDLink MX BT, OBDLink MX+ BT (for Windows, Android, iOS), and OBDLink MX Wifi.

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-'98 850/S70/V70/C70/XC70, 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 / S70 / V70 / C70 / XC70. 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 bytes (that are encapsulated by the 3-byte header and the 1-byte checksum) to 7 in both directions [ie, max total message length = 11].  When ATAL is used, the ELM327 will allow 1 more of these bytes -- up to 8 -- when sending [ie, max total sending message length = 12] and an unlimited number of those (post-header, pre-checksum) bytes when receiving.

Use of ATAL is necessary for viewing a wide variety of responses sent back from the Volvo 850 / S70 / V70 / C70 / XC70 using the Volvo keyword D3 B0 protocol (KWPD3B0).

For the '96-'98 850/S70/V70/C70/XC70, 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 ECUs mentioned in the Volvo 850 and SVC70 keyword D3 B0 protocol ECU lists (except for ECU 18).  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 the earlier ELM327 devices which have basic KWPD3B0 protocol capabilities: v1.2, v1.2a, v1.3, v1.3a.

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

"I think the ATTA command to the ELM is not necessary. Here is my rationale. For protocol 3, ATTA sets the default header and wakeup messages, until overriden by ATSH and ATWM. It doesn't set the default receive filter, because protocol 3 normally uses J1979 style headers without a tester address. However, the ELM327 will switch to accepting responses with a tester address if you use ATRA or ATSR to specify the tester address; and the STN1130 will automatically do this if it sees a tester address in the request headers you set with ATSH.

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."

That seemed to make sense to me, so I eliminated ATTA 13 from my development version of volvo850diag, and have tested it extremely thoroughly with an ELM327 v1.5 USB cable, an OBDLink SX USB cable, an OBDLink LX Bluetooth tool, an OBDLink MX+ Bluetooth tool, and a BAFX Bluetooth tool.  I encountered no problems whatsoever with elimination of ATTA 13.

My testing of skipping ATTA 13 and only doing ATSR (or ATRA), ATWM, and ATSH reveals his contention is true.  So you can almost certainly ignore the ATPP 06 alternative (that this page previously suggested for several years) when ATTA 13 is not implemented in your ELM327.

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.

Historical note:
I've also been able -- on my 850 -- to use the default F1 tester address via ATTA F1 (in conjunction with ATWM 82 51 F1 A1 and ATSH 83 51 F1) to perform the ECU 51 B9xx commands below. And I've been able to use the F1 tester address to read ECU 58 (SRS) DTCs and clear an ECU 58 (SRS) DTC. However, I don't suggest doing that, since ATTA F1 does not work for ECU 01 (ABS) and probably other of the ECUs. So you might as well just standardize on the tester address of 13 that Vol-FCR, rkam, and Brick-Diag use. That does work for all the KWPD3B0-conversant ECUs.

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.

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. That's why the ATSI command was not included in the S70 example above.

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, and that's why the 850 example above does include them.

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 83 51 13

The ATSH 83 51 13 command sets up the proper header for KWPD3B0 requests that will have 2 bytes sandwiched after the header and before the checksum.  The way to interpret this header (and 99.99% of all request headers in the Volvo keyword D3 B0 protocol) 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.

83 is equivalent to 3 bytes, so when using this "83 51 13" header, 2 bytes of data must always be specified by the user (when sending the KWPD3B0 command to the ELM327).  The "ATSH 83 51 13" command must precede KWPD3B0 commands that consist of 4 hex digits -- eg, AE01, B903, B9F0.

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 84 51 13" command must precede KWPD3B0 commands that consist of 6 hex digits -- eg, A50701 -- ie, those that involve 3 bytes (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 ECU 51 Read DTCs Command

AE01

The AE01 command is the way to retrieve the ECU 51 DTCs using the ELM327.

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

The "84 13 51 EE 01 05 DC" response to the AE01 command (in our 850 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.

The 850 example's response to AE01 means:

       ECU 51 (COMBI) has 1 DTC: 05 -> CI-113 -- Low Fuel / Fuel Level signal interrupted.

However, if our response to the AE01 command had been "83 13 51 EE 01 D6" (as in our S70 example above), 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 AE01 command (and satisfying the AE01 request).
  • 5th byte = 01 = echo of request's 5th byte (ie, the request's "subfunction" byte).
  • 6th byte = checksum = D6 for this particular message.

There's 0 DTCs after the EE 01 and before the checksum, so the S70 example's response to AE01 means:

       ECU 51 (COMBI) has 0 DTCs!

Hint:
All KWPD3B0-conversant ECUs seem to use this AE01 request / EE01 response mechanism to read their DTCs.

Interpret ELM327 ECU 51 B9xx Data

B9xx Overview

The B9xx 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 B9xx command actually generates a KWPD3B0 request represented by "83 51 13 B9 xx cs", where "xx" = 01, 02, 03, 04, ..., 0D, 0E, 0F, 10, 12, 13, 14, 15, F0, or F1, and where "cs" is the automatically generated checksum.  As you can see the "83 51 13" is the header that we specified with the ATSH command, and the "B9 xx" comes from the B9xx command sent to the ELM327.

Their F9xx positive ack responses all have similar patterns:

  • 1st byte = 84, 85, 86, 8A, or 92 implies length = 4, 5, 6, 10, or 18 (decimal) bytes = 3, 4, 5, 9, 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-10, 12-15, F0-F1 = echo of request's 5th byte (ie, request's "subfunction" byte)
                 = the "xx" of the "83 51 13 B9 xx cs" request which is being positively acked
                 = the "xx" of the originating B9xx command.
  • 6th thru last-1 bytes = command specific values (see below).
  • last byte = checksum.

Each of the specific B9xx 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.

B901

The B901 command retrieves the 1 byte: A4 (hex) = 164 (decimal) in my USA '97 850 T5:

>B901
84 13 51 F9 01 A4 86 

and B4 (hex) = 180 (decimal) in my USA '98 S70 GLT:

>B901
84 13 51 F9 01 B4 96 

These values have always remained the same in their respective cars. I don't know exactly what B901 is. At first I thought it might be the "Ländercode" (ie, Country Code) which is displayed on the Brick-Diag Kombi-Parameter screen. But -- as can be seen in the values listed below -- the B901 codes do not have a one-to-one correspondence with a particular country. So my original Country Code guess wasn't quite correct.

The values for ECU 51 B901 that have been detected by kwpd3b0_interpreter.html (as of 2019-06-08):

  • F1 hex = 241 decimal, from 1 (originally) German 1997 V70 [w/ unactivated COMBI and MSA 15.7], 1 German S70/V70/C70/XC70 w/ MSA 15.7.
  • B4 hex = 180 decimal, from 6 USA 1998 S70/V70/XC70, 1 USA SVC70 (probably turbo), 1 USA '98 S70 GLT, 1 USA '98 C70 HPT.
  • A8 hex = 168 decimal, from 3 UK 850.
  • A6 hex = 166 decimal, from 1 Australia 850 [seems to be manual, turbo, was M43, now M44], 1 Australia 1996 850 R (not M44, not MSA 15.7).
  • A4 hex = 164 decimal, from 1 USA 1997 850 T5 sedan, 1 USA 1997 850R wagon, and 3 USA 850 (probably) turbo (of some sort).
  • 24 hex = 36 decimal, from 1 USA 1996 850 non-turbo, 1 USA 850 (probably) 1996 non-turbo, 4 USA 19?? 850, and 7 USA 19?? 850 (w/ Motronic 4.4).
  • B2 hex = 178 decimal, from 2 Canada S70/V70/XC70 (probably), 2 France S70/V70/XC70 (probably), 2 Netherlands SVC70, 2 Sweden S70/V70/XC70 (probably), 1 Sweden V70 T5 2.0 M44 B5204T3 manual trans (originally sold in Italy), 1 Finland S70/V70/XC70, and 1 Poland C70.
  • A2 hex = 162 decimal, from 1 France 850, 2 Netherlands 850, 1 Germany 850, 1 Denmark 850, 1 Turkey 850, and 1 Canada 850.
  • 31 hex = 49 decimal, from 1 France 850 w/ MSA 15.7, 2 other France 850, 1 Germany 850 (probably non-turbo), 1 Czechia 850, 1 Estonia 850, 1 Bulgaria 850 w/ MSA 15.7.
  • 23 hex = 35 decimal, from 1 Thailand 850 (probably), 2 Australia 850 (probably non-turbo), 1 Australia 850 non-turbo w/ Fenix 5.2, 1 Poland 850, and 1 Finland '98 S40.
  • 21 hex = 33 decimal, from 1 Italy 850 [in which B90E is not valid], 1 Switzerland 850 (probably non-turbo) w/ Fenix 5.2, 1 Finland 1997 850 B5252s (2.4l 10V) w/ Fenix 5.2, another 2 Finland 850, 2 Sweden 850, 1 Norway 850, 1 France 850, 1 Canada 1997 850 GLT, 1 other Canada 850.

One person suggested that Market Code might more accurately describe what B901 is.  Even if that's the case, the exact decoding of B901 still remains to be discovered.

Maybe its a collection of flags?!?!  Witness the similarity of the bits in B4, A4, 24 and the similarity in A8, A4, A2 and the similarity in B4, B2.

In any case, it is apparent from the above data that each individual B901 code seems to be associated with either 850 models or SVC70 models, but not both model classes.  Also, each B901 code seems to simultaneously identify a particular class of country/countries, eg, USA vs. UK vs. Europe vs. Europe/Canada vs. Pacific/Europe, etc.  Finally, each B901 code seems to possibly also identify turbo vs. non-turbo.  Consequently, the Volvo 850/SVC70 KWPD3B0 interpreter has been updated to reflect my inferences from the above data.

B903 - Vehicle Mileage

The B903 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 (as of 2016-02):
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.

The OTP Volvo 850 Service Manuals DVD (OTP-TP-51956) document "Combined Instrument, VDO 850 1996-" (TP-3801032), says on p28 that the Total Mileage is incremented "every 16 km/10 miles".  Also, that same DVD's document "Combined Instrument Yazaki S70/V70/C70 1998-" (TP-3802201) says the same thing on its p10.  So both the 850 VDO cluster and the S70/V70/C70 Yazaki clusters increment the Total Mileage after the same "16 km/10 miles" interval.

Since 1 mile = 1.609344 km (not 1.6 km), it remains to be seen which of the figures -- 16 km or 10 miles (that the OTP TP-3801032 and TP-3802201 documents refer to) -- correctly states when B903 is incremented.  It could be:

  1. every 10.0 mi (16.09344 km), or
  2. every 16.0 km (9.941939 mi).

Or it might even be some sort of approximation of both of the values, eg:

  1. every 16.1 km (10.0040762 mi).

Since this calculation is very hard to precisely measure beyond 1/50 or so, I've arbitrarily chosen the "ECU 51 B903 increments every 10.0 mi (16.09344 km)" paradigm -- the first one listed above -- and have converted (most all) the jonesrh Volvo 850 OBDII portal to use that paradigm.

You might think this doesn't matter much.  After all, a 10.0 mi - 9.941939 mi discrepancy of almost 0.06 mi every 10 miles is hardly noticeable after 10 miles.  But after 150000 miles, that amounts to a 900 mile discrepancy.

It remains to be seen if that paradigm is the absolutely, most accurate one (of the 3 listed).  But that's the one I've settled on -- probably permanently.

Thanks:
Many thanks to XantheFIN, mikeri, several other owners of 850 / S70 / V70 in countries that measure distance in kilometers, and the OTP Volvo 850 DVD for helping me see that B903 increments approximately every 10 mi or 16 km -- most probably for all the '96-'98 850 / S70/V70/C70/XC70 worldwide !!!

As you recall the 850 example's B903 command and its response were:

>B903
85 13 51 F9 03 34 30 49 

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

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

  2. Swap those two bytes. In our 850 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 850 example's 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 my particular 850's 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.

There is probably some way to estimate the lost mileage based on B90A. However, it's not yet fully understood how that works, so I'll not mention it any further in this B903 section.

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.

Even though it is titled as "Volvo 850 Mileage Converter", it works well as both a '96-'97 850 Mileage Converter and a '97-'98 Volvo S70/V70/C70/XC70 Mileage Converter.

Thank you, potatofi.com.

The S70 example's B903 command and its response were:

>B903
85 13 51 F9 03 83 4D B5 

I'll leave it to you to try its calculation using the 4-steps listed above for the 850 example.

  • 4D83 hex = 19973.
  • 19843 * 10 = 198430. That's the approximate miles.
  • 198430 * 1.609344 = 319342. That's the approximate km.

So 198430 miles (319342 km) is the S70 example's Vehicle Mileage (minus any lost mileage).

B904 - Mileage at Service Light Reset

The B904 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 B903.

As you recall the 850 example's B904 command and its response were:

>B904
85 13 51 F9 04 24 19 23 

The way to calculate the mileage from the 2 bytes in the B904 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 850 example, that is "24 19". Remember those are hex values.

  2. Swap those two bytes. In our 850 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 850 example's Vehicle Mileage (minus any lost mileage) when the last Service Light Reset was performed.

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

Note:
The remainder of this section just contains some specifics of my '97 850 T5 which help show a Service Light Reset was performed on ~2002-12-26, over 10 years in the past, and that help to show that car probably still had the original cluster.  If you're not interested in that, then feel free to skip to the B905 section below (or go elsewhere).

There likely were 0 lost miles at 64360, since an ABS would normally not fail by then, so I assume that 64360 miles is the actual mileage, plus or minus 10 miles.

My CarFax records an oil and filter change at 63921 miles. That is a discrepancy of 64360 - 63921 = 439 miles between the two mileage figures. It's equivalent to a 439 / 64360 = 0.68% difference.

I would speculate that the 63921 is what appeared on the mechanical odometer, and the "Service Facility", presumably a Volvo dealer, entered that mechanical odometer reading into whatever computer or bookkeeping system that eventually caused the oil and filter change to appear in the CarFax report. That's certainly what happened 3 years later when another unspecified type of servicing occurred and the mileage was recorded as 75776. And that's certainly what happened 6.25 years later when a tail light bulb was replaced at a Volvo dealer and the mileage was recorded as 75774. In those 2 cases the mileage recorded was essentially the same (75774) as what I saw on my mechanical odometer at 2013-04-20 19:32 -- the time these B903 thru B909 readings were made -- ~10.3 years after the 64360 oil and filter change on 2002-12-26.

I further speculate that the B904 mileage of 64360 and the mechanical odometer mileage of 63921 correspond to the exact same point in time, since the B906 value, as we see below in the B906 section, increments once every 6 hours (calendar time), and my B906 value can be interpreted as the exact number of 6-hour intervals between that 2002-12-26 oil and filter change service at 63921 miles and the 2013-04-20 19:32 scan of B906 -- 10.318 years in the past (!!!!!). It's highly likely that B904 and B906 were updated at the same time -- B904 being overwritten with the B903 value and B906 being zeroed.

So -- if B904's 64360 and mechanical odometer's 63921 correspond to the same time -- I wonder why there's a 2/3 of 1% discrepancy?

  • Maybe the mechanical odometer was underreporting for some reason. Maybe it already had a problem that was manifesting. After all, it did definitely fail within 75776 - 63921 = 11855 miles of the 63921 oil and filter change.

  • Someone on Matthew's Volvo Site said there's almost always a discrepancy (that can be as high as this one) between the miles reported by the dealer using the Volvo Scan Tool (VST) and the physical odometer reading.

  • Maybe some sort of initial factory testing of a vehicle causes the B903 value to get ahead of the mechanical odometer reading.

  • 2016-02-13 brainstorm: The 2/3 of 1% discrepancy -- to be exact 0.68% -- referred to in this section's jonesrh B904 historical notes is surprisingly similar to the 10.0 mi vs. 9.941939 mi discrepancy (ie, 0.58% discrepancy) implied in the New understanding of B903 value note.

    If we interpret our present example's 1924 hex using the "every 16.0 km (9.941939 mi)" paradigm, instead of the arbitrarily chosen "every 10.0 mi (16.09344 km)" paradigm, the following calculations arise:

    1. Convert the 1924 hex to decimal, then multiply by 16.  In our case we have: 1924 hex = 6436 decimal, and 6436 * 16 = 102976.  That represents 102976 km.

    2. Convert to miles by dividing by 1.609344 km/mile.  In our case we have: 102976 km / (1.609344 km/mile) = 63986 miles.

    That 63986 miles calculation -- resulting from an "increment ECU 51 B903 once every 16 km" approach -- yields only a 0.1% error compared to the odometer observed of 63921 miles.  Very interesting!  That seems to suggest I might need to switch to the "every 16.0 km (9.941939 mi)" paradigm instead, or at least incorporate it as an alternative interpretation.

Who knows?  Maybe there's a knowledgeable Volvo guru out there who can inform us.

B905 - Service Reminder Interval in Kilometers / 500

The B905 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 both the 850 and S70 examples' B905 command and response were:

>B905
84 13 51 F9 05 10 F6 

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

  1. Get the one byte after the "F9 05" and before the checksum. In our examples, 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.

  • B90A, lost_km_manipulation, and lost_miles_manipulation are not part of the comparison.  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-'98 850 / S70 / V70 / XC70 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.

For some details on the new info concerning B903, B905, and B90A, see items 03, 05, and 0A in jonesrh's ECU 51 B9 Meaning of Values raw notes.

Slight inaccuracy in formula that predicts when SERVICE light will illuminate:
On 2018-09-08, when my '98 S70's B905 SRI Mileage limit was 5000 km, the SERVICE light came on somewhere between ~4 miles and ~30 miles **AFTER** when it was predicted to come on. So there is a slight inaccuracy in the formula above that predicts when the SERVICE light will come on.  The amount of the slight inaccuracy will probably predict SERVICE light illumination ~16-32 km (~10-20 miles) for every 5000 km (~3107 miles) **before** the SERVICE light actually does illuminate (when engine turned on).

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

Then display the new Service Reminder Interval Mileage limit with:

>ATSH 83 51 13
>B905

Alternatively, to reprogram this Service Reminder Interval Mileage limit with a pushbutton GUI, either:

  • download volvo850diag.zip to a Windows machine, follow its setup instructions, then use volvo850diag's "Select SERVICE Reminder Indicator (SRI) limit(s)" pulldown and "Reprogram SRI limit(s)" button;
or:

B906 - 1/4 Days since Service Light Reset

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

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

>B906
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 B906 request's F906 response is:

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

  2. Swap those two bytes. In our 850 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.

B907 - Service Reminder Interval in 1/4 Days

The B907 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 850 and S70 examples' B907 command and response were:

>B907
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 B907 request's F907 response is:

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

  2. Swap those two bytes. In our examples, 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,

and especially since all but 10 of the observed 850/S70/V70/XC70 have this B907 value set at 1440, and since 5 of those 10 exception cases equalled:

  • 02D0 hex =  720 decimal -> 180 days = 6 months (at 30 days/mo),

and 1 of the 10 exceptions equalled:

  • 0B40 hex =  2880 decimal -> 720 days = 24 months (at 30 days/mo),
we can reasonably assume that: a) the factory setting is probably 1440 decimal -> 360 days ~= 12 months, or either: b) the VST uses the Service Reminder Interval in Months to calculate the # of 1/4 days by using the simple 30 * 4 multiplier (if the VST does that automatically), or c) quite a few service technician have used the lazy, but close enough, 30 days = 1 month calculation.

The other 4 of the 10 exception cases equalled:

  • 02EE hex =  750 decimal -> 187.5 days = 6 calendar months,

At the present time, I speculate that the 187.5 days cases have been reprogrammed sometime after the factory -- maybe with Brick-Diag Full, maybe with the VST or a VST lookalike, or maybe with info from volvo850diag, this page, or elsewhere that I've published the info.

Back to our example... It is probably true that if the Service light were to illuminate due to our example's 12 month interval transpiring (ie, our B907 = 1440 case), 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

Then display the new Service Reminder Interval 1/4 Days limit with:

>ATSH 83 51 13
>B907

Alternatively, to reprogram this Service Reminder Interval 1/4 Days limit with a pushbutton GUI, either:

  • download volvo850diag.zip to a Windows machine, follow its setup instructions, then use volvo850diag's "Select SERVICE Reminder Indicator (SRI) limit(s)" pulldown and "Reprogram SRI limit(s)" button;
or:

B908 - Engine Hours since Service Light Reset

The B908 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 850 example's B908 command and response were:

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

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

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

  2. Swap those two bytes. In our 850 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.

B909 - Service Reminder Interval in Engine Hours

The B909 command retrieves 2 bytes which equal the Service Reminder Interval in Engine Hours -- also known as the Service Reminder Interval Engine Hours limit.

On my car, this value had always equaled 500 (until I experimented with reprogramming it).

The 850 example's B909 command and response were:

>B909
85 13 51 F9 09 F4 01 E0 

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

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

  2. Swap those two bytes. In our examples, 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 B905 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

Then display the new Service Reminder Interval Engine Hours limit with:

>ATSH 83 51 13
>B909

Alternatively, to reprogram this Service Reminder Interval Engine Hours limit with a pushbutton GUI, either:

  • download volvo850diag.zip to a Windows machine, follow its setup instructions, then use volvo850diag's "Select SERVICE Reminder Indicator (SRI) limit(s)" pulldown and "Reprogram SRI limit(s)" button;
or:

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

The B90A 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.

Also, that same OTP 850 DVD's document "Combined Instrument Yazaki S70/V70/C70 1998-" (TP-3802201) says similar things about "Manipulation" on p10, p77, p134, and p138.

So both the 850 VDO cluster and the S70/V70/C70 Yazaki clusters keep track of the hours of mileage "Manipulation" when the Vehicle Speed Sensor (VSS) was missing.

The Volvo '96-'97 850 VDO cluster's "Manipulation hours" and the Volvo '97-'98 S70/V70/C70/XC70 Yazaki cluster's "Manipulation hours" is further believed to indirectly approximate the "lost" mileage from when the ABS module was not supplying the Vehicle Speed Sensor (VSS) signal.

ECU 51 B90A is thought to be that "Manipulation hours" value (or some other reflection -- one way or another -- of "lost" mileage).

The 850 example's B90A command and response were:

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

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

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

  2. Swap those two bytes. In our 850 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 B90A section, and jump directly to B90B.

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

Note:
The complicated lost_mileage_manipulation calculations included in many 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!  But this section does provide a brief explanation of two guesses (along with a link to explore some alternative ideas).

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

    Judging from forums that discuss Brick-Diag Free v0.0.6.6 details and, especially, judging from the OTP Volvo 850 Service Manuals DVD's "Combined Instrument..." documents, and knowing that the primary reason for a missing Vehicle Speed Sensor (VSS) is failing ABS solders, the 34 (in our 850 example above) presumably means 34 hours that the VSS from the ABS was not being supplied properly to the COMBI.

    If so, then the only way I can think of to calculate "lost" mileage from that 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

    For details to this "B90A * 500 km" approach, see item 0A in jonesrh's ECU 51 B9 Meaning of Values raw notes.

    Admittedly, there is nothing in the OTP Volvo 850 DVD which would lend credibility to this approach, but it's the only thing that's worked reasonably well for me so far.

To test my hypotheses, I propose that other 1996-1998 Volvo 850 / S70 / V70 / C70 / XC70 owners, especially those with both non-functioning speedometers and the ABS light on, make B903, B904, B905, B908, and B90A measurements to verify:

  • if B903 does not increment at all, or increments much less than the actual driven miles (as checked via a GPS, highway mileage markers, Google Maps, Mapquest, etc), and

  • when B90A increments.

We shall see if the "B90A * 500 km" approach or the "B90A-derived hours * Avg MPH or Avg Km/h" approach or some other approach works better as feedback comes in from other '96-'98 850/S70/V70 owners with ECU 51 B90A > 0.  We might even find that ECU 51 B90A has absolutely nothing to do with the "Manipulation in hours" parameter and "lost" mileage.

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.

Notes:
The OTP Volvo 850 DVD indicates that the "Manipulation" parameter is read only.  It is apparently a permanent record of "lost" mileage (involving the present instrument cluster).

I've come to the tentative conclusion that the B90A value likely has never caused any sort of increase to the B903 counter.

Idea for further exploration:
For some details on the early 2016 changes concerning B903, B905, and B90A, see items 03, 05, and 0A in jonesrh's ECU 51 B9 Meaning of Values raw notes.

B90B

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

The 850 and S70 examples' B90B command and response were:

>B90B
84 13 51 F9 0B FF EB 

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

  1. Get the one byte after the "F9 0B" and before the checksum. In our examples, 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.  The two values which have been seen so far are:

  • FF (all cars -- both turbo and non-turbo, both 850 and SVC70 -- except for following 6 cars),
  • 80 (seen on 1 '98 V70, 1 USA '98 C70 HPT, 1 '98 XC70, and 3 other apparent S70/V70/C70/XC70).

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?

B90C

The B90C command retrieves 3 bytes which I think might represent 3 different temperatures.

On my 850, those 3 bytes have never changed. They are the same on the initial reading -- when the bad ABS module was sending flaky speed signals -- and now when the repaired ABS module has consistently sent good speed signals for over 2 years.

Nothing on the Brick-Diag Kombi-Parameter screen (or OTP Volvo 850 DVD) seems to suggest an explanation for these values.

The 850 example's B90C command and response were:

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

Possible ways to calculate something meaningful from the 3 bytes in the B90C request's F90C response are:

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

  2. Convert them each individually from hex to ASCII. That yields "Knx".

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

  4. Swap the order of the three bytes. In our 850 example, that becomes 786E4B hex.

  5. Convert that hex value to decimal. In our case we have: 786E4B hex = 7892555 decimal.

  6. Convert each byte individually assuming they are 3 different temperatures.

I can't think of a possible meaning for either "Knx" or 7892555.

I think it is unlikely that the "75 110 120" sequence represents 75000, 110000, and 120000 miles or 75000, 110000, and 120000 km.

But the "75 110 120" sequence could potentially be explained as 3 temperatures which are used in the algorithm to control the Instrument Panel's Temp gauge.  Two different ways of interpreting as temperature have now been evaluated:

  • 6a. This site's original temperature interpretation, in which the temperatures were assumed to be converted in the exact same manner as the temperature in: the response to the OBDII emission diagnostic 0105 command, and the response to the KWPD3B0 command for ECU 51 A50401.

    Hint:
    For details on the ECU 51 A5xx01 data, issue everything up through A50901 in the elm327_volvo_850_svc70_scan_combi_and_all_dtcs.txt section, then feed all the results to Volvo 850 V70 keyword D3 B0 protocol interpreter.  The resultant "Gleanings" for the ECU 51 E5xx responses will serve as their explanations.

    This original temperature calculation for each byte involved:

    • Convert the byte from hex to decimal.
    • Subtract 40 to get the temperature in Celsius.
    • If desired, convert the Celsius to Fahrenheit using the formula (C * 9/5) + 32 = F.

    In our 850 example, the three bytes yielded:

    • 4B hex =  75 ->  75 - 40 = 35 C =  95 F.
    • 6E hex = 110 -> 110 - 40 = 70 C = 158 F.
    • 78 hex = 120 -> 120 - 40 = 80 C = 176 F.
  • 6b. The newer, much simpler, temperature interpretation -- courtesy of XantheFIN -- in which the temperatures are assumed to be in Celsius, requiring no conversion (other than to Fahrenheit).

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

    This "near horizontal to red zone" temperature calculation for each byte involves:

    • Convert the byte from hex to decimal.
    • Assume that is the temperature in Celsius -- no substraction is needed.
    • If desired, convert the Celsius to Fahrenheit using the formula (C * 9/5) + 32 = F.

    In our 850 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.

It is known from OTP Volvo 850 DVD documents that a normal operating temp is 80 C to 105 C -- at least for the 850 Motronic 4.4.

The original "three temperatures" interpretation involved: 95 F (35 C), 158 F (70 C), and 176 F (80 C). Those temperatures correspond to my 850 Temp gauge's: bottom tick mark, 1/3 mark, and 1/2 (horizontal) mark of normal operating temperature. Actually, the 95 F is reached about 1-2 minutes before the gauge begins rising (from its very bottom, resting state).

The "near horizontal to red zone three temperatures" interpretation involves: 167 F (75 C), 230 F (110 C), and 248 F (120 C).  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.

Note:
On 2015-12-05, I checked precisely when my '97 850 T5 Temp Gauge needle first becomes horizontal and when the needle first goes below horizontal.  The results were:

OBDII 0105 73 = needle 10-15 degree angle below horizontal = 75 C = 174 F = B90C 4B.

OBDII 0105 77 = needle definitely below horizontal = 79 C = 174 F.
OBDII 0105 78 = needle maybe at / maybe below horiz = 80 C = 176 F = normal oper temp.
OBDII 0105 79 = needle appears to be horizontal = 81 C = 178 F.
OBDII 0105 7A = needle definitely horizontal = 82 C = 180 F = B90C 52.

That agrees with the idea that the normal operating temp begins at 80 C, and suggests the Temp Gauge needle goes horizontal at or very close to when the normal operating temp is reached.

That agrees only marginally with the 6b idea that 75 C is "almost horizontal".  But it definitely agrees with the 6b idea that 110 C and 120 C are above the normal operating temp range (that terminates at 105 C), so they could conceivably be the points at which the needle rises above horizontal and reaches the red zone, respectively.

Previously I'd seen that when my car idles for long periods of time (while the car is idling at 70 F ambient temp conditions), the Temp gauge needle stays on horizontal while the coolant temp continues to rise to 217 F, then the fan kicks on for a short while, the temp falls to 199 F within a few seconds, then the cycle repeats from 93 C (199 F) to 103 C (217 F) and back, over and over.

That agrees with the idea that the normal operating temp goes up to 105 C.

Here's another temperature fact. It is known from OTP Volvo 850 DVD documents that if the ECM reaches 110 C the Motronic 4.3 will set the "EFI-513 Temperature warning level 2" DTC. So maybe the 6E hex = 110 refers to a temp at which the COMBI will say "I'm too hot". I doubt that, since no such COMBI DTC is mentioned anywhere, but I suppose it's possible.

Yet another possibility for explaining B90C is what the Brick-Diag Kombi-Parameter screen calls "Drehzahl", ie, RPMs.  Brick-Diag's author, daniel2345, suggests this is 5000 / 7000, but I can't see how to get values like that out of these 3 bytes.

My 1st choice is the "three temperatures" interpretation (updated on 2015-12-09) to use the higher numbers which might correspond to temperatures when the Temp needle "almost reaches horizontal", "begins to rise above horizontal", and "reaches red zone".  I no longer have a 2nd choice.  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.

By the way, it appears that B90C is consistently different between the 850 and TDI SVC70 vs. the non-TDI S70/V70/C70/XC70 (ie, the SVC70 which do *not* use MSA 15.7).  On a total of 51 separate 850 (and 2 separate SVC70 w/ MSA 15.7) -- apparently from USA, Canada, UK, Netherlands, Norway, Sweden, Finland, Estonia, Poland, Denmark, Germany, France, Switzerland, Italy, Bulgaria, Turkey, Thailand, and Australia -- that have had their ECU 51 B90C data submitted to kwpd3b0_interpreter, the B90C command and response were always the same as the 850 example above.  Whereas, on 19 different S70/V70/C70/XC70 [none of which are known to use MSA 15.7], the B90C command always produced the following (different from 850) response:

>B90C
86 13 51 F9 0C 52 73 7E 32 

If interpreted as temperatures using the new (as of 2015-12-09) "three Celsius temperatures from near horizontal to red zone" interpretation, that '98 S70/V70/C70/XC70 response to B90C corresponds to: 180 F (82 C), 239 F (115 C), and 259 F (126 C).  All of those temps are higher than any B90C values (interpreted as temps) that have been seen on any 850 data submitted to kwpd3b0_interpreter.html.

Two pieces of info which seem to (at least mildly) support the idea that the 2nd ECU 51 B90C value might be the temp at which the needle begins rising above horizontal:

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

B90D - Fuel Level Adjustment  <<< NEW INTERPRETATION in 2017-03! <<<

The B90D command retrieves 1 byte. On my '98 S70 GLT, this has been discovered to apparently be a Fuel Level Adjustment which affects:

  • at what fuel level the COMBI turns on the Low Fuel light, and
  • what fuel level is displayed at the left side of the dash.

For those with a 6-function Trip Computer on an S70/V70/C70/XC70, this is suspected to also affect:

  • what is displayed by the Trip Computer's "miles -> 0" or "km -> 0" function.

This ECU 51 B90D value is usually 00 (for 850 and some SVC70) or 05 (for the majority of SVC70).  For all 850 cars (seen by kwpd3b0_interpreter.html), it has always been 00.  But a 05 has been seen in some 70-series cars: 1 '97 V70 T5, 1 '97 V70 TDI, 1 '98 S70 GLT, 3 different '98 V70, 1 SVC70 TDI, 1 SVC70 (probably turbo), 1 Poland C70, and 8 other 70-series cars.  But the 1 known-to-be '98 XC70 that's been observed, had 00 for B90D.  Also, 1 other '98 V70, 1 USA '98 C70 HPT, and 3 other (probable) S/V/C70 had 00 for B90D.  So it's clear the 05 is not always used by the '97-'98 SVC70.

The S70 example's B90D command and response were:

>B90D
84 13 51 F9 0D 05 F3 

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

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

  2. Convert the hex to decimal. In our S70 example, we have: 05 hex = 5 decimal.

Judging from the info in the OTP Volvo 850 DVD's document on the 1998 Yazaki S70/V70/C70/XC70 COMBI, this is (purportedly) always one of the following for the S70/V70/C70/XC70:

      -5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5

But Brick-Diag Free v0.0.6.6 only shows the following values in its pulldown menu for: instruments Yazaka / MY98 / fuel gauge:

      -5, -4, -3, -2, -1, 0, +1

The OTP Volvo 850 DVD document mentions that the Fuel Level Adjustment can be -5 liters to +5 liters in increments of 1 liter, or can be from -2 US gallons to +2 US gallons in increments of 0.5 gallon.

But in my experimentation with reprogramming the Fuel Level Adjustment, I discovered that all values of B90D from 00 to 7D can be used. With a tank half-full at 9 gallons, and starting with a B90D value of 00 [already changed from its original value of 05], then incrementally reprogramming B90D to an ever higher value until finally reaching the max of 7D, the Fuel Level needle is observed to do the opposite -- go lower and lower and lower (albeit very, very slowly [it can take several minutes for the needle to finish its change]), until finally ceasing the adjustment at around 2 gallons. Then reprogramming B90D once more from 7D to 00 will cause the needle to suddenly jump back to its pre-test position around 9 gallons.  Voila!  There's a much wider range of Fuel Level Adjustment than the OTP Volvo 850 DVD document describes -- ~7 US gal -- and none of those adjustments were done with a negative value (like the ones shown in the OTP Volvo 850 DVD document or like the ones shown in the Brick-Diag Free v0.0.6.6 "fuel gauge" pulldown menu).

SVC70 ECU 51 B90D = 5 -- ie, the most commonly observed value for the SVC70 -- is suspected to mean "no adjustment", ie, 0.0 US gal = 0.0 L = the "0" in the Brick-Diag Free v0.0.6.6 "fuel gauge" list.

SVC70 ECU 51 B90D = 0 -- ie, the only other value seen so far in SVC70 (other than during my own experimentation, or during other SVC70 owner's obvious experimentation) -- is suspected to correspond to the Brick-Diag Free v0.0.6.6 "fuel gauge" list "+1" value.


Using my observation that raw hex 7D (ie, 125) equates to a range of 7 US gal, and using raw hex 05 as the "zero point", the following simplified table for SVC70 ECU 51 B90D can be derived:

00  = +0.280 US gal ~= +1 L = possibly Brick-Diag Free's +1
05  =  0.000 US gal  =  0 L = possibly Brick-Diag Free's  0
0A  = -0.280 US gal ~= -1 L = possibly Brick-Diag Free's -1
0E ~= -0.5   US gal ~= -2 L = possibly Brick-Diag Free's -2
13  = -0.784 US gal ~= -3 L = possibly Brick-Diag Free's -3
17 ~= -1.0   US gal
18  = -1.064 US gal ~= -4 L = possibly Brick-Diag Free's -4
1D  = -1.344 US gal ~= -5 L = possibly Brick-Diag Free's -5
20 ~= -1.5   US gal
29 ~= -2.0   US gal
7D  = -6.720 US gal  = -25.438 L

The 850 example's B90D command and response were:

>B90D
84 13 51 F9 0D 00 EE 

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

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

  2. Convert the hex to decimal. In our 850 example, we have: 00 hex = 0 decimal.

This is suspected to always be 0 for the 850, ie, that Fuel Level Adjustment is not possible on the 850 VDO COMBI.

For more details on interpreting SVC70 (and 850) ECU 51 B90D as Fuel Level Adjustment, see item 0D in jonesrh's ECU_51_B9_Meaning_of_Values_raw_notes.rtf That item 0D also provides a clue on how to reprogram the S70/V70/C70/XC70 ECU 51 B90D Fuel Level Adjustment (and it shows a more detailed table than the simplified table shown above).

Maybe someone can chime in now about how much my interpretation of the Fuel Level Adjustment differs from the VST's "official" interpretation.

But regardless how much my interpretation might be off quantitatively, we at least know now how to reprogram the SVC70 Fuel Level Adjustment somehow, if the need arises.

B90E - Tire Size

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

The 850 example's B90E command and response were:

>B90E
84 13 51 F9 0E C3 B2 

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

  1. Get the 1 byte after the "F9 0E" and before the checksum. In our 850 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, there's two things which conflict with that "B90E = Tire Width (in mm)" idea:

  • 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 tire revolution, not just one of those 3 values.

  • Several Volvo owners have submitted values to kwpd3b0_interpreter.html which don't look anything like a tire width in mm.

    Here's a list of the B90E values that kwpd3b0_interpreter.html has seen (as of 2019-06-08):

    • hex C3 = 195 -> 195 mm =
      A factory installed tire (section) width mentioned in the 1997 850 Owner's Manual. That's the only one that's almost certainly a Tire Width.
      It has been seen in my USA 850 and in 1 Finland 850.

    • hex 0F = 15 -> 15 in =
      A wheel diameter (presumably).
      Has been seen in 1 USA 1998 S70 GLT, 2 USA 1998 V70, 1 USA S70/V70/XC70 (probably), 1 Canada S70/V70/XC70 (probably), 2 Netherlands SVC70, 1 France S70/V70/XC70 (probably), 1 German S70/V70/C70/XC70 w/ MSA 15.7, 1 Sweden (original Italy) '97 V70 T5, 1 Sweden SVC70 (probably non-turbo), and 1 Finland SVC70.

    • hex 27 = 39 =
      Has been seen in 1 USA 1998 XC70 and in 1 USA 1998 V70.
      Approximately halfway between 38.1 cm (15 in) and 40.64 cm (16 in).
      Is this a cm estimate of wheel diameter?

    • hex 22 = 34 =
      Has been seen in 1 USA '98 C70 HPT, 2 USA '98 SVC70, 1 USA SVC70 (probably turbo), 1 Canada S70/V70/XC70 (probably), and 1 France SVC70.  Not sure what this value of 34 means. Maybe it is 2 * 17 inches.

    • hex 1E = 30 =
      Has been seen in what is believed to be 22 different European 1996-1997 850 (1 from UK, 1 w/ MSA 15.7 from France, 4 others from France, 3 from Netherlands, 1 from Denmark, 2 from Germany, 1 w/ Fenix 5.2 from Switzerland, 1 from Czechia, 1 from Poland, 1 from Norway, 2 from Sweden, 1 '97 850 B5252s (2.4l 10V) w/ Fenix 5.2 from Finland, 1 other 850 from Finland, 1 from Estonia, and 1 w/ MSA 15.7 from Bulgaria), as well as 1 from Thailand, 5 from Australia, and 1 from New Zealand.  Has also been seen in 1 USA 1997 850R wagon, 3 USA 850 w/ Motronic 4.4, another 9 USA 850, 1 Canada '97 850 GLT, 2 other Canada 850, and in 1 850 (probably from USA, but possibly from Japan).

      In all 46 of those B90E = 1E cases, each car's B90B thru B90E have the same respective values: B90B = FF, B90C = 4B 6E 78, B90D = 00, B90E = 1E.

      Unknown what this decimal 30 might be referring to?!?!  Maybe it's some sort of index in a table listing different tire sizes.

      In any case, it is the most often observed value for ECU 51 B90E.

      [There has been 1 additional car with B90E = hex 1E -- ie, a Poland C70. This is mentioned separately, since it is the first such SVC70 observed with ECU 51 B90E = hex 0F, and this situation is considered to be an anomaly, possibly due to owner reprogramming of ECU 51 B90E via the "850 OBD-II" Android app.]

    • hex ?? = N.A. (Not Applicable, or Not Available)
      This case describes the 6 cars that responded to the ECU 51 B90E request with "7F B9 12", which suggests the COMBI might have an earlier form of its firmware that had not yet implemented Tire Size programming.

For some details on those two situations that conflict with the "B90E = Tire Width (in mm)" idea, see jonesrh's ECU 51 B9 Meaning of Values raw notes item 0E as well as the calculations in Tire Size comparison between 195/60 R15, 205/55 R16, etc..

It remains to be seen exactly how to interpret this parameter, though my B90E tests in 2014-08 indicate that it *is* very likely some sort of encoding of the Tire Size.

I'm open to suggestions on its interpretation, especially the hex 27 and hex 1E mentioned above. And I'm curious what other '96-'98 850/S70/V70/C70/XC70 owners show for their ECU 51 B90E value.

Any variance of the COMBI's Tire Size parameter vs. the actual tire size might explain any differences in mileage between what the Instrument Panel reports -- either via the mechanical odometer or B903 and B904 mileages -- vs. the actual mileage that is transversed and is measured by mile markers along the highway.

Since I am unable to obtain Brick-Diag Full, I've experimented with changing ECU 51 B90E to see how it affects the counting of miles. In 2014-08 I changed my B90E value from 0xC3 = 195 to 0xCD = 205 just like the following Hint explains.

Hint:
The way to use an ELM327 compatible device to manually reprogram this purported Tire Size parameter is to use the ECU 51 B80Exx command.  For example, "B80E CD" reprograms the encoded Tire Size parameter to 205 when issued as:

>ATSH 84 51 13
>B80E CD

Then display the new B90E (encoded Tire Size) parameter with:

>ATSH 83 51 13
>B90E

I did this partially to experiment with B90E, and partially because my car has always had 205/55-R16 tires on it (at least while I've owned it), and I figured 205 would better match the 205/55-R16 tires and give a more accurate reading of the mileage. But such was not the case!  It turns out that the value of ECU 51 B90E = 0xCD = 205 read 0.1 miles extra per 8.25 miles. In other words, it counted 1.2121% too high, compared to the actual miles traversed by my car. The comparison was made between the Trip Computer's Odometer vs. the freeway mile markers.

So I then changed ECU B90E back to its original value of 0xC3 = 195, which it had been previously for (at least) as long as I've owned the car. The commands used are shown in the following Hint. Of course, I was already connected to ECU 51 when issuing those commands.

Hint:
The way to use an ELM327 compatible device to manually reprogram this purported Tire Size parameter is to use the ECU 51 B80Exx command.  For example, "B80E C3" reprograms the encoded Tire Size parameter to 195 when issued as:

>ATSH 84 51 13
>B80E C3

Then display the new B90E (encoded Tire Size) parameter with:

>ATSH 83 51 13
>B90E

I then went for a drive and duplicated the previous freeway mile markers test.  Surprise!  Even though I have 205/55-R16 tires on the car, a value of ECU 51 B90E = 0xC3 = 195 causes the Trip Computer Odometer to track the freeway mile markers near perfectly -- off by about 0.02 mile per 25 miles, ie, better than 99.9% accuracy. I was amazed!  That's way better than I expected!

I can't explain: a) why ECU 51 B90E = 205 doesn't read 2.748% more miles like my Tire Size comparison between 195/60 R15, 205/55 R16, etc. analysis suggests it would, instead of the 1.2121% more that I observed. Nor can I explain: b) why a value of 195 would match up very well with my 205/55-R16 tires. It confounds me.

But even though I can't explain those 2 things, I do have enough sense to leave my car's COMBI B90E value at 0xC3 = 195.

Moral of this ECU 51 B90E reprogramming story:
If your Trip Computer Odometer tracks the freeway mile markers well, then do not change ECU 51 B90E. In that case, leave B90E alone.

But if your Trip Computer Odometer does not track the freeway mile markers (or GPS, or other accurate mileage marker) -- eg, after you change your wheel/tire size -- then you might consider reprogramming ECU 51 B90E to one of the values that have been seen on other cars:

  • C3
  • 1E (the most common value for 850 model)
  • 0F
  • 27

or you might try the value that I experimented with:

  • CD
substituting one of those hex values in the "B80E xx" command displayed in one of the two Hint boxes above.
Warning:
The OTP Volvo 850 DVD suggests Tire Size should seldom ever need reprogramming.

Apparently, for the VDO cluster used with '96 850, the Tire Size parameter should be reprogrammed only when replacing the printed circuit board.

Apparently, for the Yazaki cluster used with '98 S70/V70/C70, the Tire Size should be reprogrammed when switching from small circumference to large circumference tires.

That info can be seen in the OTP Volvo 850 DVD's documents:
  • "Combined Instrument, VDO 850 1996-" (TP-3801032), p28 and p154.

  • "Combined Instrument Yazaki S70/V70/C70 1998-" (TP-3802201), p11 and p139.  In this document you can search for "tire size" to find those pages.  The second page seems to suggest that all '97-'98 S70/V70/C70/XC70 Yazaki "Tire Size" values map into either "STANDARD - 195/60 R15 - Small circumference" or "205/55 R16 - Large Circumference".

B9F0 - Hardware & Software Versions

The B9F0 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 850 example's ECU 51 (COMBI) B9F0 command and response were:

>B9F0
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 B9F0 request's F9F0 response is:

  1. Get the 15 bytes after the "F9 F0" and before the checksum. In our 850 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 case, it equals "001". This is the software revision #.

Hint:
B9F0 is an excellent ECU identification tool.

All KWPD3B0-conversant ECUs seem to use this B9F0 request / F9F0 response mechanism, and they use the same format for the part # and the revision #.

If you scan for all ECUs on a Volvo and find one that connects via ISO9141-2, identifies itself with keywords D3 B0, responds to B9F0, but has an ECU # whose purpose is not yet known, then you can usually do a web search for the Hardware # derived from the F9F0 response and discover the ECU's function.

B9F1 - Date/Time

The B9F1 command retrieves 7 bytes which contain a Date and Time of the ECU.

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

>B9F1
8A 13 51 F9 F1 19 96 06 03 08 00 00 98 

This likely means: 1996-06-03 08:00:00, ie, year-month-day hour:minute:second.

The SVC70 COMBI seem to have the B9F1 command, but the 850 COMBI seem to not have it.

B902

The B902 command retrieves 1 byte whose meaning is unknown.

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

>B902
84 13 51 F9 02 01 E4 

So B902 = 01 hex in this case. Its meaning remains to be discovered.

B90F

The B90F command retrieves 1 byte whose meaning is unknown.

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

>B90F
84 13 51 F9 0F 00 F0 

So B90F = 00 hex in this case. Its meaning remains to be discovered.

B910

The B910 command retrieves 1 byte whose meaning is unknown.

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

>B910
84 13 51 F9 10 80 71 

So B910 = 80 hex in this case. Its meaning remains to be discovered.

B912

The B912 command retrieves 1 byte whose meaning is unknown.

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

>B912
84 13 51 F9 12 32 25 

So B912 = 32 hex in this case. Its meaning remains to be discovered.

B913

The B913 command retrieves 1 byte whose meaning is unknown.

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

>B913
84 13 51 F9 13 32 26 

So B913 = 32 hex in this case. Its meaning remains to be discovered.

B914

The B914 command retrieves 2 bytes whose meaning is unknown.

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

>B914
85 13 51 F9 14 0A 0F 0F 

So B914 could equal:

  • 0A hex = 10, and 0F hex = 15, ie, two (2) separate values.
  • 0A0F hex = 2575.
  • 0F0A hex = 3850.
  • ??something else??

Its meaning remains to be discovered.

B915

The B915 command retrieves 1 byte whose meaning is unknown.

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

>B915
84 13 51 F9 15 00 F6 

So B915 = 00 hex in this case. Its meaning remains to be discovered.

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, AE01 or B903 or B9F0) 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 elsewhere on this portal:

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

  • ELM327 Commands to Scan Volvo 850 and SVC70.
    This contains elm327_volvo_850_svc70_scan_all.txt, a very extensive list of the ELM327 commands to do a thorough scan of the Volvo 850 / S70 / V70 / C70 / XC70 -- 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 perusal, 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's responses (either 850 or S70/V70/C70/XC70), you can paste the contents of that log into the Volvo 850 V70 keyword D3 B0 protocol interpreter page's Paste Volvo 850/SVC70 communication here box, then press the Interpret button, to gain some understanding 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-'98 Volvo 850/S70/V70/C70/XC70. The contents of its automatically generated log can be pasted into the KWPD3B0 interpreter's Paste box, followed by pressing the Interpret button, to make some sense out of the hex mumbo-jumbo in the log file (and Realterm Terminal pane).

Here's two alternative tools to help you read the mileage from the instrument cluster of a '96-'97 Volvo 850 (or '97-'98 Volvo S70/V70/C70/XC70).  Some people may find one of the following two alternatives easier to use than either: a) the semi-automated volvo850diag approach (just mentioned), or b) the manual issuing of commands to an ELM327 terminal emulator (mentioned earlier on this page). Both of these alternative solutions automatically interpret the raw mileage data into miles and/or km.

  • mikeri's milageread (Python source, plus link to pre-built Windows .exe), or
    jonesrh's enhancements to milageread (source only) and 2017-10-17 release info.
    This utility reads the mileage and automatically displays the mileage in plain English. There's no need for an extra, separate interpretation step (as there is with volvo850diag).

    Also, milageread helps to identify the specific reasons that likely cause particular error messages, thereby simplifying the setup process. [The 2017-10-17 release has the most accurate, most up-to-date error message analysis.]

    Furthermore, milageread explicitly informs you if your purported ELM327-compatible tool is incapable of communicating via the KWPD3B0 protocol, listing each of the specific commands which your purported ELM327-compatible tool does *not* respond to correctly (if any, and which thereby make your ELM327 tool probably incapable of reading the mileage).

    I believe mikeri has used milageread on both Linux and WinXP systems. I've successfully used mikeri's milageread.exe on WinXP, Win7, and Win10 systems. I've successfully used both mikeri's milageread.py Python source script and the jonesrh enhanced milageread.py Python script on my WinXP and Win7 systems [see README.txt in jonesrh supplied .zip for details on my WinXP and Win7 systems' Python and PySerial configuration].

    Presumably it is possible to get milageread.py running on an iOS or MacOS system.  But if you have an Android device, it is easier to just use the following "xiaotec 850 OBD-II" Android app solution to read the '96-'98 850/S70/V70 mileage.

    Note: "milage" is the Norwegian spelling of "mileage".

  • xiaotec "850 OBD-II" Android app (V1.1.6 -- released 2019-01-03).
    XantheFIN's "Volvo 850 OBD-II" Android app can be found on Google Play by searching for "xiaotec 850 OBD-II".

    Hint:
    "850 OBD-II" app's Live / COMBI function is simple way to read 96-97 850 mileage.

    Watch this video by "Robert DIY" to get a quick overview of:

    • pairing a Bluetooth ELM327 tool with an Android phone,
    • finding xiaotec "850 OBD-II" app on Google Play,
    • using "850 OBD-II" to read Vehicle Mileage from Live / COMBI screen.

    Thank you, Robert !!

    That mechanism is believed to work only for '96-'97 850 with VDO instrument clusters, or '97-'98 S70/V70/C70/XC70 with Yazaki instrument clusters.

    If you are inclined to explore "850 OBD-II" app further, you might want to read my following analysis of that same V1.1.6 version that Robert demo-ed in the video...

    Download / install / run "850 OBD-II" app from Google Play, pair your Bluetooth device, enter the app's "Settings" screen, get everything setup properly, click the triangle (Connect) icon to connect to your Bluetooth device, wait for the triangle icon to turn green, then...

    Hint:
    The following itemized list assumes the "850 OBD-II" V1.1.6 app's "Settings" screen "SCAN options" = "Default (Full)").

    Experiment with these "850 OBD-II" app's capabilities:

    • It displays the mileage (read from the COMBI) in miles or km [your choice].
      • How-To: Click "Service" / click solid triangle (to left of Bluetooth icon) if triange is not already green / click "Scan" / wait 1-3 minutes till Scan finishes, then page backwards until the Summary page is visible.
      • How-To: To swap between Metric and Imperial, click "Settings" (instead of "Service") / somewhere on that Settings page, swap between metric and English units. From then on, the new units will apply.
    • It reads / interprets OBDII DTCs and Pending DTCs, and
      it reads / interprets DTCs for several of the KWPD3B0-conversant ECUs.
      • How-To: Click "Service", then "Scan", then wait for Scan to finish, then examine the Summary for any DTCs (much like the mileage example).
      • In V1.1.6, this "Scan" function works for *all* my USA '98 S70 GLT ECUs.
    • It clears all DTCs at the same time.
      • In a single "ClearDTC" function, initiated by a single tap/click, xiaotec "850 OBD-II" app attempts to clear all DTCs for as many of the KWPD3B0-conversant ECUs that it can connect to, one after the other.  OBDII DTCs are also cleared during this ClearDTC function.
      • There is no capability in "850 OBD-II" app to interactively select an ECU, followed by interactively selecting a Clear DTCs function -- the way Vol-FCR, Brick-Diag Free, and volvo850diag operate.
      • The advantage of the "850 OBD-II" approach is simplicity.
        The disadvantage of that approach is it takes longer to get a DTC cleared.
      • How-To: Click "Service", then "ClearDTC", and wait for 1-2 minutes till the DTC clearing finishes.  It's a good idea to perform a "Scan" afterwards to verify if all the DTCs are gone, or if some of them have returned immediately.
      • In V1.1.6, this "ClearDTC" function works for *all* my USA '98 S70 GLT ECUs.
    • It turns off the SERVICE light by resetting SERVICE Reminder Interval counters.
      • How-To: Click "Service", then "ResetSRI", then wait a short time until the ResetSRI finishes.  [Worked in V1.1.0; I've not yet retested with V1.1.6.]
      • How-To: Verify success by either:
        a) obtaining a "Scan", then observing in the Summary that the SRI counters are zero (ie, the items in the first column under "SERVICE Light Calculation" are zero: eg, 0mi or 0km, 0 Days, 0 Hours), or
        b) turning off the engine for 10 seconds, then restarting the engine and observing that the SERVICE light does not stay on for 2 minutes, but instead is extinguished after first lighting briefly when engine is turned on.
    • It has an easy-to-use Live data function which is much faster than volvo850diag.
      • For several of the ECUs -- COMBI, AW 50-42, ABS, SRS, OBDII, M4.4, and purportedly MSA15.7 -- "850 OBD-II" app V1.1.6's Live data scanning works well enough to be quite useful and revealing.  And it interprets some more of the SRS, ABS, and AW 50-42 Live data items than the "(local) volvo850diag / (online) kwpd3b0_interpreter.html" combo do.
      • How-To: For the V1.1.6 release's "Live" data function, ensure either:
        • engine is on      [works for all ECUs], or
        • ignition at pos II [works for all ECUs], or
        • ignition at pos I  [works for SRS],
        then click "Live", then click "Connect" if its triangle icon is not green, then click "Start", then wait a few seconds for the Setup commands to be issued and the initial Live data display to appear.  In V1.1.6, I seldom (if ever) had to press "Start" a second time to help get the Live data connection established to my '98 S70 GLT.  The vast majority of the time, it just worked!!
      • How-To: If the Live display's data appears static, then turn on the engine, rev it a little, apply the brakes, shift the gears, drive the car a bit, etc -- as appropriate for whatever ECU's live data you are scanning -- then watch how the Live data display changes.
      • How-To: You can change "on the fly" which ECU the Live function is scanning -- click the box, which is (usually) at the top center or (sometimes) at the middle center, which identifies the ECU. That is a **very** convenient way to swap between ECUs.  I found V1.1.6 to reliably switch between the ECUs without me having to do hardly any "Disconnect old ECU / Connect new ECU" chores.
    • It displays the Service Interval parameters.
      • How-To display Service Interval counters/limits: Click "Service", then "Scan", wait till it finishes, then in the resultant Summary's "SERVICE Light Calculation" section, view counters in the 1st column, and view limits in the 2nd column [the 2nd column should always show non-zero entries for mi or km / Months / Hours].
    • It allows reprogramming the Service Interval limits.
      • How-To reprogram Service Interval parameters: Click "Service", click "Advanced", click "Instruments", click "Service Light Program", select specific limits or click "CUSTOM".  If "CUSTOM" is chosen, then there are more steps to specify 1, 2, or 3 limits to reprogram, followed by clicking "Done" (or "Cancel").  Regardless which of the limits were chosen, and regardless if you chose CUSTOM or not, now is the time to click "PROGRAM" to finalize the reprogramming (or to click "Cancel" and abort). Reprogramming takes a fraction of a minute.  [I've tested this very thoroughly with V1.1.0; only CUSTOM Engine Hours programming has been tested with V1.1.6.]
      • How-To (after reprogramming): It is *always* recommended to verify your reprogramming went as intended.  To do that, click "Scan", then verify in the resultant Summary that the reprogramming worked as intended -- ie, the values in the 2nd column of the "SERVICE Light Calculation" section are what you intended.
    • It allows some testing of Motronic 4.4 control functions.
      • How-To test one of several Motronic 4.4 control functions: Click "Service", click "Advanced", click "Motronic", select an M44 control function, click "???" or "???", listen for changes occurring under the hood.
        [I've tested this only minimally with V1.1.6 by first selecting "Engine Coolant Fan Test" / "Engine Coolant Fan High", then waiting roughly 1 minute while listening to the fan speed; then secondly selecting "Engine Coolant Fan Test" / "Engine Coolant Fan Low", then waiting 1 minute while listening to the fan speed; then thirdly by examining the logs to see that the correct requests and responses were generated.]
      • The tests available in V1.1.6 are:
        • Engine Coolant Fan High
        • Engine Coolant Fan Low.
        • (IAC) Valve Test.
        • Injector #1 Test
        • Injector #2 Test
        • Injector #3 Test
        • Injector #4 Test
        • Injector #5 Test
        • Fuel Pump Relay Test.
    • It performs a COMBI "Gauge Test".
      • How-To: Click "Service", then "GaugeTest", then wait 1 minute or so for the dash gauges to cease moving.
    • It can function as an easy-to-use standalone ELM327 terminal emulator to interactively / manually issue commands to the ELM327.
      • How-To: Click "Service" / click the Connect triangle (if not already green, ie, if not already connected) / wait for the triangle to change to a green double bar / type a single AT command, ST command, or data request on line to left of SEND button / make the virtual keyboard go away (by clicking your phone's Back button, or do whatever it takes so the SEND button is clickable again) / click SEND / repeat the type/SEND sequence until all desired commands and data requests have been sent to the ELM327.

    For those that want to do their '96-'98 850 / S70 / V70 / C70 / XC70 diagnostics of COMBI / SRS / ABS / AW50-42 / M4.4 / MSA15.7 / etc using an Android app that does the scanning and interpretation with a single button tap, xiaotec "850 OBD-II" is the only choice that I know of (as of 2021-06-07)!!!  Plus, whenever the "850 OBD-II" app doesn't do what you want it to do, you can always revert to using the app's built-in ELM327 terminal emulator to manually issue AT commands, ST commands, and data requests to get the job done!

    It's not perfect.  But overall, the xiaotec "850 OBD-II" Android app (as of V1.1.6) has evolved to be an extremely useful and convenient tool for owners of 1996-1997 850 and 1997-1998 S70/V70/C70/XC70 !!!

    Kudos, xiaotec / XantheFIN / Aleksi !!

    The "850 OBD-II" app only costs $1.99.  To me that seems like a pittance for those '96-'98 850/S70/V70 DIYers that use Android and need at least 1 of the 10 (xiaotec "850 OBD-II") capabilities listed above.

    Note: My most recent "thorough" testing (in 2019-01) was with xiaotec "850 OBD-II" app V1.1.6 (dated 2019-01-03), downloaded from Google Play to an Android 4.4 phone, and tested with a ScanTool.net OBDLink LX Bluetooth ELM327-compatible tool.

    Analysis of "850 OBD-II" app "SCAN Options" choices
    The new (available by V1.1.6) "SCAN Options" setting **is** useful for some people as follows:
    • The "Default (Full)" choice is the best choice to try first.
    • The "No info Scan" choice eliminates the ATPPS and ATDP as compared to the normal "Default(Full)" choice.
      • That is a minor convenience for the people that already know what their ELM327-compatible devices' ATPPS and ATDP values are.
    • The "No info or Generic OBDII" choice is same as "No info Scan", except that generic OBDII requests/responses are also eliminated.
      • That is useful for non-USA '96-'98 850/SVC70 that do *NOT* have any OBDII capability, since it lessens needless scanning time.
      • That is also useful for any '96-'98 850/SVC70 owner that prefers to do all OBDII scanning via a mature OBDII scanning program/app, eg, OBDwiz, TouchScan, OBDlink, Torque, etc.
    • The "Generic OBDII only" choice avoids all setup and communication via KWPD3B0.
      • It's Scan completes very quickly.
      • This could be useful to someone that had a cheap, ELM327 pseudo-clone, which is *not* KWPD3B0-capable, but can still be used to perform some generic OBDII diagnostics, even though it may also not work with one or more generic OBDII diagnostics software programs/apps.
    Further capabilities available by V1.2.9:
    The V1.2.9 version of xiaotec "850 OBD-II" [released to Google Play on 2019-06-07] also includes:
    • test/control capabilities for MSA 15.7 diesel timing, AW 50-42 solenoids, ABS solenoids;
    • scanning of some ECUs available strictly on C70;
    • ability to Clear DTCs of only one single ECU;
    • and more useful goodies.
    The new test/control capabilities and the scanning of some C70-specific ECUs are at least 4 different additional things that "850 OBD-II" app can do that volvo850diag v0.9 still can not do !!!
    Further capabilities (purportedly) available in V1.3.4:
    The V1.3.4 version of xiaotec "850 OBD-II" [released to Google Play on 2020-04-14] also includes:
    • more live data for M44 and MSA15.7;
    • VIN code reading (if available).
    The new MSA15.7 live data and the VIN code reading are 2 additional things that "850 OBD-II" app can do that volvo850diag v0.9 still can not do !!!
    Yet further capabilities in V1.3.5 thru V1.4.2 (and beyond):
    Scroll through the changelog at the bottom of this xiaotec.fi page to see the most recently added capabilities to "850 OBD-II" app.
    Warning:
    Do *NOT* experiment with "850 OBD-II" app's Tire Size or Country Code reprogramming!!!

    **Avoid**
    programming via Service / Advanced / Instruments / Tire Size Program.
    **Avoid**
    programming via Service / Advanced / Instruments / Contry Code Program.


    You should avoid experimenting with those two COMBI programming functions, since: a) they are *not* well understood, b) their behavior is very non-intuitive, and c) there's a high probability you would *not* be able to use the app to reprogram them back to their original settings (except by interactively issuing commands to the app's terminal emulator, and you would be responsible for determining what those commands should be).  Note: Reason c) was observed in V1.0.9. That problem may have been eliminated by V1.1.6.

    I will no longer test Tire Size or Country Code reprogramming.  V1.0.9 was the last version with which I tested the Tire Size reprogramming.

    In my opinion, the realm of Tire Size and/or Country Code reprogramming is best left to the Volvo dealer. 
    But if you insist on exploring them yourself, then it would probably be a good idea to contact the author at obdii@xiaotec.fi and pick his brain to more fully understand the "Tire Size Program" and "Contry Code Program" function uncertainties / pitfalls / limitations / etc (and thereby avoid unnecessary headaches).

See Volvo 850 Diagnostic Links for additional reference links.


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

This page was forked from its "1996-1997 850-specific" parent -- elm327_reads_volvo_850_mileage.html -- in order to have a page which documents a set of instructions which can read the mileage equally well from either the 1996-1997 850 or the 1998 S70/V70/C70/XC70 instrument clusters.

This "generalized for 1996-1998 850/S70/V70/C70/XC70" page was (first) released to the public on 2014-03-21.

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