Why my PLUTO cant capture the signals

17 次查看(过去 30 天)
Mert
Mert 2025-9-2,14:01
编辑: Umar 2025-9-3,5:33
I cant recieve my signals to another pc with different adalm pluto. And i cant find any documents about it.
TX Code:
clc
%% User params
targetBits = 1e7;
M = 16;
insertDCNull = true;
numGuardBands = [6; 5];
cyclicPrefixLen = 16;
windowingEnabled = false;
oversamplingFact = 1;
txCenterHz = 2.4e9;
txGain = -10;
airtimeSec = 10;
VIDEO_PATH = 'C:\Users\hp\Desktop\test1.mp4';
scs = 312.5e3;
%% OFDM mod
ofdmMod = comm.OFDMModulator( ...
'FFTLength', 64, ...
'NumGuardBandCarriers', numGuardBands, ...
'InsertDCNull', insertDCNull, ...
'CyclicPrefixLength', cyclicPrefixLen, ...
'Windowing', windowingEnabled, ...
'OversamplingFactor', oversamplingFact, ...
'NumSymbols', 100, ...
'NumTransmitAntennas', 1, ...
'PilotInputPort', false);
%% Pluto
MAX_FS = 61.44e6;
Fs_req = ofdmMod.FFTLength * scs * ofdmMod.OversamplingFactor;
if Fs_req > MAX_FS
scs = MAX_FS / (ofdmMod.FFTLength * ofdmMod.OversamplingFactor);
warning('SCS düşürüldü: %.1f kHz (Fs=%.2f MHz, Pluto limiti).', scs/1e3, MAX_FS/1e6);
end
Fs = ofdmMod.FFTLength * scs * ofdmMod.OversamplingFactor;
%%
ofdmInfo0 = info(ofdmMod);
Ndata = ofdmInfo0.DataInputSize(1);
bps = log2(M);
bitsPerOFDMsym = Ndata * bps;
%% --- ---
inBits = load_file_as_bits(VIDEO_PATH);
fileLenBytes = uint64(numel(inBits)/8);
lenBytes = zeros(8,1,'uint8');
for i = 1:8
lenBytes(i) = uint8(bitand(bitshift(fileLenBytes, -8*(i-1)), 255));
end
lenBits = de2bi(lenBytes, 8, 'left-msb').';
lenBits = lenBits(:);
payloadBitsNoPad = [lenBits; inBits];
NsymNeeded = ceil(numel(payloadBitsNoPad) / bitsPerOFDMsym);
release(ofdmMod);
ofdmMod.NumSymbols = NsymNeeded;
ofdmInfo = info(ofdmMod);
ofdmSize = ofdmInfo.DataInputSize;
totalBitsNeeded = prod(ofdmSize) * bps;
padBits = totalBitsNeeded - numel(payloadBitsNoPad);
if padBits > 0
txBits = [payloadBitsNoPad; false(padBits,1)];
else
txBits = payloadBitsNoPad(1:totalBitsNeeded);
padBits = 0;
end
totalBits = numel(txBits);
%% QA m
dataQAM = qammod(uint8(txBits), M, 'gray', 'InputType', 'bit', 'UnitAveragePower', true);
expectedLen = prod(ofdmSize);
if numel(dataQAM) ~= expectedLen
error('QAM veri uzunluğu (%d), beklenen OFDM giriş uzunluğuyla (%d) eşleşmiyor.', ...
numel(dataQAM), expectedLen);
end
dataQAM = reshape(dataQAM, ofdmSize);
%% --- PATCH #2: Training sequence ---
rng(0);
ofdmModTrain = comm.OFDMModulator( ...
'FFTLength', 64, ...
'NumGuardBandCarriers', numGuardBands, ...
'InsertDCNull', insertDCNull, ...
'CyclicPrefixLength', cyclicPrefixLen, ...
'Windowing', windowingEnabled, ...
'OversamplingFactor', oversamplingFact, ...
'NumSymbols', 1, ...
'NumTransmitAntennas', 1, ...
'PilotInputPort', false);
trainBits = randi([0 1], Ndata,1);
trainSym = 1 - 2*trainBits;
trainQAM = reshape(trainSym,[Ndata,1,1]);
trainWave = ofdmModTrain(trainQAM);
preambleWave = [trainWave; trainWave];
%% Payload wave
payloadWave = ofdmMod(dataQAM);
%% TX
txWave = [preambleWave; payloadWave];
%% G
sa = spectrumAnalyzer('SampleRate', Fs);
sa(txWave);
release(sa);
cd = comm.ConstellationDiagram('ColorFading', true, ...
'ShowTrajectory', false, 'ShowReferenceConstellation', false);
cd(dataQAM(:));
release(cd);
showResourceMapping(ofdmMod);
release(ofdmModTrain);
%% Pluto TX
plutoTx = sdrtx('Pluto', RadioID='usb:0');
plutoTx.CenterFrequency = txCenterHz;
plutoTx.Gain = txGain;
plutoTx.BasebandSampleRate = Fs;
plutoTx.ShowAdvancedProperties = true;
plutoTx.FrequencyCorrection = 0;
transmitRepeat(plutoTx, txWave);
pause(airtimeSec);
release(plutoTx);
%%
fprintf(['Transmission stopped.\n' ...
'--- OFDM/Link Özeti ---\n' ...
'FFTLength : %d\n' ...
'GuardBands [L;U] : [%d;%d]\n' ...
'InsertDCNull : %d\n' ...
'CP length : %d\n' ...
'Windowing : %d\n' ...
'OversamplingFactor : %d\n' ...
'Subcarrier Spacing : %.1f kHz\n' ...
'Fs (Baseband) : %.2f MHz\n' ...
'Active data subcarriers: %d\n' ...
'QAM order (M) : %d\n' ...
'Bits / OFDM symbol : %d\n' ...
'Header bits : %d\n' ...
'Payload bits : %d\n' ...
'Pad bits : %d\n' ...
'Num OFDM symbols : %d\n' ...
'Total bits (TX stream) : %d\n'], ...
ofdmMod.FFTLength, numGuardBands(1), numGuardBands(2), insertDCNull, ...
cyclicPrefixLen, windowingEnabled, oversamplingFact, ...
scs/1e3, Fs/1e6, Ndata, M, bitsPerOFDMsym, ...
64, numel(inBits), padBits, NsymNeeded, totalBits);
inf0 = info(ofdmMod);
Nfft = ofdmMod.FFTLength;
Ndata2 = inf0.DataInputSize(1);
bps2 = log2(M);
fprintf('FFT=%d, Guard=[%d;%d], DCnull=%d -> Veri taşıyıcı: %d, Bit/sembol: %d\n', ...
Nfft, ofdmMod.NumGuardBandCarriers(1), ofdmMod.NumGuardBandCarriers(2), ...
ofdmMod.InsertDCNull, Ndata2, Ndata2*bps2);
%%
function bits = load_file_as_bits(filePath)
fid = fopen(filePath,'rb');
assert(fid~=-1, 'Cannot open file: %s', filePath);
c = onCleanup(@() fclose(fid)); %#ok<NASGU>
data = fread(fid, Inf, 'uint8=>uint8');
bits = de2bi(data, 8, 'left-msb').';
bits = bits(:);
end
RX Code
clc; clearvars; close all;
%% ----------------- USER PARAMETERS -----------------
OUTPUT_PATH = 'C:\Users\hk\Desktop\rx_recovered.mp4';
M = 16;
FFT_LEN = 64;
numGuardBands = [6;5];
insertDCNull = true;
cyclicPrefixLen = 16;
windowingEnabled = false;
oversamplingFact = 1;
scs = 312.5e3;
Fs = FFT_LEN * scs * oversamplingFact;
rxCenterHz = 2.4e9;
rxGain = 30;
airtimeSec = 12;
samplesPerFrame = 4096;
%% ----------------- OFDM OBJECTS -----------------
ofdmModTrain = comm.OFDMModulator( ...
'FFTLength', FFT_LEN, ...
'NumGuardBandCarriers', numGuardBands, ...
'InsertDCNull', insertDCNull, ...
'CyclicPrefixLength', cyclicPrefixLen, ...
'Windowing', windowingEnabled, ...
'OversamplingFactor', oversamplingFact, ...
'NumSymbols', 1, ...
'NumTransmitAntennas', 1, ...
'PilotInputPort', false);
ofdmDemod = comm.OFDMDemodulator( ...
'FFTLength', FFT_LEN, ...
'NumGuardBandCarriers', numGuardBands, ...
'InsertDCNull', insertDCNull, ...
'CyclicPrefixLength', cyclicPrefixLen, ...
'Windowing', windowingEnabled, ...
'OversamplingFactor', oversamplingFact, ...
'NumReceiveAntennas', 1, ...
'PilotOutputPort', false);
Ndata = info(ofdmModTrain).DataInputSize(1);
%% ----------------- DETERMINISTIC PREAMBLE REBUILD -----------------
rng(0);
trainBits = randi([0 1], Ndata, 1);
trainSym = 1 - 2*trainBits;
trainQAM = reshape(trainSym, [Ndata, 1, 1]);
trainWave = ofdmModTrain(trainQAM);
preambleWave = [trainWave; trainWave];
symLen = FFT_LEN + cyclicPrefixLen;
%% ----------------- PLUTO RX CAPTURE -----------------
plutoRx = sdrrx('Pluto','RadioID','usb:0', ...
'CenterFrequency', rxCenterHz, ...
'BasebandSampleRate', Fs, ...
'SamplesPerFrame', samplesPerFrame, ...
'OutputDataType', 'double', ...
'GainSource','Manual','Gain', rxGain);
nFrames = ceil(airtimeSec * Fs / samplesPerFrame);
rxBuf = zeros(nFrames * samplesPerFrame, 1);
idx = 1;
disp('Receiving...');
for k = 1:nFrames
s = plutoRx();
if isempty(s); continue; end
rxBuf(idx:idx+numel(s)-1) = s;
idx = idx + numel(s);
end
release(plutoRx);
rxBuf = rxBuf(1:idx-1);
disp('Capture done.');
if numel(rxBuf) < 2*symLen
error('Yetersiz örnek: Preamble''ın tamamı yakalanmamış görünüyor.');
end
%% ----------------- PREAMBLE DETECTION (XCORR) -----------------
corr = abs(conv(rxBuf, flipud(conj(preambleWave))));
[~, peakIdx] = max(corr);
startIdx = peakIdx - numel(preambleWave) + 1;
if startIdx < 1
error('Preamble not found (startIdx < 1).');
end
fprintf('Preamble detected at sample %d\n', startIdx);
%% ----------------- CFO ESTIMATION & CORRECTION -----------------
L = numel(trainWave);
if startIdx + 2*L - 1 > numel(rxBuf)
error('Veri eksik: iki training sembolü tam değil.');
end
r1 = rxBuf(startIdx : startIdx + L - 1);
r2 = rxBuf(startIdx + L : startIdx + 2*L - 1);
phi = angle(sum(conj(r1) .* r2));
cfoEst = phi / L;
n = (0:numel(rxBuf)-1).';
rxBufCFO = rxBuf .* exp(-1j * cfoEst * n);
%% ----------------- CHANNEL ESTIMATION FROM PREAMBLE -----------------
ofdmDemod.NumSymbols = 2;
preBlock = rxBufCFO(startIdx : startIdx + 2*symLen - 1);
Rpre = ofdmDemod(preBlock);
if ndims(Rpre) > 2
Rpre = squeeze(Rpre);
end
Rtrain = Rpre(:,1);
Strain = trainQAM(:);
H_est = Rtrain ./ Strain;
H_est(abs(H_est) < 1e-12) = 1e-12;
%% ----------------- PAYLOAD EXTRACTION & OFDM DEMOD -----------------
payloadStart = startIdx + 2*symLen;
remain = numel(rxBufCFO) - payloadStart + 1;
numSyms = floor(remain / symLen);
if numSyms <= 0
error('Payload için yeterli sembol yok.');
end
ofdmDemod.NumSymbols = numSyms;
rxPayloadTrunc = rxBufCFO(payloadStart : payloadStart + numSyms*symLen - 1);
rxSymbols = ofdmDemod(rxPayloadTrunc);
if ndims(rxSymbols) > 2
rxSymbols = squeeze(rxSymbols);
end
%% ----------------- EQUALIZATION -----------------
eqSymbols = rxSymbols ./ H_est;
rxQAMvec = eqSymbols(:);
%% ----------------- QAM DEMOD -> BITS -----------------
rxBits = qamdemod(rxQAMvec, M, 'gray', 'OutputType','bit', 'UnitAveragePower', true);
rxBits = rxBits(:);
%% ----------------- READ 64-BIT LITTLE-ENDIAN LENGTH HEADER -----------------
if numel(rxBits) < 64
error('Yetersiz bit: 64-bit uzunluk başlığı alınamadı.');
end
lenBits = rxBits(1:64);
lenBytesM = reshape(lenBits, 8, []).';
lenVals = uint8(bi2de(lenBytesM, 'left-msb'));
fileLen = uint64(0);
for i = 1:numel(lenVals)
fileLen = fileLen + uint64(lenVals(i)) * uint64(2)^((i-1)*8);
end
fprintf('Recovered file length (header): %d bytes\n', fileLen);
%% ----------------- EXTRACT PAYLOAD BITS SAFELY -----------------
payloadBits = rxBits(65:end);
maxBytes = floor(numel(payloadBits) / 8);
if fileLen > maxBytes
warning('Header %d byte diyor ama yalnizca %d byte mevcut. Kırpılıyor.', fileLen, maxBytes);
fileLen = uint64(maxBytes);
end
payloadBits = payloadBits(1:double(fileLen) * 8);
%% ----------------- BITS -> BYTES -> WRITE FILE -----------------
if isempty(payloadBits)
error('Payload boş: dosya çıkarılamadı.');
end
bytesMat = reshape(payloadBits, 8, []).';
bytes = uint8(bi2de(bytesMat, 'left-msb'));
fid = fopen(OUTPUT_PATH, 'wb');
assert(fid ~= -1, 'Cannot open output file: %s', OUTPUT_PATH);
fwrite(fid, bytes, 'uint8');
fclose(fid);
fprintf('Saved file: %s (bytes written: %d)\n', OUTPUT_PATH, numel(bytes));

回答(1 个)

Umar
Umar 2025-9-3,5:25
编辑:Umar 2025-9-3,5:33

Hi @Mert,

Based on the RX code you shared and your comment about not receiving signals on a different PC with a different ADALM-PLUTO, the likely issue is that your RX object hard-codes the device ID (RadioID='usb:0'). On a different PC, the OS may enumerate the Pluto radios differently, causing the RX to connect to the wrong device or none at all.

MathWorks recommends dynamically detecting the connected Pluto using findPlutoRadio to ensure the correct device is selected:

connectedRadios = findPlutoRadio;
plutoRx = sdrrx('Pluto', 'RadioID', connectedRadios(1).RadioID, ...);

References (MathWorks Documentation):

1. findPlutoRadio – Detect Connected Pluto Radios:
 https://www.mathworks.com/help/comm/plutoradio/ref/findplutoradio.html

2. sdrrx – Create Pluto SDR Receiver Object:
 https://www.mathworks.com/help/comm/plutoradio/ref/sdrrx.html

Next Steps: 1. Update your RX code to use dynamic RadioID detection. 2. Verify that the RX successfully connects and captures samples. 3. Only then consider verifying preamble detection or other processing steps.

Since you haven’t shared full details, this is my assumption based on the code provided.

类别

Help CenterFile Exchange 中查找有关 Communications Toolbox 的更多信息

产品


版本

R2025a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by