Reconstructing Sine wave using Fundamental frequency, Amplitude and zero crossing Points

조회 수: 6 (최근 30일)
Hello Everyone
I am trying to construct a sine wave using the formula sinewave = amplitude*sin(2*pi*F*T) where i know the values of F and amplitude. I want to construct the signal such that it crosses over zero at points that i have precalculated. The main idea is i have PWM line to line voltages from inverter. I did a FFT to get the fundamental frequency and amplitude for one phase. I also calculated the zero crossing points of the PWM signals.
Now i want to create a sine wave from the above data. But my sine wave calculation seems not correct as i am not getting the appropriate amplitude.
Can someone please have a look and help me?
Thanks in advance
Kind regards
%%Script to convert data from <CSV
data = readtable('Terminal Voltage.csv');
t = data{:,1};
x = data{:,2};
y = data{:,3};
z = data{:,4};
hFig1 = figure;
plot(t,x)
title('Line to Line Voltage')
xlabel('t (seconds)')
ylabel('Voltage(V)')
hold on
plot(t,y)
hold on
plot(t,z)
hold off
figure(hFig1);
ax = hFig1.Children;
ln = ax.Children;
xv = ln.XData;
yv = ln(1).YData;
phase=atan2(imag(Y),real(Y))*180/pi; %phase information(Y);
%Fast Fourier Tranform to get the Fundamental Frequency
Ts = mean(diff(xv)); % Sampling Interval
Fs = 1/Ts; % Sampling Frequency
Fn = Fs/2; % Nyquist Frequency
L = numel(xv); % Signal Length
Y = fft(yv)/L; % Fouriet Transform (Normalised)
%Y = fft(yv,[],2)./L; % Fouriet Transform (Normalised) TS
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:numel(Fv); % Index Vector
%Plotting the FFT for only one phase
figure(1);
subplot(2,1,1)
plot(Fv, abs(Y(1, Iv))*2)
grid on
title(' Spectrum Amp vs Freq');
xlabel('Frequency')
ylabel('Amplitude')
%Plotting one phase angle
subplot(2,1,2)
plot(Fv, phase(Iv))
grid on
xlim([0,50])
title(' Spectrum Phase vs Freq');
xlabel('Frequency(Hz)')
ylabel('Phase (rad)')
Ts = mean(diff(t)); % Sampling Interval
Fs = 1/Ts; % Sampling Frequency
NN = 4;
Wn = 0.005; % normalized to Nyquist frequency
[B,A] = butter(NN,Wn);
figure(2)
xs = filtfilt(B,A,x);
plot(t,x,t,xs);legend('Raw','Smoothed');
title(['Data samples at Fs = ' num2str(round(Fs)) ' Hz / Filtered with butterworth LP' ]);
grid on
% zero crossing detection => mesure cycle to cycle time intervals (and derive frequency from time intervals)
threshold = 0;
[t0_pos,s0_pos,t0_neg,s0_neg]= crossing_V7(xs,t,threshold,'linear'); % positive (pos) and negative (neg) slope crossing points
% t0 => corresponding time (x) values
% s0 => corresponding function (y) values , obviously they must be equal to "threshold"
figure(3)
plot(t,xs,t0_pos,s0_pos,'+r',t0_neg,s0_neg,'+g','linewidth',2,'markersize',12);grid on
legend('signal','positive slope crossing points','negative slope crossing points');
xlabel('Time (s)');
time_interval = diff(t0_pos); % cycle to cycle time intervals
%% Constructing sinus waveformn over the zero crossing points with Fundamental Frequency and Amplitude
% select crossing points for t > 0.05 s (don't bother with initial
% transient)
t0_pos2 = t0_pos(t0_pos>0.05);
t0_neg2 = t0_neg(t0_neg>0.05);
t0_all = unique(sort([t0_pos2 t0_neg2])); % merge all crossing points , sort them ascending order and keep only unique values
amplitude = 251.4; % Amplitude calculated by FFT analysis
sign = 1;
F = 12.64; %Fundamental frequency calulated above in FFT
for ci = 1:length(t0_all)-1
t_start = t0_all(ci);
t_end = t0_all(ci+1);
ind = find(t>=t_start & t<t_end);
tt = t(ind);
T = linspace(0,pi,length(ind));
xss_tmp = sign*amplitude*sin(2*pi*F*T);
sign = -1*sign; % alternate half wave sinus absolute phase
end
figure(3)
plot(t,x,T,xss_tmp,t0_pos,s0_pos,'+r',t0_neg,s0_neg,'+g','linewidth',2,'markersize',12);grid on
legend('signal','sinus approx','positive slope crossing points','negative slope crossing points');
xlabel('Time (s)');
function [t0_pos,s0_pos,t0_neg,s0_neg] = crossing_V7(S,t,level,imeth)
% [ind,t0,s0,t0close,s0close] = crossing_V6(S,t,level,imeth,slope_sign) % older format
% CROSSING find the crossings of a given level of a signal
% ind = CROSSING(S) returns an index vector ind, the signal
% S crosses zero at ind or at between ind and ind+1
% [ind,t0] = CROSSING(S,t) additionally returns a time
% vector t0 of the zero crossings of the signal S. The crossing
% times are linearly interpolated between the given times t
% [ind,t0] = CROSSING(S,t,level) returns the crossings of the
% given level instead of the zero crossings
% ind = CROSSING(S,[],level) as above but without time interpolation
% [ind,t0] = CROSSING(S,t,level,par) allows additional parameters
% par = {'none'|'linear'}.
% With interpolation turned off (par = 'none') this function always
% returns the value left of the zero (the data point thats nearest
% to the zero AND smaller than the zero crossing).
%
% [ind,t0,s0] = ... also returns the data vector corresponding to
% the t0 values.
%
% [ind,t0,s0,t0close,s0close] additionally returns the data points
% closest to a zero crossing in the arrays t0close and s0close.
%
% This version has been revised incorporating the good and valuable
% bugfixes given by users on Matlabcentral. Special thanks to
% Howard Fishman, Christian Rothleitner, Jonathan Kellogg, and
% Zach Lewis for their input.
% Steffen Brueckner, 2002-09-25
% Steffen Brueckner, 2007-08-27 revised version
% Copyright (c) Steffen Brueckner, 2002-2007
% brueckner@sbrs.net
% M Noe
% added positive or negative slope condition
% check the number of input arguments
error(nargchk(1,4,nargin));
% check the time vector input for consistency
if nargin < 2 | isempty(t)
% if no time vector is given, use the index vector as time
t = 1:length(S);
elseif length(t) ~= length(S)
% if S and t are not of the same length, throw an error
error('t and S must be of identical length!');
end
% check the level input
if nargin < 3
% set standard value 0, if level is not given
level = 0;
end
% check interpolation method input
if nargin < 4
imeth = 'linear';
end
% make row vectors
t = t(:)';
S = S(:)';
% always search for zeros. So if we want the crossing of
% any other threshold value "level", we subtract it from
% the values and search for zeros.
S = S - level;
% first look for exact zeros
ind0 = find( S == 0 );
% then look for zero crossings between data points
S1 = S(1:end-1) .* S(2:end);
ind1 = find( S1 < 0 );
% bring exact zeros and "in-between" zeros together
ind = sort([ind0 ind1]);
% and pick the associated time values
t0 = t(ind);
s0 = S(ind);
if strcmp(imeth,'linear')
% linear interpolation of crossing
for ii=1:length(t0)
%if abs(S(ind(ii))) > eps(S(ind(ii))) % MATLAB V7 et +
if abs(S(ind(ii))) > eps*abs(S(ind(ii))) % MATLAB V6 et - EPS * ABS(X)
% interpolate only when data point is not already zero
NUM = (t(ind(ii)+1) - t(ind(ii)));
DEN = (S(ind(ii)+1) - S(ind(ii)));
slope = NUM / DEN;
slope_sign(ii) = sign(slope);
t0(ii) = t0(ii) - S(ind(ii)) * slope;
s0(ii) = level;
end
end
end
% extract the positive slope crossing points
ind_pos = find(sign(slope_sign)>0);
t0_pos = t0(ind_pos);
s0_pos = s0(ind_pos);
% extract the negative slope crossing points
ind_neg = find(sign(slope_sign)<0);
t0_neg = t0(ind_neg);
s0_neg = s0(ind_neg);
end

답변 (0개)

카테고리

Help CenterFile Exchange에서 Signal Operations에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by