UOMOP
디지털 변조를 이용한 사진 송수신 using Adalm Pluto 본문
if isempty(ver('wlan')) % Check for WLAN Toolbox install
error('Please install WLAN Toolbox to run this example.');
elseif ~license('test', 'WLAN_System_Toolbox') % Check that a valid license is present
error( ...
'A valid license for WLAN Toolbox is required to run this example.');
end
% Setup handle for image plot
if ~exist('imFig', 'var') || ~ishandle(imFig)
imFig = figure;
imFig.NumberTitle = 'off';
imFig.Name = 'Image Plot';
imFig.Visible = 'off';
else
clf(imFig); % Clear figure
imFig.Visible = 'off';
end
% Setup Spectrum viewer
spectrumScope = dsp.SpectrumAnalyzer( ...
'SpectrumType', 'Power density', ...
'SpectralAverages', 10, ...
'YLimits', [-130 -50], ...
'Title', 'Received Baseband WLAN Signal Spectrum', ...
'YLabel', 'Power spectral density', ...
'Position', [69 376 800 450]);
% Setup the constellation diagram viewer for equalized WLAN symbols
constellation = comm.ConstellationDiagram(...
'Title', 'Equalized WLAN Symbols', ...
'ShowReferenceConstellation', false, ...
'Position', [878 376 460 460]);
% Initialize SDR device
deviceNameSDR = 'Pluto'; % Set SDR Device
radio = sdrdev(deviceNameSDR); % Create SDR device object
txGain = -0;
% Input an image file and convert to binary stream
fileTx = 'peppers.png'; % Image file name
fData = imread(fileTx); % Read image data from file
scale = 0.2; % Image scaling factor
origSize = size(fData); % Original input image size
scaledSize = max(floor(scale.*origSize(1:2)),1); % Calculate new image size
heightIx = min(round(((1:scaledSize(1))-0.5)./scale+0.5),origSize(1));
widthIx = min(round(((1:scaledSize(2))-0.5)./scale+0.5),origSize(2));
fData = fData(heightIx,widthIx,:); % Resize image
imsize = size(fData); % Store new image size
txImage = fData(:);
% Plot transmit image
figure(imFig);
imFig.Visible = 'on';
subplot(211);
imshow(fData);
title('Transmitted Image');
subplot(212);
title('Received image will appear here...');
set(gca,'Visible','off');
set(findall(gca, 'type', 'text'), 'visible', 'on');
pause(1); % Pause to plot Tx image
msduLength = 2304; % MSDU length in bytes
numMSDUs = ceil(length(txImage)/msduLength);
padZeros = msduLength-mod(length(txImage),msduLength);
txData = [txImage; zeros(padZeros,1)];
txDataBits = double(reshape(de2bi(txData, 8)', [], 1));
% Divide input data stream into fragments
bitsPerOctet = 8;
data = zeros(0, 1);
for ind=0:numMSDUs-1
% Extract image data (in octets) for each MPDU
frameBody = txData(ind*msduLength+1:msduLength*(ind+1),:);
% Create MAC frame configuration object and configure sequence number
cfgMAC = wlanMACFrameConfig('FrameType', 'Data', 'SequenceNumber', ind);
% Generate MPDU
[mpdu, lengthMPDU]= wlanMACFrame(frameBody, cfgMAC);
% Convert MPDU bytes to a bit stream
psdu = reshape(de2bi(hex2dec(mpdu), 8)', [], 1);
% Concatenate PSDUs for waveform generation
data = [data; psdu]; %#ok<AGROW>
end
nonHTcfg = wlanNonHTConfig; % Create packet configuration
nonHTcfg.MCS = 6; % Modulation: 64QAM Rate: 2/3
nonHTcfg.NumTransmitAntennas = 1; % Number of transmit antenna
chanBW = nonHTcfg.ChannelBandwidth;
nonHTcfg.PSDULength = lengthMPDU; % Set the PSDU length
sdrTransmitter = sdrtx(deviceNameSDR); % Transmitter properties
sdrTransmitter.RadioID = 'usb:0';
% Resample the transmit waveform at 30 MHz
fs = wlanSampleRate(nonHTcfg); % Transmit sample rate in MHz
osf = 1.5; % Oversampling factor
sdrTransmitter.BasebandSampleRate = fs*osf;
sdrTransmitter.CenterFrequency = 2.432e9; % Channel 5
sdrTransmitter.ShowAdvancedProperties = true;
sdrTransmitter.Gain = txGain;
% Initialize the scrambler with a random integer for each packet
scramblerInitialization = randi([1 127],numMSDUs,1);
% Generate baseband NonHT packets separated by idle time
txWaveform = wlanWaveformGenerator(data,nonHTcfg, ...
'NumPackets',numMSDUs,'IdleTime',20e-6, ...
'ScramblerInitialization',scramblerInitialization);
% Resample transmit waveform
txWaveform = resample(txWaveform,fs*osf,fs);
fprintf('\nGenerating WLAN transmit waveform:\n')
% Scale the normalized signal to avoid saturation of RF stages
powerScaleFactor = 0.8;
txWaveform = txWaveform.*(1/max(abs(txWaveform))*powerScaleFactor);
% Transmit RF waveform
sdrTransmitter.transmitRepeat(txWaveform);
sdrReceiver = sdrrx(deviceNameSDR);
sdrReceiver.RadioID = 'usb:0';
sdrReceiver.BasebandSampleRate = sdrTransmitter.BasebandSampleRate;
sdrReceiver.CenterFrequency = sdrTransmitter.CenterFrequency;
sdrReceiver.GainSource = 'Manual';
sdrReceiver.Gain = 10;
sdrReceiver.OutputDataType = 'double';
captureLength = 2*length(txWaveform);
spectrumScope.SampleRate = sdrReceiver.BasebandSampleRate;
% Get the required field indices within a PSDU
indLSTF = wlanFieldIndices(nonHTcfg,'L-STF');
indLLTF = wlanFieldIndices(nonHTcfg,'L-LTF');
indLSIG = wlanFieldIndices(nonHTcfg,'L-SIG');
Ns = indLSIG(2)-indLSIG(1)+1; % Number of samples in an OFDM symbol
%%
% *Capture Receive Packets*
%%
% The transmitted waveform is captured using the PlutoSDR.
fprintf('\nStarting a new RF capture.\n')
burstCaptures = capture(sdrReceiver, captureLength, 'Samples');
% Show power spectral density of the received waveform
spectrumScope(burstCaptures);
% Downsample the received signal
rxWaveform = resample(burstCaptures,fs,fs*osf);
rxWaveformLen = size(rxWaveform,1);
searchOffset = 0; % Offset from start of the waveform in samples
% Minimum packet length is 10 OFDM symbols
lstfLen = double(indLSTF(2)); % Number of samples in L-STF
minPktLen = lstfLen*5;
pktInd = 1;
sr = wlanSampleRate(nonHTcfg); % Sampling rate
fineTimingOffset = [];
packetSeq = [];
displayFlag = 0; % Flag to display the decoded information
% Perform EVM calculation
evmCalculator = comm.EVM('AveragingDimensions',[1 2 3]);
evmCalculator.MaximumEVMOutputPort = true;
% Receiver processing
while (searchOffset + minPktLen) <= rxWaveformLen
% Packet detect
pktOffset = wlanPacketDetect(rxWaveform, chanBW, searchOffset, 0.8);
% Adjust packet offset
pktOffset = searchOffset+pktOffset;
if isempty(pktOffset) || (pktOffset+double(indLSIG(2))>rxWaveformLen)
if pktInd==1
disp('** No packet detected **');
end
break;
end
% Extract non-HT fields and perform coarse frequency offset correction
% to allow for reliable symbol timing
nonHT = rxWaveform(pktOffset+(indLSTF(1):indLSIG(2)),:);
coarseFreqOffset = wlanCoarseCFOEstimate(nonHT,chanBW);
nonHT = helperFrequencyOffset(nonHT,fs,-coarseFreqOffset);
% Symbol timing synchronization
fineTimingOffset = wlanSymbolTimingEstimate(nonHT,chanBW);
% Adjust packet offset
pktOffset = pktOffset+fineTimingOffset;
if (pktOffset<0) || ((pktOffset+minPktLen)>rxWaveformLen)
searchOffset = pktOffset+1.5*lstfLen;
continue;
end
fprintf('\nPacket-%d detected at index %d\n',pktInd,pktOffset+1);
% Extract first 7 OFDM symbols worth of data for format detection and
% L-SIG decoding
nonHT = rxWaveform(pktOffset+(1:7*Ns),:);
nonHT = helperFrequencyOffset(nonHT,fs,-coarseFreqOffset);
% Perform fine frequency offset correction on the synchronized and
% coarse corrected preamble fields
lltf = nonHT(indLLTF(1):indLLTF(2),:); % Extract L-LTF
fineFreqOffset = wlanFineCFOEstimate(lltf,chanBW);
nonHT = helperFrequencyOffset(nonHT,fs,-fineFreqOffset);
cfoCorrection = coarseFreqOffset+fineFreqOffset; % Total CFO
% Channel estimation using L-LTF
lltf = nonHT(indLLTF(1):indLLTF(2),:);
demodLLTF = wlanLLTFDemodulate(lltf,chanBW);
chanEstLLTF = wlanLLTFChannelEstimate(demodLLTF,chanBW);
% Noise estimation
noiseVarNonHT = helperNoiseEstimate(demodLLTF);
% Packet format detection using the 3 OFDM symbols immediately
% following the L-LTF
format = wlanFormatDetect(nonHT(indLLTF(2)+(1:3*Ns),:), ...
chanEstLLTF,noiseVarNonHT,chanBW);
disp([' ' format ' format detected']);
if ~strcmp(format,'Non-HT')
fprintf(' A format other than Non-HT has been detected\n');
searchOffset = pktOffset+1.5*lstfLen;
continue;
end
% Recover L-SIG field bits
[recLSIGBits,failCheck] = wlanLSIGRecover( ...
nonHT(indLSIG(1):indLSIG(2),:), ...
chanEstLLTF,noiseVarNonHT,chanBW);
if failCheck
fprintf(' L-SIG check fail \n');
searchOffset = pktOffset+1.5*lstfLen;
continue;
else
fprintf(' L-SIG check pass \n');
end
% Retrieve packet parameters based on decoded L-SIG
[lsigMCS,lsigLen,rxSamples] = helperInterpretLSIG(recLSIGBits,sr);
if (rxSamples+pktOffset)>length(rxWaveform)
disp('** Not enough samples to decode packet **');
break;
end
% Apply CFO correction to the entire packet
rxWaveform(pktOffset+(1:rxSamples),:) = helperFrequencyOffset(...
rxWaveform(pktOffset+(1:rxSamples),:),fs,-cfoCorrection);
% Create a receive Non-HT config object
rxNonHTcfg = wlanNonHTConfig;
rxNonHTcfg.MCS = lsigMCS;
rxNonHTcfg.PSDULength = lsigLen;
% Get the data field indices within a PPDU
indNonHTData = wlanFieldIndices(rxNonHTcfg,'NonHT-Data');
% Recover PSDU bits using transmitted packet parameters and channel
% estimates from L-LTF
[rxPSDU,eqSym] = wlanNonHTDataRecover(rxWaveform(pktOffset+...
(indNonHTData(1):indNonHTData(2)),:), ...
chanEstLLTF,noiseVarNonHT,rxNonHTcfg);
constellation(reshape(eqSym,[],1)); % Current constellation
pause(0); % Allow constellation to repaint
release(constellation); % Release previous constellation plot
refSym = wlanClosestReferenceSymbol(eqSym,rxNonHTcfg);
[evm.RMS,evm.Peak] = evmCalculator(refSym,eqSym);
% Decode the MPDU and extract MSDU
[cfgMACRx, msduList{pktInd}, status] = wlanMPDUDecode(rxPSDU, rxNonHTcfg); %#ok<*SAGROW>
if strcmp(status, 'Success')
disp(' MAC FCS check pass');
% Store sequencing information
packetSeq(pktInd) = cfgMACRx.SequenceNumber;
% Convert MSDU to a binary data stream
rxBit{pktInd} = reshape(de2bi(hex2dec(cell2mat(msduList{pktInd})), 8)', [], 1);
else % Decoding failed
if strcmp(status, 'FCSFailed')
% FCS failed
disp(' MAC FCS check fail');
else
% FCS passed but encountered other decoding failures
disp(' MAC FCS check pass');
end
% Remove header and FCS. Extract the MSDU.
macHeaderBitsLength = 24*bitsPerOctet;
fcsBitsLength = 4*bitsPerOctet;
msduList{pktInd} = rxPSDU(macHeaderBitsLength+1 : end-fcsBitsLength);
% Extract and store sequence number
sequenceNumStartIndex = 23*bitsPerOctet+1;
sequenceNumEndIndex = 25*bitsPerOctet - 4;
packetSeq(pktInd) = bi2de(rxPSDU(sequenceNumStartIndex:sequenceNumEndIndex)');
% MSDU binary data stream
rxBit{pktInd} = double(msduList{pktInd});
end
% Display decoded information
if displayFlag
fprintf(' Estimated CFO: %5.1f Hz\n\n',cfoCorrection); %#ok<UNRCH>
disp(' Decoded L-SIG contents: ');
fprintf(' MCS: %d\n',lsigMCS);
fprintf(' Length: %d\n',lsigLen);
fprintf(' Number of samples in packet: %d\n\n',rxSamples);
fprintf(' EVM:\n');
fprintf(' EVM peak: %0.3f%% EVM RMS: %0.3f%%\n\n', ...
evm.Peak,evm.RMS);
fprintf(' Decoded MAC Sequence Control field contents:\n');
fprintf(' Sequence number:%d\n',packetSeq(pktInd));
end
% Update search index
searchOffset = pktOffset+double(indNonHTData(2));
pktInd = pktInd+1;
% Finish processing when a duplicate packet is detected. The
% recovered data includes bits from duplicate frame
if length(unique(packetSeq))<length(packetSeq)
break
end
end
% Release the state of sdrTransmitter and sdrReceiver object
release(sdrTransmitter);
release(sdrReceiver);
%%
% *Reconstruct Image*
%%
% The image is reconstructed from the received MAC frames.
if ~(isempty(fineTimingOffset)||isempty(pktOffset))&& ...
(numMSDUs==(numel(packetSeq)-1))
% Remove the duplicate captured MAC fragment
rxBitMatrix = cell2mat(rxBit);
rxData = rxBitMatrix(1:end,1:numel(packetSeq)-1);
startSeq = find(packetSeq==0);
rxData = circshift(rxData,[0 -(startSeq(1)-1)]);% Order MAC fragments
% Perform bit error rate (BER) calculation
bitErrorRate = comm.ErrorRate;
err = bitErrorRate(double(rxData(:)), ...
txDataBits(1:length(reshape(rxData,[],1))));
fprintf(' \nBit Error Rate (BER):\n');
fprintf(' Bit Error Rate (BER) = %0.5f.\n',err(1));
fprintf(' Number of bit errors = %d.\n', err(2));
fprintf(' Number of transmitted bits = %d.\n\n',length(txDataBits));
% Recreate image from received data
fprintf('\nConstructing image from received data.\n');
decdata = bi2de(reshape(rxData(1:length(txImage)*bitsPerOctet), 8, [])');
receivedImage = uint8(reshape(decdata,imsize));
% Plot received image
if exist('imFig', 'var') && ishandle(imFig) % If Tx figure is open
figure(imFig); subplot(212);
else
figure; subplot(212);
end
imshow(receivedImage);
title(sprintf('Received Image'));
end
displayEndOfDemoMessage(mfilename)
tx.gain이 0dB였을 때는 원 신호를 거의 그대로 다 송신하기 때문에 power spectrum density 결과파형이 약 ‘-110dBm/Hz ~ -70dBm/Hz’사이에서 도시되었다. 또한 성상도에는 64QAM 이기 때문에 64개의 점에 좌표가 찍히는 것을 확인할 수 있었고, 수신단에서 사진이 보내진 것을 관측할 수 있었다.
하지만 tx.gain을 낮출수록 역시 power spectrum density 결과파형의 값이 낮아 졌고, 성상도에서는 I/Q가 제대로 찍히지 못하는 것을 확인했다. 또한 수신단에서 사진이 확인이 안되는 것으로 보아 통신이 제대로 이루어지지 않았음을 알 수 있다.
'Wireless Comm. > Matlab' 카테고리의 다른 글
Wave Propagation (0) | 2022.01.20 |
---|---|
Filter 특성 확인 using Matlab (0) | 2022.01.20 |
Multi-tone Signal의 분석 using Matlab (0) | 2022.01.20 |
주파수 응답 특성 확인 using Matlab (0) | 2022.01.19 |
Fourier Series using Matlab (0) | 2022.01.19 |
Comments