- 正常波形与噪声波形的区别
正常方波信号的特征:一个周期内的数据按时间单调变化,则仅有2种情况:① 数据在上升或下降边沿时,其两边的数据则是一边大一边小(如下图中C和D点);② 数据处于平稳时,则两边大小差不多相等(如下图中B点)。
噪声波形的特征:噪声左右两边的数据,均比噪声的最高点小(如下图中A)。
- 提取噪声的步骤
1. 假设参考点A为噪声的最高点,其电压为VA,如上图中A点;
2. 在其左右两边各取不超过半个周期的采样点数据;(可使用噪声峰值A的左右各15个点作为比较,因为一个高或低电平的采样点数为50个点);
3. 获取步骤2中噪声A左右两边数据的最小值电压Vminl和Vminr;
4. 根据实际特点,设置A点与步骤3中最小值的电压差为Vthreshold=0.1V。即A与最小值超过0.1V,代表A为噪声点。
(matlab代码在最底下)
- 使用matlab提取的图片最终效果如下:
- 使用matlab提取到噪声的位置记录如下:
Start time 2022-02-15 20:12:56.
0.bin UP index is 08388602.
0.bin Down index is 08389640.
0.bin UP index is 09723078.
1.bin Down index is 08388607.
1.bin Down index is 09830547.
End time 2022-02-15 20:13:22.
- Matlab代码如下:
% 使用Matlab提取ADC采样数据中的噪声
% 本代码实现对ADC数据的噪声提取,并记录噪声的数据编号以及存储噪声图片
% 采样频率为一个波形周期采样100个点
%
% 提取噪声的方法如下:
% 1. 假设参考点A为噪声的最高电压Vmax
% 2. 那么其左右两边上一定点数的最小值电压Vminl和Vminr必小于Vmax(本处用A的左右各Number_left_right = 15个点,因为一个高或低电平为50个点)
% 3. 根据实际特点,设置Vthreshold=0.1V
%
% 使用时可能需要修改的内容
% 1. 须根据实际文件夹的路径进行修改folderpath
% 2. 须根据实际噪声修改Vminl和Vminr
% 3. 须根据实际波形的噪声特点修改Vthreshold
% 4. 须根据实际波形的周期点数,修改Number_left_right
% 5. 须根据实际数据文件的数量,file_start_serial和file_end_serial
% 6. 须根据实际数据的名称修改'rBufPt_'字符串
%
% 运行后的结果
% 1. 运行完成后,会在folderpath文件夹下生成一个记录噪声位置的log.txt以及存放噪声图片的picture
% 清理命令行中的内容
clc;
% 清理内存变量
clear;
% 手动设置文件路径
folderpath = 'E:\data\tmp\';
% 自动新建用于存放图片的文件夹
picfolder = [folderpath,'picture'];
mkdir(picfolder);
% 手动设置2大参数
Vthreshold = 0.1;
Number_left_right = 15;
% 自动在log.txt中记录启动时间
fid_log=fopen([folderpath,'\log.txt'],'at+');%写入文件路径
fprintf(fid_log,'Start time %s.\n',datestr(now,31));
fclose(fid_log);
% 手动设置数据文件编号的范围:文件读到最后一个数据文件
file_start_serial = 0;
file_end_serial = 1;
for file_serial = file_start_serial : file_end_serial
% 在命令行中打印当前file_serial的值和启动时间,方便查看当前运行进程
fprintf('NO %d.\n',file_serial);
fprintf('Percent %d%%.\n',file_serial/file_end_serial*100);
fprintf('%s.\n',datestr(now,31));
% 打开文档,并读取数据到内存中
fid_data = fopen([folderpath,'/rBufPt_',num2str(file_serial),'.bin'],'rb');
[rBuf] = fread(fid_data);
fclose(fid_data);
% 仅读取1组数据,每隔8个字节取数据
rBuf1 = rBuf(1:8:end);
% 将有效数字量转换成模拟量
parfor i = 1:length(rBuf1)
if rBuf1(i)>127
rBuf1(i) = rBuf1(i) - 256 ;
end
rBuf1(i) = (rBuf1(i) * 8.29)/1000 ;
rBuf1(i)=rBuf1(i) + 0.9 ;
end
% 启动秒表计时器
tic
%读取有效模拟量的长度
length_rBuf1 = length(rBuf1);
%设置变量,用于代表上次出现噪声信号的index
last_log_index = 0;
% STEP = 1,对数据从头到尾进行处理(4200000前采到的数据不正常,不使用)
for index = 4200000+Number_left_right : length_rBuf1-Number_left_right
% 读取被计算点的左右两边各15点的最大值
max_buf1 = max(rBuf1(index-Number_left_right : index));
max_buf2 = max(rBuf1(index : index+Number_left_right));
% 如果某点两边的最大值均比此点值大0.1,那么认为发生噪声
if (rBuf1(index)+Vthreshold < max_buf1)
if(rBuf1(index)+Vthreshold < max_buf2)
%如果与上次保存的数据在图片中位置相差不大,不保存(比如不到50个点)
if index > last_log_index +50
last_log_index = index;
% 将Noise的编号记录到log中
fid_log=fopen([folderpath,'/log.txt'],'at+');
fprintf(fid_log,'%d.bin Down index is %.8d.\n',file_serial,index);
fclose(fid_log);
% 将噪声图片保存
figure(1);
plot(rBuf1);
legend('LVDS-CH4');
hold on;
xstart = index - 1000;
xend = index + 1000;
xlim([xstart xend]);
saveas(gcf,[picfolder,'/rBufPt_',num2str(file_serial),'_',num2str(index),'.jpg']);
hold off;
end
end
end
% 读取被计算点的左右两边各15点的最小值
min_buf1 = min(rBuf1(index-Number_left_right : index));
min_buf2 = min(rBuf1(index : index+Number_left_right));
% 如果某点两边的最大值均比此点值大0.1,那么认为发生噪声
if (rBuf1(index) >min_buf1+Vthreshold)
if(rBuf1(index) >min_buf2+Vthreshold)
%如果与上次保存的数据在图片中位置相差不大,不保存(比如不到50个点)
if index > last_log_index +50 %如果与上次保存的数据在图片中位置相差不大,不保存
last_log_index = index;
% 将Noise的编号记录到log中
fid_log=fopen([folderpath,'/log.txt'],'at+');%写入文件路径
fprintf(fid_log,'%d.bin UP index is %.8d.\n',file_serial,index);
fclose(fid_log);
% 将噪声图片保存
figure(1);
plot(rBuf1);
legend('LVDS-CH4');
hold on;
xstart = index - 1000;
xend = index + 1000;
xlim([xstart xend]);
saveas(gcf,[picfolder,'/rBufPt_',num2str(file_serial),'_',num2str(index),'.jpg']);
hold off;
end
end
end
end
% 从秒表读取已用时间
tfly = toc;
% 在命令行打印单次运行的耗时
tfly
end
% 任务结束,发出火车叫声
% for i = 1:10
% load train;
% sound(y,Fs);
% end
% 在log中记录此程序结束的日期与时间
fid_log=fopen([folderpath,'/log.txt'],'at+');%写入文件路径
fprintf(fid_log,'End time %s.\n',datestr(now,31));
fclose(fid_log);
% 程序运行结束,60s后关闭电脑
% system('shutdown -s -t 60')