Forum: Digitale Signalverarbeitung / DSP / Machine Learning Signale vergleichen


von Horsti (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe mit verschiedenen Sensoren eine Sinussignal gemessen. Dieses 
hat immer die gleiche Frequenz, gleiche Länge und gleiche Abtastrate. 
Jetzt möchte ich auf basis von dem genausten Sensor, die Anderen in 
Bezug auf ihrer Genauigkeit vergleichen. Ich habe schon versucht jeweils 
die Kreuzkorrelation mit Matlab zu berechnen, aber bin nicht in der Lage 
das Resultat zu deuten. Woran erkenn ich das die Messung verrauscht oder 
verzerrt ist? Wie würdet ihr die relative Genauigkeit bestimmen?

Hab mal ein Beispiel von der Kreuzkorrelation angehängt.

von ---- (Gast)


Lesenswert?

Diese Informationen können direkt aus dem Spektrum heraus bestimmt 
werden. Dazu gibt es freie Tools wie z.B. VisualAnalog von Analog 
Devices (Fensterung nicht vergessen!).
Gruss

von Matlab (Gast)


Lesenswert?

Das was dir evtl. besser hilft ist der Korrelationskoeffizient:
http://de.wikipedia.org/wiki/Korrelationskoeffizient

Den kann auch Matlab berechnen.

von Matlab (Gast)


Lesenswert?


von ---- (Gast)


Lesenswert?

Der Korrelationskoeffizient wird nicht viel bringen, denn er will wissen 
ob das Signal verrauscht oder verzerrt ist. Solche Grössen bestimmt man 
besten über den SNR und THD. Aus diesen Werten lässt sich direkt den 
genausten Sensor bestimmen.

von Horsti (Gast)


Angehängte Dateien:

Lesenswert?

Danke für die Antworten. Werde mir THD und SNR mal genauer anschauen. 
Dafür brauche ich ja das Frequenzspektrum. Mein Signal ist 500 Samples 
lang und wurde mit 7kHz abgetastet. Habe ich da nicht nur sehr 
beschränkte Möglichkeiten über eine FFT an das Spektrum zu kommen? Wenn 
ich ein Sinus mit 50 Hz analysiere bekomme ich den Peak im 
Frequenzbereich bei 52 Hz und die Harmonischen Oberschwingung sind nicht 
sichtbar. :(

von ---- (Gast)


Lesenswert?

Wen du die Y Achse in deinem Spektrum logarithmisch darstellst, sollten 
die Harmonischen sichtbar werden.

von Detlef _. (detlef_a)


Lesenswert?

Horsti, Du hast bei der FFT Methode die Fenstereffekte mit drin, die 
machen Dir die Spektrallinie breit und erschweren die Bestimmung des SNR 
(SNR hat übrigens mit Spektrum nichts zu tun, das ist das Verhältnis vom 
Signal zum Rauschen). SNR Bestimmung geht auch ohne FFT, script anbei. 
Für schlechtere SNRs als 25dB oder so geht das allerdings nicht so gut, 
da muß man was anderes nehmen.

hope that helps
Cheers
Detlef


clear
w=15.3*2*pi/128
sig = 1.34*sin(w*(0:127)+0.123);
Psig=sum(sig.^2);
noise=1e-2*randn(size(sig));
Pnoise=sum(noise.^2);
sig=sig+noise;
Psn=sum(sig.^2);
n=length(sig);
%sig(n-1)+sig(n+1)=2*cos(w)*sig(n);
s1=sig(1:n-2)+sig(3:n);
s2=sig(2:n-1);
% Regression s1 auf s2
M= [s2.' ones(length(s1),1)];
coff=inv(M'*M)*M'*s1.';
wn=acos(coff(1)/2);

M=[cos((0:n-1)*wn).' sin((0:n-1)*wn).'];
coff=inv(M'*M)*M'*sig.';

cc=coff(2)+j*coff(1);
amp=abs(cc);
ph=angle(cc);

sigr=amp*sin(wn*(0:127)+ph);
noiser=sig-sigr;
Pnoiser=sum(noiser.^2);
Psigr=sum(sigr.^2);
disp(sprintf('SNR vorgegeben: %.2fdB SNR bestimmt  %.2fdB', ...
    10*log10(Psig/Pnoise),10*log10(Psigr/Pnoiser)));
n=length(sig);
plot([sig ; sigr].')

von ---- (Gast)


Lesenswert?

SNR lässt sich mit einem FFT sehr gut bestimmen, da sich die Signal und 
Rausch Leistungen einfach daraus ermitteln lassen.

Ich empfehle dir das VisualAnalog, da kannst du ausser der Fensterung 
nicht viel falsch machen.

von Horsti (Gast)


Angehängte Dateien:

Lesenswert?

@Detlef:
Danke, dass du dir die Mühe gemacht hast ein Beispielskript zu posten. 
Ehrlich gesagt verstehe ich nicht, was du für ein Verfahren benutzt. Hab 
dein Besipiel mal mit einem Signal ausprobiert, was dem von mir 
untersuchten ähnlich ist. Dabei ist die Abweicheung des bestimmten SNR 
zum vorgegeben zu groß. Kann natürlich sein, dass ich irgendeinen Mist 
gebaut habe. Wie gesagt bin nicht ganz durch gestiegen. Verändertes 
Skript ist im Anhang

@Anderen:
Bezüglich THD

Hat natürlich geholfen die Y Achse logarithmisch darzustellen. Dennoch 
bereitet mir der Leakage Effekt Probleme. Die harmonischen sind dadurch 
nicht sichtbar. Um das zuvermeiden wird empfohlen, die Anzahl der 
Samples so zuwählen, dass sie ein ganzahliges vielfaches der 
Periodendauer des Signals sind. Damit die Harmonischen genau in den 
Nullstellen des sin(k)/k sitzen.
Kein Problem.
f = 50 Hz, T= 0.02 s, Fs = 7 kHz, N = Anzahl der Samples, B = 
Beobachtungsfenster
B = n * T= 0.06 = N * 1/7kHz
n = 3, N = 42
Das Problem die Nullstellen liegen eben nicht genau auf den Vielfachen 
der Signalfrequenz

Ok zweite Möglichkeit wäre den Leakageffekt mit einer Fensterung zu 
verringern. Aber wie geht das? Nehm ich das Fenster und verschieb es 
immer um ein ganzahliges der Signalfrequenz um den Betrag der 
verschiedenen Harmonischen zu bekommen?

Visual Analog habe ich mir mal angeschaut. Komme damit aber überhaupt 
nicht klar. Bekomm noch nicht mal die csv Datei geladen. Außerdem würde 
ich gerne Matlab benutzen, damit die Grafiken zu Illustration konsistent 
sind.

Eine Weitere Frage zur Berechnung des SNR. Kann ich mit einem Tiefpass 
Filter die Leistung meines Signals und mit einem Hochpassfilter die 
Leistung des Rauschens bestimmen? Oder wie geht das?

von Werner (Gast)


Lesenswert?

Horsti schrieb:
> Kann ich mit einem Tiefpass Filter die Leistung meines Signals und mit
> einem Hochpassfilter die Leistung des Rauschens bestimmen?

Nein, ein Rauschspektrum enthält i.A. alle Frequenzen. Mit einem Hochpaß
würdest du den niederfrequenten Anteil abschneiden.
In der Fouriertransformierten kannst du beides direkt ablesen.

Horsti schrieb:
> Wie würdet ihr die relative Genauigkeit bestimmen?

Was meinst du mit Genauigkeit? Verwechselst du da was mit 
Signal-Rausch-Verhältnis?

von Horsti (Gast)


Lesenswert?

Wie bekomme ich denn dann die Rauschleistung?
Stimmt ich bringe, dass immer durcheinander. Ich möchte bestimmen, 
welcher Sensor am besten ist. Also hohes SNR, niedriges THD und nochwas?

von ---- (Gast)


Lesenswert?

Habe vor Jahren dieses Skript für die Spezifikation eines ADCs 
geschrieben, daraus sollte ersichtlich sein wie so was gemacht wird.
1
% Dieses Script analysiert die Signaleigenschaften wie, snr, thd, sinad, sfdr 
2
% und enob.
3
load JitterCorrectedData_0.txt;
4
signal = JitterCorrectedData_0;
5
numberOfSamples = length(signal);
6
samplingRate = 5e9;
7
maxNumberOfHarmonics = 5;
8
harmonicWidth = 9; % breite der Peaks
9
10
% Spektrum berechen
11
window = blackman(numberOfSamples);
12
signal = signal(:,1);
13
signal = signal .* window;
14
signal = abs(fft(signal));
15
signal = signal(1:numberOfSamples/2);
16
17
% DC und erste Harmonische suchen. Der grösste Wert, ausser DC, wird als erste 
18
% Harmonische gedeutet.
19
levels = signal(1);
20
positions = 0;
21
[level positionH1] = max(signal(2:numberOfSamples/2));
22
positionH1 = positionH1;
23
levels = [levels level];
24
positions = [positions positionH1];
25
26
% Alle anderen Harmonischen finden.
27
currentPosition = 2 * positionH1;
28
while currentPosition-2 < numberOfSamples/2 && length(levels) < maxNumberOfHarmonics
29
  [level lastPosition] = max(signal(currentPosition-2:min(currentPosition+2, numberOfSamples/2)));
30
  lastPosition = lastPosition + currentPosition - 3;
31
  levels = [levels level];
32
  positions = [positions lastPosition];
33
  currentPosition = currentPosition + positionH1;
34
end;
35
36
% Pegels skalieren damit die 1. Harmonische eins beträgt.
37
levelScalingFactor = 1 / levels(2);
38
levels = levels * levelScalingFactor;
39
signal = signal * levelScalingFactor;
40
41
% Noise vom Signal trennen und Leistungen der Harmonischen berechnen.
42
noiseMasked = signal;
43
harmonicWidth2 = ceil(harmonicWidth/2);
44
noiseMasked(1:harmonicWidth2) = zeros(1,harmonicWidth2)*-1;
45
powers = sum(signal(1:harmonicWidth2).^2);
46
for i=2:length(positions)
47
  from = positions(i) - harmonicWidth2 + 2;
48
  to = from + harmonicWidth - 1;
49
  noiseMasked(from:to) = zeros(1,harmonicWidth)*-1;
50
  power = sum(signal(from:to).^2);
51
  powers = [powers power];
52
end;
53
54
% Lehrstellen aus dem noiseMasked Vektor entfernen.
55
noiseContinuous = [];
56
for i=1:length(noiseMasked)
57
  if noiseMasked(i) ~= 0
58
    noiseContinuous = [noiseContinuous; noiseMasked(i)];
59
  end;
60
end;
61
62
% snr, thd, sinad, sfdr und enob berechnen.
63
noisePower = sum(noiseContinuous.^2);
64
signalPower = powers(2);
65
harmonicsPower = sum(powers(3:end));
66
67
snr = 10*log10(signalPower/noisePower);
68
thd = 10*log10(harmonicsPower/signalPower);
69
sinad = 10*log10(signalPower/(noisePower+harmonicsPower));
70
71
[highestHarmonicsLevel highestHarmonicsPosition] = max(levels(3:end));
72
[highestNoiseLevel highestNoisePosition] = max(noiseMasked);
73
sfdr = mag2db(levels(2)/max([highestHarmonicsLevel highestNoiseLevel]));
74
enob = (sinad - 1.76) / 6.02;
75
76
% Resultate ausgeben.
77
disp(['SNR    = ' num2str(snr) ' dB']);
78
disp(['THD    = ' num2str(thd) ' dB']);
79
disp(['SINAD  = ' num2str(sinad) ' dB']);
80
disp(['SFDR   = ' num2str(sfdr) ' dB']);
81
disp(['ENOB   = ' num2str(enob) ' bit']);
82
83
% Plotten.
84
xScalingFactor = samplingRate/numberOfSamples;
85
x = linspace(0,samplingRate/2-xScalingFactor,numberOfSamples/2);
86
plot(x, mag2db(signal));
87
hold on
88
plot(x, mag2db(noiseMasked), 'LineWidth', 3);
89
plot(0, mag2db(levels(1)), 'rs');
90
plot(positions(2)*xScalingFactor, mag2db(levels(2)), 'rv');
91
plot(positions(3:end)*xScalingFactor, mag2db(levels(3:end)), 'ro');
92
plot((highestNoisePosition-1)*xScalingFactor, mag2db(highestNoiseLevel), 'rd');
93
hold off;
94
95
legendText = num2str(round(mag2db(1/levels(3))));
96
for i=4:length(levels)
97
  legendText = [legendText  ', ' num2str(round(mag2db(1/levels(i))))];
98
end;
99
100
legend('signal', ...
101
       'noise', ...
102
       ['dc component ' num2str(round(mag2db(1/levels(1)))) ' dBc'], ...
103
       'fundamental signal', ...
104
       ['harmonics ' legendText ' dBc'], ...
105
       ['highest spur ' num2str(round(mag2db(1/highestNoiseLevel(1)))) ' dBc']);
106
107
title('Frequency Domain Analysis');
108
xlabel('Frequency [Hz]');
109
ylabel('Level [dB]');
110
set(gca,'YLim',[-80 20]);

von Horsti (Gast)


Lesenswert?

Vielen Dank. Mittlerweile ist mir die Berechnung von THD, SNR auch klar 
geworden. Aber vielleicht werde ich auch SFDR und ENOB mit in die 
Analyse mit einbeziehen. Obwohl sich ENOB, wenn ich das richtig 
verstanden habe, mehr auf ADCs bezieht. Gibt es eine Fenstermethode die 
generell zu empfehlen ist? Mit hamming bekomme ich schon ganz gute 
Werte. Mit kaiser oder blackmanharris bekomme ich qualitativ die selben 
Ergebnisse. Dafür ist das SNR generell etwas niedriger.

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
Noch kein Account? Hier anmelden.