tp/scripts/spice_exported_data_plots/sim/main.m (11529B)
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');
