Analyze: dac noise, pre-amp noise, amp bandwidth

This commit is contained in:
Thomas Dehaeze 2021-01-21 19:02:02 +01:00
parent 408a7d0aef
commit 1bac507d7c
5 changed files with 503 additions and 1 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

504
index.org
View File

@ -179,7 +179,313 @@ addpath('./matlab/');
addpath('./mat/');
#+end_src
*** Noise when shunting the input (50 Ohms)
*** Pre-Amp Noise
#+begin_src matlab
preamp = load('mat/noise_preamp_5113.mat', 't', 'Vn', 'notes');
#+end_src
#+begin_src matlab
preamp.Vn = preamp.Vn/preamp.notes.pre_amp.gain;
preamp.Vn = preamp.Vn - mean(preamp.Vn);
#+end_src
#+begin_src matlab
figure;
plot(preamp.t, preamp.Vn);
xlabel('Time [s]');
ylabel('Voltage [V]');
#+end_src
#+begin_src matlab :exports none
% Sampling time / frequency
Ts = (preamp.t(end) - preamp.t(1))/(length(preamp.t) - 1);
Fs = 1/Ts;
#+end_src
#+begin_src matlab
win = hanning(ceil(0.5/Ts));
[pxx, f] = pwelch(preamp.Vn, win, [], [], Fs);
preamp.pxx = pxx;
preamp.f = f;
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(preamp.f, sqrt(preamp.pxx));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
#+end_src
*** DAC (16bits) Noise
#+begin_src matlab
dac = load('mat/noise_preamp_5113_dac.mat', 't', 'Vn', 'notes');
#+end_src
#+begin_src matlab
dac.Vn = dac.Vn/dac.notes.pre_amp.gain;
#+end_src
#+begin_src matlab
dac.Vn = dac.Vn - mean(dac.Vn);
#+end_src
#+begin_src matlab
figure;
plot(dac.t, 1e6*dac.Vn);
xlabel('Time [s]');
ylabel('Voltage [$\mu V$]');
#+end_src
#+begin_src matlab :exports none
% Sampling time / frequency
Ts = (dac.t(end) - dac.t(1))/(length(dac.t) - 1);
Fs = 1/Ts;
#+end_src
The PSD of the measured noise is computed and the ASD is shown in Figure [[fig:asd_noise_3uF]].
#+begin_src matlab
win = hanning(ceil(0.5/Ts));
[pxx, f] = pwelch(dac.Vn, win, [], [], Fs);
dac.pxx = pxx;
dac.f = f;
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(dac.f, sqrt(dac.pxx), 'DisplayName', 'DAC');
plot(dac.f, ones(size(dac.f))*(10/2^16)/sqrt(12*Fs)/dac.notes.pre_amp.gain, 'k--', 'DisplayName', 'ADC quant.');
plot(preamp.f, sqrt(preamp.pxx), 'DisplayName', 'Pre Amp');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
#+end_src
*** SSI2V DAC (20bits) Noise
#+begin_src matlab
ssi2v = load('mat/noise_preamp_5113_SSI2V.mat', 't', 'Vn', 'notes');
#+end_src
#+begin_src matlab
ssi2v.Vn = ssi2v.Vn/ssi2v.notes.pre_amp.gain;
ssi2v.Vn = ssi2v.Vn - mean(ssi2v.Vn);
#+end_src
#+begin_src matlab
figure;
plot(ssi2v.t, 1e6*ssi2v.Vn);
xlabel('Time [s]');
ylabel('Voltage [$\mu V$]');
#+end_src
#+begin_src matlab :exports none
% Sampling time / frequency
Ts = (ssi2v.t(end) - ssi2v.t(1))/(length(ssi2v.t) - 1);
Fs = 1/Ts;
#+end_src
The PSD of the measured noise is computed and the ASD is shown in Figure [[fig:asd_noise_3uF]].
#+begin_src matlab
win = hanning(ceil(0.5/Ts));
[pxx, f] = pwelch(ssi2v.Vn, win, [], [], Fs);
ssi2v.pxx = pxx;
ssi2v.f = f;
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(dac.f, sqrt(dac.pxx), 'DisplayName', 'DAC');
plot(ssi2v.f, sqrt(ssi2v.pxx), 'DisplayName', 'SSI2V');
plot(ssi2v.f, ones(size(ssi2v.f))*(10/2^16)/sqrt(12*Fs)/ssi2v.notes.pre_amp.gain, 'k--', 'DisplayName', 'ADC quant.');
plot(preamp.f, sqrt(preamp.pxx), 'DisplayName', 'Pre Amp');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
#+end_src
*** Noise when shunting the input (50 Ohms) - After Warmup
#+begin_src matlab :exports none
%% Load all the measurements
pd200w = {};
for i = 1:7
pd200w(i) = {load(['mat/noise_PD200_' num2str(i) '_3uF_warmup.mat'], 't', 'Vn', 'notes')};
end
#+end_src
#+begin_src matlab :exports none
%% Take into account the pre-amplifier gain
for i = 1:7
pd200w{i}.Vn = pd200w{i}.Vn/pd200w{i}.notes.pre_amp.gain;
end
#+end_src
The time domain measurements of the amplifier noise are shown in Figure [[fig:noise_shunt_time_3uF]].
#+begin_src matlab :exports none
figure;
hold on;
for i = 1:7
plot(pd200w{i}.t, 1e3*pd200w{i}.Vn)
end
hold off;
xlabel('Time [s]');
ylabel('Voltage [mV]');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/noise_shunt_time_3uF_warmup.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:noise_shunt_time_3uF_warmup
#+caption: Time domain measurement of the amplifier output noise
#+RESULTS:
[[file:figs/noise_shunt_time_3uF_warmup.png]]
The obtained RMS and peak to peak values of the measured noises are shown in Table [[tab:rms_pkp_noise]].
#+begin_src matlab :exports none
%% Compute the RMS and Peak to Peak noise
Vn_rms = zeros(7,1); % RMS value [uV rms]
Vn_pkp = zeros(7,1); % Peak to Peak Value in 20Hz bandwidth [mV]
for i = 1:7
Vn_rms(i) = 1e6*rms(pd200w{i}.Vn);
Vn_lpf = lsim(1/(1 + s/2/pi/20), pd200w{i}.Vn, pd200w{i}.t);
Vn_pkp(i) = 1e3*(max(Vn_lpf)-min(Vn_lpf));
end
#+end_src
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
data2orgtable([[714; Vn_rms], [4.3; Vn_pkp]], {'Specification [10uF]', 'PD200_1', 'PD200_2', 'PD200_3', 'PD200_4', 'PD200_5', 'PD200_6', 'PD200_7'}, {'*RMS [uV]*', '*Peak to Peak [mV]*'}, ' %.1f ');
#+end_src
#+name: tab:rms_pkp_noise
#+caption: RMS and Peak to Peak measured noise
#+attr_latex: :environment tabularx :width \linewidth :align lXX
#+attr_latex: :center t :booktabs t :float t
#+RESULTS:
| | *RMS [uV]* | *Peak to Peak [mV]* |
|----------------------+------------+---------------------|
| Specification [10uF] | 714.0 | 4.3 |
| PD200_1 | 565.1 | 3.7 |
| PD200_2 | 767.6 | 3.5 |
| PD200_3 | 479.9 | 3.0 |
| PD200_4 | 615.7 | 3.5 |
| PD200_5 | 651.0 | 2.4 |
| PD200_6 | 473.2 | 2.7 |
| PD200_7 | 423.1 | 2.3 |
#+begin_src matlab :exports none
% Sampling time / frequency
Ts = (pd200w{1}.t(end) - pd200w{1}.t(1))/(length(pd200w{1}.t) - 1);
Fs = 1/Ts;
#+end_src
The PSD of the measured noise is computed and the ASD is shown in Figure [[fig:asd_noise_3uF]].
#+begin_src matlab
win = hanning(ceil(0.5/Ts));
for i = 1:7
[pxx, f] = pwelch(pd200w{i}.Vn, win, [], [], Fs);
pd200w{i}.f = f;
pd200w{i}.pxx = pxx;
end
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
for i = 1:7
plot(pd200w{i}.f, sqrt(pd200w{i}.pxx), 'DisplayName', sprintf('PD200W-%i', i));
end
plot(preamp.f, sqrt(preamp.pxx), 'k-', 'DisplayName', 'Pre Amp');
plot(dac.f, ones(size(dac.f))*(10/2^16)/sqrt(12*Fs)/pd200w{1}.notes.pre_amp.gain, 'k--', 'DisplayName', 'ADC quant.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
% ylim([5e-7, 1e-3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/asd_noise_3uF_warmup.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:asd_noise_3uF_warmup
#+caption: Amplitude Spectral Density of the measured noise
#+RESULTS:
[[file:figs/asd_noise_3uF_warmup.png]]
#+begin_src matlab
Gn = 1e-6*(s + 2*pi*40)^2/(s + 2*pi)^2;
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 4, 1000);
figure;
hold on;
for i = 1:7
plot(pd200w{i}.f, sqrt(pd200w{i}.pxx), 'DisplayName', sprintf('PD200W-%i', i));
end
plot(freqs, abs(squeeze(freqresp(Gn, freqs, 'Hz'))), 'k--', 'DisplayName', '$|G_n(j\omega)|$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
#+end_src
*** Load / No Load :noexport:
#+begin_src matlab
pd200_load = load('noise_PD200_7_3uF_warmup.mat');
pd200_no_load = load('noise_PD200_7_no_load.mat');
#+end_src
#+begin_src matlab
pd200_load.Vn = pd200_load.Vn/pd200_load.notes.pre_amp.gain;
pd200_no_load.Vn = pd200_no_load.Vn/pd200_no_load.notes.pre_amp.gain;
#+end_src
#+begin_src matlab :exports none
% Sampling time / frequency
Ts = (pd200_load.t(end) - pd200_load.t(1))/(length(pd200_load.t) - 1);
Fs = 1/Ts;
#+end_src
The PSD of the measured noise is computed and the ASD is shown in Figure [[fig:asd_noise_3uF]].
#+begin_src matlab
win = hanning(ceil(0.5/Ts));
[pxx_load, f] = pwelch(pd200_load.Vn, win, [], [], Fs);
[pxx_no_load, ~] = pwelch(pd200_no_load.Vn, win, [], [], Fs);
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(f, sqrt(pxx_load), 'DisplayName', 'Load');
plot(f, sqrt(pxx_no_load), 'DisplayName', 'No Load');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
#+end_src
*** Noise when shunting the input (50 Ohms) :noexport:
#+begin_src matlab :exports none
%% Load all the measurements
@ -310,6 +616,111 @@ exportFig('figs/asd_noise_3uF.pdf', 'width', 'wide', 'height', 'tall');
#+RESULTS:
[[file:figs/asd_noise_3uF.png]]
*** Noise with DAC at the input of the PD200
#+begin_src matlab :exports none
%% Load all the measurements
pd200dac = {};
for i = 1:7
pd200dac(i) = {load(['mat/noise_PD200_' num2str(i) '_3uF_DAC.mat'], 't', 'Vn', 'notes')};
end
#+end_src
#+begin_src matlab :exports none
%% Take into account the pre-amplifier gain
for i = 1:7
pd200dac{i}.Vn = pd200dac{i}.Vn/pd200dac{i}.notes.pre_amp.gain;
pd200dac{i}.Vn = pd200dac{i}.Vn - mean(pd200dac{i}.Vn);
end
#+end_src
The time domain measurements of the amplifier noise are shown in Figure [[fig:noise_shunt_time_3uF]].
#+begin_src matlab :exports none
figure;
hold on;
for i = 1:7
plot(pd200dac{i}.t, 1e3*pd200dac{i}.Vn)
end
hold off;
xlabel('Time [s]');
ylabel('Voltage [mV]');
xlim([0, 0.1]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/noise_shunt_time_3uF_dac.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:noise_shunt_time_3uF_dac
#+caption: Time domain measurement of the amplifier output noise
#+RESULTS:
[[file:figs/noise_shunt_time_3uF_dac.png]]
#+begin_src matlab :exports none
% Sampling time / frequency
Ts = (pd200dac{1}.t(end) - pd200dac{1}.t(1))/(length(pd200dac{1}.t) - 1);
Fs = 1/Ts;
#+end_src
The PSD of the measured noise is computed and the ASD is shown in Figure [[fig:asd_noise_3uF]].
#+begin_src matlab
win = hanning(ceil(0.5/Ts));
for i = 1:7
[pxx, f] = pwelch(pd200dac{i}.Vn, win, [], [], Fs);
pd200dac{i}.f = f;
pd200dac{i}.pxx = pxx;
end
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
for i = 1:7
plot(pd200dac{i}.f, sqrt(pd200dac{i}.pxx), 'DisplayName', sprintf('PD200DAC-%i', i));
end
plot(preamp.f, sqrt(preamp.pxx), 'k-', 'DisplayName', 'Pre Amp');
plot(dac.f, 20*sqrt(dac.pxx), 'k-', 'DisplayName', 'ADC noise');
plot(dac.f, ones(size(dac.f))*(10/2^16)/sqrt(12*Fs)/pd200dac{1}.notes.pre_amp.gain, 'k--', 'DisplayName', 'ADC quant.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
% ylim([5e-7, 1e-3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/asd_noise_3uF_dac.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:asd_noise_3uF_dac
#+caption: Amplitude Spectral Density of the measured noise
#+RESULTS:
[[file:figs/asd_noise_3uF_dac.png]]
#+begin_src matlab :exports none
figure;
hold on;
plot(pd200dac{1}.f, sqrt(pd200dac{1}.pxx), 'DisplayName', 'PD200 + DAC');
plot(pd200w{1}.f, sqrt(pd200w{1}.pxx), 'DisplayName', 'PD200');
plot(dac.f, 20*sqrt(dac.pxx), 'k-', 'DisplayName', 'DAC');
plot(preamp.f, sqrt(preamp.pxx), 'k-', 'DisplayName', 'Pre Amp');
plot(dac.f, ones(size(dac.f))*(10/2^16)/sqrt(12*Fs)/pd200dac{1}.notes.pre_amp.gain, 'k--', 'DisplayName', 'ADC quant.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD [$V/\sqrt{Hz}$]');
legend('location', 'southwest');
xlim([1, Fs/2]);
% ylim([5e-7, 1e-3]);
#+end_src
#+begin_important
The output noise of the PD200 amplifier is limited by the noise of the DAC.
#+end_important
*** TODO Noise with SSI2V at the input of the PD200
* Transfer Function measurement
** Setup
In order to measure the transfer function from the input voltage $V_{in}$ to the output voltage $V_{out}$, the test bench shown in Figure [[fig:setup-dynamics-measurement]] is used.
@ -327,7 +738,98 @@ For this measurement, the sampling frequency of the Speedgoat ADC should be as h
#+caption: Schematic of the test bench to estimate the dynamics from voltage input $V_{in}$ to voltage output $V_{out}$
[[file:figs/setup-dynamics-measurement.png]]
** Maximum Frequency/Voltage to not overload the amplifier
The maximum current is 1A [rms] which corresponds to 0.7A in amplitude of the sin wave.
The impedance of the capacitance is:
\[ Z_C(\omega) = \frac{1}{jC\omega} \]
Therefore the relation between the output current and the output voltage is (in amplitude):
\[ V_{out} = \frac{1}{C\omega} I_{out} \]
There is a gain of 20 between the input voltage and the output voltage:
\[ 20 V_{in} = \frac{1}{C\omega} I_{out} \]
For a specified voltage input amplitude $V_{in}$, the maximum frequency is then:
\[ \omega_{\text{max}} = \frac{1}{20 C V_{in}} I_{out,\text{max}} \]
#+begin_src matlab
Iout_max = 0.7; % Maximum output current [A]
C = 3e-6; % Load Capacitance [F]
V_in = linspace(0, 5, 100); % Input Voltage [V]
w_max = 1./(20*C*V_in) * Iout_max; % [rad/s]
figure;
plot(V_in, w_max/2/pi);
xlabel('Input Voltage Amplitude [V]');
ylabel('Maximum Frequency [Hz]');
set(gca, 'yscale', 'log');
#+end_src
** Results
*** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no
addpath('./matlab/mat/');
addpath('./matlab/');
#+end_src
#+begin_src matlab :eval no
addpath('./mat/');
#+end_src
*** First test
#+begin_src matlab
pd200_1V_1 = load('mat/tf_pd200_7_1V.mat', 't', 'Vin', 'Vout', 'Iout');
#+end_src
#+begin_src matlab
Ts = (pd200_1V_1.t(end) - pd200_1V_1.t(1))/(length(pd200_1V_1.t)-1);
Fs = 1/Ts;
#+end_src
#+begin_src matlab
win = hanning(ceil(1*Fs));
[tf_1, f] = tfestimate(pd200_1V_1.Vin, pd200_1V_1.Vout, win, [], [], 1/Ts);
#+end_src
#+begin_src matlab :exports none
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(f, abs(tf_1));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $V_{out}/V_{in}$ [V/V]'); set(gca, 'XTickLabel',[]);
hold off;
ylim([1e-1, 1e1]);
ax2 = nexttile;
hold on;
plot(f, 180/pi*angle(tf_1));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
yticks(-360:15:360);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
ylim([-45, 15]);
linkaxes([ax1,ax2],'x');
xlim([1, 2e3]);
#+end_src
* Conclusion
#+name: tab:table_name