Hallo, folgende Frage: Ich habe zwei Zeitsignale von zwei unterschiedlichen Sensoren, die ich sampleweise miteinander verrechnen möchte. Das Problem dabei ist, dass die Sensoren in ihrer Abtastrate leicht differieren (+-2%), sodass das eine Signal von t1 bis t2 bespielsweise 1000 Samples enthält, das andere aber 1025. Wie konditioniere ich die Signale ab besten, sodass ich meine Berechnung durchführen kann. Grüße, Alex
Du willst zeitlich undefiniert versetzte Signale miteinander verrechnen? Glaub ich nicht. Mir fällt kein Szenario ein, bei dem das Sinn machen könnte.
Wenn's nicht so genau geht, 25 gleichmäßig verteilte Werte verwerfen. Oder beim kleineren Datensatz 25 gleichmäßig verteilte Stellen interpolieren. Das macht natürlich nur Sinn, wenn das Signal nur niedrige Frequenzen aufweist.
@stänkerFritz Sie Signale sind nicht undefiniert versetzt. Start und Endzeitpubkt sind bekannt, nur die Abtastrate differiert etwas. @mech, Signalquellen sind zwei ADXL355 von Analog Devices, und da ist der Samplequarz eben nur so genau wie oben geschrieben. Samplefrequenz ist 1000Hz, der Sensor stellt denn internen Tiefpass auf fs/4, allerdings ist das gemessene mechanische System recht träge, sodass ich keine Frequenzen mit nennenswerter Amplitude über 50Hz erwarte.
Tatsächlich kommt das ja immer vor, wenn man 2 vermeintlich synchrone Quellen sampelt. Merken nur viele Leute gar nicht, weil sie samples vergessen oder den internen fifo nicht benutzen. Also, du kannst tatsächlich interpolieren. Aber dafür musst du eine konkrete Frequenz haben. Und einen gemeinsamen Teller finden. Bei niederfrequenten Systemen nimmst du einfach einen Mittelwertfilter. Jeder sensor hat seine eigene abtastrate, also gibt es auch Module/Instanzen. Jede Instanz weiss den momentanen Wert. Zb durch periodisches Abrufen des FIFOs. Nur nicht aufeinander warten lassen, das ergibt Probleme
Hallo, wenn ich die Frage richtig verstehe, möchtest Du aus dem aus 1025 Abtastwerten bestehenden Signal ein Signal gleicher Dauer mit nur 1000 Abtastwerten machen. In MatLab oder Gnu Octave gibt es dazu die Funktion interp1, die Dir dabei helfen kann, die Signale zu interpolieren. Beispielcode: % s1 = ... (Dein Signal) t1 = 1:1025; t1neu = 1025/1000:1025/1000:1025; s1neu = interp1(t1,s1,t1neu,'spline'); Viele Grüße Michael
stänkerFritz schrieb: > Du willst zeitlich undefiniert versetzte Signale miteinander verrechnen? > Glaub ich nicht. Mir fällt kein Szenario ein, bei dem das Sinn machen > könnte. Mir fallen NUR solche Anwendungen ein, weil in keinem Messsystem alle Sensoren voll synchron arbeiten. Da heisst es interpolieren und auf ein und dieselbe Zeit ummünzen, wenn sie verglichen werden sollen, Mein aktueller Fall: Strom und Spannung in einem Mehrphasensystem. Der Stromsensor arbeitet mit 20kHz +/- 2kHz Rate, wegen dynamischer Regelung und Umschaltung der PWM und die Spannung (an anderem Punkt gemessen) kommt mit 50kHz. Man könnte den ADC auf den Strommesspunkt triggern, wäre aber immer eine Messperiode hinterher. Also die Spannung mit 150kHz interpolieren und dem Regelsystem zur Verfügung stellen, wenn es einen neuen Stromwert hat.
Hallo, danke für die vielen Antworten. Zum Thema Interpolieren müsste ich noch ergänzen, dass ich die Daten in einer Anwendung verarbeite, die ich gerade selbst schreibe (C#, WPF). Das heißt, ich müsste das Ganze "zu Fuß" implementieren. Michael schrieb: > Beispielcode: > % s1 = ... (Dein Signal) > t1 = 1:1025; > t1neu = 1025/1000:1025/1000:1025; > s1neu = interp1(t1,s1,t1neu,'spline') Wie arbeitet denn die interp1-Funktion? Upsampling um Faktor 1025 und dann downsampling um Faktor 1000 mit entsprechender Filterung und dem ganzen Prozedere, das dazu gehört (Stichwort CIC-Filter)? Eine Implementierung würde ich mir in entsprechender Zeit gerade noch zutrauen, aber vielleicht fändeich da auch was Fertiges. Grüße, Alex
Alexander H. schrieb: > Wie arbeitet denn die interp1-Funktion? Upsampling um Faktor 1025 und > dann downsampling um Faktor 1000 mit entsprechender Filterung und dem > ganzen Prozedere, das dazu gehört (Stichwort CIC-Filter)? Nein. Das ist ganz einfache Interpolation mit splines. Da werden keine sampleraten oder so berücksichtigt und du musst die abtastwerte selbst übergeben. Die Funktion decimate https://www.mathworks.com/help/signal/ref/decimate.html filtert hingegen.
Wenn du die Signale nicht direkt während der Messung, sondern erst im Nachhinein auswertest, kannst du auch eine sin(x)/x-Interpolation verwenden, wie es bspw. auch Digitaloszis tun. Sie ist nicht schwieriger umzusetzen als eine Spline-Interpolation, liefert aber für Signale, die das Abtasttheorem erfüllen (also nur Frequenzanteile unterhalb der halben Abtastfrequenz haben), mathematisch perfekte Ergebnisse. Hier steht, wie es geht: https://de.wikipedia.org/wiki/Sinc-Funktion#Signalverarbeitung Etwas ausführlicher: https://en.wikipedia.org/wiki/Whittaker%E2%80%93Shannon_interpolation_formula Da bei dir die Abtastfrequenz (1kHz) viel höher als die erwartete höchste Signalfrequenz (50Hz) liegt, wird der Unterschied zwischen den einzelnen Interpolationsarten (linear, Spline, sin(x)/x) allerdings nicht sehr groß sein.
Alexander H. schrieb: > Das heißt, ich müsste das Ganze "zu > Fuß" implementieren. Ja und wo ist das Problem? Nennt sich Programmieren. Da deine Signale deutlich langsamer als die Abtastrate sind sollte eine lineare Interpolation zwischen 2 Stützstellen doch reichen.
@Yalu: ich habe noch ein Verständnisproblem, bezüglich Interpolation. Wenn ich das recht verstanden habe, muss ich mit der von dir erwähnten Interpolation aus den 1025 Abtastwerten mein "Originalsignal" rekonstruieren, um das dann mit 1000Hz abzutasten. Stimmt das so? In dem Wiki-Artikel ist ja von zeitkontinuerliche die Rede und da ist eine Summe von -unendlich bis +unendlich. Ich finde gerade den Einstieg nicht. Kannst du mir bitte kurz erläutern, welche Schritte ich der Reihe nach unternehmen muss, um von dem 1025Hz-Signal zum 1000Hz-Signal zu kommen.
Warum nimmst du nicht einfach den letzten Abtastwert? Alles andere ist doch superkompliziert, und nur notwendig, wenn du genauer als 0.x% sein willst... und meiner Einschätzung nach weisst du noch nicht mal wie genau das Ergebnis sein muss...
Udo K. schrieb: > Warum nimmst du nicht einfach den letzten Abtastwert? Sorry, aber ich verstehe deine Frage nicht. Nehmen wofür?
mech schrieb: > Wenn's nicht so genau geht, 25 gleichmäßig verteilte Werte > verwerfen. NEIN > Oder beim kleineren Datensatz 25 gleichmäßig verteilte Stellen > interpolieren. Ja, u.U. genügt wiederholen, statt interpol.. die Werte sind ohnehin mit einem Quantisierungstauschen belegt.
Moin, Alexander H. schrieb: > Das heißt, ich müsste das Ganze "zu > Fuß" implementieren. Du koenntest auch schauen, ob dir das Dingens hier weiterhelfen koennte: http://www.mega-nerd.com/libsamplerate/index.html Gruss WK
Ich hab mal versucht, die Interpolation zu implementieren. Kann das mal einer querlesen bitte.
1 | private List<DataPoint> Interpolate(IList<DataPoint> data, int sampleRateNew) |
2 | { |
3 | if (data is null) |
4 | return null; |
5 | |
6 | List<DataPoint> result = new List<DataPoint>(sampleRateNew); |
7 | |
8 | double startTime = data[0].X; |
9 | double endTime = data[data.Count - 1].X; |
10 | double timeStep = (endTime - startTime) / sampleRateNew; |
11 | double sampleTimeOld = data.Count / (endTime - startTime); |
12 | |
13 | |
14 | for (int i = 0; i < sampleRateNew; i++) |
15 | { |
16 | double time = startTime + i * timeStep; |
17 | double yValue = 0; |
18 | for (int j = 0; j < data.Count; j++) |
19 | yValue += data[j].Y * Sinc((time - j * sampleTimeOld) / sampleTimeOld); |
20 | |
21 | result.Add(new DataPoint(time, yValue)); |
22 | } |
23 | |
24 | return result; |
25 | } |
26 | |
27 | private double Sinc(double value) |
28 | { |
29 | return value == 0 ? 1.0 : Math.Sin(Math.PI * value) / (Math.PI * value); |
30 | } |
:
Bearbeitet durch User
Hallo, am besten überprüfst Du es selbst anhand von Testdaten und vergleichst die Zahlen mit denen, die Octave liefert. Hier findest Du beispielsweise Gnu Octave https://octave-online.net/ Hier ein Beispielcode für eine Interpolation: fs = 1000; t1 = 1/fs*(0:102); s1 = sin(2*pi*50*t1); t1neu = 0:1/fs*103/100:1/fs*102; s1linear = interp1(t1,s1,t1neu,'linear'); s1cubic = interp1(t1,s1,t1neu,'cubic'); s1spline = interp1(t1,s1,t1neu,'spline'); figure(1); clf; plot(t1,s1,'b.-'); hold on; plot(t1neu,s1linear,'r.-'); plot(t1neu,s1cubic,'g.-'); plot(t1neu,s1spline,'k.-'); legend('Original','Linear','Cubic','Spline'); grid on; hold off; Die Daten kannst Du Dir durch eine Eingabe wie s1 (ohne Semikolon; anschließend Drücken der Returntaste) anzeigen lassen. Viele Grüße Michael
Alexander H. schrieb: > ie konditioniere ich die Signale ab besten, sodass ich meine > Berechnung durchführen kann. Entweder in der Zeitebene resampeln oder in der Frequenzebene diskret transformieren.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.