信号处理-转速计算

1.   转速自定义计算

matlab 的tachorpm函数解析

function [rpm, t] = tachorpmauto(signal, fs, ppr, varargin)
% MY_TACHORPM 自定义实现的转速计算函数
% 输入参数:
%   signal  : 转速计脉冲信号(一维数组)
%   fs      : 采样率 (Hz)
%   ppr     : 每转脉冲数 (Pulses Per Revolution)
% 可选参数:
%   'EdgeType'      : 边沿类型 ('rising'(默认)/'falling'/'both')
%   'MinPeakHeight' : 最小峰值高度阈值(默认:信号最大值的50%)
%   'MinPeakDist'   : 最小脉冲间隔(默认自动计算)
% 输出参数:
%   rpm : 转速序列 (RPM)
%   t   : 时间序列 (秒)

% 参数解析
p = inputParser;
addRequired(p, 'signal', @isvector);
addRequired(p, 'fs', @isscalar);
addRequired(p, 'ppr', @isscalar);
addParameter(p, 'EdgeType', 'rising', @(x) any(validatestring(x, {'rising','falling','both'})));
addParameter(p, 'MinPeakHeight', [], @isscalar);
addParameter(p, 'MinPeakDist', [], @isscalar);
parse(p, signal, fs, ppr, varargin{:});

% 转换为行向量
signal = signal(:)'; 
edgeType = lower(p.Results.EdgeType);
minPeakHeight = p.Results.MinPeakHeight;
minPeakDist = p.Results.MinPeakDist;

%% 1. 信号预处理:移动平均滤波
windowSize = 5;
filtered = movmean(signal, windowSize);

%% 2. 自动计算阈值
if isempty(minPeakHeight)
    maxVal = max(filtered);
    minPeakHeight = 0.5 * maxVal;
end

%% 3. 计算最小脉冲间隔(基于最大预期RPM)
if isempty(minPeakDist)
    maxRpm = 6000; % 预期最大转速
    minInterval = 60/(maxRpm * ppr); % 最短时间间隔(s)
    minPeakDist = floor(minInterval * fs); % 转换为采样点数
end

%% 4. 脉冲检测
[locs_rise, locs_fall] = deal([]);

% 检测上升沿
if contains(edgeType, {'rising','both'})
    [~, locs_rise] = findpeaks(filtered, 'MinPeakHeight',minPeakHeight,...
                                      'MinPeakDistance',minPeakDist);
end

% 检测下降沿
if contains(edgeType, {'falling','both'})
    [~, locs_fall] = findpeaks(-filtered, 'MinPeakHeight',-minPeakHeight,...
                                       'MinPeakDistance',minPeakDist);
end

% 合并并排序脉冲位置
locs = sort([locs_rise, locs_fall]);

% 检查有效脉冲数
if numel(locs) < 2
    error('检测到不足2个脉冲,无法计算转速!');
end

%% 5. 计算RPM
intervals = diff(locs)/fs; % 脉冲间隔(秒)
rpm_pulses = 60./(intervals * ppr); % 脉冲间RPM

% 脉冲时间点(取后一个脉冲时刻)
t_pulses = locs(2:end)/fs; 

%% 6. 插值到原始时间轴
t = (0:length(signal)-1)/fs; % 完整时间序列
rpm = interp1(t_pulses, rpm_pulses, t, 'nearest', 'extrap');   % nearest  linaer  spline

end


使用方法测试

%%  ------渥太华数据 ------
load I-C-2.mat;
fs= 200000;
x = Channel_1(1:fs*10);
x = x;
speed = Channel_2(1:fs*10);
t = (0:length(x)-1) / fs ;
%%  计算转速
rpm= tachorpm(speed, fs ,'FitPoints', 50, 'PulsesPerRev', 1024) ;
% 自定义函数
ppr = 1024 ;  %%  每转 2 个脉冲
rpm1 = tachorpmauto(speed,fs, ppr,'EdgeType', "rising")'; % , "rising"
% rpm1 = tachorpm_auto(speed,fs, ppr,'MinPeakHeight')'
%%  ------tachorpm 测试------
levels = statelevels(speed);
figure()
subplot(2,1,1)
plot(rpm1) ;
title('tachorpm-auto')
window_length = 51; % 根据数据调整
poly_order = 3;
%% rpm_smoothed = sgolayfilt(rpm1, poly_order, window_length);
% rpm_smoothed1 = sgolayfilt(rpm1, poly_order, window_length);
% 数据处理
rpm_smoothed = rpm1;
rpmtemp1 = zeros(length(rpm_smoothed),1);
N11 = length(rpm_smoothed);
for  i = 1: length(rpm_smoothed)
    if(i<(N11 -1024))
        rpmtemp1(i) = mean(rpm_smoothed(i:i+1024));
    else
        rpmtemp1(i) = mean(rpm_smoothed(i:end));
    end
    
end
rpm_smoothed= rpmtemp1;
N11 = length(rpm_smoothed);
for  i = 1: length(rpm_smoothed)
    if(i<(N11 -1024))
        rpmtemp1(i) = mean(rpm_smoothed(i:i+1024));
    else
        rpmtemp1(i) = mean(rpm_smoothed(i:end));
    end
    
end
figure()
plot(rpm)
hold on;
plot(rpmtemp1)
legend('tachorpm', 'tachorpm-auto')
title('对比')

使用方式:


function [rpm, t] = tachorpmauto(signal, fs, ppr, varargin)
% MY_TACHORPM 自定义实现的转速计算函数
% 输入参数:
%   signal  : 转速计脉冲信号(一维数组)
%   fs      : 采样率 (Hz)
%   ppr     : 每转脉冲数 (Pulses Per Revolution)
% 可选参数:
%   'EdgeType'      : 边沿类型 ('rising'(默认)/'falling'/'both')
%   'MinPeakHeight' : 最小峰值高度阈值(默认:信号最大值的50%)
%   'MinPeakDist'   : 最小脉冲间隔(默认自动计算)
% 输出参数:
% rpm : 转速序列 (RPM)  %  t : 时间序列 (秒)

% 参数解析
p = inputParser;
addRequired(p, 'signal', @isvector);
addRequired(p, 'fs', @isscalar);
addRequired(p, 'ppr', @isscalar);
addParameter(p, 'EdgeType', 'rising', @(x) any(validatestring(x, {'rising','falling','both'})));
addParameter(p, 'MinPeakHeight', [], @isscalar);
addParameter(p, 'MinPeakDist', [], @isscalar);
parse(p, signal, fs, ppr, varargin{:});

% 转换为行向量
signal = signal(:)'; 
edgeType = lower(p.Results.EdgeType);
minPeakHeight = p.Results.MinPeakHeight;
minPeakDist = p.Results.MinPeakDist;

%% 1. 信号预处理:移动平均滤波
windowSize = 5;
filtered = movmean(signal, windowSize);

%% 2. 自动计算阈值
if isempty(minPeakHeight)
    maxVal = max(filtered);
    minPeakHeight = 0.5 * maxVal;
end

%% 3. 计算最小脉冲间隔(基于最大预期RPM)
if isempty(minPeakDist)
    maxRpm = 6000; % 预期最大转速
    minInterval = 60/(maxRpm * ppr); % 最短时间间隔(s)
    minPeakDist = floor(minInterval * fs); % 转换为采样点数
end

%% 4. 脉冲检测
[locs_rise, locs_fall] = deal([]);

% 检测上升沿
if contains(edgeType, {'rising','both'})
    [~, locs_rise] = findpeaks(filtered, 'MinPeakHeight',minPeakHeight,...
                                      'MinPeakDistance',minPeakDist);
end

%% -----自定义实现  4.0 脉冲检测 - 上------
tempx = zeros(1,100);
Li=1;
for i =2:(length(filtered)-1)
    temp11 = filtered(i) - filtered(i-1);
    temp12= filtered(i+1) - filtered(i);
    
    if(temp11 >= 0 && temp12< 0 &&filtered(i)>0.8)
        if(Li>1)
            if((i-tempx(Li-1))<5)
                tempx(Li-1) = i;   %  去除邻近值
            else
                tempx(Li) = i;
                Li = Li+ 1;
            end
        else
            tempx(Li) = i;
            Li = Li+ 1;
        end
    end
end 
%%  去除邻近值
% for j = 2:(length(tempx)-1)
%     tempx1 = tempx(j) - tempx(j-1);
%     if(tempx1<5)
%         tempx(j-1) =0;
%     end
% 
% end

tempxx =sort(tempx);
recordnoequal = zeros(1,500);
N3= 1;
N1=1;  
N2 = 1;
for j= 1:length(locs_rise)

    boolx11 = ismember(locs_rise(j), tempx);
    if(~boolx11)
        recordnoequal(N3) =locs_rise(j);
        N3 = N3  + 1  ;
    end

end

asdfg= 1;
%% -----自定义实现4.0 脉冲检测 -下------

% 检测下降沿
if contains(edgeType, {'falling','both'})
    [~, locs_fall] = findpeaks(-filtered, 'MinPeakHeight',-minPeakHeight,...
                                       'MinPeakDistance',minPeakDist);
end

% 合并并排序脉冲位置
locs = sort([locs_rise, locs_fall]);

% 检查有效脉冲数
if numel(locs) < 2
    error('检测到不足2个脉冲,无法计算转速!');
end
%%  ---- 测试---
locs = tempxx;

%% 5. 计算RPM
intervals = diff(locs)/fs; % 脉冲间隔(秒)
rpm_pulses = 60./(intervals * ppr); % 脉冲间RPM

% 脉冲时间点(取后一个脉冲时刻)
t_pulses = locs(2:end)/fs; 

%% 6. 插值到原始时间轴
t = (0:length(signal)-1)/fs; % 完整时间序列
rpm = interp1(t_pulses, rpm_pulses, t, 'nearest', 'extrap');   % nearest  linaer  spline

end

测试计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值