2013-02-27 9 views
8

Ich habe eine Reihe von CSV-Werten, die einen digitalen Ausgang darstellen. Es wurde mit einem analogen Oszilloskop erfasst, so dass es kein perfektes digitales Signal ist. Ich versuche, die Daten herauszufiltern, um ein perfektes digitales Signal für die Berechnung der Perioden zu erhalten (die variieren können). Ich möchte auch den maximalen Fehler definieren, den ich von dieser Filtration erhalte.Digitalisieren eines analogen Signals

Etwas wie folgt aus:

enter image description here

Idee

eine treshold od die Daten übernehmen. Hier ist ein Pseudocode:

Es gibt zwei Probleme, die mich stören.

  1. Das scheint ein häufiges Problem in der digitalen Signalverarbeitung zu sein, aber ich habe keine vordefinierte Standardfunktion dafür gefunden. Ist dies eine gute Möglichkeit, die Filterung durchzuführen?
  2. Wie bekomme ich den maximalen Fehler?
+0

Komplett tangential, aber ein analoges Oszilloskop ist auf einer Bank viel besser als ein digitales Oszilloskop. Digitale Oszilloskope haben eine minimale Granularität (sowohl bei der Eingabe als auch bei der Anzeige) und neigen dazu, Ausreißer zu überdecken. – L0j1k

+0

Haben Sie [Matlab?] (Http://www.mathworks.com/products/matlab/) in Kombination mit Python in Betracht gezogen, siehe [Dies] (https://sites.google.com/site/pythonforscientists/python- vs-Matlab). und [This] (http://matplotlib.org/) –

+0

@ L0j1k Nun, es ist tatsächlich digital, wir verwenden nur die analogen Sonden, so dass wir die Umwandlung selbst machen können :) – TheMeaningfulEngineer

Antwort

6

Hier ist ein Stück Code, die helfen könnten.

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() 

Der Ausgang:

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

Sie könnten numpy.histogram und/oder matplotlib.pyplot.hist weiter zu analysieren, um die Anordnung von periods(t, y, threshold) zurückgegeben.

1

Wenn Sie wirklich nur an der Periode interessiert sind, könnten Sie die Fourier-Transformation plotten, Sie werden eine Spitze haben, wo die Frequenz der Signale auftritt (und so haben Sie die Periode). Je breiter die Spitze in der Fourier-Domäne, desto größer ist der Fehler in der Periodenmessung

import numpy as np 

data = np.asarray(my_data) 

np.fft.fft(data) 
+0

Coole Idee, aber wir suchen ein Histogramm der Perioden, so dass wir sagen können, in welchem ​​Prozentsatz es unseren Bedürfnissen entspricht. Es ist für ein Experiment im Bereich der Implementierung verschiedener Software-PWMs auf Himbeerpy. – TheMeaningfulEngineer

1

Ihre Filterung ist in Ordnung, es ist im Grunde das gleiche wie ein Schmitt-Trigger, aber das Hauptproblem Sie mit ihm haben könnte, ist Geschwindigkeit. Der Vorteil der Verwendung von Numpy ist, dass es so schnell wie C sein kann, während Sie jedes Element einmal durchlaufen müssen.

Ähnliches können Sie mit dem Median-Filter von SciPy erreichen. Die folgende Beschreibung ist ein ähnliches Ergebnis erzielen (und nicht auf irgendwelchen Größen abhängig sein):

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

einzustellen, können Sie die Stärke des Medianfilterung mit medfilt(raw, n_samples), n_samples standardmäßig 3.

Wie für die Fehler, Das wird sehr subjektiv sein. Ein Weg wäre, das Signal ohne Filterung zu diskretisieren und dann nach Unterschieden zu vergleichen. Zum Beispiel:

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

Dies ist keine Antwort auf Ihre Frage, nur und Vorschlag, die helfen können. Ich schreibe es hier, weil ich Bild in Kommentar nicht setzen kann.

Ich denke, Sie sollten Daten irgendwie vor jeder Verarbeitung normalisieren.

Nach der Normalisierung auf den Bereich 0 ... 1 sollten Sie Ihren Filter anwenden.

enter image description here

+1

Danke für den Tipp. In diesem konkreten Beispiel wandle ich das Signal in boolesche Werte um, sodass ich den Vorteil der Normalisierung nicht sehe. – TheMeaningfulEngineer

Verwandte Themen