电机的输入电压和电流波形上叠加的有高频信号,在进行计算前,如果需要求得有效值,则必须进行整周期判定。这里提供了一个Matlab函数可以做这个事情,它会把U/I信号中的一个完整的周期相关采样数据摘出来,存储为独立的文件。需要三个数据通道——电压、电流、转子转速,另外的一个额外参数是电机的极对数,实际处理时用到了一些简化处理,如果发现最终输出的不是一个完整周期,可以调整特定的门限值。
没啥技术含量,纯粹是堆代码:
%{
文件: engine_input_vol_curr_freq_calc_from_sample_data.m
功能: 识别电机参数
编制: 冯旭辉( https://www.zhihu.com/people/twicave )
版本: V0.1.20230504
V1.3.20230424
原始文件格式:
double column: sampletime: sample_value
%}
function [] = engine_input_vol_curr_freq_calc_from_sample_data()
clear all
offline_engine_params_recognize_inner(5);
offline_engine_params_recognize_inner(25);
offline_engine_params_recognize_inner(45);
offline_engine_params_recognize_inner(49);
offline_engine_params_recognize_inner(58);
offline_engine_params_recognize_inner(66);
offline_engine_params_recognize_inner(70);
offline_engine_params_recognize_inner(81);
end
function [] = offline_engine_params_recognize_inner(snOfDataFile)
%%清空工作区
snOfDataFile
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 参数设置区
%%
memo = '35Hz信号'; %图表备注
filepath = 'D:\fengxh\git2023\20230504_示波器数据解析'; % 数据文件目录
freqFilename = 'C1vi,ai,s%05d.trc.txt';
UFilename = 'C2vi,ai,s%05d.trc.txt';
IFilename = 'C3vi,ai,s%05d.trc.txt';
ResultFilename = 'C3vi,ai,s%05d.tgt.txt';
UFullCycle = "V%05d_FullCycle.txt";
IFullCycle = "I%05d_FullCycle.txt";
jds=3; %电机极对数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 原始数据的读取和截取抽样等过程
%% 读取单个txt文件
%% => rawData原始数据 | rawDataSize 数据点数 | idx序号 自动识别,\n这两类数据
filename = sprintf(freqFilename, snOfDataFile);
fullpathname = '';
fullpathname = strcat(fullpathname, filepath);
fullpathname = strcat(fullpathname, '\');
fullpathname = strcat(fullpathname, filename);
rawData= csvread(fullpathname, 0,0);
rawDataSize = size(rawData,1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 获取实际转速
[upCycle1, downCycle1, up2Cycle1, down2Cycle1, min1Cycle1, max1Cycle1, min2Cycle1, max2Cycle1, dtCycle1] = GetHeadOfWave(1, rawData, rawDataSize);
%找到了四个沿儿
ptSpanOfRealRPM = up2Cycle1 - upCycle1;
timeSpanOfRealRPM = rawData(up2Cycle1,1) - rawData(upCycle1,1);
ptSpanOfRealRPM
timeSpanOfRealRPM
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 查找电流通道的完整区间 - 整周期
filename = sprintf(IFilename, snOfDataFile);
fullpathname = '';
fullpathname = strcat(fullpathname, filepath);
fullpathname = strcat(fullpathname, '\');
fullpathname = strcat(fullpathname, filename);
rawData = csvread(fullpathname, 0, 0);
rawDataSize = size(rawData,1);
currData = rawData;
currDataSize = rawDataSize;
[upCycle1, downCycle1, up2Cycle1, down2Cycle1, min1Cycle1, max1Cycle1, min2Cycle1, max2Cycle1, dtCycle1] = GetHeadOfWave(1, currData, currDataSize);
%依据dt,first edge,ptSpanOfRealRPM找到对应的精确的下一个周期。
up2Cycle2 = up2Cycle1+floor(ptSpanOfRealRPM/jds/2); %2是半周期
while(up2Cycle2<currDataSize)
[upCycle2, downCycle2, up2Cycle2, down2Cycle2, min1Cycle2, max1Cycle2, min2Cycle2, max2Cycle2, dtCycle2] = GetHeadOfWave(up2Cycle2, currData, currDataSize);
if((dtCycle2 - dtCycle1)/dtCycle1 < 0.2)
break;
end
end
ptSpanOfCycleCurr =upCycle2 - upCycle1;
timeSpanOfCyleCurr= rawData(upCycle2,1) - rawData(upCycle1,1);
if((timeSpanOfRealRPM/3 - timeSpanOfCyleCurr)/timeSpanOfCyleCurr) > 0.65
%依据dt,first edge,ptSpanOfRealRPM找到对应的精确的下一个周期。
up2Cycle2 = up2Cycle2+floor(ptSpanOfCycleCurr/2); %2是半周期
while(up2Cycle2<currDataSize)
[upCycle2, downCycle2, up2Cycle2, down2Cycle2, min1Cycle2, max1Cycle2, min2Cycle2, max2Cycle2, dtCycle2] = GetHeadOfWave(up2Cycle2, currData, currDataSize);
if((dtCycle2 - dtCycle1)/dtCycle1 < 0.1)
break;
end
end
ptSpanOfCycleCurr =upCycle2 - upCycle1;
timeSpanOfCyleCurr = rawData(upCycle2,1) - rawData(upCycle1,1);
end
%截断
currFullCycle = rawData(upCycle1:upCycle2);
filename = sprintf(IFullCycle, snOfDataFile);
fullpathname = '';
fullpathname = strcat(fullpathname, filepath);
fullpathname = strcat(fullpathname, '\');
fullpathname = strcat(fullpathname, filename);
csvwrite(fullpathname, currFullCycle);
t = rawData(upCycle1:upCycle2, 1);
y = rawData(upCycle1:upCycle2, 2);
plot(t, y);
ptSpanOfCycleCurr
timeSpanOfCyleCurr
filename = sprintf(UFilename, snOfDataFile);
fullpathname = '';
fullpathname = strcat(fullpathname, filepath);
fullpathname = strcat(fullpathname, '\');
fullpathname = strcat(fullpathname, filename);
rawData = csvread(fullpathname, 0, 0);
rawDataSize = size(rawData,1);
volData = rawData;
volDataSize = rawDataSize;
%截断
volFullCycle = rawData(upCycle1:upCycle2);
filename = sprintf(IFullCycle, snOfDataFile);
fullpathname = '';
fullpathname = strcat(fullpathname, filepath);
fullpathname = strcat(fullpathname, '\');
fullpathname = strcat(fullpathname, filename);
csvwrite(fullpathname, volFullCycle);
%<the end>
end
% 在rawData[idxOfHead:rawDataSize]中,在基波波形上找到过零点的前两组小峰
function [edgeUp,edgeDown,edgeUp2,edgeDown2, min1, max1, min2, max2, dt] = GetHeadOfWave(idxOfHead, rawData, rawDataSize)
edgeUp = -1;
edgeDown = -1;
edgeUp2 = -1;
edgeDown2 = -1;
for n=idxOfHead:rawDataSize-1
if(rawData(n,2)<0) && (rawData(n+1,2)>=0)
if(edgeUp == -1)
edgeUp = n;
else
edgeUp2 = n;
if(edgeDown2 ~= -1)
break;
end
end
else
if(rawData(n,2)>=0) && (rawData(n+1,2)<0)
if(edgeDown == -1)
edgeDown = n;
else
edgeDown2 = n;
if(edgeUp2 ~= -1)
break;
end
end
end
end
end
min1 = -1;
max1 = -1;
min2 = -1;
max2 = -1;
dt = -1;
if(edgeDown<edgeUp) %下降沿first.
min1 = edgeDown;
for n=edgeDown:edgeUp %get first min
if rawData(min1,2)> rawData(n, 2)
min1 = n;
end
end
max1 = edgeUp;
for n = edgeUp: edgeDown2 %get first max
if rawData(max1, 2)< rawData(n, 2)
max1 = n;
end
end
min2 = edgeDown2;
for n=edgeUp2:edgeDown2 %get first max
if rawData(min2, 2)>rawData(n,2)
min2 = n;
dt = min2 - min1;
end
end
else
max1 = edgeUp;
for n=edgeUp:edgeDown %get first max
if rawData(max1,2)< rawData(n, 2)
max1 = n;
end
end
min1 = edgeDown;
for n = edgeDown: edgeUp2 %get first min
if rawData(min1, 2)> rawData(n, 2)
min1 = n;
end
end
max2 = edgeUp2;
for n=edgeUp2:edgeDown2 %get first max
if rawData(max2, 2)<rawData(n,2)
max2 = n;
dt = max2 - max1;
end
end
end
end