E46 diagnostics: what a dongle reads, and the M3's one-byte codes
What a Bluetooth OBD-II dongle can and cannot read on a BMW E46 and E46 M3, the K-line body bus, the 20-pin port, and the MSS54 one-byte code trap.
The E46 is the 3 Series most of us still drive hard, and it is also the one where a Bluetooth OBD-II dongle gives the most false comfort. The dongle reads the engine, finds nothing, and tells you the car is clean while the cluster shows a stability control light. On the M3 there is a second trap: tools that read the engine computer's fault memory the wrong way and print codes that do not exist. My own app did it to a member's car, which is why I am writing this down.
What a dongle can and cannot read on an E46
The E46 was built from December 1997 to November 2006, as a saloon, Touring, coupe, convertible and Compact. Petrol engines run from the M43, N40, N42 and N46 fours to the M52TU, M54 and M56 sixes and the M3's S54, with M47 and M57 diesels. OBD-II became mandatory on US passenger cars for 1996, so every E46 has the 16-pin port in the cabin.
That standard is about emissions, so what it promises is the engine. On an E46 the engine answers OBD-II on the K-line on pin 7, which is the pin the standard uses for ISO 9141-2 and KWP2000. A dongle gets the VIN, live values and P-codes. That part works well: an E46 M3 streamed 13 live values to The Analogue through an ordinary read.
What the dongle cannot read:
- the instrument cluster, light control, immobiliser, climate and stability control
- each of those modules' own fault memories, which are separate from the engine's OBD-II codes
- the engine computer's BMW fault memory, which can hold faults OBD-II never reports
None of that is a fault in the dongle. It speaks the emissions protocol. Those computers speak BMW's.
K-line, DS2, and where D-CAN fits
A K-line is a single wire carrying serial data both ways. The OBD-II standard defines pin 7. Pin 8 is left to the maker, and on some BMWs it is a second K-line. On the E46 the body modules sit on that second line, and they answer DS2: BMW's own protocol, 9600 baud, even parity, every module at its own address.
This is where the K+DCAN cable name confuses people. D-CAN is the CAN-based diagnostic line of later BMWs. The Analogue treats every E46 as a K-line car, so on an E46 it is the K-line half of the cable that matters, and specifically its pin 7/8 switch. In one position you reach the powertrain on pin 7; in the other, the body bus on pin 8. On my E39, which shares this layout, the engine answered in both positions, which is exactly why half the car can stay invisible without anything looking broken.
A note on the later cars: some later E46 engine computers speak KWP2000 rather than DS2. I have not proven those on a car, so I make no claim for them here.
The round 20-pin port on early E46s
Early E46s have a round 20-pin socket under the bonnet as well as the 16-pin port in the cabin. The adapter sellers list the E46 with the round port for roughly 1998 to 2000, and put BMW's move to the cabin port alone at around 2000. My site's car finder says an E46 built before late 2000 may need the 20-pin to 16-pin adapter.
On cars with both, the seller of that adapter describes the cabin port as mainly for emissions testing and recommends the round socket for full diagnostics. If yours has it, use it.
The E46 M3 and the MSS54: one-byte fault codes
The M3 uses the 3.2 litre S54 straight six, and its engine computer is the MSS54. E46 M3 owners compiled and published a table of its fault codes on nam3forum, alongside the dealer tools' names and OBD-II cross-references. The key fact is simple: the MSS54 numbers its faults with one byte, 0x01 to 0xFF.
That matters because the fault memory comes back as a run of bytes, and the reader has to know how long each record is. Get that wrong and you invent codes.
Here is how I know. A founder's 2002 E46 M3 scanned through the MasterLink showed four engine codes: 01B3, 0128, 268A and 437E. None of them is on the MSS54 list. They are not even the right shape. My app had fallen back to a generic reader that grouped the bytes in threes, a layout that belongs to other modules, and printed whatever came out. Worse, the learning loop then gave 01B3 a meaning ("electric fan output stage") for a code that does not exist.
What I changed:
- The engine computer is never read with the three-byte grouping again. A test fails the build if anything calls the old reader.
- Codes are decoded only when the record proves itself: the count and the length have to agree, or a decoded code has to match a P-code the engine reported over OBD-II in the same scan.
- When the record cannot be proven, the screen says "faults present, codes unreadable" and keeps the raw bytes. That is an honest answer. A made-up code is not.
- The owner-published MSS54 list is in the app, used only for an E46 with the S54.
There is a related trap on the OBD-II side. On an E46 M3 a P0008 once appeared that was a padding byte plus a checksum read as a code. If an M3 shows a P-code that makes no sense for the engine, suspect the reader before the car.
If your M3 shows a four-digit code from its engine computer in any tool, treat it with suspicion.
What reading the rest of an E46 takes
- A wire to pin 8, through a K+DCAN cable with a pin 7/8 switch, or the round socket on an early car.
- DS2 sent with tight timing: the right address, the right request for each module, 9600 baud and even parity.
- The right computer for the right car. The Z4 M also has an S54, but its engine computer is an MSS70 that speaks KWP2000 at a different address and numbers its faults differently. Same engine, different diagnostic stack. An E46 M3's MSS54 answers DS2 at 0x12; member scans have read it that way.
- A reader that can say "I do not know" when a record will not decode, rather than guess.
Questions owners ask
Can a Bluetooth OBD-II dongle read all the modules on a BMW E46?
No. A generic dongle reads the engine computer's standard OBD-II data and P-codes over the K-line on pin 7. The E46's body computers, such as the instrument cluster, lights, immobiliser, climate and stability control, answer a BMW protocol called DS2 on a second K-line on pin 8, and a generic dongle never asks them.
Does the BMW E46 use K-line or D-CAN?
The Analogue treats every E46 as a K-line car: the engine on pin 7 and the body modules on pin 8. D-CAN is the CAN-based diagnostic line on later BMWs. A K+DCAN cable covers both, and on an E46 it is the K-line half, with its pin 7/8 switch, that matters.
Why does my E46 M3 show four-digit engine fault codes?
The E46 M3's MSS54 engine computer numbers its faults with one byte, 0x01 to 0xFF. A four-digit code on an M3's engine computer is not on the owner-published MSS54 list and usually means the reading tool grouped the bytes wrongly. My own app made exactly this mistake and invented four codes on a member's car before I fixed it.
Do I need a 20-pin adapter for my E46?
Only on early cars. Adapter sellers list the E46 with the round 20-pin socket under the bonnet for roughly 1998 to 2000 builds, and BMW moved to the 16-pin port in the cabin around 2000. If your E46 was built before late 2000, check under the bonnet for the round socket.