Code MATLAB pour calculer l’intermodulation et l’interception du troisième ordre (d’un amplificateur)

Natalie Johnson

Code MATLAB pour calculer l’intermodulation et l’interception du troisième ordre (d’un amplificateur)


Mon code MATLAB et mon graphique bien annotés tentent de calculer l’ordonnée à l’origine du troisième ordre d’un amplificateur.

  1. J’ai des données brutes d’une courbe de transfert non linéaire, Voltage in (array) et la tension amplifiée out (array)
  2. Je génère deux sinusoïdes et je les additionne pour créer une forme d’onde.
  3. La forme d’onde est normalisée de sorte qu’elle est contrainte à l’intérieur du positif et du négatif d’une seule valeur d’entrée de tension provenant du réseau de courbes de transfert.
  4. Ceci est bouclé pour toutes les valeurs d’entrée de tension dans le réseau. (Une boucle principale).
  5. Chaque fois que la boucle progresse à travers les valeurs d’entrée de tension, la forme d’onde est amplifiée par la courbe de transfert (une équation d’ajustement polynomial)
  6. En d’autres termes, c’est un balayage de puissance sur la plage d’entrée de l’amplificateur, où la forme d’onde augmente progressivement en puissance.
  7. Une transformée de Fourier est calculée chaque fois que la tension d’entrée augmente (donnant une amplification plus élevée), ce qui révèle les amplitudes des fréquences des produits d’intermodulation.
  8. Enfin, un tracé est produit de l’intermod à chaque point voltage_in / voltage out_point sur la courbe de transfert et l’ordonnée à l’origine du troisième ordre (TOI) calculée. Le gradient intermod est de 3: 1 sur un graphique log-log et le gain linéaire est de 1: 1 sur un graphique log log (qui est inclus ci-dessous et sur le code).

Je sais que l’interception du troisième ordre de cet amplificateur est de -6,8 dBW. Mais j’obtiens 0,78 dBW.

S’il vous plaît, quelqu’un peut-il m’aider, j’y suis allumé et éteint depuis plus de 3 mois et ça me rend fou.

Le script est bien annoté, s’exécute en moins d’une seconde et possède d’excellents tracés.

 clear all format long % ==== Section 1 Raw Data ================== %Raw Data in DB (To start : Power in was given in dBm, Power out was dBW) p_in_tc = [-53.07 -52.66 -52.25 -51.83 -51.42 -51.01 -50.60 -50.18 -49.77 -49.36 -48.95 -48.53 -48.12 -47.71 -47.30 -46.88 -46.47 -46.06 -45.65 -45.23 -44.82 -44.41 -44.00 -43.58 -43.17 -42.76 -42.35 -41.94 -41.52 -41.11 -40.70 -40.29 -39.87 -39.46 -39.05 -38.64 -38.22 -37.81 -37.40 -36.99 -36.57 -36.16 -35.75 -35.34 -34.92 -34.51 -34.10 -33.69 -33.27 -32.86 -32.45]'; p_in_tc = p_in_tc - 30; % 30dbM = 0dBW Converted to dBw p_out_tc = [-36.31 -35.91653 -35.53542 -35.08876 -34.68977 -34.24591 -33.87132 -33.41216 -33.03855 -32.63183 -32.21841 -31.79861 -31.40797 -30.98433 -30.58884 -30.16253 -29.77254 -29.35253 -28.9475 -28.53066 -28.13344 -27.73318 -27.32436 -26.91283 -26.51466 -26.09394 -25.69517 -25.2961 -24.8958 -24.49461 -24.10408 -23.69662 -23.29808 -22.91381 -22.51055 -22.11622 -21.73276 -21.33714 -20.94937 -20.56428 -20.19364 -19.80442 -19.44888 -19.06418 -18.71527 -18.34826 -17.99767 -17.65278 -17.29772 -16.97233 -16.65949]'; %Input Data to Volts p_in_watts = 10.^((p_in_tc)/10); v_in_rms = (p_in_watts .* 50) .^(1/2); v_in_peak = v_in_rms' .* sqrt(2); %Use this Input %Output Data to Volts p_out_watts = 10.^((p_out_tc)/10); v_out_rms = (p_out_watts .* 50) .^(1/2); v_out_peak = v_out_rms' .* sqrt(2) ; %Use this Output % ===== Section 2 - Generate Waveform ============== power = 3; exponent = 1*10^power; freq_spacing = 1; freq_range = (3:freq_spacing:4)*exponent; Fs =10*max(freq_range); Ts = 1/Fs; end_time = 10*10^(-power); n = 0 : Ts : end_time-Ts; for c=1:length(v_in_peak) %Master Loop (Power sweep across all input voltage values, creating a waveform for each input voltage). %Make the number of waves in the frequency range for a = 1:length(freq_range) random_phase(a) = 0; y_exp(a,:) = (exp(i*(2*pi .* freq_range(a) .* n + random_phase(a)))); end waveform = sum(y_exp); % ==== Section 3 Normalisation (Keep waveform within input voltage ================== low = -v_in_peak(c); high = v_in_peak(c); mini = min(real(waveform)); maxi = max(real(waveform)); low2 = -v_in_peak(c); high2 = v_in_peak(c); mini2 = min(imag(waveform)); maxi2 = max(imag(waveform)); for a=1:length(waveform) wave_recon_real(a) = low + ( (real(waveform(a)) - mini) * (high-low) ) / (maxi-mini); wave_recon_imag(a) = low2 + ( (imag(waveform(a)) - mini2) * (high2-low2) ) / (maxi2-mini2); wave_recon_normalised(a) = wave_recon_real(a) + (i*wave_recon_imag(a)); waveform(a) = wave_recon_normalised(a); end % ==== Section 4 Amplification ================== p = polyfit(v_in_peak,v_out_peak,3); for a=1:length(waveform) %Gives straight line but with a flatness to start with %waveform_amp(a) = polyval(p,abs(waveform(a))) / abs(waveform(a)); %Amplify the current phasor and divide by the current phasor length to cancel out phasor in waveform in next step %waveform_amp(a) = waveform_amp(a) * waveform(a) ; %Now multiply original wave so just the amplified summed current phasor is left %Gives straight line intermods waveform_amp_real(a) = polyval(p,real(waveform(a))) ; waveform_amp_imag(a) = polyval(p,imag(waveform(a))) ; waveform_amp(a) = waveform_amp_real(a) + (i*waveform_amp_imag(a)); end %Setup Fast Fourier Transform N=length(n); freq_domain = (0:N/2); %Show positive frequency only freq_domain = freq_domain * Fs / N; %Fast Fourier Transform of Amplified wave ft2 = fft(waveform_amp)/N; ft2_spectrum = 2*abs(ft2); % 2* to compensate for negative frequency energy ft2_spectrum = ft2_spectrum(1:N/2+1); %Show positive Frequency Only %Bin Spacing Bins_per_freq= (N/Fs); %Intermods (third order only) intermod_1 = 2*freq_range(2) - freq_range(1); intermod_2 = 2*freq_range(1) - freq_range(2); freq_range_im3 = [intermod_1 intermod_2]; %Get the bin numbers of the intermods im_bins = round(Bins_per_freq * (freq_range_im3) +1); %Get the intermod bin Numbers, Domain starts at 0, so add 1 %Intermod amplitudes im = ft2_spectrum(im_bins); %Store one intermod for each power sweep, the master loop variable is c im_sweep = im(1) ; intermod_power(c) = 10*log10( (((im_sweep* (1/sqrt(2))) .^2 ) /50 )); %The Frequencies in the waveform freq_bins = round(Bins_per_freq * (freq_range) +1); %Get the frequency bin Numbers, Domain starts at 0, so add 1 freq_bin_amplitudes = ft2_spectrum(freq_bins); single_frequency = freq_bin_amplitudes(1); %Store one frequency power for each power sweep, the master loop variable is c single_frequency_power(c) = 10*log10( (((single_frequency* (1/sqrt(2))) .^2) /50 )); % ==== Section 5 Final power sweep, make the plots and caulcate TOI ================== if c == length(v_in_peak) %Final input voltage value %Obtain linear line from polynomial for a=1:length(v_in_peak) v_out_linear(a) = p(3)*((v_in_peak(a))^1); p_out_linear(a) = 10*log10(((v_out_linear(a)/sqrt(2))^2)/50); end % -- Transfer Curve Linear Line (From linear line equation) -- % Simple y=mx+c Algebra to make a straight line x1_tc = p_in_tc(1); x2_tc = p_in_tc(2); y1_tc = p_out_linear(1); y2_tc = p_out_linear(2); m_tc = 1; c_tc = y1_tc - (m_tc*x1_tc); eqn_x_tc = p_in_tc; eqn_y_tc = (m_tc .* p_in_tc) + c_tc; % -- Intermod Linear Line -- % Simple y=mx+c Algebra to make a straight line x1_im = p_in_tc(end-10); x1_im_idx = nearestpoint(x1_im,p_in_tc); x2_im = p_in_tc(end-5); x2_im_idx = nearestpoint(x2_im,p_in_tc); y1_im = intermod_power(x1_im_idx); y2_im = intermod_power(x2_im_idx); m_im = 3; c_im = y1_im - (m_im*x1_im); eqn_x_im = p_in_tc; eqn_y_im = (m_im .* p_in_tc) + c_im; %Find when lines intersect x_intersect = (c_im - c_tc) / (m_tc - m_im); y_intersect = m_im * x_intersect + c_im %Extrapolate past the intersect point for visualisation on plot eqn_x_tc_int = min(eqn_x_tc):1:x_intersect+4; eqn_y_tc_int = interp1(eqn_x_tc,eqn_y_tc,eqn_x_tc_int,'linear','extrap'); eqn_x_im_int = p_in_tc(x1_im_idx):1:x_intersect+4; eqn_y_im_int = interp1(eqn_x_im,eqn_y_im,eqn_x_im_int,'linear','extrap'); figure(1);clf; bar(freq_domain,ft2_spectrum) ax=gca; set(gca,'Fontsize',7,'Ticklength',[-0.005 0]); ax.XAxis.Exponent = power; title('Output Waveform - Frequency','Fontsize',7); xlabel('Frequency (MHz)','Fontsize',7);ylabel('Actual Amplitude (V)','Fontsize',7); %xlim([((freq_range(1)-1)*exponent) (freq_range(end)+1)*exponent]); figure(2);clf; ax=gca; set(gca,'Fontsize',7) hold on;grid on; grid minor; title('RMS Input Power vs RMS Output Power ','Fontsize',7); xlabel('Input Power (dBW) ','Fontsize',7); ylabel('Output Power (dBW) ','Fontsize',7); plot(p_in_tc,p_out_tc,'--b','DisplayName','Transfer Curve (Raw Data) - RMS'); plot(p_in_tc, single_frequency_power,'-.m*','DisplayName','Single Frequency Power - RMS','MarkerSize',2); plot(p_in_tc, intermod_power,'r','DisplayName','Intermod Power - RMS'); plot(p_in_tc,p_out_linear,'*g','DisplayName','Poly Order 1 (linear gain)'); plot(eqn_x_tc_int,eqn_y_tc_int,'k','linestyle','--','DisplayName','Linear Gain Extrapolated'); plot(eqn_x_im_int,eqn_y_im_int,'k','linestyle','--','DisplayName','Intermods Extrapolated'); legend('toggle','Location','northwest') legend('boxoff') hold off end %Final MASTER LOOP clearvars -except p_in_tc p_out_tc phase_tc v_in_peak v_out_peak power exponent freq_spacing freq_range Fs Ts end_Time nc freq_domain intermod_power single_frequency_power end 

EDIT: Voici la figure, la ligne pointillée bleue est la caractéristique de transfert mesurée, les lignes pointillées grises sont les ajustements linéaires extrapolés aux données.

C’est une parcelle log-log. Le gradient intermod est de 3, ce qui donne 3: 1. L’extrapolation linéaire provient du polynôme en utilisant le terme d’ordre 1. Vous pouvez clairement voir que le TOI est trop élevé.

Tracé d'interception de 3e ordre

bruits forts

C’est toujours un bon début quand un script MATLAB commence par un warning off !

bruits forts

Comment savez-vous que l’ordonnée à l’origine du troisième ordre est de -6,8 dBW? D’où viennent ces données?

bruits forts

Votre code manque le point le plus nearestpoint() , provient-il de cet échange de fichiers?

bruits forts

D’après la figure que vous n’avez pas ajoutée à votre message, il est clair qu’un ajustement linéaire est insuffisant pour modéliser l’interception de 3e ordre. Essayez un polynôme d’ordre supérieur.

Natalie Johnson

Également. Je connais son -6,8 dBW car il a été mesuré et le fabricant le déclare. L’ajustement linéaire, 1: 1 est tracé le long des intermods qui est une pente 3: 1. Le polynôme est d’ordre 3, et des intermodes de troisième ordre apparaissent avec le terme cubique du polynôme. Merci pour votre contribution, mettez son déjà présent dans le script.

Réponses


 analogsystemsrf

Exécutez vos points de test sur une plage d’entrée de 20, 30 ou 40 dB, et prenez log10 des valeurs d’entrée et de sortie. Prenez des données tous les 5 ou 10 dB. Jetez les données à moins de 10 dB des points de compression.

Attendez-vous à voir exactement !! Pente d’entrée / sortie 1: 1 pour le Vin / Vout du fondamental.

Attendez-vous à voir exactement !! 3: 1 pente d’entrée / sortie pour le Vin / Vout de l’énergie du 3ème ordre.

analogsystemsrf

Quelle est votre plage de puissance d’entrée? Optez pour 20 ou 30 ou 40 dB.


 bruits forts

Je vais juste préfacer cette réponse en disant que vous devez traiter les personnes qui vous aident gratuitement avec plus de respect. Personne ici ne vous doit de réponse.

En regardant quelles sont vos données vraisemblablement mesurées de la fonction de transfert, il est évident qu’un ajustement linéaire n’est pas précis car les données mesurées ne sont pas linéaires.

Par conséquent, au lieu d’extrapoler à l’aide de l’ interp1 linéaire, vous devriez utiliser l’ fit .

Ci-dessous, j’ai tracé des polynômes de deuxième et troisième ordre adaptés à vos données mesurées. Le deuxième ordre a une intersection autour de -3,8 dB, le troisième ordre autour de -8 dB.

Comme vous l’avez dit, vous vous attendez à -6,8 dB exactement, ce dont vous avez réellement besoin, ce sont de meilleures mesures. L’extrapolation à un tel point supprimé vous donnera toujours une inexactitude. Vous devez faire ce que analogsystemrf a dit et obtenir des données à moins de 10 dB.

Voici le code que j’ai ajouté pour s’adapter aux polynômes d’ordre supérieur.

 poly2Fit = fit(p_in_tc, p_out_tc, 'poly2'); poly3Fit = fit(p_in_tc, p_out_tc, 'poly3'); plot(poly2Fit,'g') plot(poly3Fit,'b') 

entrez la description de l'image ici

EDIT: Dans le cas où vous devez absolument utiliser un ajustement linéaire, vous devez utiliser le gradient à partir de la fin de la courbe et non du début, par exemple

  startPoint = 0.95; endpoly1Fit = fit(p_in_tc(ceil(startPoint*end):end),... p_out_tc(ceil(startPoint*end):end),... 'poly1'); 

Ce code utilise uniquement les données de 95% le long de la courbe mesurée et donne une intersection autour de -5 dB:

entrez la description de l'image ici

Natalie Johnson

Salut. N’était pas impoli avec mes réponses. Merci de répondre.

bruits forts

@NatalieJohnson Je me suis trompé alors! Toutes mes excuses pour ne pas avoir pu aider. Je dirais que si vous avez confiance en votre extrapolation, elle se situe quelque part dans le polynôme que vous utilisez pour modéliser la caractéristique de distorsion.

 

#et, #pour, Amplificateur, calculer, code, d’un, du, l’interception, l’intermodulation, Matlab, ordre, troisième

 

google

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *