matlab-call-nidaqmx

$npx mdskill add matlab/matlab-agentic-toolkit/matlab-call-nidaqmx

Translates NI-DAQmx C function calls into MATLAB calldaqlib calls for Data Acquisition Toolbox R2026a+

  • Solves the problem of translating NI-DAQmx C function signatures into correct `calldaqlib` MATLAB calls.
  • Depends on understanding and applying projection rules, multi-task semantics, start() clobber, device-level empty-daq workaround, dictionary returns, string getter placeholder, array getter placeholder for DAQmxCfgSampClkTiming, DAQmxExportSignal, etc.
  • Decides what to do based on the user's mention of `calldaqlib`, specific DAQmx* C function names, or need for NI-DAQmx functionality not exposed by the daq object.
  • Delivers translated calls directly to MATLAB, enabling users to interact with NI-DAQmx functionalities such as retriggerable acquisition and export signal.

SKILL.md

.github/skills/matlab-call-nidaqmxView on GitHub ↗
---
name: matlab-call-nidaqmx
description: >
  Translate NI-DAQmx C function signatures into correct calldaqlib MATLAB calls.
  Use when the user mentions calldaqlib, any DAQmx* C function name
  (DAQmxCfgSampClkTiming, DAQmxExportSignal, DAQmxSetStartTrigRetriggerable,
  DAQmxGetSampClkRate, etc.), or needs NI-DAQmx functionality not exposed by
  the daq object. Covers: projection rules (taskHandle implicit, output pointers
  become return values, buffer-size args, enum-as-string), multi-task semantics,
  start() clobber, device-level empty-daq workaround, dictionary returns, string
  getter placeholder, array getter placeholder.
  Trigger contexts: low-level DAQ, escape hatch, retriggerable acquisition,
  shared timebase, export signal, connect terminals, external sample clock,
  trigger configuration, NI driver, C function translation.
license: MathWorks BSD-3-Clause
compatibility: ">=R2026a"
metadata:
  author: MathWorks
  version: "1.0"
---

# matlab-call-nidaqmx

Translate NI-DAQmx C signatures into correct `calldaqlib` MATLAB calls on
Data Acquisition Toolbox R2026a+.

## When to Use

- User explicitly mentions `calldaqlib` or a specific `DAQmx*` C function
- User needs NI-DAQmx capability the daq object doesn't expose (retriggerable,
  export signal, reference triggers, enhanced alias rejection, digital filters)
- User is debugging at the driver level (reading back what the NI driver holds)
- User is translating existing C/LabVIEW code to MATLAB

## When NOT to Use

- User describes a capability achievable with the daq object alone (`dq.Rate`,
  `addtrigger`, `addclock`, `addinput`, `read`, `write`, `start`, `stop`)
- User asks about the Session-based (legacy) DAQ interface
- User needs `DAQmxCreateTask` or `DAQmxLoadTask` (these cannot work through
  calldaqlib — it owns task creation internally)

## Decision Tree

### Step 0 — Read the user's intent

Did the user explicitly mention `calldaqlib` or a specific DAQmx C function?

- **Yes** — Write the calldaqlib call they asked for. Do NOT redirect to the
  daq object. They have a reason (driver debugging, matching C code, capability
  gap, learning). Skip to Step 2.
- **No** — They described a capability without naming calldaqlib. Go to Step 1.

### Step 1 — Pick the right tool

Can the daq object property/method do this? (`dq.Rate`, `addtrigger`,
`addclock`, `addinput`, `dq.NumScansAvailable`, etc.)

- **Yes** — Recommend the daq object. Mention calldaqlib only if the user needs
  driver-level diagnostics or a capability outside daq object coverage.
- **No** — Proceed to Step 2.

### Step 2 — Device-level check

Does the C function lack a `taskHandle` parameter (device-level API)?

- Functions like `DAQmxGetDevIsSimulated`, `DAQmxGetDevAISupportedMeasTypes`:
  Use an **empty daq object** (no channels added). Pass the device name as an
  argument. Returns a plain scalar or array, not a dictionary.
- Functions like `DAQmxCreateTask`, `DAQmxLoadTask`: These **do not work**
  through calldaqlib at all (calldaqlib owns task creation internally).
- Functions like `DAQmxConnectTerms`, `DAQmxDisconnectTerms`: Use an **empty
  daq object** (same as device-level queries). These work on X-series devices.

### Step 3 — Multi-task check

Does the daq object have multiple internal task handles (e.g., AI + DIO)?

- **Getters with a channel arg**: The call runs on both tasks. The irrelevant
  task warns. Read the dictionary key you care about. Acceptable.
- **Setters targeting one measurement type**: No scoping mechanism. Split into
  separate daq objects (loses synchronized start/stop).

### Step 4 — Buffer placeholder check

Is this a getter returning a string or array?

- **String getter** (`char *data, uInt32 bufferSize` in C): Pass `""` then
  `bufferSize`. Example: `calldaqlib(dq, "DAQmxGetSampClkSrc", "", 256)`
- **Array getter** (`int32 data[], uInt32 arraySize` in C): Pass
  `zeros(1,N,'type')` then `N`. Example:
  `calldaqlib(dq, "DAQmxGetDevAISupportedMeasTypes", "Dev1", zeros(1,32,'int32'), 32)`

### Step 5 — Enum check

Does any argument correspond to a C `int32` enum slot?

- **Always use the string form**: `"DAQmx_Val_RisingSlope"` not `int32(10280)`.
  Both work, but strings are self-documenting and prevent silent wrong-enum bugs.
- See `references/enum-constants.md` for the 15 most-used enum names.

## Call Forms

Six distinct patterns cover all `calldaqlib` usage:

### 1. Config (DAQmxCfg*)

```matlab
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*)

```matlab
calldaqlib(dq, "DAQmxSetStartTrigRetriggerable", true);
```

### 3. Getter — scalar (DAQmxGet* returning numeric)

```matlab
result = calldaqlib(dq, "DAQmxGetSampClkRate");
rate = result("Dev1_ai0");
```

Returns a `dictionary` keyed by channel name — even on single-channel objects.

### 4. Getter — string (DAQmxGet* with char output)

```matlab
result = calldaqlib(dq, "DAQmxGetSampClkSrc", "", 256);
source = result("Dev1_ai0");
```

The `""` is required as a placeholder for the `char *data` output slot.
`bufferSize` follows immediately. Use 256 for short names, 1024 for long paths.

### 5. Getter — array (DAQmxGet* with typed array output)

```matlab
dEmpty = daq("ni");
result = calldaqlib(dEmpty, "DAQmxGetDevAISupportedMeasTypes", ...
    "Dev1", zeros(1, 32, "int32"), 32);
measTypes = result(result ~= 0);
```

Pre-allocate a typed buffer (`zeros(1,N,'int32')`) matching the C signature's
array type. Filter unused slots with `result(result ~= 0)`.

### 6. Device-level (no taskHandle in C signature)

```matlab
dEmpty = daq("ni");
isSim = calldaqlib(dEmpty, "DAQmxGetDevIsSimulated", "Dev1");
```
Use an empty daq (no channels added). Pass device name as argument.
Returns a plain scalar (not a dictionary).

Also works for terminal routing on X-series devices:

```matlab
dEmpty = daq("ni");
calldaqlib(dEmpty, "DAQmxConnectTerms", "/Dev1/PFI0", "/Dev1/PFI1", "DAQmx_Val_DoNotInvertPolarity");
calldaqlib(dEmpty, "DAQmxDisconnectTerms", "/Dev1/PFI0", "/Dev1/PFI1");
```

## C-to-calldaqlib Translation

| C argument | calldaqlib equivalent |
|---|---|
| `TaskHandle taskHandle` | **Omit** — daq object owns it |
| `const char source[]` | MATLAB string `"/Dev1/PFI0"` |
| `float64 rate` | MATLAB double |
| `int32 activeEdge` (enum) | Enum name string `"DAQmx_Val_Rising"` |
| `uInt64 sampsPerChan` | `uint64(1000)` |
| `bool32 data` (input) | `true` / `false` |
| `float64 *data` (output scalar) | Becomes return value (dictionary) |
| `int32 *data` (output scalar) | Becomes return value (dictionary) |
| `char *data, uInt32 bufferSize` (output pair) | Pass `""` + bufferSize |
| `int32 data[], uInt32 arraySize` (output array) | Pass `zeros(1,N,'int32')` + N |
| Any getter return | Always a `dictionary` keyed by `DevN_chanName` |

## Hard Rules

1. **taskHandle is implicit.** The daq object owns it. Never pass it.

2. **calldaqlib loops over every internal task.** A daq with AI + DIO has 2
   NI tasks; both get the call. For getters with a channel arg, ignore the
   warning from the irrelevant task and read the dictionary key you want.
   For setters targeting one measurement type, split into separate daq objects.

3. **Output-pointer args still need a placeholder + bufferSize.** String
   getters: pass `""` before bufferSize. Array getters: pass
   `zeros(1,N,'type')` before arraySize.

4. **start() clobbers calldaqlib-set rate and clock source.** `start()`
   reapplies `dq.Rate` to the driver. If you set rate via
   `DAQmxCfgSampClkTiming` then call `start()`, it snaps back to `dq.Rate`.
   Fix: set `dq.Rate` first, use calldaqlib only for parameters the daq
   object does not track. Alternative: use `DAQmxStartTask`/`DAQmxStopTask`
   via calldaqlib to bypass the daq object's commit pass entirely.

5. **Enum constants: use the string form.** `"DAQmx_Val_RisingSlope"` not
   `int32(10280)`. Strings are readable and prevent wrong-enum bugs. The
   error on a bad string is misleading ("Value must be of type int32") —
   it means the string wasn't recognized, not that you should pass an int.

6. **Device-level APIs need an empty daq.** Functions whose C signature has
   no `taskHandle` (like `DAQmxGetDevIsSimulated`,
   `DAQmxGetDevAISupportedMeasTypes`) work only when the daq object has no
   channels. Create `dEmpty = daq("ni")` and pass the device name as an arg.

7. **`DAQmxCreateTask` and `DAQmxLoadTask` cannot work through calldaqlib.**
   These functions create a new task — calldaqlib already owns task creation
   internally. `DAQmxConnectTerms`/`DAQmxDisconnectTerms` DO work via an
   empty daq object on X-series devices (same pattern as device-level queries).

8. **Property values are scalar.** Passing a vector where a scalar is
   expected errors. To set the same property on multiple channels, loop.

9. **Channel/device paths are not validated client-side.** A bad path
   produces no error until `start()`.

10. **Trigger support is per-device.** Not all devices support all trigger
    types. Error -200077 lists the supported enum values — read it.

11. **All task-level getter results return a `dictionary`.** Keyed by
    `DevN_chanName`. Never expect a bare scalar. Use `result("Dev1_ai0")`
    or iterate `keys(result)`.

12. **Buffer-size too small returns NI Error -200228.** The error message
    includes "Required Buffer Size in Bytes: N" — parse it and retry with N.
    Heuristic: 256 for short names, 1024 for long paths/channel lists.

13. **Array getters return a fixed-size buffer.** Filter unused trailing
    zeros with `result(result ~= 0)`.

## Conventions

- Always set `dq.Rate` before using calldaqlib for timing config
- Always use enum name strings, never raw integers
- Always expect a dictionary return from task-level getters
- Always pass `""` before bufferSize for string getters
- Always pre-allocate typed buffer for array getters
- Use empty daq (no channels) for device-level queries
- Warn about multi-task semantics in prose before the code block
- Configure trigger type before enabling retriggerable mode
- Retriggerable mode requires `DAQmx_Val_FiniteSamps` — it does not work with `ContSamps`
- Use specific getter function names (`DAQmxGetSampClkRate`) not generic attribute getters (`DAQmxGetTimingAttribute`)

## References

- `references/hot-signatures.md` — 20 most-used calldaqlib signatures by category
- `references/enum-constants.md` — 15 DAQmx_Val_* enum name strings
- `references/common-mistakes.md` — Mistakes from discovery trials and customer usage

----

Copyright 2026 The MathWorks, Inc.

----

More from matlab/matlab-agentic-toolkit

SkillDescription
matlab-access-datafeed>
matlab-add-awgnRead BEFORE writing any code that adds Additive White Gaussian Noise (AWGN) to signals and converts between SNR, Eb/No, Es/No, and per-subcarrier SNR for communications simulations, using awgn(), convertSNR(), berawgn(). The default MATLAB patterns for AWGN (e.g., 'measured' option, manual SNR formulas) produce subtly incorrect results. This skill specifies the correct calling conventions, required function usage, and critical anti-patterns that must be avoided.
matlab-analyze-ams-waveformAnalyze AMS waveform data using Mixed-Signal Blockset utilities: phase noise measurement, clock jitter, anti-aliased resampling, timing measurements, lock time, INL/DNL, ADC/DAC calibration, HSpice import. Use when analyzing time-domain voltage from PLL/VCO/clock simulations, measuring phase noise from variable-step solver output, computing jitter, or resampling non-uniform data.
matlab-analyze-dataAnalyze data using MATLAB. Use when the task involves tables, timetables, time-series data, numeric arrays, sensor matrices, or gridded data — including but not limited to exploring, filtering, sorting, cleaning, transforming, aggregating, smoothing, padding, trimming, and answering questions about data. MATLAB provides extensive, easy-to-use built-in functions for these workflows with no additional products required.
matlab-analyze-dependenciesAnalyze the effective toolbox file set to produce a Dependency Manifest — classify all transitive dependencies as included, product, add-on, or external-unresolved, then present resolution options with tradeoffs. Use after matlab-define-toolbox-api when the spec is approved.
matlab-analyze-emS-parameters, insertion loss, fields, currents, mesh control, and solver selection for RF PCB performance validation. TRIGGER: user asks to compute S-parameters, analyze insertion/return loss, extract fields or currents, compare MoM vs FEM, or control mesh for any RF PCB component. Invoke BEFORE writing sparameters() or solver code — API is non-obvious. SKIP: designing or creating components (use the specific matlab-design-pcb-* skill), material/stackup setup only (use matlab-manage-pcb-material), optimization sweeps (use matlab-optimize-pcb-design), PDN/IR-drop analysis (use matlab-analyze-pcb-pdn).
matlab-analyze-installed-antennaAnalyze antennas installed on electrically large conducting platforms using MATLAB Antenna Toolbox. Loads platform geometry from STL/STEP/IGES, installs antenna elements, selects electromagnetic solvers (MoM-PO, FMM, MoM), and computes patterns, impedance, coupling, and efficiency. Use when the user wants to model an antenna on a vehicle, aircraft, ship, satellite, or other large structure.
matlab-analyze-pcb-pdnPDN DC voltage/current analysis, IR drop, design rule checking, and multi-net batch analysis on imported PCB layouts. TRIGGER: user asks about power integrity, PDN analysis, IR drop, voltage distribution, current density, power nets, or design rule checking on a PCB. Invoke BEFORE writing code — the PDN API chain is specialized and non-obvious. SKIP: importing a PCB file (use matlab-read-pcb-layout), EM field/S-parameter extraction (use matlab-analyze-em), material/stackup setup only (use matlab-manage-pcb-material), transmission line design (use matlab-design-pcb-txline).
matlab-analyze-rcsCalculate and visualize monostatic and bistatic radar cross section (RCS) using MATLAB Antenna Toolbox. Computes RCS of platforms, antennas, and arrays with PO, MoM, and FMM solvers, supporting HH/VV/HV/VH polarization, GPU acceleration, and near-field observation. Use when the user wants to compute, plot, or analyze radar cross section.
matlab-analyze-rf-propagationAnalyze RF propagation and plan wireless sites using MATLAB Antenna Toolbox. Creates transmitter/receiver sites, computes signal strength, coverage maps, SINR, line-of-sight, and ray tracing in geographic or indoor environments. Supports multiple propagation models (free-space, close-in, Longley-Rice, ray tracing, rain/gas/fog), custom terrain, building data, and directional antennas. Use when the user wants to compute coverage, signal strength, path loss, SINR, ray tracing, or plan a wireless network.