Windows 下 Python 调用近红外 SDK 说明与例程

概述

本文介绍如何在 Windows 64 位系统下,使用 Python 通过 SDK 动态库从近红外光谱仪或模组读取波长和强度数据。SDK 基于 C 语言封装,Python 通过 ctypes 标准库即可直接调用,无需额外安装第三方包。该方案适用于 DLP 型近红外光谱模块(900–1700 nm),提供 228 个像素点的全波段数据。


一、基本函数介绍

SDK 开放了 6 个必要函数,实际操作中已足够绝大多数应用场景。

1.1 通过 USB 打开设备

int dlpOpenByUsb(int index);
  • 参数 index:已连接光谱仪的设备索引,从 0 开始。若仅连接一台设备,设置为 0 即可
  • 返回0 打开成功,<0 打开失败

1.2 关闭 USB 接口

void dlpClose();
  • 关闭设备连接,无参数,无返回值

1.3 读取波长

int dlpGetWavelengths(double *wls, int length);
  • 参数 wls:波长指针,对应长度不超过 228 的 double 型数组
  • 参数 length:数据长度,推荐设为 228(全波段数据点)
  • 返回0 读取成功,<0 失败

1.4 读取强度值

int dlpGetIntensities(int activeIndex, int *intensities, int length);
  • 参数 activeIndex:激活配置索引,新设备推荐使用默认 column 配置(索引 0)
  • 参数 intensities:强度指针,长度为 228 的 int 型数组
  • 参数 length:数据长度,推荐 228
  • 返回0 读取成功,<0 失败

1.5 控制光源

int dlpSetLampOn(int status);
  • 参数 status1 打开光源(仅针对反射型),0 关闭光源
  • 返回0 设置成功,<0 失败

1.6 设置增益倍数

int dlpSetPgaGain(int pga);
  • 参数 pga:增益倍数,仅支持 1、2、4、8、16、32、64。信号不饱和时推荐设为 64,饱和时按需降低
  • 注意:默认值为 64。设置为其他值时可能存在兼容性问题,建议保持 64

二、完整示例代码

以下代码展示了从连接设备到读取、打印波长和强度数据的完整流程:

import ctypes

# ==================== 基本函数 ====================

# 加载共享库
libwrapper = ctypes.CDLL("lib/libwrapper.dll")

# 定义函数原型
libwrapper.dlpOpenByUsb.argtypes = [ctypes.c_int]
libwrapper.dlpOpenByUsb.restype = ctypes.c_int

libwrapper.dlpGetWavelengths.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_int]
libwrapper.dlpGetWavelengths.restype = ctypes.c_int

libwrapper.dlpGetIntensities.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_int),
                                         ctypes.c_int]
libwrapper.dlpGetIntensities.restype = ctypes.c_int

libwrapper.dlpSetLampOn.argtypes = [ctypes.c_int]
libwrapper.dlpSetLampOn.restype = ctypes.c_int

libwrapper.dlpSetPgaGain.argtypes = [ctypes.c_int]
libwrapper.dlpSetPgaGain.restype = ctypes.c_int

# 封装为 Python 函数
def dlpOpenByUsb(index):
    return libwrapper.dlpOpenByUsb(index)

def dlpClose():
    return libwrapper.dlpClose()

def dlpGetWavelengths(wls, wlsNum):
    return libwrapper.dlpGetWavelengths(wls, wlsNum)

def dlpGetIntensities(activeIndex, intensities, wlsNum):
    return libwrapper.dlpGetIntensities(activeIndex, intensities, wlsNum)

def dlpSetLampOn(index):
    return libwrapper.dlpSetLampOn(index)

def dlpSetPgaGain(index):
    return libwrapper.dlpSetPgaGain(index)

# ==================== 调用示例 ====================

PIXEL_NUM = 228  # 900-1700nm 光谱模组为 228 个数据点

# 打开设备
index = 0
result = dlpOpenByUsb(index)
if result >= 0:
    print("HID USB 打开成功!\n")
else:
    print("HID USB 打开失败!\n")

# 打开光源
dlpSetLampOn(1)

# 设置增益倍数
dlpSetPgaGain(64)

# 读取波长
wls_buf = (ctypes.c_double * PIXEL_NUM)()
print("打印前 5 个波长:\n")
result = dlpGetWavelengths(wls_buf, PIXEL_NUM)
if result >= 0:
    for i in range(5):
        print(f"{wls_buf[i]:.2f}")

# 读取强度值
intensities_buf = (ctypes.c_int * PIXEL_NUM)()
activeIndex = 0
print("\n打印前 5 个波长和对应强度值:\n")
result = dlpGetIntensities(activeIndex, intensities_buf, PIXEL_NUM)
if result >= 0:
    for i in range(5):
        print(f"{wls_buf[i]:.2f}: {intensities_buf[i]}")

# 关闭光源
dlpSetLampOn(0)

代码解析

  1. 加载动态库:使用 ctypes.CDLL() 加载 libwrapper.dll
  2. 定义函数原型:使用 argtypesrestype 显式声明参数类型和返回值类型
  3. 创建 C 类型缓冲区(ctypes.c_double * PIXEL_NUM)() 分配与 C 数组兼容的内存
  4. 调用 SDK 函数:按顺序执行 打开设备 → 控制光源 → 设置增益 → 读取波长 → 读取强度

三、常见问题

3.1 dlpSetPgaGain 设置为非 64 时未生效

初步测试发现将增益设置为非 64 值时,实际增益未变化。建议保持默认值 64,若信号饱和则通过降低积分时间或遮挡/衰减光路来调整。

3.2 设备连接失败

  • 检查 USB 数据线是否正常
  • 确认设备已通电并处于可用状态
  • 打开设备管理器查看是否识别到 HID 设备

本文由谱研互联整理编写