mcpField
M
matlab-call-nidaqmx

matlab-call-nidaqmx

github.com/matlab开发1.2k57 次安装1 天前更新
代码仓库

关于 matlab-call-nidaqmx

用于在 Data Acquisition Toolbox R2026a+ 中将 NI-DAQmx C 函数签名转换为 `calldaqlib` 调用的 MATLAB 技能,说明调用形式、参数映射及任务句柄和字典返回值等限制。

主要功能

  1. 01将 C 参数映射为 MATLAB 调用
  2. 02涵盖六种 `calldaqlib` 调用形式
  3. 03说明 Getter 缓冲区及返回值
  4. 04记录设备级和多任务限制

适用场景

  1. 01将 NI-DAQmx C 代码转换为 MATLAB
  2. 02调用 daq 对象未涵盖的 DAQmx 函数
  3. 03检查或配置 NI 驱动级设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-call-nidaqmx

安装后在 Claude Code 中输入/matlab-call-nidaqmx确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
references/
common-mistakes.md
enum-constants.md
hot-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 rateMATLAB double
int32 activeEdge(枚举)枚举名称字符串 "DAQmx_Val_Rising"
uInt64 sampsPerChanuint64(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

硬性规则

  1. taskHandle 是隐式的。 daq 对象持有它。切勿传入。

  2. calldaqlib 会遍历每个内部任务。 带 AI + DIO 的 daq 有 2 个 NI 任务;两个任务都会调用该函数。对于带通道参数的获取器,忽略 无关任务发出的警告,并读取所需的字典键。对于针对某种测量类型的 设置器,请拆分为单独的 daq 对象。

  3. 输出指针参数仍需要占位符 + bufferSize。 字符串获取器:在 bufferSize 前传入 ""。数组获取器:在 arraySize 前传入 zeros(1,N,'type')。

  4. start() 会覆盖通过 calldaqlib 设置的速率和时钟源。 start() 会将 dq.Rate 重新应用到驱动程序。如果你通过 DAQmxCfgSampClkTiming 设置速率后调用 start(),速率会恢复为 dq.Rate。解决方法:先设置 dq.Rate,仅使用 calldaqlib 设置 daq 对象未跟踪的参数。或者,通过 calldaqlib 使用 DAQmxStartTask/DAQmxStopTask,完全绕过 daq 对象的提交过程。

  5. 枚举常量:使用字符串形式。 使用 "DAQmx_Val_RisingSlope",而非 int32(10280)。字符串可读性更好,也能避免枚举错误。错误字符串 的报错信息具有误导性(“Value must be of type int32”)——这表示 系统无法识别该字符串,并不意味着你应该传入整数。

  6. 设备级 API 需要空 daq。 C 签名中没有 taskHandle 的函数 (例如 DAQmxGetDevIsSimulated、 DAQmxGetDevAISupportedMeasTypes)仅在 daq 对象没有通道时有效。 创建 dEmpty = daq("ni"),并将设备名称作为参数传入。

  7. DAQmxCreateTask 和 DAQmxLoadTask 无法通过 calldaqlib 使用。 这些函数会创建新任务,而 calldaqlib 已在内部负责创建任务。 DAQmxConnectTerms/DAQmxDisconnectTerms 可以通过 X 系列设备上的 空 daq 对象使用(与设备级查询的模式相同)。

  8. 属性值必须是标量。 需要标量时传入向量会报错。要在多个通道上 设置相同属性,请使用循环。

  9. 客户端不会验证通道/设备路径。 路径错误要等到 start() 才会 触发错误。

  10. 触发器支持因设备而异。 并非所有设备都支持所有触发器类型。 错误 -200077 会列出支持的枚举值,请查阅。

  11. 所有任务级获取器的结果都会返回 dictionary。 键为 DevN_chanName。切勿期望得到裸标量。使用 result("Dev1_ai0") 或遍历 keys(result)。

  12. 缓冲区大小过小会返回 NI Error -200228。 错误消息中会包含 “Required Buffer Size in Bytes: N”——解析出 N 并使用该值重试。 经验值:短名称用 256,长路径/通道列表用 1024。

  13. 数组获取器会返回固定大小的缓冲区。 使用 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.


评论

支持 Markdown