%Create a bluetooth LE transmitter
%RF Channels: 40
%Symbol Rate: 1Msym/s
%Modulation: GFSK
%Transmission Mode: LE1M i.e. Uncoded PHY with data rate of 1Mbps
%Preamble: 01010101 or 10101010 dependent on the first value of access
%address
%Access address: 32 bit field
%Payload maximum size is 2080 (includes every part of packet)
%%BLE Transmitter
clc;
phyMode = 'LE1M';
commSupportPackageCheck('BLUETOOTH'); %Check that MATLAB bluetooth is on system
symbolRate = 1e6;
channelBW = 2e6;
%Configure the advertising channel PDU
cfgLLAdv = bleLLAdvertisingChannelPDUConfig;
cfgLLAdv.PDUType = 'Advertising indication';
cfgLLAdv.AdvertisingData = '0123456789ABCDEF';
cfgLLAdv.AdvertiserAddress = '1234567890AB';
%Generate the message, pack into message bits
messageBits = bleLLAdvertisingChannelPDU(cfgLLAdv);
[status, value] = bleLLAdvertisingChannelPDUDecode(messageBits); %Loop exists here to go through octets of data entry
%For visualization purposes
numIter = 1;
sps = 8; % Samples per symbol
accessAddLen = 32;% Length of access address
accessAddHex = '8E89BED6'; % Access address value in hexadecimal
accessAddBin = de2bi(hex2dec(accessAddHex),accessAddLen)'; % Access address in binary
%Setting up visualization
% Create a spectrum analyzer object
specAn = dsp.SpectrumAnalyzer('SpectrumType','Power density');
specAn.SampleRate = symbolRate*sps;
% Create a time scope object
timeScope = timescope('SampleRate', symbolRate*sps,'TimeSpanSource','Auto',...
'ShowLegend',true);
rng default; %controlled repetiton
for numIdx = 1:numIter
channelIdx = randi([37 39],1,1);
%channelIdx = 37; % Channel index value in the range [0,39]
%Generate the waveform
txWaveform = bleWaveformGenerator(messageBits,...
'Mode', phyMode,...
'SamplesPerSymbol',sps,...
'ChannelIndex', channelIdx,...
'AccessAddress', accessAddBin);
% txWaveform = awgn(txWaveform,20,'measured');
% Initialize the parameters required for signal source
if channelIdx == 37
txCenterFrequency = 2.402e9;
elseif channelIdx == 38
txCenterFrequency = 2.426e9;
else
txCenterFrequency = 2.480e9;
end
txFrameLength = length(txWaveform);
txNumberOfFrames = 1; %1e4
txFrontEndSampleRate = symbolRate*sps;
% specAn.FrequencyOffset = channelBW*channelIdx;
specAn.Title = ['Spectrum of ',phyMode,' Waveform for Channel Index = ', num2str(channelIdx)];
channelIdx;
tic
while toc < 0.5 % To hold the spectrum for 0.5 seconds
specAn(txWaveform);
end
% Plot the generated waveform
timeScope.Title = ['BLE ',phyMode,' Waveform for Channel Index = ', num2str(channelIdx)];
timeScope(txWaveform);
end
sigSink = comm.BasebandFileWriter('CenterFrequency',txCenterFrequency,...
'Filename','bleCaptures.bb',...
'SampleRate',txFrontEndSampleRate);
sigSink(txWaveform); % Writing to a baseband file 'bleCaptures.bb'
%So basically it is a .bb because I can save the data
release(sigSink)
constDiagram = comm.ConstellationDiagram('SamplesPerSymbol',sps, ...
'SymbolsToDisplaySource','Property','SymbolsToDisplay',100);
constDiagram(txWaveform)
%% End
%Receiver
%%BLE Receiver
load 'Port ECG 1 [shielded 2020 10cm]-2020.09.30.17.01.31.716.MAT'
clc;
phyMode = 'LE1M';
bleParam = helperBLEReceiverConfig(phyMode);
bbFileName = 'bleCaptures.bb';
sigSrc = comm.BasebandFileReader(bbFileName);
sigSrcInfo = info(sigSrc);
sigSrc.SamplesPerFrame = sigSrcInfo.NumSamplesInData;
bbSampleRate = sigSrc.SampleRate;
bleParam.SamplesPerSymbol = bbSampleRate/bleParam.SymbolRate;
%View the received signal
spectrumScope = dsp.SpectrumAnalyzer( ...
'SampleRate', bbSampleRate,...
'SpectrumType', 'Power density', ...
'SpectralAverages', 10, ...
'YLimits', [-130 -10], ...
'Title', 'Received Baseband BLE Signal Spectrum', ...
'YLabel', 'Power spectral density');
dataCaptures = sigSrc();
% Show power spectral density of the received waveform
spectrumScope(dataCaptures);
agc = comm.AGC('MaxPowerGain',20,'DesiredOutputPower',2);
freqCompensator = comm.CoarseFrequencyCompensator('Modulation','OQPSK', ...
'SampleRate',bbSampleRate,...
'SamplesPerSymbol',2*bleParam.SamplesPerSymbol,...
'FrequencyResolution',100);
prbDet = comm.PreambleDetector(bleParam.RefSeq,'Detections','First');
length(dataCaptures)
bleParam.MinimumPacketLen;
pktCnt = 0;
crcCnt = 0;
displayFlag = true;%false; % true if the received data is to be printed
%while length(dataCaptures) > bleParam.MinimumPacketLen
% Consider two frames from the captured signal for each iteration
startIndex = 1;
endIndex = min(length(dataCaptures),2*bleParam.FrameLength);
rcvSig = dataCaptures(startIndex:endIndex);
rcvAGC = agc(rcvSig); % Perform AGC
rcvDCFree = rcvAGC - mean(rcvAGC); % Remove the DC offset
rcvFreqComp = freqCompensator(rcvDCFree); % Estimate and compensate for the carrier frequency offset
rcvFilt = conv(rcvFreqComp,bleParam.h,'same'); % Perform gaussian matched filtering
% Perform frame timing synchronization
[~, dtMt] = prbDet(rcvFilt);
release(prbDet)
prbDet.Threshold = max(dtMt);
prbIdx = prbDet(rcvFilt);
prbIdx;
% Extract message information
[cfgLLAdv,pktCnt,crcCnt,remStartIdx] = helperBLEPhyBitRecover(rcvFilt,...
prbIdx,pktCnt,crcCnt,bleParam);
% Remaining signal in the burst captures
dataCaptures = dataCaptures(1+remStartIdx:end);
% Display the decoded information
if displayFlag && ~isempty(cfgLLAdv)
disp('we are here')
fprintf('Advertising PDU Type: %s\n',cfgLLAdv.PDUType);
fprintf('Advertising Address: %s\n',cfgLLAdv.AdvertiserAddress);
end
% Release System objects
release(freqCompensator)
release(prbDet)
%end
% Release the signal source
release(sigSrc)
%%