brendan-w / python-OBD

OBD-II serial module for reading engine data
GNU General Public License v2.0
1.02k stars 360 forks source link

Multiple queries of same command fail to send data #131

Closed yaleman closed 5 years ago

yaleman commented 5 years ago

This is similar to #104, where multiple queries return None after the first two.

Example code:

#!/usr/bin/env python
import obd
import time

obd.logger.setLevel(obd.logging.DEBUG)
connection = obd.OBD(portstr="/dev/ttyUSB0) # auto-connects to USB or RF port

while True: 
    cmd =  # select an OBD command (sensor)
    response = connection.query(obd.commands.SPEED) # send the command, and parse the response
    print(response.value) # returns unit-bearing values thanks to Pint
    time.sleep(1)

Logging output:

[obd.obd] ======================= python-OBD (v0.7.0) =======================
[obd.obd] Explicit port defined
[obd.elm327] Initializing ELM327: PORT=/dev/ttyUSB0 BAUD=38400 PROTOCOL=6
[obd.elm327] write: b'ATZ\r\n'
[obd.elm327] wait: 1 seconds
[obd.elm327] read: b'\r\n\r\nELM327 v1.5\r\n\r\n>'
[obd.elm327] write: b'ATE0\r\n'
[obd.elm327] read: b'ATE0\r\nOK\r\n\r\n>'
[obd.elm327] write: b'ATH1\r\n'
[obd.elm327] read: b'OK\r\n\r\n>'
[obd.elm327] write: b'ATL0\r\n'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'ATTP6\r\n'
[obd.elm327] read: b'OK\r\r>'
[obd.elm327] write: b'0100\r\n'
[obd.elm327] read: b'7E8 06 41 00 BE 1D A8 13 \r\r>'
[obd.protocols.protocol] map ECU 0 --> ENGINE
[obd.elm327] Connected Successfully: PORT=/dev/ttyUSB0 BAUD=38400 PROTOCOL=6
[obd.obd] querying for supported commands
[obd.obd] Sending command: b'0100': Supported PIDs [01-20]
[obd.elm327] write: b'0100\r\n'
[obd.elm327] read: b'7E8 06 41 00 BE 1D A8 13 \r\r>'
[obd.obd] Sending command: b'0120': Supported PIDs [21-40]
[obd.elm327] write: b'0120\r\n'
[obd.elm327] read: b'7E8 06 41 20 90 05 80 11 \r\r>'
[obd.obd] Sending command: b'0140': Supported PIDs [41-60]
[obd.elm327] write: b'0140\r\n'
[obd.elm327] read: b'7E8 06 41 40 FA DC 80 01 \r\r>'
[obd.obd] Sending command: b'0600': Supported MIDs [01-20]
[obd.elm327] write: b'0600\r\n'
[obd.elm327] read: b'7E8 06 46 00 C0 00 00 01 \r\r>'
[obd.obd] Sending command: b'0620': Supported MIDs [21-40]
[obd.elm327] write: b'0620\r\n'
[obd.elm327] read: b'7E8 06 46 20 80 00 08 01 \r\r>'
[obd.obd] Sending command: b'0640': Supported MIDs [41-60]
[obd.elm327] write: b'0640\r\n'
[obd.elm327] read: b'7E8 06 46 40 C0 00 00 01 \r\r>'
[obd.obd] Sending command: b'0660': Supported MIDs [61-80]
[obd.elm327] write: b'0660\r\n'
[obd.elm327] read: b'7E8 06 46 60 00 00 00 01 \r\r>'
[obd.obd] Sending command: b'0680': Supported MIDs [81-A0]
[obd.elm327] write: b'0680\r\n'
[obd.elm327] read: b'7E8 06 46 80 80 00 00 01 \r\r>'
[obd.obd] Sending command: b'06A0': Supported MIDs [A1-C0]
[obd.elm327] write: b'06A0\r\n'
[obd.elm327] read: b'7E8 06 46 A0 F8 00 00 00 \r\r>'
[obd.obd] finished querying with 94 commands supported
[obd.obd] ===================================================================
[obd.obd] Sending command: b'010D': Vehicle Speed
[obd.elm327] write: b'010D\r\n'
[obd.elm327] read: b'7E8 03 41 0D 00 \r\r>'
0 kph
[obd.obd] Sending command: b'010D': Vehicle Speed
[obd.elm327] write: b'010D1\r\n'
[obd.elm327] read: b'7E8 03 41 0D 00 \r\r>'
0 kph
[obd.obd] Sending command: b'010D': Vehicle Speed
[obd.elm327] write: b'\r\n'
[obd.elm327] read: b'?\r\r>'
[obd.OBDCommand] b'010D': Vehicle Speed did not recieve any acceptable messages
None

If you look at the "write" command it's not sending anything the third time. This is running on linux with python 3.6.6, installed from pip today.

The hardware works with other software (the ubuntu scantool package) and I'm testing on a 2018 C12 Nissan Pulsar (Tiida in Asian markets), if that matters.

I'm happy to help fix with code patches, just wondering if this is a known issue or something else?

yaleman commented 5 years ago

Have tested this with the latest version from github with the same result, if you make two requests each cycle in the loop it seems to work OK.

Ircama commented 5 years ago

Please, try using the fast=False option in OBD or Async.

It should disable sending the carriage return to repeat the previous command that appears not to be supported by your adapter. (You are anyway not using an original ELM327 chipset as the version of your adapter is v1.5.)

Notice that the behavior of python-OBD reflects ELM327 documentation, page 9/94:

One other feature of the ELM327 is the ability to repeat any command (AT or OBD) when only a single carriage return character is received. If you have sent a command (for example, 01 0C to obtain the rpm), you do not have to resend the entire command in order to resend the request to the vehicle – simply send a carriage return character, and the ELM327 will repeat the command for you. The memory buffer only remembers one command though, and there is no provision in the current ELM327 to provide storage for any more.

yaleman commented 5 years ago

Adding fast=False worked perfectly, sorry for the mis-attributed bug :)