TB066

Análisis de Circuitos (TB066)
Index Commits Files Refs
   1 clc; clear all; close all;
   2 
   3 pkg load control signal
   4 
   5 %% Configuración de Octave
   6 
   7 set(0, "defaultAxesColorOrder", [
   8         1.0000 0.0000 0.0000;  % red
   9         0.0000 0.0000 1.0000;  % blue
  10         1.0000 0.4980 0.0549;  % orange
  11         0.1725 0.6275 0.1725;  % green
  12         0.5804 0.4039 0.7412;  % purple
  13         0.5490 0.3373 0.2941;  % brown
  14         0.8902 0.4667 0.7608;  % pink
  15         0.4980 0.4980 0.4980;  % gray
  16 ]);
  17 
  18 set(0, "DefaultFigureColor", [1 1 1]);
  19 set(0, "DefaultAxesColor", [1 1 1]);
  20 set(0, "DefaultAxesXColor", [0 0 0]);
  21 set(0, "DefaultAxesYColor", [0 0 0]);
  22 set(0, "DefaultTextColor", [0 0 0]);
  23 set(0, "DefaultAxesGridColor", [0 0 0]);
  24 set(0, 'DefaultAxesGridAlpha', 1.00);
  25 set(0, "DefaultAxesMinorGridColor", [0 0 0]);
  26 set(0, 'DefaultAxesMinorGridAlpha', 0.20);
  27 set(0, "DefaultLineLinewidth", 3.00);
  28 set(0, "DefaultAxesFontSize", 16);
  29 set(0, "DefaultTextFontSize", 16);
  30 set(0, "DefaultAxesLineWidth", 1.00);
  31 set(0, "DefaultAxesXGrid", "on");
  32 set(0, "DefaultAxesYGrid", "on");
  33 set(0, "DefaultAxesZGrid", "on");
  34 set(0, "DefaultAxesXMinorGrid", "on");
  35 set(0, "DefaultAxesYMinorGrid", "on");
  36 set(0, "DefaultAxesXMinorTick", "on");
  37 set(0, "DefaultAxesYMinorTick", "on");
  38 set(0, 'DefaultAxesGridAlpha', 0.50);
  39 set(0, "defaultAxesFontName", "Nimbus Sans");
  40 set(0, "defaultaxesminorgridlinestyle", ":");
  41 
  42 set(0, "defaultfigurepaperunits", "inches");
  43 set(0, "defaultfigurepapersize", [10 4]);
  44 set(0, "defaultfigurepaperposition", [0 0 10 4]);
  45 
  46 % No abrir ventanas para ninguna figura
  47 set(0, "defaultfigurevisible", "off");
  48 
  49 %% Funcion para leer archivss
  50 
  51 function [steps_data, step_names] = ltspice_step_file(filename)
  52     % IMPORTAR_LTSPICE_STEPS Lee archivos de LTspice exportados 
  53     % con directivas .STEP
  54     %
  55     % Uso: [data, nombres] = ltspice_step_file("archivo.csv")
  56     
  57     % Abrir el archivo en modo lectura
  58     fid = fopen(filename, 'r');
  59 
  60     if fid == -1
  61         error('No se pudo abrir el archivo: %s. Revisa la ruta.', filename);
  62     end
  63 
  64     steps_data = {};  % Celda donde guardaremos los datos de cada paso
  65     step_names = {};  % Nombres de los pasos (ej: "F=250")
  66     current_step = 0; % Contador de pasos detectados
  67     temp_data = [];
  68 
  69     % Leer línea por línea
  70     while !feof(fid)
  71         linea = fgetl(fid);
  72         
  73         % Si la línea está vacía o es la cabecera original, se ignora
  74         if isempty(linea) || startsWith(linea, 'time')
  75             continue;
  76         end
  77         
  78         % Detectar si la línea contiene información de un nuevo paso (Step)
  79         if !isempty(strfind(linea, 'Step Information:'))
  80             % Si ya veníamos acumulando datos de un paso anterior, los guardamos
  81             if current_step > 0 && !isempty(temp_data)
  82                 steps_data{current_step} = temp_data;
  83                 temp_data = [];
  84             end
  85             
  86             current_step = current_step + 1;
  87             
  88             % Extraer el identificador del parámetro usando expresiones regulares
  89             tokens = regexp(linea, 'Step Information:\s*([^\(]+)', 'tokens');
  90             if !isempty(tokens)
  91                 step_names{current_step} = strtrim(tokens{1}{1});
  92             else
  93                 step_names{current_step} = sprintf('Step %d', current_step);
  94             end
  95             
  96         else
  97             % Si no es un header de Step, es una línea con números (Tiempo y Voltaje)
  98             valores = sscanf(linea, '%f %f');
  99             if length(valores) == 2
 100                 temp_data = [temp_data; valores'];
 101             end
 102         end
 103     end
 104 
 105     % No olvidar guardar el último paso leído al llegar al final del archivo
 106     if current_step > 0 && !isempty(temp_data)
 107         steps_data{current_step} = temp_data;
 108     end
 109 
 110     fclose(fid);
 111     printf('Se importaron con éxito %d pasos desde: %s\n', ...
 112         length(steps_data), filename);
 113 end
 114 
 115 % f = logspace(0, 5, 1000);
 116 % w = 2*pi*f;
 117 
 118 %% Transferencia ideal
 119 
 120 H1 = tf([1 250], [1 500])
 121 H2 = tf([4000^2], [1 4000^2/9000 4000^2])
 122 H = 12*H1*H2
 123 
 124 %% Transferencia normalizada
 125 
 126 H1_norm = tf([1 252.52], [1 505.05])
 127 H2_norm = tf([4014.80^2], [1 4014.80/2.264 4014.80^2])
 128 H_norm = 12*H1_norm*H2_norm
 129 
 130 %% Diagrama de Bode
 131 
 132 % Datos simulaciones LTSpice
 133 
 134 filename = "data/sim_bode.csv";
 135 fid = fopen(filename, "r");
 136 fgetl(fid); % Saltear encabezado
 137 data = textscan(fid, "%f %s", "Delimiter", "\t");
 138 fclose(fid);
 139 freq = data{1};
 140 w = 2*pi*freq;
 141 response = data{2};
 142 N = numel(freq);
 143 mag = zeros(N, 1);
 144 phase = zeros(N, 1);
 145 
 146 for k = 1:N
 147     tokens = regexp(response{k}, ...
 148         '\(([-+0-9.eE]+)dB,([-+0-9.eE]+)°\)', ...
 149         'tokens');
 150 
 151     mag_circ(k)   = str2double(tokens{1}{1});
 152     pha_circ(k) = str2double(tokens{1}{2});
 153 end
 154 
 155 % Transferencia ideal
 156 [mag_tf, pha_tf] = bode(H, w);
 157 
 158 % La funcion `bode` devuelve el eje `y` en escala lineal
 159 mag_tf = squeeze(mag_tf);
 160 pha_tf = squeeze(pha_tf);
 161 mag_tf = 20*log10(mag_tf);
 162 
 163 % Transferencia normalizada
 164 [mag_tf_norm, pha_tf_norm] = bode(H_norm, w);
 165 
 166 % La funcion `bode` devuelve el eje `y` en escala lineal
 167 mag_tf_norm = squeeze(mag_tf_norm);
 168 pha_tf_norm = squeeze(pha_tf_norm);
 169 mag_tf_norm = 20*log10(mag_tf_norm);
 170 
 171 % Magnitud
 172 
 173 ax1 = subplot(2, 1, 1);
 174 set(gcf, "paperunits", "inches");
 175 set(gcf, "papersize", [10 5]);
 176 set(gcf, "paperposition", [0 0 10 5]);
 177 
 178 grid on;
 179 hold on;
 180 
 181 y1 = semilogx(w, mag_tf, "LineWidth", 3.50);
 182 y2 = semilogx(w, mag_tf_norm, "LineWidth", 2.75);
 183 y3 = semilogx(w, mag_circ, "LineWidth", 2.00);
 184 
 185 ylim([-35 35])
 186 yticks([-20 0 20]);
 187 xlim([1 1e5])
 188 ylabel("MAGNITUD [dB]");
 189 set(ax1, "XTickLabel", []); % Ocultar x-tick del gráfico superior
 190 
 191 % Fase
 192 
 193 ax2 = subplot(2, 1, 2)
 194 grid on;
 195 hold on;
 196 
 197 semilogx(w, pha_tf, "LineWidth", 3.00);
 198 semilogx(w, pha_tf_norm, "LineWidth", 2.75);
 199 semilogx(w, pha_circ, "LineWidth", 2.00);
 200 
 201 ylim([-225 45])
 202 yticks([-180 -90 0]);
 203 xlim([1 1e5])
 204 xlabel("FRECUENCIA  [rad/s]");
 205 ylabel("FASE  [grados]");
 206 
 207 % Ejes invisibles para `legend`
 208 ax0 = axes("Position", [0 0 1 1], ...
 209            "Visible", "off", ...
 210            "Units", "normalized");
 211 
 212 lgd = legend(ax0, [y1 y2 y3], ...
 213              {"H", "H normalizada", "Circuito"});
 214 
 215 set(lgd, "position", [0.16 0.54 0.10 0.05]);
 216 set(lgd, "numcolumns", 1);
 217 
 218 % Reducir espacio entre sub-figuras
 219 set(ax1, "Position", [0.13 0.58 0.80 0.38]);
 220 set(ax2, "Position", [0.13 0.13 0.80 0.38]);
 221 
 222 print("plot/raw/sim_bode.png", "-dpng", "-r500");
 223 
 224 %% Respuesta al impulso (solo para las transferencias)
 225 
 226 t = linspace(0, 0.010, 10000);
 227 [h1, t1] = impulse(H, t);
 228 [h2, t2] = impulse(H_norm, t);
 229 
 230 figure();
 231 grid on;
 232 hold on;
 233 
 234 y1 = plot(t1*1e3, h1, 'linewidth', 3.00, 'displayname', 'G1');
 235 y2 = plot(t2*1e3, h2, 'linewidth', 2.25, 'displayname', 'G2');
 236 
 237 xlabel("TIEMPO  t  [ms]");
 238 ylabel("AMPLITUD");
 239 xlim([0 10])
 240 xticks(0:1:16);
 241 ylim([-35000 35000])
 242 
 243 legend("location", "southeast");
 244 
 245 legend(gca, [y1 y2], {"H", "H normalizada"});
 246 
 247 print('plot/raw/impulse.png', '-dpng', '-r500');
 248 
 249 %% Respuesta al escalon
 250 
 251 % Datos simulacion LTSpice
 252 filename = "data/sim_step.csv";
 253 fid = fopen(filename, 'r');
 254 fgetl(fid); % Saltear encabezado
 255 data = fscanf(fid, '%f %f', [2, Inf]); % Leer dos columnas
 256 fclose(fid);
 257 data = data'; 
 258 
 259 t0  = data(:, 1);
 260 u0 = data(:, 2);
 261 
 262 % Transferencias
 263 [u1, t1] = step(H, t0);
 264 [u2, t2] = step(H_norm, t0);
 265 
 266 % Plot
 267 figure();
 268 grid on;
 269 hold on;
 270 
 271 y1 = plot(t1*1e3, u1, 'linewidth', 3.50);
 272 y2 = plot(t2*1e3, u2, 'linewidth', 2.75);
 273 y0 = plot(t0*1e3, u0, 'linewidth', 2.00);
 274 
 275 xlabel("TIEMPO  t  [ms]");
 276 ylabel("AMPLITUD");
 277 legend('location', 'northeast');
 278 
 279 legend(gca, [y0 y1 y2], ...
 280     {"Circuito", 'H_{1}', 'H_{1} normalizada'});
 281 
 282 xlim([0 10])
 283 xticks(0:1:16);
 284 ylim([0 20])
 285 
 286 print('plot/raw/step.png', '-dpng', '-r500');
 287 
 288 %% Respuesta a señales senoidales
 289 
 290 set(0, "defaultAxesColorOrder", [
 291         0.1725 0.6275 0.1725;  % green
 292         0.0000 0.0000 1.0000;  % blue
 293         1.0000 0.4980 0.0549;  % orange
 294         1.0000 0.0000 0.0000;  % red
 295 ]);
 296 
 297 % Abrir el archivo en modo lectura
 298 file_path = "data/sim_sin.csv";
 299 [data, steps_name] = ltspice_step_file(file_path);
 300 
 301 freqs = [250, 636.6, 10e3]; % Frequencias [Hz]
 302 
 303 for i = 1:length(data)
 304     f = freqs(i);
 305 
 306     figure();
 307     grid on;
 308     hold on;
 309 
 310     xlabel("TIEMPO  t  [ms]");
 311     ylabel("AMPLITUD");
 312 
 313     switch i
 314         case 1
 315             sin_signal_lgd = sprintf("Señal senoidal 250 Hz");
 316             save_filename = sprintf("plot/raw/sim_sine_resp_250.png");
 317             % t = 0:1e-6:500e-3;
 318             xlim([0 50])
 319             xticks(0:5:50);
 320             ylim([-4 4])
 321             yticks([-3 -1.5 0 1.5 3]);
 322         case 2
 323             sin_signal_lgd = sprintf("Señal senoidal 637 Hz");
 324             save_filename = sprintf("plot/raw/sim_sine_resp_637.png", f);
 325             % t = 0:1e-6:10e-3;
 326             xlim([0 10])
 327             xticks(0:1:10);
 328             
 329             ylim([-4 4])
 330             yticks([-3 -1.5 0 1.5 3]);
 331         case 3
 332             sin_signal_lgd = sprintf("Señal senoidal 10 kHz");
 333             save_filename = sprintf("plot/raw/sim_sine_resp_10k.png");
 334             % t = 0:1e-9:100e-6;
 335             xlim([0 10])
 336             % xticks(0:0.1:0.5);
 337             xticks(0:1:10);
 338             ylim([-2.5 2.5])
 339             yticks([-2 -1 0 1 2]);
 340         otherwise
 341     end
 342 
 343     step_data = data{i};
 344     t = step_data(:, 1);
 345     y_circ = step_data(:, 2);
 346 
 347     u = .1*sin(2*pi*f*t);
 348     y      = lsim(H, u, t);
 349     y_norm = lsim(H_norm, u, t);
 350 
 351     y0 = plot(t*1e3, u, 'linewidth', 3.00);
 352     y1 = plot(t*1e3, y, 'linewidth', 3.75);
 353     y2 = plot(t*1e3, y_norm, 'linewidth', 3.00);
 354     y3 = plot(t*1e3, y_circ, 'linewidth', 2.25);
 355 
 356     legend("location", "southeast");
 357 
 358     legend(gca, [y0 y1 y2 y3], ...
 359         {sin_signal_lgd,...
 360             "H", "H normalizada", "Circuito"});
 361 
 362     print(save_filename, "-dpng", "-r500");
 363 end
 364 
 365 %% Respuesta a señales cuadradas
 366 
 367 file_path = "data/sim_squ.csv";
 368 [data, steps_name] = ltspice_step_file(file_path);
 369 
 370 freqs = [10, 250, 2.5e3]; % Frequencias [Hz]
 371 
 372 for i = 1:length(data)
 373     f = freqs(i);
 374 
 375     figure();
 376     grid on;
 377     hold on;
 378 
 379     xlabel("TIEMPO  t  [ms]");
 380     ylabel("AMPLITUD");
 381     % xticks(0:1:16);
 382 
 383     switch i
 384         case 1
 385             sig_lgd = sprintf("Señal cuadrada 10 Hz");
 386             save_file_name = sprintf("plot/raw/sim_square_resp_10.png");
 387             % t = 0:1e-6:500e-3;
 388             xlim([0 300])
 389             % xticks(0:1:10);
 390             ylim([-3 3])
 391             % yticks([-12 -6 0 6 12]);
 392         case 2
 393             sig_lgd = sprintf("Señal cuadrada 250 Hz");
 394             save_file_name = sprintf("plot/raw/sim_square_resp_250.png");
 395             % t = 0:1e-6:10e-3;
 396             xlim([0 25])
 397             xticks(0:5:25);
 398             ylim([-6 6])
 399         case 3
 400             sig_lgd = sprintf("Señal cuadrada 2.5 kHz");
 401             save_file_name = sprintf("plot/raw/sim_square_resp_2k5.png");
 402             % t = 0:1e-9:10e-6;
 403             xlim([0 5])
 404             xticks(0:1:5);
 405             ylim([-5 5])
 406             yticks([-4 -2 0 2 4]);
 407         otherwise
 408     end
 409 
 410     step_data = data{i};
 411     t = step_data(:, 1);
 412     y_circ = step_data(:, 2);
 413 
 414     u = .1*square(2*pi*f*t);
 415     y      = lsim(H, u, t);
 416     y_norm = lsim(H_norm, u, t);
 417 
 418     y0 = plot(t*1e3, u, 'linewidth', 3.00);
 419     y1 = plot(t*1e3, y, 'linewidth', 3.50);
 420     y2 = plot(t*1e3, y_norm, 'linewidth', 2.75);
 421     y3 = plot(t*1e3, y_circ, 'linewidth', 2.00);
 422 
 423     % legend("location", "southeast");
 424 
 425     legend(gca, [y0 y1 y2 y3], ...
 426         {sig_lgd, "H", "H normalizada", "Circuito"});
 427 
 428     print(save_file_name, "-dpng", "-r500");
 429 end
 430 
 431 % legend('location', 'southeast');
 432 % xlim([0 10])
 433 % ylim([0 20])
 434 
 435 % print('tf_step.png', '-dpng', '-r500');