公众号【调皮连续波】
【正文】
编辑 | 调皮哥的小助理 审核 | 调皮哥
1、仿真
闲来无事编程序,正好把之前上学时后留下的这个毫米波雷达呼吸心跳检测动态波形绘制拿出来完善一下。
原文的链接是:干货 | IWR1642EVM呼吸心跳原始数据采集与仿真分析(含MATLAB代码和数据),不过代码已经更新了,旧版的不能用了。
感觉效果还可以,先上视频:
整体来说,这个前面的程序改动不大,就是修改了一些之前感觉不对的参数,然后对数据解析部分做了修改,目的是适应当前的数据集。
代码如下图所示:
部分代码片段如下图所示:
%% 本程序仅供学习交流使用
%% 微信公众号:调皮连续波
%% 知乎:调皮连续波
%% 采用平台 IWR1642EVM+DCA1000
%% 时间:2023年03月
%% 功能:单人呼吸心跳原始数据采集与MATLAB仿真
%% ========================================================================
clc;
clear all;
close all;
%% =========================================================================
%% 读取数据部分
numADCSamples = 200; % number of ADC samples per chirp
numADCBits = 16; % number of ADC bits per sample
numRX = 4; % number of receivers
numLanes = 2; % do not change. number of lanes is always 2
isReal = 0; % set to 1 if real only data, 0 if complex data0
chirpLoop = 2;
%% 雷达参数设置
Fs=4e6; %ADC采样率 见配置说明
c=3*1e8; %光速
ts=numADCSamples/Fs;%ADC采样时间
slope=70e12; %调频斜率
B_valid =ts*slope; %有效带宽
detaR=c/(2*B_valid);%距离分辨率
addpath('.\data\man');
addpath('.\data\woman');
%% 读取Bin文件
Filename = 'woman_0.5m_1min_1.bin'; %文件名 用户需要按照自己的文件名修改
fid = fopen(Filename,'r');
adcDataRow = fread(fid, 'int16');
if numADCBits ~= 16
l_max = 2^(numADCBits-1)-1;
adcDataRow(adcDataRow > l_max) = adcDataRow(adcDataRow > l_max) - 2^numADCBits;
end
fclose(fid);
fileSize = size(adcDataRow, 1);
PRTnum = fix(fileSize/(numADCSamples*numRX));
fileSize = PRTnum * numADCSamples*numRX;
adcData = adcDataRow(1:fileSize);
% real data reshape, filesize = numADCSamples*numChirps
if isReal
numChirps = fileSize/numADCSamples/numRX;
LVDS = zeros(1, fileSize);
%create column for each chirp
LVDS = reshape(adcData, numADCSamples*numRX, numChirps);
%each row is data from one chirp
LVDS = LVDS.';
else
numChirps = fileSize/2/numADCSamples/numRX; %含有实部虚部除以2
LVDS = zeros(1, fileSize/2);
%combine real and imaginary part into complex data
%read in file: 2I is followed by 2Q
counter = 1;
for i=1:4:fileSize-1
LVDS(1,counter) = adcData(i) + sqrt(-1)*adcData(i+2);
LVDS(1,counter+1) = adcData(i+1)+sqrt(-1)*adcData(i+3); counter = counter + 2;
end
% create column for each chirp
LVDS = reshape(LVDS, numADCSamples*numRX, numChirps);
%each row is data from one chirp
LVDS = LVDS.';
end
%% 重组数据
adcData = zeros(numRX,numChirps*numADCSamples);
for row = 1:numRX
for i = 1:numChirps
adcData(row, (i-1)*numADCSamples+1:i*numADCSamples) = LVDS(i, (row-1)*numADCSamples+1:row*numADCSamples);
end
end
retVal= reshape(adcData(1, :), numADCSamples, numChirps); %取第二个接收天线数据,数据存储方式为一个chirp一列
process_adc = retVal(:,1:4:end);
%% 距离维FFT(1个chirp)
% figure;
% plot((1:numADCSamples)*detaR,db(abs(fft(process_adc(:,1)))));
% xlabel('距离(m)');
% ylabel('幅度(dB)');
% title('距离维FFT(1个chirp)');
% figure;
% plot(db(abs(fft(process_adc(:,1)))))
%% 相位解缠绕部分
RangFFT = 512;
fft_data_last = zeros(1,RangFFT);
range_max = 0;
adcdata = process_adc;
numChirps = size(adcdata, 2);
%% 距离维FFT
fft_data = fft(adcdata,RangFFT);
fft_data = fft_data.';
fft_data_abs = abs(fft_data);
fft_data_abs(:,1:4)=0; %去除直流分量
real_data = real(fft_data);
imag_data = imag(fft_data);
for i = 1:numChirps
for j = 1:RangFFT %对每一个距离点取相位 extract phase
angle_fft(i,j) = atan2(imag_data(i, j),real_data(i, j));
end
end
% Range-bin tracking 找出能量最大的点,即人体的位置
for j = 1:RangFFT
for i = 1:numChirps % 进行非相干积累
fft_data_last(j) = fft_data_last(j) + fft_data_abs(i,j);
end
if ( fft_data_last(j) > range_max)
range_max = fft_data_last(j);
max_num = j;
end
end
%完整代码需单独联系调皮哥。
2、数据集
之前采集了一大包1642的数据集,大小总共有160组,文件大小7个G,有性别区分、距离远近和时间区分。下图所示仅为一小部分。
上述代码和数据集是完全配合使用的,需要数据集可以找调皮哥。