工作中需要使用CameraLink接口自带的串口与设备进行通信,DALSA采集卡软件中可以将CameraLink接口里的串口映射到一个COM口,但是在使用第三方串口库(nodejs的serialport、python的serial)提供的获取串口列表接口,都无法枚举到这个映射的COM口,切Windows的设备管理器也无法识别到该COM口。本文记录一种以访问注册表的方式成功获取到该COM口的方法
Nodejs serialport获取串口列表
serialport.list()方法会返回一个串口列表数组,遍历该数组,元素的path就是串口名称(COMx)。程序中可以通过创建一个定时器或者线程来定时轮询该列表
import serialport from 'serialport'
setInterval(() => {
serialport.list().then(
ports => {
if (ports.length > 0) {
/* do something */
ports.forEach((item, index, arr) => {
console.log('name:' + item.path)
})
}
}
)
}, 500)
Python serial获取串口列表
serial.tools.list_ports()方法可以获取到串口列表数组,遍历数组,每个元素的name属性就是串口名称(COMx)
import serial
import serial.tools.list_ports
plist = list(serial.tools.list_ports.comports())
ports = [p.name for p in plist]
print(ports)
Python通过注册表获取串口列表
以上两种方式都无法获取不在Windows设备管理器中的COM口。Python中可以使用win32api和win32con来枚举注册表中的硬件信息,从而获取比较全的COM口列表,这种方式可以枚举到采集卡映射的COM口。以下是函数示例
import win32api
import win32con
def get_serial_ports():
ports = []
key = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE,
"HARDWARE\DEVICEMAP\SERIALCOMM", 0, win32con.KEY_READ)
try:
i = 0
while True:
name, value, type1 = win32api.RegEnumValue(key, i)
print("name:{} value:{}".format(name, value))
i += 1
ports.append(value)
except:
print('except')
win32api.RegCloseKey(key)
return ports
需注意以下几点
- 访问串口列表的注册表路径是固定的,即 HKEY_LOCAL_MACHINE + "HARDWARE\DEVICEMAP\SERIALCOMM"
- 通过RegOpenKey()打开键值,时候完毕后需要通过RegCloseKey()关闭键值
- 通过RegEnumValue()来枚举可迭代的键值,枚举返回name、value和type,其中的value是串口名
以上其实是提供了访问PC外设资源的一种方式,不管是使用Python、JavaScript、C++等语言,在Windows环境中都可以以访问注册表的方式来实现访问外设资源的功能