0
votes

i'm trying to interface a raspberry Pi 3B+ to a Bluetooth ELM327 OBD scanner but i'm having some troubles. I've connected the raspberry to the OBD Scanner by running the following commands from terminal:

bluetoothctl
power on
default-agent
pair <scanner MAC address>
trust <scanner MAC address>
sudo rfcomm bind rfcomm0 <scanner MAC address>

I've then proceded to run the following python script, which uses Python-OBD library

import obd
connection = obd.OBD(protocol="8")
cmd=obd.commands.RPM
response = connection.query(cmd)
print(response.value)

From this script i got a '010C: Engine RPM' is not supported response although I know from using a smartphone app, that this value is supported from the scanner. Same goes for most of the commands, only a couple of them (i.e. ELM_VERSION, ELM_VOLTAGE) seems to work. I've already tried a couple of changes on the code, such as specifying the protocol on the connection constructor (I've set the same protocol that's set on the smartphone app), I've tried disabling fast command optimization and also tried to use force=True on query to force unsupported commands to be sent.

I've checked connection.status() which returned "car connected" meaning that it recons there was a successful communication with the ELM327 and the vehicle ignition is on. I've then tried to check the connection.supported_commands for hints on what's going on and that was the result

    set([OBDCommand('MIDS_A', 'Supported MIDs [01-20]', '0600', 0, raw_string, ecu=ECU.ALL, fast=False),
 OBDCommand('ELM_VOLTAGE', 'Voltage detected by OBD-II adapter', 'ATRV', 0, raw_string, ecu=1, fast=False),
 OBDCommand('CLEAR_DTC', 'Clear DTCs and Freeze data', '04', 0, raw_string, ecu=ECU.ALL, fast=False),
 OBDCommand('GET_CURRENT_DTC', 'Get DTCs from the current/last driving cycle', '07', 0, raw_string, ecu=ECU.ALL, fast=False),
 OBDCommand('GET_DTC', 'Get DTCs', '03', 0, raw_string, ecu=ECU.ALL, fast=False),
 OBDCommand('ELM_VERSION', 'ELM327 version string', 'ATI', 0, raw_string, ecu=1, fast=False),
 OBDCommand('PIDS_A', 'Supported PIDs [01-20]', '0100', 6, raw_string, ecu=ECU.ENGINE, fast=True)])

I really don't know how to go about troubleshooting this, and i hope you can help me out.

----------EDIT 1 --------

I've enabled the debug logging and here's the result:

 [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=8
    [obd.elm327] Response from baud 38400: '\x7f\x7f\r?\r\r>'
    [obd.elm327] Choosing baud 38400
    [obd.elm327] write: 'ATZ\r'
    [obd.elm327] wait: 1 seconds
    [obd.elm327] read: b'ATZ\r\xfc\r\rELM327 v1.5\r\r>'
    [obd.elm327] write: 'ATE0\r'
    [obd.elm327] read: b'ATE0\rOK'
    [obd.elm327] write: 'ATH1\r'
    [obd.elm327] read: b'OK'
    [obd.elm327] write: 'ATL0\r'
    [obd.elm327] read: b'OK'
    [obd.elm327] write: 'AT RV\r'
    [obd.elm327] read: b'14.0V\r\r>'
    [obd.elm327] write: 'ATTP8\r'
    [obd.elm327] read: b'OK\r\r'
    [obd.elm327] write: '0100\r'
    [obd.elm327] read: b'>'
    [obd.elm327] Connected Successfully: PORT=/dev/rfcomm0 BAUD=38400 PROTOCOL=8
    [obd.obd] querying for supported commands
    [obd.obd] Sending command: 0100: Supported PIDs [01-20]
    [obd.elm327] write: '0100\r'
    [obd.elm327] read: b'NO DATA\r\r>'
    [obd.OBDCommand] 0100: Supported PIDs [01-20] did not receive any acceptable messages
    [obd.obd] No valid data for PID listing command: 0100: Supported PIDs [01-20]
    [obd.obd] Sending command: 0600: Supported MIDs [01-20]
    [obd.elm327] write: '0600\r'
    [obd.elm327] read: b'NO DATA\r\r>'
    [obd.obd] finished querying with 7 commands supported
    [obd.obd] ===================================================================
    Car Connected
    [obd.obd] Sending command: 010C: Engine RPM
    [obd.elm327] write: '010C\r'
    [obd.elm327] read: b'NO DATA\r\r>'
    [obd.OBDCommand] 010C: Engine RPM did not receive any acceptable messages

----------EDIT 2 --------

I've tried various combinations of protocols/baud rates with no luck, i ended up using automatic detection with fast mode off and i seems like i get some kind of result from the commands 0100 and 010C but it's not recognised as acceptable from the library...

[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: '?\r\r>'
[obd.elm327] Choosing baud 38400
[obd.elm327] write: 'ATZ\r'
[obd.elm327] wait: 1 seconds
[obd.elm327] read: b'\xfc\r\rELM327 v1.5\r\r>'
[obd.elm327] write: 'ATE0\r'
[obd.elm327] read: b'ATE0\rOK'
[obd.elm327] write: 'ATH1\r'
[obd.elm327] read: b'OK'
[obd.elm327] write: 'ATL0\r'
[obd.elm327] read: b'OK'
[obd.elm327] write: 'AT RV\r'
[obd.elm327] read: b'14.2V\r\r>'
[obd.elm327] write: 'ATSP0\r'
[obd.elm327] read: b'OK'
[obd.elm327] write: '0100\r'
[obd.elm327] read: b'\r\r>'
[obd.elm327] write: 'ATDPN\r'
[obd.elm327] read: b'A0\r\r>'
[obd.elm327] ELM responded with unknown protocol. Trying them one-by-one
[obd.elm327] write: 'ATTP6\r'
[obd.elm327] read: b'OK\r\r'
[obd.elm327] write: '0100\r'
[obd.elm327] read: b'>'
[obd.elm327] Connected Successfully: PORT=/dev/rfcomm0 BAUD=38400 PROTOCOL=6
[obd.obd] querying for supported commands
[obd.obd] Sending command: 0100: Supported PIDs [01-20]
[obd.elm327] write: '0100\r'
[obd.elm327] read: b'7E8 06 41 00 BE 3E B8 11 \r\r>'
[obd.OBDCommand] 0100: Supported PIDs [01-20] did not receive any acceptable messages
[obd.obd] No valid data for PID listing command: 0100: Supported PIDs [01-20]
[obd.obd] Sending command: 0600: Supported MIDs [01-20]
[obd.elm327] write: '0600\r'
[obd.elm327] read: b'7E8 06 46 00 C0 00 00 01 \r\r>'
[obd.obd] Sending command: 0620: Supported MIDs [21-40]
[obd.elm327] write: '0620\r'
[obd.elm327] read: b'7E8 06 46 20 80 00 00 00 \r\r>'
[obd.obd] finished querying with 11 commands supported
[obd.obd] ===================================================================
Car Connected
[obd.obd] Sending command: 010C: Engine RPM
[obd.elm327] write: '010C\r'
[obd.elm327] read: b'7E8 04 41 0C 10 10 \r\r>'
[obd.OBDCommand] 010C: Engine RPM did not receive any acceptable messages
2
You could increase the log level and observe the output in the console (maybe attach here) to find out what is going on. The loglevel can be increased by calling this line obd.logger.setLevel(obd.logging.DEBUG) directly after import odbM. Spiller
@M.Spiller thanks for the suggestion, i've added the log in the question, do you see something off about it?Sebastiano franceschin
Actually this looks good. You get a RPM value of hex 0x1010 which maps to a RPM of 1028. Seems somewhat reasonable. Also the response to 0100 looks good; the bit for 0x0C (RPM) is set.M. Spiller
But the response from the library is still "[obd.OBDCommand] 010C: Engine RPM did not receive any acceptable messages" and the response.value is still "none".. the only thing that i see could be a problem, is that my response always end with the symbol '>' and on the examples on the troubleshooting guide (python-obd.readthedocs.io/en/latest/Troubleshooting) the responses end with \r, maybe the library does not expect the response to contain that character and therfore doesn't recognize the response as a valid hex value... I'll see if i can verify that guess later..Sebastiano franceschin
From what I see the problem is that there is no response to the first time 0100 is sent (right after ATTP6). This seems to make python-obd think that there are no ECUs and is causing errors later on. Maybe you could try to increase the timeout parameter obd.OBD(timeout=30)M. Spiller

2 Answers

0
votes

Your first example is using a strange init sequence, usually it is recommended to use auto negotiation (SPA), then negotiate by sending any PID (0100) and finally print the protocol to find out which protocol your car and adapter negotiated (DPN).

Now I don't know the library you're using, however it looks like this library does either not understand the protocol format your adapter has negotiated with the car or it doesn't know which protocol has been selected (hence tries to parse a slightly different format). The actual answers you receive in the second example look OK as far as I can see, so you might want to check the init sequence or whether you need to use the library differently.

0
votes

try the below connection string:

connection = obd.OBD(protocol="7", baudrate="9600", fast=False)

This worked for me