使用pyUSB从ELM327 OBDII读取数据到USB设备

时间:2013-05-08 15:30:23

标签: python usb libusb pyusb obd-ii

我在使用pyUSB库将数据从ELM327 OBDII读取到USB设备时遇到问题。我知道我需要在写端点上向设备写入命令,并在读端点上读回接收到的数据。它似乎并不想为我工作。

我为此写了自己的类obdusb:

import usb.core

class obdusb:

      def __init__(self,_vend,_prod):

    '''Handle to USB device'''
    self.idVendor = _vend
    self.idProduct = _prod
    self._dev = usb.core.find(idVendor=_vend, idProduct=_prod) 

    return None


def GetDevice(self):
    '''Must be called after constructor'''
    return self._dev


def SetupEndpoint(self):
    '''Must be called after constructor'''
    try: 
        self._dev.set_configuration()

    except usb.core.USBError as e:
        sys.exit("Could not set configuration")

    self._endpointWrite = self._dev[0][(0,0)][1]
    self._endpointRead = self._dev[0][(0,0)][0]

    #Resetting device and setting vehicle protocol (Auto)
    #20ms is required as a delay between each written command

    #ATZ resets device
    self._dev.write(self._endpointWrite.bEndpointAddress,'ATZ',0)
    sleep(0.002)
    #ATSP 0 should set vehicle protocol automatically
    self._dev.write(self._endpointWrite.bEndpointAddress,'ATSP 0',0) 
    sleep(0.02)

    return self._endpointRead


def GetData(self,strCommand):

    data = []
    self._dev.write(self._endpintWrite.bEndpointAddress,strCommand,0)
    sleep(0.002)
    data = self._dev.read(self._endpointRead.bEndpointAddress, self._endpointRead.wMaxPacketSize)

    return data

然后我使用这个类并使用以下代码调用GetData方法:

import obdusb

#Setting up library,device and endpoint
lib = obdusb.obdusb(0x0403,0x6001)
myDev = lib.GetDevice()
endp = lib.SetupEndpoint()

#Testing GetData function with random OBD command
#0902 is VIN number of vehicle being requested
dataArr = lib.GetData('0902')
PrintResults(dataArr)

raw_input("Press any key")

def PrintResults(arr):

    size = len(arr)

    print "Data currently in buffer:"

    for i in range(0,size):
        print "[" + str(i) + "]: " + str(make[i])

这只会打印数组中[0]和[1]元素的数字1和60。没有其他数据从命令返回。无论设备是否连接到汽车,都是这种情况。我不知道这2条信息是什么。我希望它返回一串十六进制数字。有谁知道我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

如果你不使用ATST或ATAT,你必须在开始时,每个写/读组合之间预计超时200ms。

你在每个命令后发送一个'\ r'吗?看起来你没有,所以它永远等待回程。

并提示:用010D或010C等测试。 09xx可能很难期待。

更新: 你可以两种方式做到这一点。只要你用回车“分开”每个命令。

http://elmelectronics.com/ELM327/AT_Commands.pdf http://elmelectronics.com/DSheets/ELM327DS.pdf(扩展名单)。

那个命令列表对我来说非常有用。

ATAT可用于调整超时。 当您发送010D时,ELM芯片将正常等待200 ms,以获得所有可能的反应。有时你可以得到更多的回报,所以等待200毫秒。

你也可以做什么,这是一个谜,因为只有scantools倾向于实现这一点:

'010D1 / R'

命令后面的1,指定ELM应该报告回来,当它有来自总线的1个回复时。因此,它可以非常有效地减少延迟,代价是无法从地址'010D'获得更多值。 (这是速度!)

对不起我的英语,我希望能把你带到正确的方向。