通過示波器數據進行正弦信號參數估計

實驗要求

第一次作業中的第二小題,練習了根據信號的波形寫出對應信號的表達式。但在實際中,我們觀測到的信號往往是在示波器上的波形,此時該如何獲得這些波形的數學表達式?
測量波形的示波器

測量波形的示波器

本質上講,實際信號中都會帶有隨機性,是沒有確定的數學表達式的。但在某些情況下,我們是預先知道信號的類型的,比如正弦波,但不知道信號的一些參數。例如幅值、頻率和相位。如果這些參數知道了,便可以寫出對應的信號數學表達式了。在這種情況下,從觀測到的帶有噪聲的信號波形中回覆處信號,則屬於信號參數估計的內容了。
部分電子元器件

部分電子元器件

在實際應用中,信號的參數往往非常重要。下面舉一個例子:如果手邊只有一個萬用表,但沒有能夠測量電容、電感的RCL橋,爲了想知道一個電容器件的準確容值,可以將待測的電容與一個電阻串聯在一起。電阻的阻值可以使用萬用表精確測量。使用一個信號源產生一個正弦波信號施加在RC串聯電路上,使用示波器同時測量信號源的信號以及RC分壓後的信號。

利用RC測量電子器件參數電路

利用RC測量電子器件參數電路

根據電路原理,可以知道上述電路穩態輸入輸出正弦信號之間的關係如下:

V˙=1j2πfC1R1+1j2πfC1U˙=11+j2πfR1C1U˙\dot V = {{{1 \over {j2\pi fC_1 }}} \over {R_1 + {1 \over {j2\pi fC_1 }}}}\dot U = {1 \over {1 + j2\pi fR_1 C_1 }}\dot U

實測測量電路和示波器

實測測量電路和示波器

因此,輸入輸出正弦信號的幅度之比爲:
α=V˙U˙=11+(2πfRC)2\alpha = {{\left| {\dot V} \right|} \over {\left| {\dot U} \right|}} = {1 \over {\sqrt {1 + \left( {2\pi fRC} \right)^2 } }}

輸入輸出正弦信號的相位差爲:θ\thetatan(θ)=2πfRC\tan \left( \theta \right) = 2\pi f \cdot RC

所以,只要能夠測量出U,V兩個正弦信號的幅度或者相位,頻率,再加上已知電阻阻值R\1.,便可以計算出來待測電容的容值。
C=tanθ2πfR=1α2α12πfRC = {{\tan \theta } \over {2\pi f \cdot R}} = {{\sqrt {1 - \alpha ^2 } } \over \alpha } \cdot {1 \over {2\pi f \cdot R}}

已知上面的串聯電路中的電阻\nR\1.=1009歐姆。示波器顯示波形的數值可以通過已經存儲在CH12.MAT中,數值的採樣時間間隔fs=10微妙。

示波器採集的數值波形

示波器採集的數值波形

請根據以上分析,求出待測電容\nC\1.的容值是多少。

提示:

  1. 在MATLAB中通過load()命令讀取CH12.MAT中的數據;
  2. ch12(:,1) 是V的數據, ch12(:,2)是U的數據。
  3. 使用MATLAB中fit命令來估計數據中的參數。
    f = fit(x,y,‘fourier1’)
  4. 上面fit命令輸出 f(x)=a0+a1cos(xw)+b1sin(xw)
    中的a0,a1,b1,w等參數。

 

使用MATLAB計算出現的問題

使用MATLAB計算步驟

  1. 調入數據並繪製波形圖
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倍的差異。tan(θ)=1.677,    1α2α=2.6480\tan \left( \theta \right) = 1.677,\,\,\,\,{{\sqrt {1 - \alpha ^2 } } \over \alpha } = 2.6480

相關的矢量方差如下圖所示:
MATLAB計算出的參數的問題

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曲線

兩個通道正弦波及其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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章