SmartDriver 二次开发用户手册
SmartDriver 二次开发用户手册
概述
SmartDriver 是用于操作光纤光谱仪的 SDK 动态库,提供 C 语言接口,支持 Windows 和 Linux 双平台。通过调用 SmartDriver 提供的 API 函数,用户可以在自有软件中集成光谱仪控制与数据采集功能,实现从设备枚举到光谱读取的完整工作流。本文档介绍 SmartDriver 的基本操作流程、函数详解,并提供 C 语言和 Python 的完整调用例程。
一、基本操作流程
以下 8 个步骤涵盖了从光谱仪初始化到读取光谱数据的基础流程,可满足绝大部分常规测量需求:
- 枚举设备:
int Init(int commType)— 获取已连接的光谱仪数量 - 打开设备:
int Open(int index)— 以指定通讯方式打开光谱仪 - 获取序列号:
int GetSerialNumber(int index, char *serialNumber)— 读取设备唯一标识 - 设置积分时间:
int SetIntegrationTime(int index, double integrationTimeMs)— 单位 ms - 设置平均次数:
int SetAverageTime(int index, int averageTime)— 多次平均提升信噪比 - 获取波长数量:
int GetWavelengthsNumber(int index, int *number)— 默认 2048 个像素 - 获取波长值:
int GetWavelengths(int index, float *wls)— 读取 2048 个波长点 - 获取光谱强度:
int GetScopes(int index, unsigned short *scopes)— 读取对应强度值
如果需要配合闪烁氙灯使用,还需额外执行以下两个步骤(SmartDriver v2.2.2 起支持):
-
配置氙灯触发脉冲:
int SetXenonPulse(int index, int period, int discharge)。参数period为脉冲周期,默认值为 1,510,000 个 10 ns(即 15.1 ms);discharge为放电时间(高电平持续时间),默认值 10,000 个 10 ns(即 0.1 ms)。如不理解参数含义,使用默认值即可。 -
配置氙灯触发模式:
int SetXenonModel(int index, int mode)。mode = 0,不开启触发(默认);mode = 1,单次脉冲模式;mode = 2,连续脉冲模式。
单次脉冲模式:积分时间大于一个脉冲周期时,仅触发一次,配合平均次数可实现高频触发。此为最常用模式。
连续脉冲模式:积分时间为脉冲周期的整数倍时,氙灯按周期连续触发,适用于氙灯强度不足需累积光强的场景。
注意:设置氙灯触发模式后,只要光谱仪不断电,该模式会一直保存在寄存器中。断电后需重新配置。
二、函数详解
2.1 初始化与枚举
int Init(int commType);
- 描述:初始化光谱仪,获取已连接光谱仪数量
- 参数
commType:通讯类型,0为启用 USB 通讯 - 返回:
>0为已连接设备数量;<0为错误码
2.2 打开与关闭
int Open(int index);
int Close(int index);
- 参数
index:光谱仪索引,从 0 开始 - 返回:
0成功,<0为错误码
2.3 获取序列号
int GetSerialNumber(int index, char *serialNumber);
- 参数
serialNumber:用于存储序列号的字符串指针,长度 ≥ 8
2.4 设置积分时间与平均次数
int SetIntegrationTime(int index, double integrationTimeMs);
int SetAverageTime(int index, int averageTime);
- 积分时间单位为 ms;增加平均次数可提升信噪比但延长测量耗时
2.5 获取波长与强度
int GetWavelengthsNumber(int index, int *number);
int GetWavelengths(int index, float *wls);
int GetScopes(int index, unsigned short *scopes);
- 波长数组长度默认 2048;强度值类型为
unsigned short(16 位)
2.6 氙灯控制
int SetXenonPulse(int index, int period, int discharge);
int SetXenonModel(int index, int mode);
- 配置氙灯脉冲前需先配置触发脉冲;关闭软件前建议先关闭光谱仪再退出
三、C 语言例程
以下例程 C 和 C++ 通用,Windows 和 Linux 通用:
#include "wrapper.h"
#include <stdio.h>
int main()
{
int index = 0;
int ret = 0;
char deviceSerail[13];
float wls[2048];
unsigned short scopes[2048];
// 枚举设备
int deviceNum = Init(0);
printf("Device number: %d\n", deviceNum);
// 打开设备
ret = Open(index);
if (ret < 0) printf("Open error code: %d\n", ret);
else printf("Open successfully.\n");
// 获取序列号
ret = GetSerialNumber(index, deviceSerail);
if (ret >= 0) printf("Serial: %s\n", deviceSerail);
// 设置积分时间 100 ms,平均 5 次
SetIntegrationTime(index, 100);
SetAverageTime(index, 5);
// 获取波长
GetWavelengths(index, wls);
// 获取强度
GetScopes(index, scopes);
// 打印前 5 个像素的波长和强度
for (int i = 0; i < 5; i++)
printf("%.3f: %d\n", wls[i], scopes[i]);
// 关闭设备
Close(index);
return 0;
}
Linux 注意:运行程序需管理员权限,如
sudo ./main。
四、Python 例程
Python 通过 ctypes 模块调用 C 动态库 libwrapper.so(Linux)/ libwrapper.dll(Windows):
import ctypes
# 加载动态库(Linux 使用绝对路径)
libwrapper = ctypes.CDLL('/usr/local/lib/libwrapper.so', mode=ctypes.RTLD_GLOBAL)
# 定义函数原型
libwrapper.Init.argtypes = [ctypes.c_int]
libwrapper.Init.restype = ctypes.c_int
libwrapper.Open.argtypes = [ctypes.c_int]
libwrapper.Open.restype = ctypes.c_int
libwrapper.GetSerialNumber.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char)]
libwrapper.GetSerialNumber.restype = ctypes.c_int
libwrapper.SetIntegrationTime.argtypes = [ctypes.c_int, ctypes.c_double]
libwrapper.SetIntegrationTime.restype = ctypes.c_int
libwrapper.SetAverageTime.argtypes = [ctypes.c_int, ctypes.c_int]
libwrapper.SetAverageTime.restype = ctypes.c_int
libwrapper.GetWavelengths.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_float)]
libwrapper.GetWavelengths.restype = ctypes.c_int
libwrapper.GetScopes.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_ushort)]
libwrapper.GetScopes.restype = ctypes.c_int
# 封装为 Python 类
class Wrapper:
def __init__(self):
pass
def init(self, commType):
return libwrapper.Init(commType)
def open(self, index):
return libwrapper.Open(index)
def get_serial_number(self, index):
serial = ctypes.create_string_buffer(8)
ret = libwrapper.GetSerialNumber(index, serial)
return ret, serial.value.decode()
def set_integration_time(self, index, ms):
return libwrapper.SetIntegrationTime(index, ms)
def set_average_time(self, index, n):
return libwrapper.SetAverageTime(index, n)
def get_wavelengths(self, index):
wls = (ctypes.c_float * 2048)()
ret = libwrapper.GetWavelengths(index, wls)
return ret, [wls[i] for i in range(2048)]
def get_scopes(self, index):
scopes = (ctypes.c_ushort * 2048)()
ret = libwrapper.GetScopes(index, scopes)
return ret, [scopes[i] for i in range(2048)]
# 使用示例
wrapper = Wrapper()
index = 0
ret = wrapper.init(0)
print(f"Connected devices: {ret}")
wrapper.open(index)
wrapper.set_integration_time(index, 100)
wrapper.set_average_time(index, 5)
ret, wavelengths = wrapper.get_wavelengths(index)
ret, scopes = wrapper.get_scopes(index)
for i in range(500, 505):
print(f"{wavelengths[i]:.2f}: {scopes[i]}")
五、Linux 系统注意事项
5.1 依赖库
使用光纤光谱仪 SDK 需要两个依赖库:FTDI 通信芯片库 libftd2xx.so 和光谱仪操作库 libwrapper.so。可将其复制到 /usr/local/lib 并添加环境变量:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
5.2 卸载 VCP 驱动
Linux 系统中 VCP(Virtual COM Port)与 D2XX 驱动不兼容。使用 USB 通信前需卸载 VCP 驱动:
sudo rmmod ftdi_sio
sudo rmmod usbserial
特别注意:每次插入光谱仪时 VCP 驱动都会自动安装,因此每次使用前都需卸载。建议在软件启动脚本中自动执行上述卸载命令。
本文由谱研互联整理编写