我有一个2端口信号继电器通过USB串行接口连接到我的电脑。使用pyserial模块,我可以轻松控制这些继电器。但是,这是基于我事先知道设备分配给哪个COM端口(或/ dev-node)的假设。
对于我正在做的项目是不够的,因为我不想假设设备总是被分配给例如Windows中的COM7。我需要能够使用python在可能的平台(Win,Linux,OSX(我想这将类似于Linux方法))上以编程方式识别设备。或许正如标题所示,在系统中枚举USB设备并以某种方式获得更友好的名称。 Windows和Linux是最重要的支持平台。
非常感谢任何帮助!
修改
好像pyudev-module非常适合Linux系统。有没有人有这方面的经验?
答案 0 :(得分:7)
关于Linux,如果您只需要枚举设备,您甚至可以跳过项目的pyudev依赖关系,只需解析/sbin/udevadm info --export-db
命令的输出(不需要root权限)。它将转储有关当前设备和类的所有信息,包括USB设备的USB产品ID,这些信息应足以识别USB到串行适配器。当然,你也可以用pyudev做到这一点。
答案 1 :(得分:3)
我知道这是一篇较老的帖子,但今天我一直在努力。 最后我使用wmi库进行python,因为我在Windows机器上(抱歉,我知道我的答案仅适用于Windows,但也许它会帮助某人)。
import wmi
c = wmi.WMI()
wql = "Select * From Win32_USBControllerDevice"
for item in c.query(wql):
print item.Dependent.Caption
应该导致类似:
USB Root Hub
USB Root Hub
多产的USB转串口通讯端口(COM9)
USB Root Hub
USB Root Hub
USB复合装置
USB视频设备
USB音频设备
USB Root Hub
... ...剪断
在这种情况下,您必须对Caption进行字符串解析才能找到COM端口。您还可以查看item.Dependent对象,以查看您可能认为相关的标题旁边的USB设备的其他属性:
instance of Win32_PnPEntity
{
Caption = "USB Root Hub";
ClassGuid = "{36fc9e60-c465-11cf-8056-444553540000}";
ConfigManagerErrorCode = 0;
ConfigManagerUserConfig = FALSE;
CreationClassName = "Win32_PnPEntity";
Description = "USB Root Hub";
DeviceID = "USB\\ROOT_HUB\\4&32F13EF0&1";
HardwareID = {"USB\\ROOT_HUB&VID8086&PID3A36&REV0000",
"USB\\ROOT_HUB&VID8086&PID3A36", "USB\\ROOT_HUB"};
Manufacturer = "(Standard USB Host Controller)";
Name = "USB Root Hub";
PNPDeviceID = "USB\\ROOT_HUB\\4&32F13EF0&1";
Service = "usbhub";
Status = "OK";
SystemCreationClassName = "Win32_ComputerSystem";
SystemName = "001fbc0934d1";
};
答案 2 :(得分:2)
至少对于linux,你可以使用一些虚拟黑客来确定你的/ dev节点,例如在你附加设备之前和之后检查“ls / dev | grep ttyUSB”的输出。这在某种程度上也必须适用于OSX案例。一个好主意是使用subprocess.Popen()命令检查这些命令。对于Windows,this可能会有所帮助。
答案 3 :(得分:2)
Windows:您可以提取USB信息from WMI,但you need to be administrator。示例在.NET中,但您应该能够使用Python WMI module。这将使您可以访问USB识别字符串,其中可能包含有用的信息。对于FTDI串行设备,使用FTDI的DLL进行快捷方式,不需要特权访问。
Linux:所有可用信息都在/sys/bus/usb
下,也可以通过udev获得。 This looks like a good answer
答案 4 :(得分:1)
就Windows而言,您可以扫描注册表:
import _winreg as reg
from itertools import count
key = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, 'HARDWARE\\DEVICEMAP\\SERIALCOMM')
try:
for i in count():
device, port = reg.EnumValue(key, i)[:2]
print device, port
except WindowsError:
pass
答案 5 :(得分:0)
如果可行的话会很棒,但根据我使用COM端口的商业设备的经验,情况并非如此。大多数情况下,您需要在软件中手动设置COM端口。这是一个烂摊子,特别是在Windows(至少XP)中,在某些情况下往往会改变com端口的数量。在某些设备中,软件中有一个自动发现功能,它向每个COM端口发送一条小消息并等待正确的答案。这当然只有在仪器实现某种识别命令时才有效。祝你好运。