关于 matlab-call-nidaqmx
用于在 Data Acquisition Toolbox R2026a+ 中将 NI-DAQmx C 函数签名转换为 `calldaqlib` 调用的 MATLAB 技能,说明调用形式、参数映射及任务句柄和字典返回值等限制。
主要功能
- 01将 C 参数映射为 MATLAB 调用
- 02涵盖六种 `calldaqlib` 调用形式
- 03说明 Getter 缓冲区及返回值
- 04记录设备级和多任务限制
适用场景
- 01将 NI-DAQmx C 代码转换为 MATLAB
- 02调用 daq 对象未涵盖的 DAQmx 函数
- 03检查或配置 NI 驱动级设置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-call-nidaqmx安装后在 Claude Code 中输入/matlab-call-nidaqmx确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/common-mistakes.mdenum-constants.mdhot-signatures.md详细介绍
matlab-call-nidaqmx
在 Data Acquisition Toolbox R2026a+ 中,将 NI-DAQmx C 签名转换为正确的 calldaqlib MATLAB 调用。
使用场景
- 用户明确提到
calldaqlib或特定的DAQmx*C 函数 - 用户需要 daq 对象未提供的 NI-DAQmx 功能(可重触发、导出信号、参考触发、增强型混叠抑制、数字滤波器)
- 用户正在驱动程序层面进行调试(读取 NI 驱动程序保存的内容)
- 用户正在将现有的 C/LabVIEW 代码转换为 MATLAB
不适用场景
- 用户描述的功能仅通过 daq 对象即可实现(
dq.Rate、addtrigger、addclock、addinput、read、write、start、stop) - 用户询问基于 Session 的(旧版)DAQ 接口
- 用户需要
DAQmxCreateTask或DAQmxLoadTask(这些函数无法通过 calldaqlib 工作——calldaqlib 在内部负责创建任务)
决策树
步骤 0 — 理解用户意图
用户是否明确提到了 calldaqlib 或特定的 DAQmx C 函数?
- 是 — 编写用户要求的 calldaqlib 调用。不要引导用户改用 daq 对象。他们有自己的原因(驱动程序调试、匹配 C 代码、功能缺口、学习)。跳至步骤 2。
- 否 — 用户描述了某项功能,但没有提到 calldaqlib。转到步骤 1。
步骤 1 — 选择合适的工具
daq 对象的属性或方法能否实现该功能?(dq.Rate、addtrigger、addclock、addinput、dq.NumScansAvailable 等)
- 能 — 建议使用 daq 对象。只有在用户需要驱动程序级诊断或 daq 对象未涵盖的功能时,才提及 calldaqlib。
- 不能 — 继续执行步骤 2。
步骤 2 — 检查设备级调用
该 C 函数是否没有 taskHandle 参数(设备级 API)?
- 对于
DAQmxGetDevIsSimulated、DAQmxGetDevAISupportedMeasTypes等函数:使用空 daq 对象(不添加通道)。将设备名称作为参数传入。返回普通标量或数组,而非字典。 - 对于
DAQmxCreateTask、DAQmxLoadTask等函数:这些函数完全无法通过 calldaqlib 工作(calldaqlib 在内部负责创建任务)。 - 对于
DAQmxConnectTerms、DAQmxDisconnectTerms等函数:使用空 daq 对象(与设备级查询相同)。这些函数可用于 X-series 设备。
步骤 3 — 检查多任务情况
daq 对象是否有多个内部任务句柄(例如,AI + DIO)?
- 带通道参数的 Getter:调用会在两个任务上运行。无关的任务会发出警告。读取所需的字典键即可。此行为可以接受。
- 针对一种测量类型的 Setter:没有限定范围的机制。拆分为独立的 daq 对象(会失去同步启动/停止能力)。
步骤 4 — 检查缓冲区占位符
这是返回字符串或数组的 Getter 吗?
- 字符串 Getter(C 中的
char *data, uInt32 bufferSize):传入"",然后传入bufferSize。示例:calldaqlib(dq, "DAQmxGetSampClkSrc", "", 256) - 数组 Getter(C 中的
int32 data[], uInt32 arraySize):传入zeros(1,N,'type'),然后传入N。示例:calldaqlib(dq, "DAQmxGetDevAISupportedMeasTypes", "Dev1", zeros(1,32,'int32'), 32)
步骤 5 — 检查枚举
是否有参数对应 C int32 枚举槽位?
- 始终使用字符串形式:
"DAQmx_Val_RisingSlope",不要使用int32(10280)。两种形式都可用,但字符串更易读,可避免因枚举值错误而导致的静默错误。 - 最常用的 15 个枚举名称请参阅
references/enum-constants.md。
调用形式
以下六种模式涵盖所有 calldaqlib 用法:
1. 配置(DAQmxCfg*)
dq = daq("ni");
addinput(dq, "Dev1", "ai0", "Voltage");
calldaqlib(dq, "DAQmxCfgSampClkTiming", "/Dev1/PFI0", 5000, ...
"DAQmx_Val_Rising", "DAQmx_Val_FiniteSamps", uint64(1000));
2. Setter(DAQmxSet*)
calldaqlib(dq, "DAQmxSetStartTrigRetriggerable", true);
3. Getter — 标量(DAQmxGet* 返回数值)
result = calldaqlib(dq, "DAQmxGetSampClkRate");
rate = result("Dev1_ai0");
返回以通道名称为键的 dictionary——即使对象只有一个通道也是如此。
4. Getter — 字符串(DAQmxGet* 带字符输出)
result = calldaqlib(dq, "DAQmxGetSampClkSrc", "", 256);
source = result("Dev1_ai0");
必须使用 "" 作为 char *data 输出槽位的占位符。紧接着传入 bufferSize。短名称使用 256,较长路径使用 1024。
5. 获取器 — 数组(带类型化数组输出的 DAQmxGet*)
dEmpty = daq("ni");
result = calldaqlib(dEmpty, "DAQmxGetDevAISupportedMeasTypes", ...
"Dev1", zeros(1, 32, "int32"), 32);
measTypes = result(result ~= 0);
预先分配一个与 C 签名中的数组类型匹配的类型化缓冲区(zeros(1,N,'int32'))。使用 result(result ~= 0) 过滤未使用的槽位。
6. 设备级(C 签名中没有 taskHandle)
dEmpty = daq("ni");
isSim = calldaqlib(dEmpty, "DAQmxGetDevIsSimulated", "Dev1");
使用空 daq(不添加通道)。将设备名称作为参数传入。 返回普通标量(不是字典)。
也适用于 X 系列设备上的端子路由:
dEmpty = daq("ni");
calldaqlib(dEmpty, "DAQmxConnectTerms", "/Dev1/PFI0", "/Dev1/PFI1", "DAQmx_Val_DoNotInvertPolarity");
calldaqlib(dEmpty, "DAQmxDisconnectTerms", "/Dev1/PFI0", "/Dev1/PFI1");
C 到 calldaqlib 的转换
| C 参数 | calldaqlib 对应项 |
|---|---|
TaskHandle taskHandle | 省略 — daq 对象持有它 |
const char source[] | MATLAB 字符串 "/Dev1/PFI0" |
float64 rate | MATLAB double |
int32 activeEdge(枚举) | 枚举名称字符串 "DAQmx_Val_Rising" |
uInt64 sampsPerChan | uint64(1000) |
bool32 data(输入) | true / false |
float64 *data(输出标量) | 成为返回值(字典) |
int32 *data(输出标量) | 成为返回值(字典) |
char *data, uInt32 bufferSize(输出对) | 传入 "" + bufferSize |
int32 data[], uInt32 arraySize(输出数组) | 传入 zeros(1,N,'int32') + N |
| 任何获取器返回值 | 始终是以 DevN_chanName 为键的 dictionary |
硬性规则
-
taskHandle 是隐式的。 daq 对象持有它。切勿传入。
-
calldaqlib 会遍历每个内部任务。 带 AI + DIO 的 daq 有 2 个 NI 任务;两个任务都会调用该函数。对于带通道参数的获取器,忽略 无关任务发出的警告,并读取所需的字典键。对于针对某种测量类型的 设置器,请拆分为单独的 daq 对象。
-
输出指针参数仍需要占位符 + bufferSize。 字符串获取器:在 bufferSize 前传入
""。数组获取器:在 arraySize 前传入zeros(1,N,'type')。 -
start() 会覆盖通过 calldaqlib 设置的速率和时钟源。
start()会将dq.Rate重新应用到驱动程序。如果你通过DAQmxCfgSampClkTiming设置速率后调用start(),速率会恢复为dq.Rate。解决方法:先设置dq.Rate,仅使用 calldaqlib 设置 daq 对象未跟踪的参数。或者,通过 calldaqlib 使用DAQmxStartTask/DAQmxStopTask,完全绕过 daq 对象的提交过程。 -
枚举常量:使用字符串形式。 使用
"DAQmx_Val_RisingSlope",而非int32(10280)。字符串可读性更好,也能避免枚举错误。错误字符串 的报错信息具有误导性(“Value must be of type int32”)——这表示 系统无法识别该字符串,并不意味着你应该传入整数。 -
设备级 API 需要空 daq。 C 签名中没有
taskHandle的函数 (例如DAQmxGetDevIsSimulated、DAQmxGetDevAISupportedMeasTypes)仅在 daq 对象没有通道时有效。 创建dEmpty = daq("ni"),并将设备名称作为参数传入。 -
DAQmxCreateTask和DAQmxLoadTask无法通过 calldaqlib 使用。 这些函数会创建新任务,而 calldaqlib 已在内部负责创建任务。DAQmxConnectTerms/DAQmxDisconnectTerms可以通过 X 系列设备上的 空 daq 对象使用(与设备级查询的模式相同)。 -
属性值必须是标量。 需要标量时传入向量会报错。要在多个通道上 设置相同属性,请使用循环。
-
客户端不会验证通道/设备路径。 路径错误要等到
start()才会 触发错误。 -
触发器支持因设备而异。 并非所有设备都支持所有触发器类型。 错误 -200077 会列出支持的枚举值,请查阅。
-
所有任务级获取器的结果都会返回
dictionary。 键为DevN_chanName。切勿期望得到裸标量。使用result("Dev1_ai0")或遍历keys(result)。 -
缓冲区大小过小会返回 NI Error -200228。 错误消息中会包含 “Required Buffer Size in Bytes: N”——解析出 N 并使用该值重试。 经验值:短名称用 256,长路径/通道列表用 1024。
-
数组获取器会返回固定大小的缓冲区。 使用
result(result ~= 0)过滤末尾未使用的零值。
约定
- 使用
calldaqlib配置时序前,始终先设置dq.Rate - 始终使用枚举名称字符串,切勿使用原始整数
- 始终假定任务级 getter 返回字典
- 对字符串 getter,始终在 bufferSize 前传入
"" - 对数组 getter,始终预先分配类型化缓冲区
- 设备级查询使用空 daq(不含通道)
- 在代码块前的正文中说明多任务语义
- 启用可重触发模式前,先配置触发类型
- 可重触发模式要求使用
DAQmx_Val_FiniteSamps——与ContSamps不兼容 - 使用具体的 getter 函数名(
DAQmxGetSampClkRate),而非通用属性 getter(DAQmxGetTimingAttribute)
参考资料
references/hot-signatures.md— 按类别列出的 20 个最常用calldaqlib函数签名references/enum-constants.md— 15 个DAQmx_Val_*枚举名称字符串references/common-mistakes.md— 探索试用和客户使用中发现的常见错误
版权所有 2026 The MathWorks, Inc.