Estoy agregando mi propia respuesta para complementar las respuestas útiles que ya he recibido. Esta respuesta convierte una señal de voltaje en un espectro de frecuencia con unidades dBV.
Notas
Uso de calculadoras en línea (1) (2) (¡eliminando mi propia ignorancia!) para calcular el valor de dBV de una onda sinusoidal de 2 Vpp, creo que es aproximadamente -3 dBV, y que una señal de 0 dBV será \ $ 2 \ sqrt {2} \ $ Vpp.
Al utilizar MATLAB, generé una señal conocida según las instrucciones en la respuesta de peufeu . El código MATLAB para el experimento se encuentra al final de esta respuesta.
Mi primer descubrimiento es que la magnitud de la FFT debe ser escalada por el número de muestras en la señal para preservar las unidades del dominio del tiempo. Creo que esto se refiere al Teorema de Parseval de La respuesta de Neil_UK como si no se normalizara el tiempo, entonces está buscando energía en lugar de poder.
Al igual que en el dominio de la frecuencia, estamos inspeccionando el valor de las componentes de onda sinusoidal, para adaptar para RMS la señal también debe escalarse por la relación de pico a RMS de una onda sinusoidal, es decir, sqrt (2).
De acuerdo con el comentario de andrea: ' La corrección para los contenedores de frecuencia de CA no es lo mismo para solicitar dc; el factor de (ed: sqrt) 2 debido a la simetría de los ejes de frecuencia positiva y negativa desaparece; el dividido por N (número de puntos) permanece allí. '
Esto requiere que una variable de escala discreta se defina como:
$$
k (m) =
\ begin {cases}
\ sqrt {2}, & m \ neq 0 \\
1, & m = 0
\ end {cases}
, \ quad m = 0, \ ldots, N-1,
$$
que escala los componentes sinusoidales en \ $ \ sqrt {2} \ $ y el componente DC en 1.
Todavía no estoy seguro de si existe dBV para los valores pico o si solo existe para RMS.
Cálculo
La DFT de la tensión está dada por
$$
V (m) = \ sum_ {n = 0} ^ {N-1} v \ cdot \ mathrm {e} ^ {\ frac {-2 \ pi j} {N} m \ cdot n}, \ quad m = 0, \ ldots, N-1,
$$
donde \ $ V \ $ es el DFT de la señal de dominio de tiempo discreto \ $ v \ $, cada una de longitud \ $ N \ $. (nota: esta es solo la forma matemática de escribirlo, pero se implementa con resultados equivalentes en la mayoría de los algoritmos fft()
pero más rápido).
Este resultado se escala por longitud y amplitud RMS:
$$
\ bar {V} (m) = \ frac {k (m)} {N} V (m), \ quad m = 0, \ ldots, N-1.
$$
Finalmente, la magnitud logarítmica se calcula para dar la respuesta de amplitud en dBV:
$$
20 \ \ text {log} _ {10} \ left | \ bar {V} (m) \ right |
$$
Ejemplo numérico
La siguiente ilustración es producida por el script MATLAB. Se genera una señal en el dominio del tiempo como la suma de dos ondas sinusoidales a 50 y 100 Hz con amplitudes de pico de 1 V y sqrt (2) V respectivamente, y un desplazamiento de CC de 1 V. El resultado es tres picos en la FFT: 0 dBV @ DC, -3 dBV a 50 Hz y 0 dBV a 100 Hz.
clear;
% Sample rate, duration, number of samples
fs = 10e3;
dur = 2*(1/50); % 2 cycles
Ns = dur*fs;
% Time and frequency axis
t = (0:Ns-1)./fs;
f = (0:Ns-1).*(fs/Ns);
% Input signal, FFT, and scaled decibel magnitude
vDC = 1;
v1 = sin(2*pi*50*t);
v2 = sqrt(2)*sin(2*pi*100*t);
v = vDC + v1 + v2;
% Scaling factor is sqrt(2) except for at DC when it is 1.
k = [1, ones(1,Ns-1)*sqrt(2)];
% Amplitude response must be scaled by time length to maintain units
VdB = 20*log10(abs((k./Ns).*fft(v)));
% Plot
figure(1);
clf;
subplot(211);
plot(t, v,'k');
hold on;
plot(t, v1,'--k');
plot(t, v2','-.k');
xlabel('Time (s)');
ylabel('Voltage (V)');
ylim([-max(v)*1.2 max(v)*1.2]);
grid on;
legend('Two-tone sum','50 Hz sine','100 Hz sine');
subplot(212);
plot(f, VdB,'k');
xlabel('Frequency (Hz)');
ylabel('Amplitude (dBV)');
ylimits = ylim;
ylim([-10 5]);
xlim([-20 200]);
grid on;
indDC = 1;
peakDCLabel = sprintf('- f = %d Hz, A = %.1f dBV',f(indDC),VdB(indDC));
text(f(indDC),VdB(indDC),peakDCLabel)
ind50Hz = find(f==50);
peak50HzLabel = sprintf('- f = %d Hz, A = %.1f dBV',f(ind50Hz),VdB(ind50Hz));
text(f(ind50Hz),VdB(ind50Hz),peak50HzLabel)
ind100Hz = find(f==100);
peak100HzLabel = sprintf('- f = %d Hz, A = %.1f dBV',f(ind100Hz),VdB(ind100Hz));
text(f(ind100Hz),VdB(ind100Hz),peak100HzLabel)