2013-02-27 4 views
8

디지털 출력을 나타내는 CSV 값 배열이 있습니다. 아날로그 오실로스코프를 사용하여 수집되었으므로 완벽한 디지털 신호가 아닙니다. 나는 기간을 계산하기위한 완벽한 디지털 신호를 가지도록 데이터를 걸러 내기 위해 노력하고있다. 이 필터링에서 얻은 최대 오차를 정의하고 싶습니다. 이 같은아날로그 신호 디지타이징

뭔가 :

enter image description here

아이디어

데이터 OD treshold을 적용합니다. 다음은 의사 코드입니다.

for data_point_raw in data_array: 
    if data_point_raw < 0.8: data_point_perfect = LOW 
    if data_point_raw > 2 : data_point_perfect = HIGH 

else: 
    #area between thresholds 
    if previous_data_point_perfect == Low : data_point_perfect = LOW 
    if previous_data_point_perfect == HIGH: data_point_perfect = HIGH 

나를 괴롭히는 데는 두 가지 문제가 있습니다.

  1. 이것은 디지털 신호 처리에서 일반적인 문제인 것 같지만 미리 정의 된 표준 기능을 찾지 못했습니다. 이것은 필터링을 수행하는 좋은 방법입니까?
  2. 최대 오류는 어떻게 발생합니까?
+0

완전히 접선이지만 아날로그 오실로스코프는 디지털 스코프보다 벤치에서 훨씬 좋습니다. 디지털 스코프는 최소 입도 (입력 및 디스플레이 출력 모두)가 있으며 이상 치를 넘는 경향이 있습니다. – L0j1k

+0

Python과 함께 [Matlab?] (http://www.mathworks.com/products/matlab/)을 고려 했습니까? [This] (https://sites.google.com/site/pythonforscientists/python- 대 MATLAB). [This] (http://matplotlib.org/) –

+0

@ L0j1k 글쎄, 실제로 디지털인데, 아날로그 프로브를 사용하기 때문에 변환을 스스로 할 수 있습니다 :) – TheMeaningfulEngineer

답변

6

여기에 도움이 될 코드의 비트입니다.

from __future__ import division 

import numpy as np 


def find_transition_times(t, y, threshold): 
    """ 
    Given the input signal `y` with samples at times `t`, 
    find the times where `y` increases through the value `threshold`. 

    `t` and `y` must be 1-D numpy arrays. 

    Linear interpolation is used to estimate the time `t` between 
    samples at which the transitions occur. 
    """ 
    # Find where y crosses the threshold (increasing). 
    lower = y < threshold 
    higher = y >= threshold 
    transition_indices = np.where(lower[:-1] & higher[1:])[0] 

    # Linearly interpolate the time values where the transition occurs. 
    t0 = t[transition_indices] 
    t1 = t[transition_indices + 1] 
    y0 = y[transition_indices] 
    y1 = y[transition_indices + 1] 
    slope = (y1 - y0)/(t1 - t0) 
    transition_times = t0 + (threshold - y0)/slope 

    return transition_times 


def periods(t, y, threshold): 
    """ 
    Given the input signal `y` with samples at times `t`, 
    find the time periods between the times at which the 
    signal `y` increases through the value `threshold`. 

    `t` and `y` must be 1-D numpy arrays. 
    """ 
    transition_times = find_transition_times(t, y, threshold) 
    deltas = np.diff(transition_times) 
    return deltas 


if __name__ == "__main__": 
    import matplotlib.pyplot as plt 

    # Time samples 
    t = np.linspace(0, 50, 501) 
    # Use a noisy time to generate a noisy y. 
    tn = t + 0.05 * np.random.rand(t.size) 
    y = 0.6 * (1 + np.sin(tn) + (1./3) * np.sin(3*tn) + (1./5) * np.sin(5*tn) + 
       (1./7) * np.sin(7*tn) + (1./9) * np.sin(9*tn)) 

    threshold = 0.5 
    deltas = periods(t, y, threshold) 
    print "Measured periods at threshold %g:" % threshold 
    print deltas 
    print "Min: %.5g" % deltas.min() 
    print "Max: %.5g" % deltas.max() 
    print "Mean: %.5g" % deltas.mean() 
    print "Std dev: %.5g" % deltas.std() 

    trans_times = find_transition_times(t, y, threshold) 

    plt.plot(t, y) 
    plt.plot(trans_times, threshold * np.ones_like(trans_times), 'ro-') 
    plt.show() 

출력 :

Measured periods at threshold 0.5: 
[ 6.29283207 6.29118893 6.27425846 6.29580066 6.28310224 6.30335003] 
Min: 6.2743 
Max: 6.3034 
Mean: 6.2901 
Std dev: 0.0092793 

Plot

당신은 numpy.histogram을 사용할 수 및/또는 matplotlib.pyplot.histperiods(t, y, threshold)에 의해 반환 된 배열을 분석합니다.

1

주기에 관심이있는 사용자는 푸리에 변환을 플롯 할 수 있습니다. 신호의 주파수가 발생하는 지점 (피크닉 시간이 있으므로)이 피크가됩니다. 당신의주기 측정에 오류가 큰, 푸리에 도메인의 피크 더 넓은

import numpy as np 

data = np.asarray(my_data) 

np.fft.fft(data) 
+0

그러나 멋진 아이디어는 기간에 대한 히스토그램을 얻으려는 것이므로 우리의 요구에 맞는 비율을 알 수 있습니다. 그것은 라스베리 파이에 다른 소프트웨어 PWM을 구현하는 영역에서의 실험입니다. – TheMeaningfulEngineer

1

필터링은 기본적으로, 슈미트 트리거와 같은 좋은 것입니다,하지만 당신은 그것으로있을 수있는 가장 큰 문제는 속도입니다. Numpy를 사용할 때의 장점은 C만큼 빠르다는 것입니다. 반면에 각 요소를 한 번 반복해야합니다.

SciPy의 중간 필터를 사용하여 비슷한 효과를 얻을 수 있습니다. 다음은 유사한 결과를 얻을 수 (및 크기에 의존하지 않음)해야 다음

filtered = scipy.signal.medfilt(raw) 
filtered = numpy.where(filtered > numpy.mean(filtered), 1, 0) 

을 조정할 수 있습니다로 필터링 중간의 강도 medfilt(raw, n_samples), n_samples 기본 설정 3. 오류에 관해서는

에, 그것은 매우 주관적이 될 것입니다. 한 가지 방법은 필터링없이 신호를 이산하고 차이점을 비교하는 것입니다. 예 :

discrete = numpy.where(raw > numpy.mean(raw), 1, 0) 
errors = np.count_nonzero(filtered != discrete) 
error_rate = errors/len(discrete) 
2

이 질문은 도움이 될만한 질문이나 답변으로는 적합하지 않습니다. 내가 코멘트를 이미지에 넣을 수 없기 때문에 그것을 여기에 쓰고있다.

처리하기 전에 어떻게 든 데이터를 정상화해야한다고 생각합니다.

0 ... 1 범위로 정규화 한 후 필터를 적용해야합니다.

enter image description here

+1

팁 주셔서 감사. 그러나이 구체적인 예에서는 신호를 부울 값으로 변환하므로 정규화에서 이점이 나타나지 않습니다. – TheMeaningfulEngineer