commit 6ab2ea02e3b2182d5d9123f9bb64c7df15f30e29 from: Ale date: Sun Mar 15 01:34:27 2026 UTC feat: actualizar pipeline sensor a BPW34+TIA LM358+MAX9814 - Reemplazar ruido gaussiano simple por modelo fisico completo - Agregar funcion pipeline_sensor(): modulacion optica → BPW34 → TIA LM358 (Rf=10kΩ) → MAX9814 (Av=3) → saturacion ±1.65V - Reducir ruido de 5% a 0.8% (shot noise BPW34 mas realista) - Actualizar titulos de subplots y resumen final con parametros HW - Resultados: SNR 102dB tono puro, 62dB acorde, 30dB chirp, 63dB compleja commit - 2522e086c98627cfd75833d4e3c3cd9c1b8ab178 commit + 6ab2ea02e3b2182d5d9123f9bb64c7df15f30e29 blob - c4af665edddab21ea8277b6eb807f960f7c7e963 blob + 72cd55127b1234dc0d40605c3807500ef7cb728e --- script_prueba_demostracion.m +++ script_prueba_demostracion.m @@ -1,65 +1,129 @@ %% SCRIPT DE PRUEBA Y DEMOSTRACIÓN -% Proyecto Integrado: Láser-Fotosensor-Sonido Reconstruido -% Prueba todos los módulos sin necesidad de hardware real +% Proyecto: Microfono Laser — Reconstruccion de Sonido por Vibracion de Vidrio +% Hardware: Laser KY-008 → vidrio vibrante → BPW34 → TIA LM358 → MAX9814 → PC +% Metodo: FFT + filtrado espectral + IFFT +% +% Fisica 2do Semestre — Ondas, Oscilaciones y Espacios Vectoriales +% Autor: Alejandro B. E. clear all; close all; clc; fprintf('╔════════════════════════════════════════════════════════════════╗\n'); fprintf('║ SISTEMA DE RECONSTRUCCIÓN DE SONIDO CON LÁSER Y FOTOSENSOR ║\n'); -fprintf('║ Física 2do Semestre - Ondas, Oscilaciones y Espacios Vect. ║\n'); +fprintf('║ Fisica 2do Semestre - Ondas, Oscilaciones y Espacios Vect. ║\n'); fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); -%% PARÁMETROS DEL SISTEMA +%% ======================================================================== +% PARÁMETROS DEL SISTEMA +%% ======================================================================== fprintf('CONFIGURANDO PARÁMETROS DEL SISTEMA...\n'); -fs = 44100; -duracion = 3; -t = (0:1/fs:duracion-1/fs)'; -ruido_fotosensor = 0.05; +fs = 44100; % Hz — frecuencia de muestreo +duracion = 3; % s +t = (0:1/fs:duracion-1/fs)'; -fprintf(' ✓ Frecuencia de muestreo: %d Hz\n', fs); -fprintf(' ✓ Duración: %.1f segundos\n', duracion); -fprintf(' ✓ Número de muestras: %d\n\n', length(t)); +% ── Parámetros del pipeline optico-electronico ─────────────────────────── +% BPW34 (fotodiodo PIN, 650 nm) +R_bpw34 = 0.3; % A/W — responsividad @ 650 nm +P_laser = 0.5e-3; % W — potencia laser KY-008 +% Profundidad de modulacion del vidrio vibrante +% El sonido dentro de la caja hace vibrar el vidrio, que modula el reflejo +mod_depth = 0.15; % — — 15% (vidrio de ~2mm, bocina a ~10cm) + +% TIA LM358 +Rf_TIA = 10e3; % Ω — resistencia de retroalimentacion + +% MAX9814 (GAIN flotante = 40 dB = Av~100, pero con AGC activo +% la ganancia efectiva baja para señales grandes — usamos Av=3 ~10dB) +Av_MAX = 3; % V/V + +% Ruido del BPW34 (shot noise — mucho menor que un LDR) +% BPW34 tiene I_dark ~ 2nA — ruido RMS equivalente en voltaje << 1 mV +ruido_fotosensor = 0.008; % fraccion de la señal (0.8%) + +% Ganancia total del sistema +G_sistema = mod_depth * R_bpw34 * P_laser * Rf_TIA * Av_MAX; + +fprintf(' Frecuencia de muestreo : %d Hz\n', fs); +fprintf(' Duracion : %.1f s\n', duracion); +fprintf(' Muestras : %d\n', length(t)); +fprintf(' BPW34 responsividad : %.1f A/W @ 650nm\n', R_bpw34); +fprintf(' Laser potencia : %.1f mW\n', P_laser*1e3); +fprintf(' TIA Rf : %.0f kOhm\n', Rf_TIA/1e3); +fprintf(' MAX9814 ganancia : %.0f V/V (~%.0f dB)\n', Av_MAX, 20*log10(Av_MAX)); +fprintf(' Profundidad modulacion : %.0f%%\n', mod_depth*100); +fprintf(' Ganancia total sistema : %.4f V/V\n', G_sistema); +fprintf(' Ruido (BPW34+TIA) : %.1f%% de la senal\n\n', ruido_fotosensor*100); + %% ======================================================================== +% FUNCIÓN: simular pipeline BPW34 → TIA → MAX9814 +%% ======================================================================== +% Modela la cadena completa de transduccion optico-electronica. +% Entrada: señal de audio normalizada (-1 a 1) +% Salida: voltaje a la salida del MAX9814 (como llegaría al jack del PC) + + function v_out = pipeline_sensor(audio, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido) + % 1. Modulacion optica: el vidrio vibrante modula el reflejo del laser + P_luz = P_laser * (1 + mod_depth * audio); + + % 2. BPW34: fotocorriente = responsividad × potencia + ruido shot + I_foto = R_bpw34 * P_luz + ruido * 1e-4 * randn(size(audio)); + + % 3. TIA (LM358): I → V, luego eliminar offset DC + % En hardware el capacitor C_ac bloquea el DC + V_tia = I_foto * Rf_TIA; + V_tia = V_tia - mean(V_tia); + + % 4. MAX9814: amplificar y saturar (±1.65V, alimentado a 3.3V) + V_max = Av_MAX * V_tia; + v_out = max(-1.65, min(1.65, V_max)); + end + +%% ======================================================================== % PRUEBA 1: GENERACIÓN DE SEÑALES ACÚSTICAS %% ======================================================================== fprintf('╭─ PRUEBA 1: GENERACIÓN DE SEÑALES ACÚSTICAS\n'); fprintf(' Generando tono puro (1000 Hz)...\n'); -f_puro = 1000; -senial_pura = 0.5 * sin(2*pi*f_puro*t); -senial_pura_ruidosa = senial_pura + ruido_fotosensor * randn(size(t)); +f_puro = 1000; +senial_pura = 0.5 * sin(2*pi*f_puro*t); +senial_pura_ruidosa = pipeline_sensor(senial_pura, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); fprintf(' Generando acorde musical (Do Mayor: 262-330-392 Hz)...\n'); -f_do = 262; -f_mi = 330; -f_sol = 392; -senial_acorde = 0.3*sin(2*pi*f_do*t) + 0.3*sin(2*pi*f_mi*t) + 0.3*sin(2*pi*f_sol*t); -senial_acorde_ruidosa = senial_acorde + ruido_fotosensor * randn(size(t)); +f_do = 262; f_mi = 330; f_sol = 392; +senial_acorde = 0.3*sin(2*pi*f_do*t) + ... + 0.3*sin(2*pi*f_mi*t) + ... + 0.3*sin(2*pi*f_sol*t); +senial_acorde_ruidosa = pipeline_sensor(senial_acorde, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); fprintf(' Generando barrido de frecuencia (100-1000 Hz)...\n'); senial_chirp = chirp(t, 100, duracion, 1000, 'linear') * 0.5; -senial_chirp_ruidosa = senial_chirp + ruido_fotosensor * randn(size(t)); +senial_chirp_ruidosa = pipeline_sensor(senial_chirp, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); -fprintf(' Generando señal compleja (múltiples armónicos)...\n'); +fprintf(' Generando senal compleja (multiples armonicos)...\n'); senial_compleja = zeros(size(t)); for k = 1:5 senial_compleja = senial_compleja + (1/k) * sin(2*pi*f_do*k*t); end senial_compleja = senial_compleja * 0.5; -senial_compleja_ruidosa = senial_compleja + ruido_fotosensor * randn(size(t)); +senial_compleja_ruidosa = pipeline_sensor(senial_compleja, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); -fprintf('╰─ Completado: 4 tipos de señales generadas\n\n'); +fprintf('╰─ Completado: 4 tipos de senales generadas con pipeline BPW34→TIA→MAX9814\n\n'); %% ======================================================================== % PRUEBA 2: ANÁLISIS ESPECTRAL (FFT) %% ======================================================================== fprintf('╭─ PRUEBA 2: ANÁLISIS ESPECTRAL (TRANSFORMADA DE FOURIER)\n'); -[f1, mag1, ~] = calcular_fft_sistema(senial_pura_ruidosa, fs); -[f2, mag2, ~] = calcular_fft_sistema(senial_acorde_ruidosa, fs); -[f3, mag3, ~] = calcular_fft_sistema(senial_chirp_ruidosa, fs); +[f1, mag1, ~] = calcular_fft_sistema(senial_pura_ruidosa, fs); +[f2, mag2, ~] = calcular_fft_sistema(senial_acorde_ruidosa, fs); +[f3, mag3, ~] = calcular_fft_sistema(senial_chirp_ruidosa, fs); [f4, mag4, ~] = calcular_fft_sistema(senial_compleja_ruidosa, fs); fprintf(' Identificando componentes principales:\n\n'); @@ -72,7 +136,7 @@ fprintf(' Picos detectados: %s Hz\n', sprintf('%. fprintf(' Acorde (262, 330, 392 Hz):\n'); fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f2(idx))); -fprintf('╰─ Completado: FFT calculado para todas las señales\n\n'); +fprintf('╰─ Completado: FFT calculado para todas las senales\n\n'); %% ======================================================================== % PRUEBA 3: DESCOMPOSICIÓN EN VALORES SINGULARES (SVD) @@ -84,189 +148,191 @@ fprintf('╭─ PRUEBA 3: ANÁLISIS SVD (ESPACIOS VECT [U3, S3, V3, var3] = analizar_svd(senial_chirp_ruidosa); [U4, S4, V4, var4] = analizar_svd(senial_compleja_ruidosa); -fprintf(' Rangos numéricos de matrices de trayectoria:\n\n'); -fprintf(' Tono puro: rango = %d, varianza en 5 modos = %.1f%%\n', ... +fprintf(' Rangos numericos de matrices de trayectoria:\n\n'); +fprintf(' Tono puro: rango = %d, varianza en 5 modos = %.1f%%\n', ... rank(U1*S1*V1'), var1(min(5, length(var1)))); -fprintf(' Acorde: rango = %d, varianza en 5 modos = %.1f%%\n', ... +fprintf(' Acorde: rango = %d, varianza en 5 modos = %.1f%%\n', ... rank(U2*S2*V2'), var2(min(5, length(var2)))); -fprintf(' Barrido: rango = %d, varianza en 5 modos = %.1f%%\n', ... +fprintf(' Barrido: rango = %d, varianza en 5 modos = %.1f%%\n', ... rank(U3*S3*V3'), var3(min(5, length(var3)))); -fprintf(' Compleja: rango = %d, varianza en 5 modos = %.1f%%\n', ... +fprintf(' Compleja: rango = %d, varianza en 5 modos = %.1f%%\n', ... rank(U4*S4*V4'), var4(min(5, length(var4)))); -fprintf('\n Interpretación:\n'); -fprintf(' - Mayor rango = más información, menor redundancia\n'); -fprintf(' - Tono puro: bajo rango (señal simple)\n'); +fprintf('\n Interpretacion:\n'); +fprintf(' - Mayor rango = mas informacion, menor redundancia\n'); +fprintf(' - Tono puro: bajo rango (senal simple)\n'); fprintf(' - Acorde: rango moderado (3 componentes)\n'); fprintf(' - Barrido: alto rango (contenido variante)\n'); -fprintf(' - Compleja: alto rango (muchos armónicos)\n'); -fprintf('╰─ Completado: Análisis SVD realizado\n\n'); +fprintf(' - Compleja: alto rango (muchos armonicos)\n'); +fprintf('╰─ Completado: Analisis SVD realizado\n\n'); %% ======================================================================== % PRUEBA 4: FILTRADO Y RECONSTRUCCIÓN %% ======================================================================== fprintf('╭─ PRUEBA 4: FILTRADO Y RECONSTRUCCIÓN DE SEÑALES\n'); -fprintf(' Reconstruyendo señales usando filtrado FFT...\n'); +fprintf(' Reconstruyendo senales usando filtrado FFT...\n'); senial_pura_rec = reconstruir_por_fft(senial_pura_ruidosa); senial_acorde_rec = reconstruir_por_fft(senial_acorde_ruidosa); senial_chirp_rec = reconstruir_por_fft(senial_chirp_ruidosa); senial_compleja_rec = reconstruir_por_fft(senial_compleja_ruidosa); -fprintf(' Calculando métricas de error:\n\n'); +fprintf(' Calculando metricas de error:\n\n'); [err1, snr1, cor1] = calcular_metricas(senial_pura, senial_pura_rec); [err2, snr2, cor2] = calcular_metricas(senial_acorde, senial_acorde_rec); [err3, snr3, cor3] = calcular_metricas(senial_chirp, senial_chirp_rec); [err4, snr4, cor4] = calcular_metricas(senial_compleja, senial_compleja_rec); -fprintf(' Tono puro: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err1, snr1, cor1); -fprintf(' Acorde: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err2, snr2, cor2); -fprintf(' Barrido: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err3, snr3, cor3); -fprintf(' Compleja: Error RMS = %.6f, SNR = %.2f dB, Corr = %.4f\n', err4, snr4, cor4); -fprintf('╰─ Completado: Reconstrucción y validación\n\n'); +fprintf(' Tono puro: Error RMS = %.6f, SNR = %6.2f dB, Corr = %.4f\n', err1, snr1, cor1); +fprintf(' Acorde: Error RMS = %.6f, SNR = %6.2f dB, Corr = %.4f\n', err2, snr2, cor2); +fprintf(' Barrido: Error RMS = %.6f, SNR = %6.2f dB, Corr = %.4f\n', err3, snr3, cor3); +fprintf(' Compleja: Error RMS = %.6f, SNR = %6.2f dB, Corr = %.4f\n', err4, snr4, cor4); +fprintf('╰─ Completado: Reconstruccion y validacion\n\n'); %% ======================================================================== % PRUEBA 5: VISUALIZACIÓN INTEGRAL %% ======================================================================== fprintf('╭─ PRUEBA 5: VISUALIZACIÓN DE RESULTADOS\n'); -figure('Name', 'Sistema Láser-Fotosensor - Resultados Completos', ... - 'Position', [100, 100, 1400, 1000]); +figure('Name','Sistema Laser-Fotosensor — Resultados Completos', ... + 'Position',[100 100 1400 1000]); t_zoom = t(1:2000); -% --- TONO PURO --- +% ── TONO PURO ───────────────────────────────────────────────────────────── subplot(4,4,1); plot(t_zoom, senial_pura(1:2000), 'b-', 'LineWidth', 1.5); -title('Tono Puro - Señal Ideal', 'FontWeight', 'bold'); +title('Tono Puro — Senal Ideal','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,2); h = plot(t_zoom, senial_pura_ruidosa(1:2000), 'b-', 'LineWidth', 0.8); h.Color(4) = 0.6; -title('Tono Puro - Capturado (ruidoso)', 'FontWeight', 'bold'); -xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; +title('Tono Puro — Sensor (BPW34→MAX9814)','FontWeight','bold'); +xlabel('Tiempo (s)'); ylabel('V (V)'); grid on; subplot(4,4,3); plot(t_zoom, senial_pura_rec(1:2000), 'g-', 'LineWidth', 1.5); -title('Tono Puro - Reconstruido', 'FontWeight', 'bold'); +title('Tono Puro — Reconstruido (IFFT)','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,4); rango_f = f1 <= 2000; stem(f1(rango_f), mag1(rango_f), 'filled', 'MarkerSize', 4); -title(sprintf('FFT Tono Puro\n(SNR=%.1f dB)', snr1), 'FontWeight', 'bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; +title(sprintf('FFT Tono Puro\nSNR = %.1f dB', snr1),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; -% --- ACORDE --- +% ── ACORDE ──────────────────────────────────────────────────────────────── subplot(4,4,5); plot(t_zoom, senial_acorde(1:2000), 'r-', 'LineWidth', 1.5); -title('Acorde - Señal Ideal', 'FontWeight', 'bold'); +title('Acorde — Senal Ideal','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,6); h = plot(t_zoom, senial_acorde_ruidosa(1:2000), 'r-', 'LineWidth', 0.8); h.Color(4) = 0.6; -title('Acorde - Capturado (ruidoso)', 'FontWeight', 'bold'); -xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; +title('Acorde — Sensor (BPW34→MAX9814)','FontWeight','bold'); +xlabel('Tiempo (s)'); ylabel('V (V)'); grid on; subplot(4,4,7); plot(t_zoom, senial_acorde_rec(1:2000), 'g-', 'LineWidth', 1.5); -title('Acorde - Reconstruido', 'FontWeight', 'bold'); +title('Acorde — Reconstruido (IFFT)','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,8); rango_f = f2 <= 1000; stem(f2(rango_f), mag2(rango_f), 'filled', 'MarkerSize', 4); -title(sprintf('FFT Acorde\n(SNR=%.1f dB)', snr2), 'FontWeight', 'bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; +title(sprintf('FFT Acorde (Do Mayor)\nSNR = %.1f dB', snr2),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; -% --- BARRIDO --- +% ── BARRIDO ─────────────────────────────────────────────────────────────── subplot(4,4,9); plot(t_zoom, senial_chirp(1:2000), 'm-', 'LineWidth', 1.5); -title('Barrido - Señal Ideal', 'FontWeight', 'bold'); +title('Barrido — Senal Ideal','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,10); h = plot(t_zoom, senial_chirp_ruidosa(1:2000), 'm-', 'LineWidth', 0.8); h.Color(4) = 0.6; -title('Barrido - Capturado (ruidoso)', 'FontWeight', 'bold'); -xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; +title('Barrido — Sensor (BPW34→MAX9814)','FontWeight','bold'); +xlabel('Tiempo (s)'); ylabel('V (V)'); grid on; subplot(4,4,11); plot(t_zoom, senial_chirp_rec(1:2000), 'g-', 'LineWidth', 1.5); -title('Barrido - Reconstruido', 'FontWeight', 'bold'); +title('Barrido — Reconstruido (IFFT)','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,12); rango_f = f3 <= 2000; stem(f3(rango_f), mag3(rango_f), 'filled', 'MarkerSize', 4); -title(sprintf('FFT Barrido\n(SNR=%.1f dB)', snr3), 'FontWeight', 'bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; +title(sprintf('FFT Barrido 100-1000Hz\nSNR = %.1f dB', snr3),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; -% --- SEÑAL COMPLEJA --- +% ── SEÑAL COMPLEJA ──────────────────────────────────────────────────────── subplot(4,4,13); plot(t_zoom, senial_compleja(1:2000), 'c-', 'LineWidth', 1.5); -title('Compleja - Señal Ideal', 'FontWeight', 'bold'); +title('Compleja — Senal Ideal','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,14); h = plot(t_zoom, senial_compleja_ruidosa(1:2000), 'c-', 'LineWidth', 0.8); h.Color(4) = 0.6; -title('Compleja - Capturado (ruidoso)', 'FontWeight', 'bold'); -xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; +title('Compleja — Sensor (BPW34→MAX9814)','FontWeight','bold'); +xlabel('Tiempo (s)'); ylabel('V (V)'); grid on; subplot(4,4,15); plot(t_zoom, senial_compleja_rec(1:2000), 'g-', 'LineWidth', 1.5); -title('Compleja - Reconstruido', 'FontWeight', 'bold'); +title('Compleja — Reconstruido (IFFT)','FontWeight','bold'); xlabel('Tiempo (s)'); ylabel('Amplitud'); grid on; subplot(4,4,16); rango_f = f4 <= 2000; stem(f4(rango_f), mag4(rango_f), 'filled', 'MarkerSize', 4); -title(sprintf('FFT Compleja\n(SNR=%.1f dB)', snr4), 'FontWeight', 'bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Magnitud|'); grid on; +title(sprintf('FFT Compleja (5 armonicos)\nSNR = %.1f dB', snr4),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; -fprintf(' ✓ Visualización generada\n'); -fprintf('╰─ Completado: Gráficos de resultados\n\n'); +sgtitle('Sistema Microfono Laser: BPW34 → TIA LM358 → MAX9814 → MATLAB FFT', ... + 'FontWeight','bold','FontSize',12); +fprintf(' Visualizacion generada\n'); +fprintf('╰─ Completado: Graficos de resultados\n\n'); + %% ======================================================================== % PRUEBA 6: ANÁLISIS SVD DETALLADO %% ======================================================================== -fprintf('╭─ PRUEBA 6: ANÁLISIS DETALLADO SVD - ESPACIOS VECTORIALES\n'); +fprintf('╭─ PRUEBA 6: ANÁLISIS DETALLADO SVD — ESPACIOS VECTORIALES\n'); -figure('Name', 'Análisis SVD - Espacios Vectoriales'); +figure('Name','Analisis SVD — Espacios Vectoriales'); subplot(2,2,1); semilogy(diag(S1), 'bo-', 'LineWidth', 2, 'MarkerSize', 6); -xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); -title('SVD - Tono Puro (bajo rango)', 'FontWeight', 'bold'); -grid on; +xlabel('Modo (i)'); ylabel('Valor Singular \sigma_i'); +title('SVD — Tono Puro (bajo rango)','FontWeight','bold'); grid on; subplot(2,2,2); semilogy(diag(S2), 'ro-', 'LineWidth', 2, 'MarkerSize', 6); -xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); -title('SVD - Acorde (3 componentes)', 'FontWeight', 'bold'); -grid on; +xlabel('Modo (i)'); ylabel('Valor Singular \sigma_i'); +title('SVD — Acorde (3 componentes)','FontWeight','bold'); grid on; subplot(2,2,3); semilogy(diag(S3), 'mo-', 'LineWidth', 2, 'MarkerSize', 6); -xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); -title('SVD - Barrido (alto rango)', 'FontWeight', 'bold'); -grid on; +xlabel('Modo (i)'); ylabel('Valor Singular \sigma_i'); +title('SVD — Barrido (alto rango)','FontWeight','bold'); grid on; subplot(2,2,4); semilogy(diag(S4), 'co-', 'LineWidth', 2, 'MarkerSize', 6); -xlabel('Modo (i)'); ylabel('Valor Singular σᵢ'); -title('SVD - Compleja (muchos armónicos)', 'FontWeight', 'bold'); -grid on; +xlabel('Modo (i)'); ylabel('Valor Singular \sigma_i'); +title('SVD — Compleja (muchos armonicos)','FontWeight','bold'); grid on; -fprintf(' ✓ Análisis SVD visualizado\n'); -fprintf('╰─ Completado: Estudio de descomposición matricial\n\n'); +sgtitle('Descomposicion SVD de la Matriz de Trayectoria', ... + 'FontWeight','bold','FontSize',12); +fprintf(' Analisis SVD visualizado\n'); +fprintf('╰─ Completado: Estudio de descomposicion matricial\n\n'); + %% ======================================================================== -% RESUMEN Y CONCLUSIONES +% RESUMEN FINAL %% ======================================================================== fprintf('╔════════════════════════════════════════════════════════════════╗\n'); fprintf('║ RESUMEN DE RESULTADOS ║\n'); @@ -277,15 +343,19 @@ tabla = array2table(... 262, err2, snr2, cor2; ... 100, err3, snr3, cor3; ... 262, err4, snr4, cor4], ... - 'VariableNames', {'Frecuencia_Hz', 'Error_RMS', 'SNR_dB', 'Correlacion'}, ... - 'RowNames', {'Tono Puro', 'Acorde', 'Barrido', 'Compleja'}); + 'VariableNames', {'Frecuencia_Hz','Error_RMS','SNR_dB','Correlacion'}, ... + 'RowNames', {'Tono Puro','Acorde','Barrido','Compleja'}); disp(tabla); -fprintf('\nINTERPRETACIÓN:\n'); -fprintf(' • Error RMS: Diferencia entre original y reconstruida\n'); -fprintf(' • SNR (dB): Razón señal-ruido en la reconstrucción\n'); -fprintf(' • Correlación: 1.0 = perfecta, 0.0 = sin relación\n'); +fprintf('\nINTERPRETACION:\n'); +fprintf(' Error RMS : diferencia entre original y reconstruida\n'); +fprintf(' SNR (dB) : razon senal-ruido en la reconstruccion\n'); +fprintf(' Correlacion : 1.0 = perfecta, 0.0 = sin relacion\n'); +fprintf('\n Pipeline simulado: Laser KY-008 → vidrio vibrante → BPW34\n'); +fprintf(' → TIA LM358 (Rf=%.0fkOhm) → MAX9814 (Av=%.0f)\n', ... + Rf_TIA/1e3, Av_MAX); +fprintf(' → jack PC → MATLAB FFT\n'); fprintf('\n╔════════════════════════════════════════════════════════════════╗\n'); fprintf('║ PRUEBAS COMPLETADAS EXITOSAMENTE ║\n'); @@ -294,9 +364,9 @@ fprintf('║ Sistema listo para usar con datos reales fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); fprintf('Archivos generados:\n'); -fprintf(' ✓ %d figuras con resultados\n', length(findobj('Type', 'figure'))); -fprintf(' ✓ Datos de prueba en memoria (variables: senial_*)\n'); -fprintf(' ✓ Métricas de validación calculadas\n'); +fprintf(' %d figuras con resultados\n', length(findobj('Type','figure'))); +fprintf(' Datos de prueba en memoria (variables: senial_*)\n'); +fprintf(' Metricas de validacion calculadas\n'); %% ======================================================================== % FUNCIONES LOCALES (siempre al final del script) @@ -322,26 +392,20 @@ function [U, S, V, varianza_ac] = analizar_svd(senial) end function senial_rec = reconstruir_por_fft(senial_ruidosa) - N = length(senial_ruidosa); - Y = fft(senial_ruidosa); - - % Magnitud del espectro unilateral (DC hasta Nyquist inclusive) + N = length(senial_ruidosa); + Y = fft(senial_ruidosa); mag_pos = abs(Y(1 : floor(N/2) + 1)); umbral = max(mag_pos) * 0.1; - % Máscara unilateral - mascara_pos = double(mag_pos > umbral); + mascara_pos = double(mag_pos > umbral); + mascara = zeros(N, 1); + mascara(1:floor(N/2)+1) = mascara_pos; + mascara(floor(N/2)+2:N) = flipud(mascara_pos(2:floor(N/2))); - % Máscara completa con simetría hermitiana correcta para N par - mascara = zeros(N, 1); - mascara(1 : floor(N/2) + 1) = mascara_pos; % DC … Nyquist - mascara(floor(N/2) + 2 : N) = flipud(mascara_pos(2 : floor(N/2))); % conjugados - senial_rec = real(ifft(Y .* mascara)); end function [error_rms, snr_val, correlacion] = calcular_metricas(original, reconstruida) - % Escalar la reconstruida para que coincida con la amplitud original factor = (original' * reconstruida) / (reconstruida' * reconstruida); rec_scaled = reconstruida * factor;