У меня есть USB-устройства, использующие чип FTDI, который я могу идентифицировать в Linux:
user@user:~/src/libftdi/build$ lsusb
Bus 009 Device 008: ID 0403:faf0 Future Technology Devices International, Ltd
или:
user@user:~$ lsusb -v -d 0403:faf0
Bus 009 Device 008: ID 0403:faf0 Future Technology Devices International, Ltd
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0403 Future Technology Devices International, Ltd
idProduct 0xfaf0
bcdDevice 6.00
iManufacturer 1 Thorlabs
iProduct 2 APT DC Motor Controller
iSerial 3 83836244
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 32
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 2 APT DC Motor Controller
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0001
Self Powered
Я установил pylibftdi и выяснил, как их перечислить
In [26]: dev.driver.list_devices()
Out[26]:
[('Thorlabs', 'APT DC Motor Controller', '83836244'),
('Thorlabs', 'APT DC Motor Controller', '83838416'),
('Thorlabs', 'APT DC Motor Controller', '83837686'),
('Thorlabs', 'APT DC Motor Controller', '83836852'),
('Thorlabs', 'APT DC Motor Controller', '83837812'),
('Thorlabs', 'APT DC Motor Controller', '83825518'),
('Thorlabs', 'APT DC Motor Controller', '83838377'),
('Thorlabs', 'APT DC Motor Controller', '83838379'),
('Thorlabs', 'APT DC Motor Controller', '83836769'),
('Thorlabs', 'APT DC Motor Controller', '83837688'),
('Thorlabs', 'APT DC Motor Controller', '83836926'),
('Thorlabs', 'APT DC Motor Controller', '83837767'),
('Thorlabs', 'APT DC Motor Controller', '83836887'),
('Thorlabs', 'APT DC Motor Controller', '83836737'),
('Thorlabs', 'APT DC Motor Controller', '83838436'),
('Thorlabs', 'APT DC Motor Controller', '83837639'),
('Thorlabs', 'APT DC Motor Controller', '83836040'),
('Thorlabs', 'APT DC Motor Controller', '83837769'),
('Thorlabs', 'Brushed Motor Controller', '27251492'),
('Thorlabs', 'Brushed Motor Controller', '27251539')]
In [1]: from pylibftdi import USB_PID_LIST, USB_VID_LIST, Device
In [2]: USB_PID_LIST.append(0xFAF0)
In [3]: dev = Device()
In [4]: dev.driver.libftdi_version()
Out[4]: libftdi_version(major=0, minor=0, micro=0, version_str='< 1.0 - no ftdi_get_library_version()', snapshot_str='unknown')
В документации к pylibusb говорится, что атрибут device_id может использоваться для указания устройства, к которому я пытаюсь подключиться:
| __init__(self, device_id=None, mode='b', encoding='latin1', interface_select=None, device_index=0, **kwargs)
| Device([device_id[, mode, [OPTIONS ...]]) -> Device instance
|
| represents a single FTDI device accessible via the libftdi driver.
| Supports a basic file-like interface (open/close/read/write, context
| manager support).
:param device_id: an optional serial number of the device to open.
| if omitted, this refers to the first device found, which is
| convenient if only one device is attached, but otherwise
| fairly useless.
Вот мой простой код, в котором я создаюдва экземпляра dev1 и dev2.Для dev2 я не указываю device_id (следовательно, нет конкретного серийного номера), а для dev1 я делаю.Я могу успешно общаться с dev2, но не с dev1:
>>>from pylibftdi import USB_PID_LIST, USB_VID_LIST, Device
>>>from struct import pack, unpack
>>>USB_PID_LIST.append(0xFAF0)
>>>command = pack('BBBBBB',0x05,0x00,0x00,0x00,0x50,0x01)
>>>dev2 = Device();
>>>dev2.baudrate = 115200;
>>>dev2.writelines(command);
>>>dev2.readline()
'\x06\x00T\x00\x81P\xc0z\xf2\x04TDC001\x00\x00\x10\x00\x03\x00\x02\x00TDC001 DC Servo Drive\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00104927Apr\x00\x01\x00\x02\x00\x00\x00\x01\x00'
>>>dev1 = Device(device_id = '83838416');
>>>dev1.baudrate = 115200;
>>>dev1.writelines(command);
>>>dev1.readline()
''
Поскольку у меня есть десятки этих USB-устройств, подключенных к одному компьютеру, мне важно иметь возможность создать экземпляр и поговорить сустройство с определенным серийным номером.
Я не уверен, что это ошибка или я что-то не так делаю.
Добавлено позже:
Почему-то это зависит от истории.Если я запускаю тот же код после перезапуска Python, я получаю пустую строку в качестве ответа.Я не знаю, чем я сейчас занимаюсь, по-другому.
In [1]: from pylibftdi import USB_PID_LIST, USB_VID_LIST, Device
In [2]: from struct import pack, unpack
In [3]: USB_PID_LIST.append(0xFAF0)
In [4]: command = pack('BBBBBB',0x05,0x00,0x00,0x00,0x50,0x01)
In [5]: dev2 = Device();dev2.baudrate = 115200;dev2.writelines(command);dev2.readline();
In [6]: dev2.__dict__
Out[6]:
{'_baudrate': 115200,
'_opened': True,
'ctx': <ctypes.c_char_Array_1024 at 0x7ff2008a1b00>,
'decoder': <encodings.latin_1.IncrementalDecoder at 0x7ff2006906d0>,
'device_id': None,
'device_index': 0,
'driver': <pylibftdi.driver.Driver at 0x7ff200690610>,
'encoder': <encodings.latin_1.IncrementalEncoder at 0x7ff200681f90>,
'encoding': 'latin1',
'fdll': <CDLL 'libftdi.so.1', handle 5627c1668650 at 7ff2011d08d0>,
'interface_select': None,
'mode': 'b'}
In [8]: