Signal Erzeugung und Analyse

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
PC-Hans
User
Beiträge: 2
Registriert: Freitag 12. Januar 2018, 15:19

Freitag 12. Januar 2018, 18:51

Hallo Zusammen,

da ich zu wenig Erfahrung mit Python habe benötige ich Hilfe bei der Darstellung und Auswertung eines erzeugten Signal.
Nach ein paar Tagen suche/programmieren sehe ich leider kein brauchbares Ergebnis.
Ich arbeite im IDLE mit neuester Python-Version 3.6.

Das Signal soll sich aus drei Teilen zusammensetzten: x(t)= Ac*cos(2*pi*fc*t) + As*sin(2*pi*fs*t)+ Rauschen
Wobei Ac und As die Amplituden für cos und sin Funktion sind, fc und fs die Frequenzanteile von cos und sin. Das Rauschsnignal soll den Ampitudenwert 1 besitzen.
Die Abtastfrequenz soll 1kHz betragen und weiterhin soll sich das Signal aus 4096 Werten zusammensetzen.

Anschließend soll die FFT berechnet und dargestellt werden (später).

Code: Alles auswählen


import matplotlib.pyplot as plt
import numpy as np

#Signaldaten

Fs = 1000 # Hz Abstastfrequenz
Ts = 1/Fs # Abtastintervall
fc = 100 # Hz Cosinusschwingung
fs= 225 # Hz Sinunsschwingung
Ac=5 # Amplitude Cosinusanteil
As=3 #Amplitude Sinusanteil
Ar=1 #Ampitude Rauschsignal

#Signalerzeugung

sample = 4096
x = np.arange(sample)
Fc=Ac * np.cos(2*np.pi*fc*(x/Fs))  #Cosinussignal
Fs=As * np.sin(2*np.pi*fs*(x/Fs)) #Sinussignal
Fn=Ar * np.random.normal(0, 1, len(x)) #Rauschanteil

Fg=Fc+Fs+Fn #Gesamtsignal

# Signaldarstellung

startx, endx = 0, 100
starty, endy = -6,10
plt.xlabel('Zeit')
plt.ylabel('Funktionswert')
plt.title('Signal')
plt.axis([startx, endx, starty, endy])
plt.stem(x,Fg, 'r', )
plt.plot(x,Fg)
plt.show()


-> Das daraus dargestellte Abtastintervall erscheint mir zu groß.
-> Das Rauschsignal erscheint mir auch nicht richtig.

Für Matlab sieht der Code mit FFT so aus:

t=[0:4095]*0.001; % f_S = 1000 Hz
x=5*cos(200*pi*t)+3*sin(450*pi*t)+randn(size(t));
plot(t,x)
axis([0 .1 -10 10])
X=fft(x);
f=[0:2047]*500/2048;
plot(f,abs(X(1:2048)))

Vielen Dank schon mal für Hilfe!

Lg, PC-Hans
narpfel
User
Beiträge: 245
Registriert: Freitag 20. Oktober 2017, 16:10

Freitag 12. Januar 2018, 19:51

Moin,

was genau erscheint dir denn am Rauschsignal nicht richtig?

Zum Abtastintervall: Wie viele Punkte werden bei einer Samplerate von 1 kHz und einer Signalfrequenz von 100 (bzw. 225) Hz denn pro Periode abgetastet? Wie viele Punkte liegen bei `Fc` und `Fs` in einer Periode (eventuell mit `"."` als drittem Argument plotten)? Was genau erscheint dir daran zu groß?
PC-Hans
User
Beiträge: 2
Registriert: Freitag 12. Januar 2018, 15:19

Dienstag 16. Januar 2018, 13:47

Nach viel ausprobieren bin ich nun fast am Ziel. Die Abtastrate und Rauschsignal passen so wie Sie sind.

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt

N = 4096 #Anzahl Abtastwerte


T = 1.0 / 1000.0
xfs = np.linspace(0.0, N*T, N)

#Frequenzen
fs = 225
fc = 100

# Signalanteile
Fc = 4*np.cos(2*np.pi*fc*(xfs)) #Cosinussignal
Fs = 2*np.sin(2*np.pi*fs*(xfs)) #Sinussignal
Fn = 1*np.random.normal(0, 1, len(xfs)) #Rauschanteil

#Gesamtsignal
Fg = Fc+Fs+Fn

#FFT
yf = np.fft.fft(Fg)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)

#Darstellung
plt.figure(1)
plt.subplot(211)
plt.title('Signalanteile')
plt.axis([0, 0.05, -7, 7])
plt.ylabel('x(t)')
plt.plot(xfs, Fc, label=r'$S_{cos}$')
plt.plot(xfs, Fs, label=r'$S_{sin}$')
plt.plot(xfs, Fn, label=r'$S_{noise}$')
plt.legend(loc='upper right', frameon=True)

plt.subplot(212)
plt.title('Signal')
plt.axis([0, 0.05, -7, 7])
plt.ylabel('x(t)')
plt.xlabel('Zeit [s]')
plt.plot(xfs, Fg, label=r'$S_{gesamt}$')
plt.stem(xfs,Fg, 'r', 'x')
plt.legend(loc='upper right', frameon=True)

fig, ax = plt.subplots()
ax.plot(xf, 2.0/N * np.abs(yf[:N//2]), label=r'$FFT$')
plt.ylabel('|X(f)|')
plt.xlabel('Frequenz [$Hz$]')
plt.legend(loc='upper right', frameon=True)
plt.title('Amplitudenspektrum')
plt.show()
Nun stehe ich vor dem nächsten Problem:

Ich habe leider keine Idee bzw. noch nichts dazu gefunden wie ich das Amplitudenspektrum der FFT in dB darstelle.
Ich kann die y-Achse mit plt.yscale('log') auf den natürlichen Log. skalieren, was aber noch keine Darstellung in dB zeigt.
Gewollte Darstellung wie hier: https://de.wikipedia.org/wiki/Datei:Tri ... and_fd.png

Auch für die Darstellung des Phasenspektrums hab ich leider noch keine Lösung.
Gewollte Darstellung wie hier: https://de.wikipedia.org/wiki/Datei:Sinusburst.svg

Ich bin für jede Antwort sehr dankbar!



LG, PC-Hans
Antworten