實驗要求
在第一次作業中的第二小題,練習了根據信號的波形寫出對應信號的表達式。但在實際中,我們觀測到的信號往往是在示波器上的波形,此時該如何獲得這些波形的數學表達式?
測量波形的示波器
本質上講,實際信號中都會帶有隨機性,是沒有確定的數學表達式的。但在某些情況下,我們是預先知道信號的類型的,比如正弦波,但不知道信號的一些參數。例如幅值、頻率和相位。如果這些參數知道了,便可以寫出對應的信號數學表達式了。在這種情況下,從觀測到的帶有噪聲的信號波形中回覆處信號,則屬於信號參數估計的內容了。
部分電子元器件
在實際應用中,信號的參數往往非常重要。下面舉一個例子:如果手邊只有一個萬用表,但沒有能夠測量電容、電感的RCL橋,爲了想知道一個電容器件的準確容值,可以將待測的電容與一個電阻串聯在一起。電阻的阻值可以使用萬用表精確測量。使用一個信號源產生一個正弦波信號施加在RC串聯電路上,使用示波器同時測量信號源的信號以及RC分壓後的信號。
利用RC測量電子器件參數電路
根據電路原理,可以知道上述電路穩態輸入輸出正弦信號之間的關係如下:
實測測量電路和示波器
因此,輸入輸出正弦信號的幅度之比爲:
輸入輸出正弦信號的相位差爲:
所以,只要能夠測量出U,V兩個正弦信號的幅度或者相位,頻率,再加上已知電阻阻值R\1.,便可以計算出來待測電容的容值。
已知上面的串聯電路中的電阻\nR\1.=1009歐姆。示波器顯示波形的數值可以通過已經存儲在CH12.MAT中,數值的採樣時間間隔fs=10微妙。
示波器採集的數值波形
請根據以上分析,求出待測電容\nC\1.的容值是多少。
提示:
- 在MATLAB中通過load()命令讀取CH12.MAT中的數據;
- ch12(:,1) 是V的數據, ch12(:,2)是U的數據。
- 使用MATLAB中fit命令來估計數據中的參數。
f = fit(x,y,‘fourier1’) - 上面fit命令輸出 f(x)=a0+a1cos(xw)+b1sin(xw)
中的a0,a1,b1,w等參數。
使用MATLAB計算出現的問題
使用MATLAB計算步驟
- 調入數據並繪製波形圖
load ch12'
t = linspace(0, 1400*10e-6,1400)'
plot(t,ch12(:,1), t, ch12(:, 2))'
兩個測量數據通道的波形圖
(2)使用MATLAB 計算正弦波形參數
f1 = fit(t, ch12(:,1), 'fourier1')'
f2 = fit(t, ch12(:,2), 'fourier1')
f1: a0:119.1442, a1:-1.6132, b1:27.3382, omiga:2481
f2: a0:150.0722, a1:64.1255, b1:43.5524, omiga:2481
2. 使用MATLAB計算出現的問題
使用上述參數利用兩個公式計算,會出現1.5倍的差異。
相關的矢量方差如下圖所示:
MATLAB計算出的參數的問題
從MATLAB通過剪切板得到數據
首先在MATLAB命令窗口使用如下命令將CH12數據拷貝到WINDOWS剪切板。
cc(ch12)
然後通過下面的PYTHON程序將剪切板上的數據轉換成兩個數組,分別對應的輸出和輸入信號的採集的數據。
pastestr = clipboard.paste().strip('[').strip(']').split(';')
data1=[]
data2=[]
for s in pastestr:
ss = s.split(' ')
data1.append(int(ss[0]))
data2.append(int(ss[1]))
plt.plot(data1)
plt.plot(data2)
tspsave('CH12', ch1=data1, ch2=data2)
printf('\a')
plt.show()
進行函數擬合和參數計算
兩個通道正弦波及其FIT曲線
程序代碼如下:
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST2.PY -- by Dr. ZhuoQing 2020-02-28
#
# Note:
#============================================================
from headm import *
from scipy.optimize import leastsq
ch1, ch2 = tspload('CH12', 'ch1', 'ch2')
#------------------------------------------------------------
def make_sine_graph( params, xData):
"""
take amplitudes A and phases P in form [ C, A0, A1, A2, ..., An, P0, P1,..., Pn ]
and construct function f = C +A0 sin( w t + P0) + A1 sin( 2 w t + Pn ) + ... + An sin( n w t + Pn )
and return f( x )
"""
fr = params[0]
C = params[1]
npara = params[2:]
lp =len( npara )
amps = npara[ : lp // 2 ]
phases = npara[ lp // 2 : ]
fact = range(1, lp // 2 + 1 )
return [ sum( [ a * sin( 2 * pi * x * f * fr + p ) for a, p, f in zip( amps, phases, fact ) ]) + C for x in xData ]
def sine_residuals( params , xData, yData):
yTh = make_sine_graph( params, xData )
diff = [ y - yt for y, yt in zip( yData, yTh ) ]
return diff
def sine_fit_graph( xData, yData, freqGuess=100., dcGuess=100,sineorder = 3 ):
aStart = sineorder * [ 0 ]
aStart[0] = max( yData )
pStart = sineorder * [ 0 ]
result, _ = leastsq( sine_residuals, [ freqGuess, dcGuess ] + aStart + pStart, args=( xData, yData ) )
return result
#------------------------------------------------------------
if __name__ == '__main__':
ch1 = [c / 255 for c in ch1]
ch2 = [c / 255 for c in ch2]
t = linspace(0, 1400*10e-6, 1400, endpoint=False)
result1 = sine_fit_graph(t, ch1, freqGuess=2481/2/pi, dcGuess=0.5, sineorder=1)
result2 = sine_fit_graph(t, ch2, freqGuess=2481/2/pi, dcGuess=0.5, sineorder=1)
printf(result1, result2)
plt.plot(t, make_sine_graph(result1, t))
plt.plot(t, ch1)
plt.plot(t, make_sine_graph(result2, t))
plt.plot(t, ch2)
tspsave('fitresult', result1=result1, result2=result2)
printf(tan(result2[3] - result1[3]))$$C = {{\tan \theta } \over {2\pi f \cdot R}} = {{\sqrt {1 - \alpha ^2 } } \over \alpha } \cdot {1 \over {2\pi f \cdot R}}$$
alpha = result1[2] / result2[2]
printf(sqrt(1-alpha**2)/alpha)
plt.show()
#------------------------------------------------------------
# END OF FILE : TEST2.PY
#============================================================
根據上面的PYTHON程序重新計算輸入和輸出相應的數據對應的正弦參數,數據如下,所得到的估計參數與MATLAB相同。
輸出波形擬合正弦參數:
[ 3.95138209e+02 4.67232082e-01 1.07395207e-01 -5.89407332e-02]
輸入波形數據擬合正弦參數:
[3.95096587e+02 5.88518451e-01 3.03988482e-01 9.74184940e-01]
tan(theta)=1.6770990200351208
sqrt(1-a**2)/a=2.6480303891707053