Python 提取栅格的振幅和频率(50 Hz+;-2 Hz)以及正好位于基波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和

本练习的目的是提取: 1) 基本幅值和角度精确到3或4个有效数字。 2) 基频为50 Hz+-2 Hz的4/5和6/5的边带以及井喷

注:边带由外部逆变器引入,该逆变器在电网电压频率的1/5处调制负载电流振幅。参见下面的规范代码。 根据这些,可以计算电网阻抗(此处不计算)

边带信号小于100 mV需要5%的精度

下面给出了一个规范信号。 到目前为止,我发现锁相环是最好的。 我使用了汉宁窗和FFT陷波滤波器,但没有得到很好的效果。 你认为第一步是非常准确地得到基频吗? 然后搜索正好位于基波4/5和6/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()
"""