本文へ移動
cccskills
無料GitHub で公開

matlab-transmit-capture-usrp

Transmit and capture RF waveforms using Wireless Testbench with NI USRP radios (X410, X310, N310, N320, N321, N300, X300, E320). Use when generating test signals, transmitting over the air, capturing IQ data, performing loopback tests, configuring multi-antenna setups, or troubleshooting dropped samples and gain settings. Covers basebandTransceiver, basebandTransmitter, basebandReceiver, continuous and once transmit modes, foreground and background capture, and UseRadioBuffer options. Also use when the user mentions transmit waveform, capture signal, IQ data, loopback, RF gain, sample rate, or antenna configuration.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md21.3 KB
  • manifest.yaml482 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Transmit and Capture Waveforms with Wireless Testbench

Generate, transmit, and capture RF waveforms using NI USRP radios in MATLAB.

When to Use

  • Transmitting a waveform (test tone, standard-compliant signal, custom IQ) over the air
  • Capturing IQ data from a frequency band
  • Loopback testing (transmit and capture on the same radio)
  • Multi-antenna transmit or capture
  • Continuous transmission for prolonged testing
  • Background capture for long-duration acquisition

When NOT to Use

  • Setting up or connecting a USRP radio for the first time — use the matlab-set-up-usrp-radio skill
  • FPGA targeting workflows — see Target NI USRP Radios
  • Triggered (wake-on-signal) capture with preamble/energy detection — use the matlab-detect-capture-usrp skill
  • Multi-device synchronization — see Radio Management

Prerequisites

A saved radio configuration must exist before using any transmit/capture object. List available configurations and let the user choose which one to use:

configs = radioConfigurations;
disp(configs)

If multiple configurations exist, ask the user which one they want to work with. If no configuration exists, guide the user to set one up first (see the matlab-set-up-usrp-radio skill).

Before generating code, confirm these parameters with the user if not already specified:

  • Center frequency — Accept any numeric value within the radio's supported range. Do not present a constrained list of bands; let the user type a frequency.
  • Sample rate — Ask what sample rate they need. Suggest common values (30.72 MHz, 61.44 MHz, 122.88 MHz, 245.76 MHz) but accept any valid rate.

Choosing the Right Object

Default to basebandTransceiver. It supports all workflows — transmit only, capture only, or both simultaneously. Use it unless you have a specific reason not to.

ObjectWhen to Use
basebandTransceiverDefault choice. Transmit, capture, or both. Works for loopback, signal generation, spectrum monitoring, and full-duplex
basebandTransmitterOnly when you need a dedicated transmit-only object (e.g., a separate script controlling TX independently)
basebandReceiverOnly when you need a dedicated receive-only object (e.g., a separate script controlling RX independently)

Why default to basebandTransceiver: A single radio configuration can only be used by one object at a time. Since basebandTransceiver handles transmit, capture, or both, it covers the vast majority of workflows without needing to switch objects. The standalone objects (basebandTransmitter, basebandReceiver) are useful when separate scripts or applications each need independent control of one direction.

Property naming differs between object types:

basebandTransceiverbasebandTransmitter / basebandReceiver
GainTransmitRadioGain, CaptureRadioGainRadioGain
FrequencyTransmitCenterFrequency, CaptureCenterFrequencyCenterFrequency
AntennasTransmitAntennas, CaptureAntennasAntennas

The transceiver uses Transmit/Capture prefixes to distinguish directions. The standalone objects do not need prefixes since they only handle one direction.

Workflow

Step 1: Create the Radio Object

radio = radioConfigurations("MyN310");
bbtrx = basebandTransceiver(radio);

Preload option: Pass Preload=true to load the FPGA application at construction time rather than on first use. This avoids a multi-second delay on the first transmit or capture call.

bbtrx = basebandTransceiver(radio, Preload=true);

Standalone objects (only when needed for independent single-direction control):

bbtx = basebandTransmitter(radio);  % TX only
bbrx = basebandReceiver(radio);     % RX only

Step 2: Configure Properties

Configure the object before transmitting or capturing. Setting properties after object creation is valid, but some changes cause a reload delay.

bbtrx.SampleRate = 30.72e6;
bbtrx.TransmitCenterFrequency = 3.5e9;
bbtrx.CaptureCenterFrequency = 3.5e9;
bbtrx.TransmitRadioGain = 20;
bbtrx.CaptureRadioGain = 40;

Only set the properties for the direction you need. For transmit-only workflows, skip the Capture* properties (and vice versa).

If using standalone objects (basebandTransmitter / basebandReceiver), properties are unprefixed:

bbtx.SampleRate = 30.72e6;
bbtx.CenterFrequency = 3.5e9;    % not TransmitCenterFrequency
bbtx.RadioGain = 20;              % not TransmitRadioGain

Property guidance:

PropertyGuidance
SampleRateMust match waveform bandwidth. Common values: 30.72 MHz (LTE/NR), 61.44 MHz, 122.88 MHz, 245.76 MHz
TransmitRadioGainStart low (10–20 dB) to avoid clipping. Increase until signal strength is adequate
CaptureRadioGainStart moderate (30–40 dB). Too high clips the ADC; too low buries the signal in noise
TransmitCenterFrequency / CaptureCenterFrequencyMust be within the radio's supported range (device-dependent, typically 1 MHz – 6/8 GHz)
DroppedSamplesActionSet to "warning" during development to continue despite drops; use "error" in production

Step 3: Prepare the Transmit Waveform

The waveform must be a complex column vector (single antenna) or complex matrix (multi-antenna, one column per antenna). Values must be normalized to the range [-1, 1].

Test tone:

numSamples = 30720;
t = (0:numSamples-1)' / bbtrx.SampleRate;
txWaveform = 0.8 * exp(1j*2*pi*1e6*t);

Random OFDM-like signal:

numSamples = 30720;
txWaveform = complex(randn(numSamples,1), randn(numSamples,1));
txWaveform = 0.7 * txWaveform / max(abs(txWaveform));

Load a pre-generated waveform from file:

waveStruct = load("myWaveform.mat");
txWaveform = waveStruct.waveform;
txWaveform = 0.8 * txWaveform / max(abs(txWaveform));

Use this pattern with waveforms generated by 5G Toolbox, LTE Toolbox, WLAN Toolbox, or any custom signal generation workflow.

Waveform requirements:

RequirementDetails
Data typeComplex double, single, or int16 (controlled by TransmitDataType)
AmplitudePeak magnitude ≤ 1.0 for double/single (values > 1 clip at the DAC)
DimensionsColumn vector (single antenna) or N×M matrix (M = number of TX antennas)
Row countMust be an even number of rows
Minimum lengthWaveforms < 513 samples reserve up to 1024 samples for underflow protection

Pass TransmitDataType to the constructor when using Preload=true:

The FPGA application is configured for a specific transmit data class at construction time. Without preload, the class is inferred from the waveform on the first transmit call. With preload, the transceiver has no waveform to infer from, so pass TransmitDataType explicitly — otherwise the FPGA reloads on the first transmit call and defeats the point of preloading.

bbtrx = basebandTransceiver(radio, Preload=true, TransmitDataType="double");
% ... configure frequency/gain/sample rate ...
transmit(bbtrx, txWaveform, "continuous");   % waveform class must match TransmitDataType

Step 4: Transmit

Once (single-shot) — transmit the waveform exactly once:

transmit(bbtrx, txWaveform, "once");

The radio transmits the waveform one time and then stops automatically. Use for pulsed or one-shot testing. Add a few redundant samples to the end of the waveform for reliability in this mode.

Continuous — transmit repeatedly until stopped:

transmit(bbtrx, txWaveform, "continuous");

The waveform loops continuously on the radio until stopTransmission is called. Use for:

  • Sustained interference or signal generation
  • Loopback testing where capture timing is decoupled from transmit
  • Over-the-air tests where a receiver needs a persistent signal

Stop continuous transmission:

stopTransmission(bbtrx);

Step 5: Capture

Foreground capture (blocks MATLAB until complete):

[data, timestamp, droppedSamples] = capture(bbtrx, milliseconds(10));

The length argument accepts a duration value (e.g., seconds(1), milliseconds(10)) or a sample count as a positive integer.

Output arguments:

OutputTypeDescription
datacomplex vector/matrixIQ samples — rows = samples, columns = antennas. Data type matches CaptureDataType property. First samples may contain transients
timestampdatetimeTimestamp created immediately before hardware capture request
droppedSampleslogicaltrue if samples were dropped (network/host issue), false if clean

CaptureDataType defaults to int16 — cast before FFT, filtering, or arithmetic:

The captured data is a complex vector/matrix whose class matches CaptureDataType. The default is "int16" (fixed-point) to minimize memory. Most MATLAB signal-processing functions — including fft, abs, filter, bandpass, pwelch, and element-wise math — do not accept complex int16 and will error at runtime. Handle this in one of two ways:

% Option A — set the property before capture (all downstream code sees double)
bbtrx.CaptureDataType = "double";
[data, ~, dropped] = capture(bbtrx, milliseconds(10));
X = fft(data);   % works

% Option B — cast after capture (keep the memory savings during transfer)
[data, ~, dropped] = capture(bbtrx, milliseconds(10));
data = double(data);
X = fft(data);   % works

Use Option A by default. Only prefer Option B when memory during capture is tight and you want the compact int16 payload until processing begins.

Background capture (non-blocking):

Use background capture when:

  • Capture duration is long (> a few seconds) and MATLAB must remain responsive
  • You want to do post-processing, display updates, or other work during acquisition
  • You are combining capture with continuous transmit and need to monitor both

Use foreground capture (the default) when:

  • Capture is short and you need the data immediately for the next step
  • The script is linear (no concurrent work needed)

Choosing the right pattern:

ScenarioPattern
Short capture, need data now[data,~,dropped] = capture(bbtrx, milliseconds(100));
Long capture, data fits in RAMcapture(bbtrx, seconds(30), Background=true); then captureOutputs
Long capture, too large for RAMcapture(bbtrx, seconds(60), Background=true, SaveLocation="data.mat", UseRadioBuffer=false);
Need notification when doneAdd CompletionFcn=@(data,ts,dropped) myCallback(data)

Background capture with polling:

capture(bbtrx, seconds(30), Background=true);

% Poll until complete
while isCapturing(bbtrx)
    pause(1);
end

% Retrieve results
[data, timestamp, droppedSamples] = captureOutputs(bbtrx);

Background capture with callback (no polling needed):

capture(bbtrx, seconds(30), Background=true, ...
    CompletionFcn=@(data, ts, dropped) handleCapture(data, dropped));

Long capture to file (background + SaveLocation + direct-to-host):

For captures that exceed onboard buffer or RAM, combine all three options:

capture(bbtrx, seconds(60), ...
    Background=true, ...
    SaveLocation="captured_data.mat", ...
    UseRadioBuffer=false);

while isCapturing(bbtrx)
    pause(5);
end
filePath = captureOutputs(bbtrx);
fprintf("Saved to: %s\n", filePath);

When SaveLocation is specified, captureOutputs returns the file path instead of loading data into the workspace.

Stop a background capture early:

stopCapture(bbtrx);
[data, timestamp, droppedSamples] = captureOutputs(bbtrx);

UseRadioBuffer — choosing between radio buffer and direct-to-host:

The UseRadioBuffer name-value argument controls where captured samples are stored during acquisition. The right choice depends on capture length, sample rate, and host network capability.

% Radio buffer (default) — data is stored in onboard radio memory, then
% transferred to the host after capture completes. Most reliable option.
[data, ~, dropped] = capture(bbtrx, milliseconds(100));

% Direct-to-host — data streams continuously from radio to host over the
% network during the capture. Required when capture exceeds onboard memory.
[data, ~, dropped] = capture(bbtrx, seconds(30), UseRadioBuffer=false);

Use UseRadioBuffer=true (default) when:

  • Capture length fits within the radio's onboard memory
  • You want the most reliable capture (no dependency on sustained host throughput)
  • Sample rate is high and you cannot tolerate any drops

Use UseRadioBuffer=false when:

  • Capture length exceeds the radio's onboard buffer capacity (see table below)
  • Using USRP X310 with TwinRX daughterboard capturing more than 2 antenna channels
  • You need arbitrarily long captures (minutes or hours of data)

Onboard buffer capacities (determines when direct-to-host is required):

DeviceMax SamplesApprox Duration at 30.72 MHz
USRP E320 / N-series2^29 (~537M)~17.5 s
USRP X300 / X3102^28 (~268M)~8.7 s
USRP X4102^30 (~1.07B)~34.8 s

Direct-to-host performance considerations:

Direct-to-host capture requires sustained network throughput for the entire capture duration. The maximum achievable sample rate depends on host and network configuration and varies between runs depending on system load. If drops occur, either reduce the sample rate, reduce the number of antennas, or run radioSetupWizard to optimize host network settings for your platform.

Evaluating host performance: To find the maximum sustainable direct-to-host rate, iterate captures at decreasing sample rates with DroppedSamplesAction="none" until one succeeds:

bbrx.DroppedSamplesAction = "none";
sampleRates = 245.76e6 : -10e6 : 10e6;
for idx = 1:numel(sampleRates)
    bbrx.SampleRate = sampleRates(idx);
    [~, ~, dropped] = capture(bbrx, 2*2^28, UseRadioBuffer=false);
    if ~dropped
        fprintf("Max sustained rate: %.1f MHz\n", sampleRates(idx)/1e6);
        break
    end
end

Stop a background capture early:

stopCapture(bbtrx);
[data, timestamp, droppedSamples] = captureOutputs(bbtrx);

Step 6: Loopback Test (Transmit + Capture on Same Radio)

A loopback test verifies the full TX/RX chain using basebandTransceiver. Set TransmitCenterFrequency and CaptureCenterFrequency to the same value so the signal couples internally.

Method A: Continuous transmit then capture

Start continuous transmission, allow a brief pause for the radio front-end to stabilize, then capture.

radio = radioConfigurations("MyN310");
bbtrx = basebandTransceiver(radio, Preload=true);
bbtrx.SampleRate = 61.44e6;
bbtrx.TransmitCenterFrequency = 2.4e9;
bbtrx.CaptureCenterFrequency = 2.4e9;
bbtrx.TransmitRadioGain = 10;
bbtrx.CaptureRadioGain = 30;

% Generate test tone
numSamples = 61440;
t = (0:numSamples-1)' / bbtrx.SampleRate;
txWaveform = 0.8 * exp(1j*2*pi*1e6*t);

% Transmit continuously, pause for stabilization, then capture
transmit(bbtrx, txWaveform, "continuous");
pause(1);
[rxData, ~, droppedSamples] = capture(bbtrx, milliseconds(10));
stopTransmission(bbtrx);

% Verify
if ~droppedSamples
    fprintf("Loopback OK: captured %d samples, no drops.\n", size(rxData,1));
else
    warning("Samples were dropped during loopback.");
end

% Visualize
sa = spectrumAnalyzer(SampleRate=bbtrx.SampleRate);
sa(rxData);

Step 7: Multi-Antenna Configuration

For MIMO or multi-channel operation, set antenna properties to arrays and provide a matrix waveform.

radio = radioConfigurations("MyX410");
bbtrx = basebandTransceiver(radio);
bbtrx.SampleRate = 61.44e6;

% Configure 2 TX and 2 RX antennas
bbtrx.TransmitAntennas = ["DB0:RF0:TX/RX0", "DB0:RF1:TX/RX0"];
bbtrx.CaptureAntennas = ["DB0:RF0:RX1", "DB0:RF1:RX1"];
bbtrx.TransmitCenterFrequency = [3.5e9, 3.5e9];
bbtrx.CaptureCenterFrequency = [3.5e9, 3.5e9];
bbtrx.TransmitRadioGain = [15, 15];
bbtrx.CaptureRadioGain = [35, 35];

% Waveform: N×2 matrix (one column per TX antenna)
numSamples = 61440;
t = (0:numSamples-1)' / bbtrx.SampleRate;
tx1 = 0.7 * exp(1j*2*pi*1e6*t);
tx2 = 0.7 * exp(1j*2*pi*2e6*t);
txWaveform = [tx1, tx2];

transmit(bbtrx, txWaveform, "continuous");
[rxData, ~, dropped] = capture(bbtrx, milliseconds(10));
stopTransmission(bbtrx);

% rxData is N×2: one column per RX antenna
fprintf("Captured %d samples on %d antennas.\n", size(rxData,1), size(rxData,2));

Antenna naming varies by device — TX and RX ports have different names:

DeviceTransmitAntennasCaptureAntennas
X410"DB0:RF0:TX/RX0", "DB0:RF1:TX/RX0", "DB1:RF0:TX/RX0", "DB1:RF1:TX/RX0""DB0:RF0:RX1", "DB0:RF1:RX1", "DB1:RF0:RX1", "DB1:RF1:RX1"
X310 (UBX)"RFA:TX/RX", "RFB:TX/RX""RFA:RX2", "RFB:RX2"
N310"RF0:TX/RX", "RF1:TX/RX", "RF2:TX/RX", "RF3:TX/RX""RF0:RX2", "RF1:RX2", "RF2:RX2", "RF3:RX2"
N320/N321"RF0:TX/RX", "RF1:TX/RX""RF0:RX2", "RF1:RX2"
E320"RFA:TX/RX""RFA:RX2", "RFB:RX2"

Assign an invalid value to see the full list of accepted antenna names for your device.

Troubleshooting

SymptomCauseFix
Dropped samplesHost/network cannot sustain throughputRun radioSetupWizard to optimize host settings, or reduce sample rate / antenna count
Captured signal clippedCaptureRadioGain too highReduce gain until peak magnitude < 0.9
Captured signal in noise floorCaptureRadioGain too lowIncrease gain incrementally
TX signal distortedWaveform amplitude > 1.0Normalize: waveform = waveform / max(abs(waveform))
Multi-second delay on first callFPGA application loadingUse Preload=true at construction
"Resource not available" errorAnother object holds the radioClear existing objects: clear bbtrx
Capture length exceeds bufferOnboard memory fullUse UseRadioBuffer=false for long captures
Background capture never finishesCapture still runningCheck isCapturing(), use stopCapture() if stuck

Key Functions Reference

Function/MethodPurpose
basebandTransceiverCreate radio object (default — handles TX, RX, or both)
basebandTransmitterCreate TX-only radio object (standalone use only)
basebandReceiverCreate RX-only radio object (standalone use only)
transmit(obj, waveform, "once")Single-shot transmit
transmit(obj, waveform, "continuous")Continuous transmit (loops until stopped)
stopTransmission(obj)Stop continuous transmission
capture(obj, length)Foreground capture (blocking)
capture(obj, length, Background=true)Background capture (non-blocking)
captureOutputs(obj)Retrieve background capture results
isCapturing(obj)Check if background capture is running
stopCapture(obj)Stop a background capture
radioConfigurationsList/load saved radio configurations

Conventions

  • Default to basebandTransceiver. Use it for transmit-only, capture-only, or both. Only use basebandTransmitter/basebandReceiver when a separate script needs independent single-direction control.
  • Normalize waveforms. Always scale to peak magnitude ≤ 0.8 to leave headroom and avoid DAC clipping.
  • Start with low gain. Begin TX gain at 10–20 dB and RX gain at 30–40 dB; adjust based on observed signal levels.
  • Continuous transmit before capture. For loopback, start transmit(..., "continuous") first, then capture. This ensures the signal is present when capture begins.
  • Always stop transmission. Call stopTransmission when done to release radio resources.
  • Check dropped samples. Always inspect the third output of capture — it is logical (true = drops occurred). If true, run radioSetupWizard to optimize host settings or reduce sample rate.
  • Wait before retrieving outputs. Never call captureOutputs until isCapturing returns false or stopCapture has been called. Calling it while capture is still running will error.
  • Use duration for capture length. Prefer milliseconds(N) or seconds(N) over raw sample counts for readability and portability across sample rates.
  • Clean up objects. Call clear on radio objects when finished to release hardware for other applications.

Copyright 2026 The MathWorks, Inc.


レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Guide for accessing financial and economic data in MATLAB using the Datafeed Toolbox. Covers Bloomberg (market data via bloomberg/blp/bloombergHypermedia), FRED (Federal Reserve economic data via fredrs), Haver Analytics (economic data via haver/haverdirect/haverview), and LSEG Datastream (historical data via datastreamws). Use when connecting to any of these data providers from MATLAB.

日本語の概要は準備中です。原文の説明を表示しています。

matlab/matlab-agentic-toolkit1,1542026年10月9日 更新

Read 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/matlab-agentic-toolkit1,1542026年10月9日 更新

Analyze 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/matlab-agentic-toolkit1,1542026年10月9日 更新

Design and analyze electrically large antenna structures using MATLAB Antenna Toolbox. Covers reflector antennas (parabolic, Cassegrain, Gregorian, offset, corner, cylindrical, spherical, custom STL), reflectarrays and reconfigurable intelligent surfaces (RIS), antennas installed on platforms (vehicles, aircraft, ships, satellites), and radar cross section (RCS) analysis. Includes solver selection (MoM-PO, PO, MoM, FMM), mesh control, and GPU acceleration. Use when the user wants to design a dish/reflector antenna, reflectarray, analyze an antenna on a platform, or compute RCS.

日本語の概要は準備中です。原文の説明を表示しています。

matlab/matlab-agentic-toolkit1,1542026年10月9日 更新

Analyze 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, row 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/matlab-agentic-toolkit1,1542026年10月9日 更新

S-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/matlab-agentic-toolkit1,1542026年10月9日 更新

matlab のスキルをすべて見る

このスキルの問題を報告する