Я работаю над управлением некоторыми релейными картами из Python. Я могу отлично настроить и контролировать отдельную релейную карту (pyusb, python3.6 ubuntu 16.04). Использование стандартных методов для идентификации и настройки устройства USB.
dev = usb.core.find(idVendor=0x1a86, idProduct=0x7523)
Однако мне нужно использовать несколько устройств одного типа, и я могу найти их просто отлично:
dev = usb.core.find(idVendor=0x1a86, idProduct=0x7523, find_all=True)
Проблема возникает, потому что get_active_configuration () для обоих устройств одинаковы. Я могу запросить шину устройства и адрес устройства, однако не уверен, как использовать эту информацию USB-соединения для идентификации платы и выполнения функции последовательной записи изнутри python, используя только шину и адрес.
Примечание: в моем исследовании и документация pyusb , и несколько других сообщений на форуме указывают на использование шины и адреса USB-соединения для различения нескольких идентичных устройств, поэтому я считаю, что это правильный подход, но я я не уверен, как на самом деле написать код, чтобы сделать это, так как большинство других примеров, которые я видел, просто смотрят, чтобы соответствовать idVendor + idProduct.
Размещение здесь кода, который я сейчас использую для доступа к одному устройству:
import time
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x1a86, idProduct=0x7523)
if dev is None:
raise ValueError("Device not found")
if dev.is_kernel_driver_active(0):
dev.detach_kernel_driver(0)
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)
assert ep is not None
# example relay hex serial command
cl_all = [0x3A, 0x46, 0x45, 0x30, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x32, 0x46, 0x46, 0x46, 0x46, 0x45, 0x33, 0x0D, 0x0A]
# example write operation
ep.write(cl_all)
Таким образом, в основном, dev в основном выбирает любую из конфигураций, и если я использую флаг find_all = True в usb.core.find, я могу найти обе платы. Просто не уверен, как обращаться к ним отдельно, если нет серийного номера. После изучения этого я думаю (но я не уверен), что интерфейс второй платы затем сохраняется в cfg [(1,0)], но, во-первых, я не смог его успешно реализовать, и, во-вторых, не обязательно будет постоянным каждый раз, когда я загружаюсь или платы подключены и отключены.
Обновление / редактирование: после работы с этой картой в течение еще примерно 20 часов и переписки с производителем и некоторыми другими людьми, работающими над той же проблемой (ссылка на github ниже), я пришел к выводу, что плата не поддержка сериализации. Я перешел на ретранслятор на основе Ethernet и, хотя и стоил дороже, мне было легко устанавливать фиксированные IP-адреса для каждой платы и выполнять свои задачи. Я не верю, что эта проблема решаема с имеющейся у меня проблемой с USB-оборудованием, и, кроме того, плата не может вернуть простой статус (у меня есть две из этих плат, так что это не ошибка одного устройства).
https://github.com/ondrej1024/crelay/issues/21