Python控制柯尼卡美能达CS2000分光辐射亮度计完整指南
本文详细记录使用Python通过串口控制柯尼卡美能达CS2000分光辐射亮度计的步骤。内容涵盖Win10环境下的pySerial模块安装、COM端口识别、波特率等通信参数配置,以及初始化、单次测量和数据读取的代码实现。重点解析命令分隔符、超时设置及错误处理,旨在为屏幕亮度测量提供可靠的自动化方案。
前言
本文档旨在记录通过串口连接并控制CS2000设备的具体操作流程。
CS2000是一款分光辐射亮度计,主要用于精确测量光源的亮度数据。关于该设备的详细规格参数,可参考柯尼卡美能达官网发布的CS2000/CS-2000A页面,所有技术参数及操作规范均以官方提供的参数表和用户使用手册为准。
使用目的及环境
本次实践的核心目的是通过PC端软件控制CS2000设备,从而自动化获取屏幕的亮度测量数据。
开发环境方面,PC端采用Python语言进行编程,操作系统为Windows 10。
除了Python标准库外,还需要额外安装pySerial模块以支持串口通信功能。
设备连接方法
CS2000设备支持USB 1.1 Full-Speed接口以及RS-232C串行通信标准。官方配套软件CS-S10默认使用USB 1.1接口进行通信,安装该软件通常意味着已自动安装了相应的驱动程序。但在本方案中,我们选择配置串行通信端口COM Port进行连接。
CS2000设备支持的通信参数设定如下表所示:

在本例中,我们选定波特率为115200,数据位长度为8 bits,无校验位,停止位为1 bit。关于硬件流控(即请求发送RTS和清除发送CTS信号),在此阶段暂不作启用考虑。
程序主体流程
1. 获取计算机可用的COM端口列表;
2. 连接并打开CS2000对应的设备端口;
3. 对设备进行初始化设置(包括设定远程控制模式、禁用设备面板测试按键、设定同步模式等);
4. 执行单次测量指令并获取测量结果;
5. 操作结束后关闭串口连接;
接下来,我们将结合设备手册的具体要求,逐步展开代码操作说明。
获取端口
首先需要引入serial.tools.list_ports模块以访问系统端口信息:
def port_list():
"""
获取电脑端口列表
:return: 端口列表
"""
pl = serial.tools.list_ports.comports()
# print(pl)
print("Port List:")
for item in pl:
print("{}\t\t:\t{}".format(item.usb_description(), item.manufacturer))
在获取端口列表后,建议打印每个端口的描述信息和制造商名称,这有助于在多个端口存在时准确区分并选择CS2000所在的端口。
连接端口
需要引入serial模块来建立串口连接:
def connect_com(port, baudrate=115200, timeout=0):
"""
配置串口参数并进行连接;
:param port: 端口号,“COM1”
:param baudrate: 波特率,115200
:param timeout: 超时时间,0
:return: 连接好的串口,ser
"""
# noinspection PyBroadException
try:
ser = serial.Serial(port, baudrate, timeout=timeout)
print("Port\t\t:\t{}".format(ser.name))
print("Baudrate\t:\t{}".format(ser.baudrate))
print("Status\t\t:\t{} Connect Successful!".format(port))
return ser
except Exception:
print("Status\t\t:\t\t\tConnect COM Failed!")
定义一个函数,该函数负责配置串口参数并返回已打开的串口对象实例。
发送格式
分隔符
当PC向测量设备发送命令时,必须遵循特定的分隔符规范:
CR和LF分别对应ASCII码中的0x0D和0x0A;这意味着在每条命令发送结束后,必须附加相应的分隔符以进行数据分割。
数据字符格式
在发送的数据内容中,若涉及数字,必须以对应的字符形式发送。例如,若要发送十进制数值886,实际发送的字符序列应为886。如果输入的字符长度不足,需要使用空格进行补齐,以符合协议格式要求。
超时
PC与设备通信时的超时设定至少应设置为10秒。这是因为设备在测量亮度时需要积分时间,特别是当测试画面较暗时,积分时间会显著延长,导致返回数据的时间延迟较大,因此超时设定需至少预留10秒。
在实际测试场景中,测量较暗画面所需的时间可能超过7秒,这进一步验证了较长超时设置的必要性。
初始化
初始化过程包含多个关键环节,主要包括设置远端模式(SCMS)、关闭设备上的测量按键(MSWE)、设定同步模式等;详细逻辑可参考设备手册,理解后直接参考以下代码实现。
def remote_mode(ser):
"""
对cs2000进行远程控制设置
:param ser: cs2000的串口
:return: None
"""
data = b'RMTS,1\n'
tx_data(ser, data)
if rx_data(ser)[0] == "OK00":
print("Status\t\t:\tRemote Mode Setting OK!")
else:
print("Status\t\t:\tRemote Mode Setting ERROR!")
def meas_key_off(ser):
"""
关闭cs2000设备上的measure按键控制
:param ser: cs2000的串口
:return: None
"""
data = b'MSWE,0\n'
tx_data(ser, data)
if rx_data(ser)[0] == "OK00":
# print("Status\t\t:\tMeasure Key Disable OK!")
pass
else:
print("Status\t\t:\tMeasure Key Disable ERROR!")
def sync_mode_set(ser, freq):
"""
同步模式设定
:param ser: cs2000的串口
:param freq: 频率,单位Hz
:return: None
"""
mode = b'1,'
freq = freq.encode()
data = b'SCMS,' + mode + freq + b'00\n'
tx_data(ser, data)
if rx_data(ser)[0] == "OK00":
print("Status\t\t:\tSync Mode is {}, freq is {}Hz!".format(mode, freq))
pass
else:
print("Status\t\t:\tMeasure Key Disable ERROR!")
def sync_mode_read(ser):
"""
同步模式读取
:param ser: cs2000的串口
:return: None
"""
sync_mode_dict = {"0": "No sync",
"1": "Internal sync",
"2": "External sync"}
data = b'SCMR\n'
tx_data(ser, data)
rdata = rx_data(ser)
if rdata[0] == "OK00":
print("Status\t\t:\tSync Mode is {}. ".format(sync_mode_dict[rdata[1]]))
if rdata[1] == "1":
print("Status\t\t:\tSync frequency is {}Hz. ".format(rdata[2][:-2]))
pass
else:
print("Status\t\t:\tSync Mode read ERROR!")
def dev_init(ser):
"""
cs2000设备进行初始化,包含设置为远程控制,关闭测量按键,设置同步模式,查询同步模式数据
:param ser: cs2000的串口
:return: None
"""
remote_mode(ser)
meas_key_off(ser)
sync_mode_set(ser, SYNC_FREQ)
sync_mode_read(ser)
注意:每次发送命令后,设备均会返回响应数据。如果返回结果为OK00,则表明命令发送和接收均正常;若返回包含ERxx等字样的错误代码,则需查阅手册中的错误代码列表以确定原因并进行修正。
测量数据
获取测量数据时,需先发送测量指令,等待设备返回测量所需时间,并等待测量过程结束;
随后再发送读取测量数据的指令。
def measure(ser):
"""
向cs2000发出测量的命令
:param ser: cs2000的串口
:return: None
"""
data = b'MEAS,1\n'
tx_data(ser, data)
rdata = rx_data(ser)
if rdata[0] == "OK00":
# print("Status\t\t:\tMeasure time is {}s".format(rdata[1]))
pass
else:
print("Status\t\t:\tMeasure CMD ERROR Code {}".format(rdata[0]))
rdata_1 = rx_data(ser)
if rdata_1[0] == "OK00":
# print("Status\t\t:\tMeasurement completed!")
pass
else:
print("Status\t\t:\tMeasure Wait ERROR Code {}".format(rdata_1[0]))
def lv_read(ser):
"""
向cs2000发出测量的命令
:param ser: cs2000的串口
:return: 亮度值lv
"""
data = b'MEDR,2,0,101\n'
tx_data(ser, data)
rdata = rx_data(ser)
if rdata[0] == "OK00":
# print("Status\t\t:\tLuminance is {} cd/m²".format(rdata[1]))
return rdata[1]
else:
print("Status\t\t:\tLuminance Read ERROR Code {}".format(rdata[0]))
return None
def get_lv(ser):
"""
获取亮度值
:param ser: cs2000的串口
:return: 亮度值,单位cd/m²
"""
measure(ser)
return lv_read(ser)
def xylv_read(ser):
"""
向cs2000发出测量的命令
:param ser: cs2000的串口
:return: 色坐标,X,Y,亮度,LV
"""
data = b'MEDR,2,0,2\n'
tx_data(ser, data)
rdata = rx_data(ser)
if rdata[0] == "OK00":
print("Status\t\t:\tX,Y,LV are {} {} {}".format(rdata[1], rdata[2], rdata[3]))
return rdata[1:]
else:
print("Status\t\t:\tMeasure ERROR!")
return None
def get_xylv(ser):
"""
获取色坐标X,Y和亮度LV。
:param ser: cs2000的串口
:return: 色坐标,X,Y,亮度,LV
"""
measure(ser)
return xylv_read(ser)
返回数据的格式解析需依据所发送的指令进行,具体对应关系在设备的Datasheet中均有详细介绍。
串口收发数据的函数
为了便于调用,我们对串口的数据收发功能进行了封装,形成专用函数:
def tx_data(ser, data):
# noinspection PyBroadException
try:
ser.write(data)
# print("Status\t\t:\tSend OK!")
except Exception:
print("Status\t\t:\tSend ERROR!")
def rx_data(ser):
# noinspection PyBroadException
try:
rdata = ser.readline().decode("utf-8").replace("\n", "").split(",")
# print("Status\t\t:\tReceived {}".format(rdata))
return rdata
except Exception:
print("Status\t\t:\tReceive ERROR!")
串口关闭
串口使用完毕后,必须执行合理的关闭操作,以防止因多个程序同时运行而引发连接冲突或资源占用问题。
def serial_close(ser):
"""
关闭串口连接
:return: None
"""
# noinspection PyBroadException
try:
ser.close()
print("Port {} has been closed!".format(ser.name))
except Exception:
print("----serial_close failed!")
主函数
在所有参数传递过程中,核心是将产生的串口对象作为参数传递给各个功能模块。
if __name__ == '__main__':
port_list()
cs2000 = connect_com("COM1", timeout=5)
dev_init(cs2000)
get_lv(cs2000)
get_xylv(cs2000)
serial_close(cs2000)
写在后面
设备调试的关键在于严格参考Datasheet:cs_2000_technicalnote_en,该文档可在官网支持页面下载。熟悉手册内容后,后续的调试环节将大幅节省时间,过程也会更加顺畅。以下列举几个调试过程中遇到的典型问题及解决思路:
1. 合理设定超时时间(应基于最长可能的测量时间进行设定),在发送数据后即可等待接收响应;
2. 此处使用的分隔符为\n,需将其转换为byte类型格式后进行串口发送;
3. 部分模式设定只需执行一次,无需每次上电都重复设定,但为确保稳妥,统一将其放置在初始化代码中;
4. 在暗光环境下测试暗光源时,所需测量时间较长,手动测试版可能长达24s之多;而亮光源的测试时间通常在1s左右;
5. 程序中直接将串口对象作为参数传递的做法略显不妥,建议将该模块重构为class形式以提高代码结构合理性;
后续若遇到其他问题,将在此持续更新。
本项目源码地址:https://github.com/LJacki/CS2000
到此这篇关于总结Python连接CS2000的详细步骤的文章就介绍到这了,更多相关python连接CS2000内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









