Python 提取栅格的振幅和频率(50 Hz+;-2 Hz)以及正好位于基波4/5和6/5处的两个非常小的边带
本练习的目的是提取: 1) 基本幅值和角度精确到3或4个有效数字。 2) 基频为50 Hz+-2 Hz的4/5和6/5的边带以及井喷 注:边带由外部逆变器引入,该逆变器在电网电压频率的1/5处调制负载电流振幅。参见下面的规范代码。 根据这些,可以计算电网阻抗(此处不计算) 边带信号小于100 mV需要5%的精度 下面给出了一个规范信号。 到目前为止,我发现锁相环是最好的。 我使用了汉宁窗和FFT陷波滤波器,但没有得到很好的效果。 你认为第一步是非常准确地得到基频吗? 然后搜索正好位于基波4/5和6/5的边带振幅,得到它们的振幅。不需要角度Python 提取栅格的振幅和频率(50 Hz+;-2 Hz)以及正好位于基波4/5和6/5处的两个非常小的边带,python,Python,本练习的目的是提取: 1) 基本幅值和角度精确到3或4个有效数字。 2) 基频为50 Hz+-2 Hz的4/5和6/5的边带以及井喷 注:边带由外部逆变器引入,该逆变器在电网电压频率的1/5处调制负载电流振幅。参见下面的规范代码。 根据这些,可以计算电网阻抗(此处不计算) 边带信号小于100 mV需要5%的精度 下面给出了一个规范信号。 到目前为止,我发现锁相环是最好的。 我使用了汉宁窗和FFT陷波滤波器,但没有得到很好的效果。 你认为第一步是非常准确地得到基频吗? 然后搜索正好位于基波4/5和
`enter code here`
# first create the time signal, which has two side band frequencies +- 1/5 of fundamental
#f_s = 1000 freq range
sample_rate=1000
total_samples=1000
fund_freq = 49.6 # Hz not known
fund_ampl=300
modulating_freq=(1/5)*fund_freq #Hz
modulating_ampl= 0.2 #volts amplitude of side bands will be half
src_v=[0]*total_samples
x=np.linspace(0,1,1000)
for n in range(0,total_samples):
time=n*0.001
src_v[n]= (fund_ampl+ modulating_ampl*sin(2*pi*modulating_freq*time))*np.sin(2*pi*fund_freq*time)\
+ fund_ampl/30*np.sin(2*pi*fund_freq*3*time) + fund_ampl/30*np.sin(2*pi*fund_freq*5*time)
欢迎评论。我将尝试添加带通滤波器,看看是否可以避免锁相现象。我发现我需要大约30000个样本才能获得合理的精度。如果采样率增加,采样时间可以相应减少。
#import maths and plot libraries
import scipy # for FFTs
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy.fftpack import fft, ifft
from scipy import signal
from pylab import *
pi=math.pi
sq2=2**0.5
# create artificial genetated amplitude moduated signal fundamental amplitude signal with 3rd and 5 th harmonics
# The chalange is to accurately determine:
# the frequency and amplitude of the two side band created by fundamental amplitude modulation of fundamental amplitude
fund_freq = 52.6 # Hz s
fund_ampl=300
modulating_freq=(1/5)*fund_freq #Hz
modulating_ampl= .1 #volts ampl ofside bands willbe half
sample_rate=1000
total_time= 24 #sec
sample_time= 1/sample_rate
total_nb_samples=int(sample_rate*total_time)
print(total_nb_samples)
samples_per_cycles=20 #aprox
x=np.linspace(0,total_nb_samples,total_nb_samples)
print(total_time)
print(sample_rate)
print('length =',len(x))
src_v=[0]*total_nb_samples
for n in range(0,total_nb_samples):
time=n*sample_time
src_v[n]= (fund_ampl+ modulating_ampl*sin(2*pi*modulating_freq*time))*np.sin(2*pi*fund_freq*time)\
#+ fund_ampl/10*np.sin(2*pi*fund_freq*3*time) + fund_ampl/15*np.sin(2*pi*fund_freq*5*time)
# 1) Find fundamental frequency
# ------------------------------
# a phase lock loop approach is used to extract fundamental value to three significant figures
# any more direct r faster suggestion welcome ?
#
sync_f = 50 # guess freq, the fundamental signal can be is in range of 45 to 55 Hz
sync_amplitude=230 # guess amplitude value normal range +-30 %
src_sync_90 =[0]*sample_rate # 90 degree sync array initialise at 0
src_sync_0 =[0]*sample_rate # 0 degree sync array initialise at 0
src_v_prod =[0]*sample_rate # product of above
average_v_prod =[0]*sample_rate # running average of above over 1/2 cycle
integral_v_ave_prod=[0]*sample_rate # sum of above
left_side_fr =[0]*sample_rate #side band frequency array
#PI PLL code to extract fundamental freq
integral_gain=0.4
proportional_gain=0.003
average=0.0
error=0.0
amplitude_error=0
sum_vprod=0 # initial sample product of grid signal and src_sync_90
for n in range(0,sample_rate): # phase lock loop to 90 degree
track_freq=sync_f
time=n*sample_time
error= average_v_prod[n-1]*proportional_gain+integral_v_ave_prod[n-1]*integral_gain
error_prop=average_v_prod[n-1]*proportional_gain
error_integrate=integral_v_ave_prod[n-1]*integral_gain
src_sync_90[n]= (sync_amplitude+amplitude_error)*math.cos(2*pi*track_freq*time+error) # phase lock to 90 degree
src_sync_0[n] = sync_amplitude*math.sin(2*pi*track_freq*time+error+sample_time)# zero degree sync
src_v_prod[n] = src_v[n]*src_sync_90[n]/sync_amplitude/2
average = (src_v_prod[n]+src_v_prod[n-int(samples_per_cycles/4)])
integral_v_ave_prod[n]= integral_v_ave_prod[n-1]+average/samples_per_cycles/10
average_v_prod[n]=(integral_v_ave_prod[n]-integral_v_ave_prod[n-int(samples_per_cycles)])/2
freq_dif=0
range_diff=10
for d in range(0,10):
freq_dif += (integral_v_ave_prod[sample_rate-1-d]-integral_v_ave_prod[sample_rate-101-d])*integral_gain*range_diff/2/pi/10
calc_grid_fund_freq=fund_freq# sync_f+freq_dif
print("grid calculated freq= ",round(calc_grid_fund_freq,4))
# 2) Find grid fundamental amplitude
#---------------------------------------------
new_fund_nb_samples=sample_rate#
src_volts_new_fund=signal.resample(src_v,new_fund_nb_samples)
new_sample_time_fund=total_time/new_fund_nb_samples
print("new_sample_time=",round(new_sample_time_fund,4))
ampl_h1_cos=0
ampl_h1_sin=0
sample_range=int(new_fund_nb_samples)
for g in range(0,sample_range):
time=g*new_sample_time_fund
ampl_h1_cos+= src_v[g]*cos(2*pi*calc_grid_fund_freq*time)/(sample_range)
ampl_h1_sin+= src_v[g]*sin(2*pi*calc_grid_fund_freq*time)/(sample_range)
calc_fund_amplitude=300#2*(ampl_h1_cos **2+ampl_h1_sin **2)**0.5
print("calc fund amplitude=",round(calc_fund_amplitude,4))
# 3) Find amplitude of the side bands at 4/5 and 6/5 of fundamental freq
src_v_notch=src_v
calc_left_freq =(4/5)*calc_grid_fund_freq
calc_right_freq=(6/5)*calc_grid_fund_freq
calc_left_period=1/calc_left_freq
calc_right_period=1/calc_right_freq
side_band_samples= int(calc_left_period*total_time/2*sample_rate*60)
print('calc left sideband freq =',calc_left_freq )
print('calc_right_sideband freq =',calc_right_freq)
print('calc left period =',calc_left_period )
print('calc right period=',calc_right_period )
print('side band nb samples=',side_band_samples)
for l in range(0,total_nb_samples):
time=l*sample_time
src_v_notch[l]= src_v[l]#-calc_fund_amplitude*np.sin(2*pi*calc_grid_fund_freq*time) #flter out fundamental from original signal
#src_v_notch=signal.resample(src_v_notch,left_samples_per_40_cycles)
#src_volts_left_sb=signal.resample(src_volts,left_sb_nb_samples)
#new_sample_time_left_freq=total_time/new_left_freq_nb_samples
#print("new_sample_time_left_freq=",round(new_sample_time_left_freq,4))
ampl_left_freq_cos=0
ampl_left_freq_sin=0
ampl_right_freq_cos=0
ampl_right_freq_sin=0
samples=side_band_samples
for s in range(0,samples):
time=s*sample_time
ampl_left_freq_cos += src_v_notch[s]*cos(2*pi*calc_left_freq*time)/samples
ampl_right_freq_cos += src_v_notch[s]*cos(2*pi*calc_right_freq*time)/samples
ampl_left_freq_sin += src_v_notch[s]*sin(2*pi*calc_left_freq*time)/samples
ampl_right_freq_sin += src_v_notch[s]*sin(2*pi*calc_right_freq*time)/samples
left_freq_RMS_ampl =2*(ampl_left_freq_cos **2+ampl_left_freq_sin **2)**0.5
right_freq_RMS_ampl=2*(ampl_right_freq_cos **2+ampl_right_freq_sin **2)**0.5
print("calc left sideband mag RMS V=" ,round( left_freq_RMS_ampl,5))
print("calc right sideband mag RMS V=" ,round(right_freq_RMS_ampl,5))
#plot(x, src_v, label='Grid voltage')
#plot(x,src_v_notch, label='Src volt less fund')
#plt.plot(x,src_sync_90, label='volt sync_90')
#plt.plot(x,src_sync_0, label='Volt sync_0' )
#plt.plot(x,src_v_prod, label='volt product')
#plt.plot(x,average_v_prod, label='Average volt product')
#plt.plot(x,integral_v_ave_prod, label='Integral volt product average')
plt.legend()
plt.grid()
gcf().set_size_inches(10,3)
#show()
"""