Main Content

Image Transmission and Reception Using 802.11 Waveform and SDR

This example shows how to encode and pack an image file into WLAN packets for transmission and subsequently decode the packets to retrieve the image. The example also shows how to use a software-defined radio (SDR) for over-the-air transmission and reception of the WLAN packets.

Introduction

This example imports and segments an image file into multiple medium access control (MAC) service data units (MSDUs). It passes each MSDU to thewlanMACFrame(WLAN Toolbox)function to create a MAC protocol data unit (MPDU). This function also utilizes awlanMACFrameConfig(WLAN Toolbox)object as an input, which sequentially numbers the MPDUs through theSequenceNumberproperty. The example then passes the MPDUs to the physical (PHY) layer as PHY Layer Service Data Units (PSDUs). Each PSDU uses a single non-high-throughput (non-HT), 802.11a™ WLAN packet for transmission. This example creates a WLAN baseband waveform using thewlanWaveformGenerator(WLAN Toolbox)function. This function utilizes multiple PSDUs and processes each to form a series of physical layer convergence procedure (PLCP) protocol data units (PPDUs) ready for transmission.

The generated waveform then passes through an additive white Gaussian noise (AWGN) channel to simulate an over-the-air transmission. Subsequently, thewlanMPDUDecode(WLAN Toolbox)function takes the noisy waveform and decodes it. Then, theSequenceNumberproperty in the recovered MAC frame configuration object allows the example to sequentially order the extracted MSDUs. The information bits in the multiple received MSDUs combine to recover the transmitted image. This diagram shows the receiver processing.

Alternatively, the generated WLAN waveform can be transmitted over the air and received using these supported SDRs.

sdrFig.png

Communications Toolbox Support Package for Analog Devices®ADALM-Pluto Radio

Communications Toolbox Support Package for USRP®Embedded Series Radio

Communications Toolbox Support Package for Xilinx®Zynq®-Based Radio

Example Setup

Before running the example, set thechannelvariable to be one of these options:

  • OverTheAir: Use an SDR to transmit and receive the WLAN waveform

  • GaussianNoise: Pass the transmission waveform through an AWGN channel (default)

  • NoImpairments: Pass the transmission waveform through with no impairments

If you setchanneltoOverTheAir, set frequency band and channel, transmission gain, and desired SDR:

  • Set toPlutoto use the ADALM-Pluto Radio (default)

  • Set toE3xxto use the USRP Embedded Series Radio

  • Set toAD936xorFMCOMMS5to use the Xilinx Zynq-Based Radio

channel ="GaussianNoise";ifstrcmpi(channel,"OverTheAir") deviceName ="Pluto"; channelNumber =5; frequencyBand =2.4; txGain =-10;elseifstrcmpi(channel,"GaussianNoise")% Specify SNR of received signal for a simulated channelSNR =20;end

Configure all the scopes and figures for the example.

% Setup handle for image plotif~exist('imFig','var') || ~ishandle(imFig)%#okimFig = figure; imFig.NumberTitle ='off'; imFig.Name ='Image Plot'; imFig.Visible ='off';elseclf(imFig);% Clear figureimFig.Visible ='off';end% Setup Spectrum viewerspectrumScope = spectrumAnalyzer(...SpectrumType='power-density',...Title='Received Baseband WLAN Signal Spectrum',...YLabel='Power spectral density',...Position=[69 376 800 450]);% Setup the constellation diagram viewer for equalized WLAN symbolsrefQAM = wlanReferenceSymbols('64QAM'); constellation = comm.ConstellationDiagram(...Title='Equalized WLAN Symbols',...ShowReferenceConstellation=true,...ReferenceConstellation=refQAM,...Position=[878 376 460 460]);

Transmitter Design

These steps describe the general procedure of the WLAN transmitter.

  1. Import an image file and convert it to a stream of decimal bytes

  2. Generate a baseband WLAN signal using the WLAN Toolbox

  3. Pack the data stream into multiple 802.11a packets

If using an SDR, these steps describe the setup of the SDR transmitter.

  1. Prepare the baseband signal for transmission using the SDR hardware

  2. Send the baseband data to the SDR hardware for upsampling and continuous transmission at the desired center frequency

Prepare Image File

Read data from the image file, scale it for transmission, and convert it to a stream of decimal bytes. The scaling of the image reduces the quality by decreasing the size of the binary data stream.

The size of the binary data stream impacts the number of WLAN packets required for the transmission of the image data. The number of WLAN packets generated for transmission depends on these factors.

  1. The image scaling, set when importing the image file

  2. The length of the data carried in a packet, specified by themsduLengthvariable

  3. The modulation and coding scheme (MCS) value of the transmitted packet

The combination of the scaling factor and MSDU length determines the number of WLAN radio packets required for transmission. Settingscaleto0.2andmsduLengthto2304requires the transmission of 11 WLAN radio packets. Increasing the scaling factor or decreasing the MSDU length will result in the transmission of more packets.

% Input an image file and convert to binary streamfileTx ='peppers.png';% Image file namefData = imread(fileTx);%从文件读取图像数据scale =0.2;% Image scaling factororigSize = size(fData);% Original input image sizescaledSize = max(floor(scale.*origSize(1:2)),1);% Calculate new image sizeheightIx = 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 imageimsize = size(fData);% Store new image sizetxImage = fData(:);% Plot transmit imageimFig.Visible ='on'; subplot(211); imshow(fData); title('Transmitted Image'); subplot(212); title('Received image appears here...'); set(gca,'Visible','off');

{

set(findall(gca,'type','text'),'visible','on');

Fragment Transmit Data

Split the data stream (txImage) into smaller transmit units (MSDUs) of sizemsduLength. Then, create an MPDU for each transmit unit using thewlanMACFramefunction. Each call to this function creates an MPDU corresponding to the given MSDU and the frame configuration object. Next, create the frame configuration object usingwlanMACFrameConfigto configure the sequence number of the MPDU. All the MPDUs are then sequentially passed to the physical layer for transmission.

To ensure that the MSDU size of the transmission does not exceed the standard-specified maximum, set themsduLengthfield to2304bytes. To make all MPDUs the same size, append zeros to the data in the last MPDU.

msduLength =2304;% MSDU length in bytesnumMSDUs = 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 fragmentsbitsPerOctet = 8; data = zeros(0,1);fori=0:numMSDUs-1% Extract image data (in octets) for each MPDUframeBody = txData(i*msduLength+1:msduLength*(i+1),:);% Create MAC frame configuration object and configure sequence numbercfgMAC = wlanMACFrameConfig(FrameType='Data',SequenceNumber=i);% Generate MPDU[psdu, lengthMPDU]= wlanMACFrame(frameBody,cfgMAC,OutputFormat='bits');% Concatenate PSDUs for waveform generationdata = [data; psdu];%#okend

Generate 802.11a Baseband WLAN Signal

Synthesize a non-HT waveform using thewlanWaveformGeneratorfunction with a non-HT format configuration object created by thewlanNonHTConfig(WLAN Toolbox)object. In this example, the configuration object has a 20 MHz bandwidth, one transmit antenna and 64QAM rate 2/3 (MCS 6).

nonHTcfg = wlanNonHTConfig;% Create packet configurationnonHTcfg.MCS = 6;% Modulation: 64QAM Rate: 2/3nonHTcfg.NumTransmitAntennas = 1;% Number of transmit antennachanBW = nonHTcfg.ChannelBandwidth; nonHTcfg.PSDULength = lengthMPDU;% Set the PSDU length

Initialize the scrambler with a random integer for each packet.

scramblerInitialization = randi([1 127],numMSDUs,1);

Set the oversampling factor to1.5to generate the waveform at 30 MHz for transmission.

osf =1.5; sampleRate = wlanSampleRate(nonHTcfg);% Nominal sample rate in Hz% Generate baseband NonHT packets separated by idle timetxWaveform = wlanWaveformGenerator(data,nonHTcfg,...NumPackets=numMSDUs,IdleTime=20e-6,...ScramblerInitialization=scramblerInitialization,...OversamplingFactor=osf);

Configure SDR for Transmission

If using an SDR, set the transmitter gain parameter (txGain) to reduce transmission quality and impair the received waveform.

Create ansdrTransmitterobject using thesdrtxfunction. Set the center frequency, sample rate, and gain to the corresponding properties of thesdrTransmitterobject. For an 802.11a signal on channel 5 in the 2.4 GHz frequency band, the corresponding center frequency is 2.432 GHz as defined in section 16.3.6.3 of the IEEE Std 802.11-2016.

ThesdrTransmitterobject uses the transmit repeat functionality to transmit the baseband WLAN waveform in a loop from the double data rate (DDR) memory on the SDR.

ifstrcmpi(channel,"OverTheAir")% Transmitter propertiessdrTransmitter = sdrtx(deviceName); sdrTransmitter.BasebandSampleRate = sampleRate*osf; sdrTransmitter.CenterFrequency = wlanChannelFrequency(channelNumber,frequencyBand); sdrTransmitter.Gain = txGain;% Pass the SDR I/O directly to host skipping FPGA on Zynq Radio or USRP% Embedded Series Radioif~strcmpi(deviceName,"Pluto") sdrTransmitter.ShowAdvancedProperties = true; sdrTransmitter.BypassUserLogic = true;endfprintf('\nGenerating WLAN transmit waveform:\n')% Scale the normalized signal to avoid saturation of RF stagespowerScaleFactor = 0.8; txWaveform = txWaveform.*(1/max(abs(txWaveform))*powerScaleFactor);% Transmit RF waveformtransmitRepeat(sdrTransmitter,txWaveform);end

ThetransmitRepeatfunction transfers the baseband WLAN packets with idle time to the SDR, and stores the signal samples in hardware memory. The example then transmits the waveform continuously over the air until the release of the transmit object.

Receiver Design

The steps listed below describe the general structure of the WLAN receiver.

  1. If using SDR hardware, capture multiple packets of the transmitted WLAN signal

  2. Detect a packet

  3. Coarse carrier frequency offset is estimated and corrected

  4. Fine timing synchronization is established. The L-STF, L-LTF and L-SIG samples are provided for fine timing to allow to adjust the packet detection at the start or end of the L-STF

  5. Fine carrier frequency offset is estimated and corrected

  6. Perform a channel estimation for the received signal using the L-LTF

  7. Detect the format of the packet

  8. Decode the L-SIG field to recover the MCS value and the length of the data portion

  9. Decode the data field to obtain the transmitted data within each packet

  10. Decode the received PSDU and check if the frame check sequence (FCS) passed for the PSDU

  11. Order the decoded MSDUs based on theSequenceNumberproperty in the recovered MAC frame configuration object

  12. Combine the decoded MSDUs from all the transmitted packets to form the received image

This example plots the power spectral density (PSD) of the received waveform, and shows visualizations of the equalized data symbols and the received image.

Receiver Setup

If using an SDR, create ansdrReceiverobject using thesdrrxfunction. Set the center frequency, sample rate, and output data type to the corresponding properties of thesdrReceiverobject.

Otherwise, apply gaussian noise to thetxWaveformusing theawgn(Communications Toolbox)function or pass thetxWaveform直接通过接收机处理。

ifstrcmpi(channel,"OverTheAir") sdrReceiver = sdrrx(deviceName); sdrReceiver.BasebandSampleRate = sdrTransmitter.BasebandSampleRate; sdrReceiver.CenterFrequency = sdrTransmitter.CenterFrequency; sdrReceiver.OutputDataType ='double';if~strcmpi(deviceName,"Pluto") sdrReceiver.ShowAdvancedProperties = true; sdrReceiver.BypassUserLogic = true;end% Configure the capture length equivalent to twice the length of the% transmitted signal, this is to ensure that PSDUs are received in order.% On reception the duplicate MAC fragments are removed.sdrReceiver.SamplesPerFrame = 2*length(txWaveform); fprintf('\nStarting a new RF capture.\n') rxWaveform = capture(sdrReceiver,sdrReceiver.SamplesPerFrame,'Samples');elseifstrcmpi(channel,"GaussianNoise") rxWaveform = awgn(txWaveform,SNR,'measured');else% No ImpairmentsrxWaveform = txWaveform;end

Show the power spectral density of the received waveform.

spectrumScope.SampleRate = sampleRate*osf; spectrumScope(rxWaveform); release(spectrumScope);

Receiver Processing

Design a rate conversion filter for resampling the waveform to the nominal baseband rate for receiver processing using thedesignMultirateFIR(DSP System Toolbox)function.

aStop = 40;% Stopband attenuationofdmInfo = wlanNonHTOFDMInfo('NonHT-Data',nonHTcfg);% OFDM parametersSCS = sampleRate/ofdmInfo.FFTLength;% Subcarrier spacingtxbw = max(abs(ofdmInfo.ActiveFrequencyIndices))*2*SCS;% Occupied bandwidth[L,M] = rat(1/osf); maxLM = max([L M]); R = (sampleRate-txbw)/sampleRate; TW = 2*R/maxLM;% Transition widthb= designMultirateFIR(L,M,TW,aStop);

Resample the oversampled waveform back to 20 MHz for processing using thedsp.FIRRateConverter(DSP System Toolbox)System object and the filter designed above.

firrc = dsp.FIRRateConverter(L,M,b); rxWaveform = firrc(rxWaveform);

If using an SDR, the SDR continuously transmits the 802.11 waveform over-the-air in a loop. The first packet received by thesdrReceivermay not be the first transmitted packet. This means that the packets may be decoded out of sequence. To enable the received packets to be recombined in the correct order, their sequence number must be determined. ThewlanMPDUDecodefunction decodes the MPDU from the decoded PSDU bits of each packet and outputs the MSDU as well as the recovered MAC frame configuration objectwlanMACFrameConfig. TheSequenceNumberproperty in the recovered MAC frame configuration object can be used for ordering the MSDUs in the transmitted sequence.

To display each packet's decoded L-SIG contents, the EVM measurements, and sequence number, check thedisplayFlagbox.

displayFlag =false;

Set up required variables for receiver processing.

rxWaveformLen = size(rxWaveform,1); searchOffset = 0;% Offset from start of the waveform in samples

Get the required field indices within a PSDU.

ind = wlanFieldIndices(nonHTcfg); Ns = ind.LSIG(2)-ind.LSIG(1)+1;% Number of samples in an OFDM symbol% Minimum packet length is 10 OFDM symbolslstfLen = double(ind.LSTF(2));% Number of samples in L-STFminPktLen = lstfLen*5; pktInd = 1; fineTimingOffset = []; packetSeq = []; rxBit = [];% Perform EVM calculationevmCalculator = comm.EVM(AveragingDimensions=[1 2 3]); evmCalculator.MaximumEVMOutputPort = true;

Use awhileloop to process the received out-of-order packets.

while(searchOffset+minPktLen)<=rxWaveformLen% Packet detectpktOffset = wlanPacketDetect(rxWaveform,chanBW,searchOffset,0.5);% Adjust packet offsetpktOffset = searchOffset+pktOffset;ifisempty(pktOffset) || (pktOffset+double(ind.LSIG(2))>rxWaveformLen)ifpktInd==1 disp('** No packet detected **');endbreak;end% Extract non-HT fields and perform coarse frequency offset correction% to allow for reliable symbol timingnonHT = rxWaveform(pktOffset+(ind.LSTF(1):ind.LSIG(2)),:); coarseFreqOffset = wlanCoarseCFOEstimate(nonHT,chanBW); nonHT = frequencyOffset(nonHT,sampleRate,-coarseFreqOffset);% Symbol timing synchronizationfineTimingOffset = wlanSymbolTimingEstimate(nonHT,chanBW);% Adjust packet offsetpktOffset = pktOffset+fineTimingOffset;% Timing synchronization complete: Packet detected and synchronized% Extract the non-HT preamble field after synchronization and% perform frequency correctionif(pktOffset<0) || ((pktOffset+minPktLen)>rxWaveformLen) searchOffset = pktOffset+1.5*lstfLen;continue;endfprintf('\nPacket-%d detected at index %d\n',pktInd,pktOffset+1);% Extract first 7 OFDM symbols worth of data for format detection and% L-SIG decodingnonHT = rxWaveform(pktOffset+(1:7*Ns),:); nonHT = frequencyOffset(nonHT,sampleRate,-coarseFreqOffset);% Perform fine frequency offset correction on the synchronized and% coarse corrected preamble fieldslltf = nonHT(ind.LLTF(1):ind.LLTF(2),:);% Extract L-LTFfineFreqOffset = wlanFineCFOEstimate(lltf,chanBW); nonHT = frequencyOffset(nonHT,sampleRate,-fineFreqOffset); cfoCorrection = coarseFreqOffset+fineFreqOffset;% Total CFO% Channel estimation using L-LTFlltf = nonHT(ind.LLTF(1):ind.LLTF(2),:); demodLLTF = wlanLLTFDemodulate(lltf,chanBW); chanEstLLTF = wlanLLTFChannelEstimate(demodLLTF,chanBW);% Noise estimationnoiseVarNonHT = helperNoiseEstimate(demodLLTF);% Packet format detection using the 3 OFDM symbols immediately% following the L-LTFformat = wlanFormatDetect(nonHT(ind.LLTF(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(ind.LSIG(1):ind.LSIG(2),:),...chanEstLLTF,noiseVarNonHT,chanBW);iffailCheck fprintf(' L-SIG check fail \n'); searchOffset = pktOffset+1.5*lstfLen;continue;elsefprintf(' L-SIG check pass \n');end% Retrieve packet parameters based on decoded L-SIG[lsigMCS,lsigLen,rxSamples] = helperInterpretLSIG(recLSIGBits,sampleRate);if(rxSamples+pktOffset)>length(rxWaveform) disp('** Not enough samples to decode packet **');break;end% Apply CFO correction to the entire packetrxWaveform(pktOffset+(1:rxSamples),:) = frequencyOffset(...rxWaveform(pktOffset+(1:rxSamples),:),sampleRate,-cfoCorrection);% Create a receive Non-HT config objectrxNonHTcfg = wlanNonHTConfig; rxNonHTcfg.MCS = lsigMCS; rxNonHTcfg.PSDULength = lsigLen;% Get the data field indices within a PPDUindNonHTData = 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 constellationrelease(constellation); 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>ifstrcmp(status,'Success') disp(' MAC FCS check pass');% Store sequencing informationpacketSeq(pktInd) = cfgMACRx.SequenceNumber;% Convert MSDU to a binary data streamrxBit{pktInd} = reshape(de2bi(hex2dec(cell2mat(msduList{pktInd})),8)',[],1);else% Decoding failedifstrcmp(status,'FCSFailed')% FCS faileddisp(' MAC FCS check fail');else% FCS passed but encountered other decoding failuresdisp(' MAC FCS check pass');end% Since there are no retransmissions modeled in this example, we% extract the image data (MSDU) and sequence number from the MPDU,% even though FCS check fails.% Remove header and FCS. Extract the MSDU.macHeaderBitsLength = 24*bitsPerOctet; fcsBitsLength = 4*bitsPerOctet; msduList{pktInd} = rxPSDU(macHeaderBitsLength+1:end-fcsBitsLength);% Extract and store sequence numbersequenceNumStartIndex = 23 * bitsPerOctet + 1;层层序eNumEndIndex = 25*bitsPerOctet-4; packetSeq(pktInd) = bi2de(rxPSDU(sequenceNumStartIndex:sequenceNumEndIndex)');% MSDU binary data streamrxBit{pktInd} = double(msduList{pktInd});end% Display decoded informationifdisplayFlag 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\n',packetSeq(pktInd));end% Update search indexsearchOffset = pktOffset+double(indNonHTData(2));% Finish processing when a duplicate packet is detected. The% recovered data includes bits from duplicate frame% Remove the data bits from the duplicate frameiflength(unique(packetSeq)) < length(packetSeq) rxBit = rxBit(1:length(unique(packetSeq))); packetSeq = packetSeq(1:length(unique(packetSeq)));breakendpktInd = pktInd+1;end
Packet-1 detected at index 7
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-2 detected at index 8647
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-3 detected at index 17287
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-4 detected at index 25927
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-5 detected at index 34567
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-6 detected at index 43207
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-7 detected at index 51847
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-8 detected at index 60487
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-9 detected at index 69127
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-10 detected at index 77767
Non-HT format detected
L-SIG check pass
MAC FCS check pass
Packet-11 detected at index 86407
Non-HT format detected
L-SIG check pass

MAC FCS check pass

If using an SDR, release thesdrTransmitterandsdrReceiverobjects to stop the continuous transmission of the 802.11 waveform and to allow for any modification of the SDR object properties.

ifstrcmpi(channel,"OverTheAir") release(sdrTransmitter); release(sdrReceiver);end

Reconstruct Image

Reconstruct the image using the received MAC frames.

if~(isempty(fineTimingOffset) || isempty(pktOffset)) rxData = cell2mat(rxBit);% Remove duplicate packets if any. Duplicate packets are located at the% end of rxDataiflength(packetSeq)>numMSDUs numDupPackets = size(rxData,2)-numMSDUs; rxData = rxData(:,1:end-numDupPackets);end% Initialize variables for while loopstartSeq = []; i=-1;% Only execute this if one of the packet sequence values have been decoded% accuratelyifany(packetSeqwhileisempty(startSeq)% This searches for a known packetSeq valuei = i + 1; startSeq = find(packetSeq==i);end% Circularly shift data so that received packets are in order for image reconstruction. It% is assumed that all packets following the starting packet are received in% order as this is how the image is transmitted.rxData = circshift(rxData,[0 -(startSeq(1)-i-1)]);% Order MAC fragments% Perform bit error rate (BER) calculation on reordered databitErrorRate = comm.ErrorRate;呃= 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));enddecData = bi2de(reshape(rxData(:),8,[])');% Append NaNs to fill any missing image dataiflength(decData)elsedecData = decData(1:length(txImage));end% Recreate image from received datafprintf('\nConstructing image from received data.\n'); receivedImage = uint8(reshape(decData,imsize));% Plot received imageifexist('imFig','var') && ishandle(imFig)% If Tx figure is openfigure(imFig); subplot(212);elsefigure; subplot(212);endimshow(receivedImage); title(sprintf('Received Image'));end
Bit Error Rate (BER):
Bit Error Rate (BER) = 0.00000
Number of bit errors = 0
Number of transmitted bits = 202752
Constructing image from received data.

{

Further Exploration

  • If using an SDR, modifytxGainorrxGainto observe the difference in the EVM and BER after signal reception and processing. You may see errors in the displayed, received image.

  • If running the example without an SDR, modifySNRto observe the difference in the EVM and BER after signal reception and processing.

  • Increase the scaling factor (scale) to improve the quality of the received image by generating more transmit bits. This also increases the number of transmitted PPDUs.

  • Decrease MSDU size (msduLength) to decrease the number of bits transmitted per packet and observe the differences in EVM and BER when a signal is received with a lower SNR.

SDR Troubleshooting