树莓派(Linux arm64)下近红外 SDK 二次开发手册

概述

本文介绍如何在树莓派(arm64 架构,Ubuntu 64 位系统)上,使用 Python 调用近红外光谱仪 SDK 读取波长和强度数据。SDK 以 C 语言动态库 libwrapper.so 的形式提供,同时封装了 Python 扩展包 wrapper.py,用户只需导入该模块即可快速完成数据采集。


一、wrapper.py 基本函数

wrapper.py 已封装好 4 个核心函数,源码中通过 ctypes 加载动态库并定义函数原型:

import ctypes

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

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

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

# 封装为 Python 函数
def dlpConnect():
    """连接设备,返回已连接设备数量"""
    return libwrapper.dlpConnect()

def dlpOpenByUsb(index):
    """通过 USB 打开指定索引的设备"""

def dlpGetWavelengths(wls, wlsNum):
    """获取波长值,存入 wls 缓冲区"""

def dlpGetIntensities(activeIndex, intensities, wlsNum):
    """获取强度值,存入 intensities 缓冲区"""

函数功能简要说明:

函数 功能 返回值
dlpConnect() 枚举已连接设备 设备数量
dlpOpenByUsb(index) 打开指定索引的设备 >=0 成功,<0 失败
dlpGetWavelengths(wls, num) 读取 228 个波长点 >=0 成功
dlpGetIntensities(idx, buf, num) 读取 228 个强度值 >=0 成功

二、模块安装

用户将拿到以下文件:

  1. wrapper.py — 封装好的 Python 模块
  2. setup.py — 扩展安装脚本
  3. lib/libwrapper.so — C 动态库
  4. main.py — 调用例程

安装步骤

新建文件夹 python_demo_v1.1,将上述 4 个文件复制到该目录,并设置读写权限:

# 构建扩展包
python3 setup.py build

# 以管理员权限安装
sudo python3 setup.py install

安装完成后,在 Python 程序中直接 import wrapper 即可调用。


三、完整调用示例

import ctypes
import wrapper

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

# 1. 连接设备,获取设备数量
result = wrapper.dlpConnect()
print(f"连接设备数量: {result}\n")

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

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

# 4. 读取强度值
intensities_buf = (ctypes.c_int * PIXEL_NUM)()
activeIndex = 0
result = wrapper.dlpGetIntensities(activeIndex, intensities_buf, PIXEL_NUM)
if result >= 0:
    for i in range(5):
        print(f"{wls_buf[i]:.2f}: {intensities_buf[i]}")

代码分步解析

步骤 1 — 导入模块import wrapper 导入已安装的 SDK 扩展包

步骤 2 — 定义数据点数:DLP 近红外模组固定输出 228 个像素

步骤 3 — 连接与打开dlpConnect() 返回已插入的 USB 设备数量;dlpOpenByUsb(0) 打开第一个设备

步骤 4 — 创建 C 类型缓冲区(ctypes.c_double * PIXEL_NUM)() 创建与 C 数组兼容的内存块

步骤 5 — 读取数据:调用 dlpGetWavelengthsdlpGetIntensities 填充缓冲区

步骤 6 — 管理员执行

sudo python3 main.py

注意: 1. 由于涉及 USB HID 设备操作,必须以管理员权限执行 2. 读取波长和强度值时有扫描时间,与配置的平均次数成正比——平均次数越大,扫描耗时越长


四、常见问题

4.1 提示找不到 udev 相关信息

udev 是 Linux 系统中用于管理设备节点的守护进程。由于 SDK 涉及 USB HID 接口调用,系统需安装 libudev-dev

sudo apt-get update
sudo apt-get install libudev-dev

4.2 找不到 libwrapper.so 文件

libwrapper.so 放在 lib/ 子目录下可正常加载,但放在与 wrapper.py 同级目录时可能提示找不到文件。建议保持 lib/libwrapper.so 的目录结构。


本文由谱研互联整理编写