Can't query supported commands on Volvo V40 (2003)
Hi, I have a knock-off ELM327 OBDII dongle from AliExpress. I can connect to it using rfcomm and it does seem to return some data, but it seems either the dongle does not connect to the car, or python-OBD doesn't understand what is happening.
I have the key in the car in position II, so the head lights are on, but the engine is not running.
I think I need to use protocol ID 3 to connect to the car (ISO9414-2), as multiple sites list that as the protocol to use. It is also the only protocol where the ELM327 returns something else than 'NO DATA' or 'BUS INIT: ERROR'.
The car consistently replies 48 6B 13 41 00 BE 1F B8 11 AD
import obd
obd.logger.setLevel(obd.logging.DEBUG)
connection = obd.OBD(portstr='/dev/rfcomm0',baudrate=115200,protocol="3",timeout=20)
connection.close()
Debug output:
[obd.obd] ======================= python-OBD (v0.7.1) =======================
[obd.obd] Using scan_serial to select port
[obd.obd] Available ports: ['/dev/rfcomm0']
[obd.obd] Attempting to use port: /dev/rfcomm0
[obd.elm327] Initializing ELM327: PORT=/dev/rfcomm0 BAUD=115200 PROTOCOL=3
[obd.elm327] write: b'ATZ\r'
[obd.elm327] wait: 1 seconds
[obd.elm327] read: b'ATZ\r\xfc\r\rELM327 v1.5\r\r>'
[obd.elm327] write: b'ATE0\r'
[obd.elm327] read: b'ATE0\rOK'
[obd.elm327] write: b'ATH1\r'
[obd.elm327] read: b'OK'
[obd.elm327] write: b'ATL0\r'
[obd.elm327] read: b'OK\r'
[obd.elm327] write: b'AT RV\r'
[obd.elm327] read: b'11.2V\r\r>'
[obd.elm327] write: b'ATTP3\r'
[obd.elm327] read: b'OK\r\r'
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'BUS INIT: OK'
[obd.elm327] Connected Successfully: PORT=/dev/rfcomm0 BAUD=115200 PROTOCOL=3
[obd.obd] querying for supported commands
[obd.obd] Sending command: b'0100': Supported PIDs [01-20]
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'48 6B 13 41 00 BE 1F B8 11 AD \r\r>'
[obd.OBDCommand] b'0100': Supported PIDs [01-20] did not receive any acceptable messages
[obd.obd] No valid data for PID listing command: b'0100': Supported PIDs [01-20]
[obd.obd] finished querying with 7 commands supported
[obd.obd] ===================================================================
Alternatively, if I simply use the no-argument constructor (by doing connection = obd.OBD()) the connection also fails, in a different part. That output is below, containing the same string (r48 6B 13 41 00 BE 1F B8 11 AD).
[obd.obd] ======================= python-OBD (v0.7.1) =======================
[obd.obd] Using scan_serial to select port
[obd.obd] Available ports: ['/dev/rfcomm0']
[obd.obd] Attempting to use port: /dev/rfcomm0
[obd.elm327] Initializing ELM327: PORT=/dev/rfcomm0 BAUD=auto PROTOCOL=auto
[obd.elm327] Response from baud 38400: b'\x7f\x7f\r?\r\r>'
[obd.elm327] Choosing baud 38400
[obd.elm327] write: b'ATZ\r'
[obd.elm327] wait: 1 seconds
[obd.elm327] read: b'ATZ\r\xfc\r\rELM327 v1.5\r\r>'
[obd.elm327] write: b'ATE0\r'
[obd.elm327] read: b'ATE0\rOK'
[obd.elm327] write: b'ATH1\r'
[obd.elm327] read: b'OK'
[obd.elm327] write: b'ATL0\r'
[obd.elm327] read: b'OK\r'
[obd.elm327] write: b'AT RV\r'
[obd.elm327] read: b'13.5V\r\r>'
[obd.elm327] write: b'ATSP0\r'
[obd.elm327] read: b'OK'
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'\r\r>'
[obd.elm327] write: b'ATDPN\r'
[obd.elm327] read: b'SEARCHING...\r48 6B 13 41 00 BE 1F B8 11 AD \r\r>'
[obd.elm327] Failed to retrieve current protocol
[obd.elm327] Adapter connected, but the ignition is off
[obd.obd] Cannot load commands: No connection to car
[obd.obd] ===================================================================
OBD Connected
{OBDCommand('GET_DTC', 'Get DTCs', b'03', 0, raw_string, ecu=ECU.ALL, fast=False), OBDCommand('PIDS_A', 'Supported PIDs [01-20]', b'0100', 6, raw_string, ecu=ECU.ENGINE, fast=True), OBDCommand('ELM_VERSION', 'ELM327 version string', b'ATI', 0, raw_string, ecu=1, fast=False), OBDCommand('MIDS_A', 'Supported MIDs [01-20]', b'0600', 0, raw_string, ecu=ECU.ALL, fast=False), OBDCommand('ELM_VOLTAGE', 'Voltage detected by OBD-II adapter', b'ATRV', 0, raw_string, ecu=1, fast=False), OBDCommand('GET_CURRENT_DTC', 'Get DTCs from the current/last driving cycle', b'07', 0, raw_string, ecu=ECU.ALL, fast=False), OBDCommand('CLEAR_DTC', 'Clear DTCs and Freeze data', b'04', 0, raw_string, ecu=ECU.ALL, fast=False)}
/dev/rfcomm0
[obd.obd] Closing connection
[obd.elm327] closing port
[obd.elm327] write: b'ATZ\r'
I have used EOBD-Facile on my Macbook once successfully with this dongle to get engine RPM. So I know the dongle can work with the car.
Update. I have installed freediag and it uses ISO9414 (without the -2?) and in the logs that states it attempts to enable SAEJ1979 mode, on top of ISO9414. I'm attempting to make sense of this, but I assume that this means additional support would need to be added to python-OBD.
Based on the README of the protocols directory, it seems that I did select the correct protocol. However, I noticed when using freediag that the ID of the engine ECU is 13. Seeing that 48 6B 13 41 00 BE 1F B8 11 AD starts with the two J1850 start bytes and is followed by 13 (my engine ECU ID, 10 in the sample and hardcoded in the protocol) I think it is quite reasonable to expect everything to work if I change the ECU ID for Legacy protocol to 13.
If you have a fix please send a PR. In general though it's hard to support a knock-off chip as there is no way to know how it will behave.
It should be a legacy protocol (not CAN), possibly 1 to 5 (which I have never run into, like J1850).
Can you please try providing the trace of this program after switching ignition on?
import obd
obd.logger.setLevel(obd.logging.DEBUG)
connection = obd.OBD(portstr='/dev/rfcomm0',baudrate=115200,protocol="3",timeout=20)
print(connection.query(obd.commands.RPM))
print(connection.query(obd.commands.SPEED))
Small hint. I quickly tested this case myself and I think I found that the software does not like BUS INIT: OK.
This is what I did.
Open a terminal, run ELM327-emulator and create a special rule. Set:
emulator.counters["ELM_PIDS_A"] = 0
emulator.answer['ELM_PIDS_A'] = '\0 "BUS INIT: OK" if self.counters["ELM_PIDS_A"] < 2 else "48 6B 13 41 00 BE 1F B8 11 AD \\r" \0'
Open another terminal, run:
import obd
obd.logger.setLevel(obd.logging.DEBUG)
connection = obd.OBD('/dev/pts/0',protocol="3")
Output is the following (apologize for not having updated the version):
[obd.obd] ======================= python-OBD (v0.7.0) =======================
[obd.obd] Explicit port defined
[obd.elm327] Initializing ELM327: PORT=/dev/pts/0 BAUD=auto PROTOCOL=3
[obd.elm327] Detected pseudo terminal, skipping baudrate setup
[obd.elm327] write: b'ATZ\r'
[obd.elm327] wait: 1 seconds
[obd.elm327] read: b'\r\rELM327 v1.5\r\r>'
[obd.elm327] write: b'ATE0\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'ATH1\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'ATL0\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'AT RV\r'
[obd.elm327] read: b'13.2V\r\r>'
[obd.elm327] write: b'ATTP3\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'BUS INIT: OK'
[obd.elm327] Connected Successfully: PORT=/dev/pts/0 BAUD=9600 PROTOCOL=3
[obd.obd] querying for supported commands
[obd.obd] Sending command: b'0100': Supported PIDs [01-20]
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'48 6B 13 41 00 BE 1F B8 11 AD \r\r>'
[obd.OBDCommand] b'0100': Supported PIDs [01-20] did not receive any acceptable messages
[obd.obd] No valid data for PID listing command: b'0100': Supported PIDs [01-20]
[obd.obd] finished querying with 7 commands supported
[obd.obd] ===================================================================
Which looks the same.
Now, removing BUS INIT: OK in the emulator:
emulator.answer['ELM_PIDS_A'] = '48 6B 10 41 00 BE 1F B8 11 AD \r'
I get something more appropriate:
[obd.obd] ======================= python-OBD (v0.7.0) =======================
[obd.obd] Explicit port defined
[obd.elm327] Initializing ELM327: PORT=/dev/pts/0 BAUD=auto PROTOCOL=3
[obd.elm327] Detected pseudo terminal, skipping baudrate setup
[obd.elm327] write: b'ATZ\r'
[obd.elm327] wait: 1 seconds
[obd.elm327] read: b'\r\rELM327 v1.5\r\r>'
[obd.elm327] write: b'ATE0\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'ATH1\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'ATL0\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'AT RV\r'
[obd.elm327] read: b'13.7V\r\r>'
[obd.elm327] write: b'ATTP3\r'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'48 6B 13 41 00 BE 1F B8 11 AD \r\r>'
[obd.protocols.protocol] map ECU 19 --> ENGINE
[obd.elm327] Connected Successfully: PORT=/dev/pts/0 BAUD=9600 PROTOCOL=3
[obd.obd] querying for supported commands
[obd.obd] Sending command: b'0100': Supported PIDs [01-20]
[obd.elm327] write: b'0100\r'
[obd.elm327] read: b'48 6B 13 41 00 BE 1F B8 11 AD \r\r>'
[obd.obd] Sending command: b'0120': Supported PIDs [21-40]
[obd.elm327] write: b'0120\r'
...
Maybe it just doesn't like "OK" and self.ELM_LP_ACTIVE in buffer could be too much generic.
As a preliminary test, try modifying obd/elm327.py and change
if self.ELM_PROMPT in buffer or self.ELM_LP_ACTIVE in buffer:
with something like
if self.ELM_PROMPT in buffer or ((self.ELM_LP_ACTIVE in buffer) and (b"BUS INIT: OK\r" not in buffer)):
Does it overcome the issue?
Note: emulator rule for testing:
emulator.answer['ELM_PIDS_A'] = '\0 "BUS INIT: OK\\r48 6B 13 41 00 BE 1F B8 11 AD \\r" if self.counters["ELM_PIDS_A"] < 2 else "48 6B 13 41 00 BE 1F B8 11 AD \\r" \0'
Hi, I will test your suggestions today, many thanks for taking the time to look into this!
Your suggestion fixes at least part of the issue. I will investigate further today. I had created a pull request earlier but I ran into another issue and I'm not sure what that is.
Is the problem solved? I'm having the same kind of problem here and don't know how to fix it
I can confirm that changing obd/elm327.py
if self.ELM_PROMPT in buffer or self.ELM_LP_ACTIVE in buffer:
to
if self.ELM_PROMPT in buffer or ((self.ELM_LP_ACTIVE in buffer) and (b"BUS INIT: OK\r" not in buffer)):
does fix this for my OBD reader
I had the same issue with a Audi TT from 1998. Before the suggested change i got this:
[obd.obd] ======================= python-OBD (v0.7.1) ======================= [obd.obd] Using scan_serial to select port [obd.obd] Available ports: ['\.\COM6'] [obd.obd] Attempting to use port: .\COM6 [obd.elm327] Initializing ELM327: PORT=.\COM6 BAUD=38400 PROTOCOL=3 [obd.elm327] write: b'ATZ\r' [obd.elm327] wait: 1 seconds [obd.elm327] read: b'\xfc\r\rELM327 v1.5\r\r>' [obd.elm327] write: b'ATE0\r' [obd.elm327] read: b'ATE0\rOK\r\r>' [obd.elm327] write: b'ATH1\r' [obd.elm327] read: b'OK\r\r>' [obd.elm327] write: b'ATL0\r' [obd.elm327] read: b'OK\r\r>' [obd.elm327] write: b'AT RV\r' [obd.elm327] read: b'14.1V\r\r>' [obd.elm327] write: b'ATTP3\r' [obd.elm327] read: b'OK\r\r>' [obd.elm327] write: b'0100\r' [obd.elm327] read: b'BUS INIT: OK\r' [obd.elm327] Connected Successfully: PORT=.\COM6 BAUD=38400 PROTOCOL=3 [obd.obd] querying for supported commands [obd.obd] Sending command: b'0100': Supported PIDs [01-20] [obd.elm327] write: b'0100\r' [obd.elm327] read: b'48 6B 11 41 00 BE 1F B8 10 AA \r\r>' [obd.OBDCommand] b'0100': Supported PIDs [01-20] did not receive any acceptable messages [obd.obd] No valid data for PID listing command: b'0100': Supported PIDs [01-20] [obd.obd] finished querying with 7 commands supported [obd.obd] ===================================================================
and after changing odb/elm327.py. I got the following:
[obd.obd] ======================= python-OBD (v0.7.1) ======================= [obd.obd] Using scan_serial to select port [obd.obd] Available ports: ['\.\COM6'] [obd.obd] Attempting to use port: .\COM6 [obd.elm327] Initializing ELM327: PORT=.\COM6 BAUD=38400 PROTOCOL=3 [obd.elm327] write: b'ATZ\r' [obd.elm327] wait: 1 seconds [obd.elm327] read: b'ATZ\r\xfc\r\rELM327 v1.5\r\r>' [obd.elm327] write: b'ATE0\r' [obd.elm327] read: b'ATE0\rOK\r\r>' [obd.elm327] write: b'ATH1\r' [obd.elm327] read: b'OK\r\r>' [obd.elm327] write: b'ATL0\r' [obd.elm327] read: b'OK\r\r>' [obd.elm327] write: b'AT RV\r' [obd.elm327] read: b'14.0V\r\r>' [obd.elm327] write: b'ATTP3\r' [obd.elm327] read: b'OK\r\r>' [obd.elm327] write: b'0100\r' [obd.elm327] read: b'BUS INIT: OK\r48 6B 11 41 00 BE 1F B8 10 AA \r\r>' [obd.protocols.protocol] map ECU 17 --> ENGINE [obd.elm327] Connected Successfully: PORT=.\COM6 BAUD=38400 PROTOCOL=3 [obd.obd] querying for supported commands [obd.obd] Sending command: b'0100': Supported PIDs [01-20] [obd.elm327] write: b'0100\r' [obd.elm327] read: b'48 6B 11 41 00 BE 1F B8 10 AA \r\r>' [obd.obd] finished querying with 39 commands supported [obd.obd] ===================================================================
So this fixed the issue also for me
I can confirm that changing obd/elm327.py
if self.ELM_PROMPT in buffer or self.ELM_LP_ACTIVE in buffer:to
if self.ELM_PROMPT in buffer or ((self.ELM_LP_ACTIVE in buffer) and (b"BUS INIT: OK\r" not in buffer)):does fix this for my OBD reader
Thank you, this also fixed it for me! From 11 commands supported to 39.
Vgate iCar Pro Bluetooth 4.0 (BLE) OBD2 OBDII Fehler Code-Leser Auto Check Engine Licht mit ELM327 Adapter Mercedes Benz A Class (2019)