commit b0b0f591a7862aba7e436d256748ac56b62fe329 from: Ale date: Sun Mar 15 02:04:27 2026 UTC refactor: reorganizar estructura del repositorio y expandir README - Mover todos los scripts MATLAB a la carpeta `Scripts/` - Añadir imágenes de resultados, simulación 3D, diagrama de circuito, y análisis SVD en la carpeta `Imagenes/` - Actualizar el README con una descripción detallada del proyecto, hardware, software, resultados, método y estructura del repositorio - Adaptar referencias de rutas para la nueva organización commit - 3a1a479850af3cb443dd4d7f0c1d8f7ee1c80a8d commit + b0b0f591a7862aba7e436d256748ac56b62fe329 blob - /dev/null blob + 940000ce00347f0a2d5f73413e97ebde8e3203d0 (mode 644) Binary files /dev/null and Imagenes/Analisis SVD — Espacios Vectoriales.png differ blob - /dev/null blob + 14e2c929ca8a665f7a8239907a4729d9889fbc8f (mode 644) Binary files /dev/null and Imagenes/Diagrama de Circuito — Microfono Laser.png differ blob - /dev/null blob + 28beba0d6099ee0a7b02352a09857dd33d6d915e (mode 644) Binary files /dev/null and Imagenes/Reconstruccion FFT.png differ blob - /dev/null blob + 67a68f4fea96a5bef94bed41e9eaa45c0997f144 (mode 644) Binary files /dev/null and Imagenes/Simulacion 3D — Microfono Laser.png differ blob - /dev/null blob + fe2d1897d5993de457b1c66529cd12d61afc5f35 (mode 644) Binary files /dev/null and Imagenes/Sistema Laser-Fotosensor — Resultados Completos.png differ blob - ba7b58a6c20319e468009bdeaa92466a6b03cc26 blob + 8000f5d970a843c31e286e72f761d8a241eaee3c --- README.md +++ README.md @@ -1,3 +1,156 @@ -# Proyecto-Fisica-2do +# 🔬 Microfono Laser — Reconstruccion de Sonido por Vibracion de Vidrio -Proyecto, en MATLAB para la decodificación de ondas con un foto-sensor \ No newline at end of file +**Fisica 2do Semestre · Ondas, Oscilaciones y Espacios Vectoriales** +**Autor:** Bernal Estrada Alejandro + +--- + +## Descripcion + +Sistema optico-electronico que captura el sonido dentro de una caja insonorizada **sin contacto fisico**, usando la vibracion que el audio imprime sobre un vidrio. Un laser de 650 nm apunta al vidrio; el reflejo modulado por las vibraciones es capturado por un fotodiodo BPW34, amplificado por un TIA LM358 y un MAX9814, y digitalizado via el jack de microfono de la PC. MATLAB aplica la Transformada de Fourier para reconstruir el audio original. + +``` +Bocina → vibra vidrio → laser reflejado → BPW34 → TIA LM358 → MAX9814 → jack PC → MATLAB FFT +``` + +--- + +## Resultados + +### Sistema completo — pipeline BPW34 → TIA → MAX9814 → FFT + +![Resultados completos](Imagenes/Sistema%20Laser-Fotosensor%20—%20Resultados%20Completos.png) + +| Señal | Frec. base | Error RMS | SNR (dB) | Correlacion | +|---|---|---|---|---| +| Tono puro | 1000 Hz | 2.79 × 10⁻⁶ | **102.1 dB** | 1.0000 | +| Acorde Do Mayor | 262 Hz | 2.87 × 10⁻⁴ | **62.1 dB** | 1.0000 | +| Barrido chirp | 100–1000 Hz | 1.06 × 10⁻² | **30.5 dB** | 0.9996 | +| Compleja (5 armonicos) | 262 Hz | 3.00 × 10⁻⁴ | **63.1 dB** | 1.0000 | + +--- + +### Analisis SVD — Espacios Vectoriales + +![SVD](Imagenes/Analisis%20SVD%20—%20Espacios%20Vectoriales.png) + +La descomposicion en valores singulares revela la estructura del espacio vectorial de cada senal. El tono puro concentra el 99% de su energia en 1 modo; el acorde en 3 modos (uno por nota); la senal compleja en 5 modos (uno por armonico). + +--- + +### Reconstruccion FFT + +![Reconstruccion](Imagenes/Reconstruccion%20FFT.png) + +--- + +### Simulacion 3D del montaje experimental + +![Simulacion 3D](Imagenes/Simulacion%203D%20—%20Microfono%20Laser.png) + +Escena 3D animada del montaje completo: caja insonorizada, vidrio vibrante, laser KY-008, BPW34 en tubo negro, circuito TIA + MAX9814 en protoboard, y laptop con MATLAB. + +--- + +### Diagrama de circuito + +![Diagrama](Imagenes/Diagrama%20de%20Circuito%20—%20Microfono%20Laser.png) + +--- + +## Hardware + +| Componente | Funcion | Valor clave | +|---|---|---| +| Laser KY-008 (650 nm) | Fuente de luz | P = 0.5 mW | +| BPW34 (fotodiodo PIN) | Luz → corriente | R = 0.3 A/W @ 650 nm | +| LM358 (TIA) | Corriente → voltaje | Rf = 10 kΩ, Cf = 100 pF | +| Capacitor C_ac | Bloqueo DC | 10 µF | +| MAX9814 HiLetgo | Amplificador AGC | Av = 40 dB (GAIN flotante) | +| Capacitor C_sal | Bloqueo offset salida | 47 µF | +| Jack 3.5 mm | Interfaz PC | Entrada microfono | + +**Alimentacion:** +5V + GND +**Costo estimado:** ~$150–230 MXN (sin componentes ya disponibles) + +--- + +## Software + +### Estructura del repositorio + +``` +Proyecto-Fisica-2do/ +├── Scripts/ +│ ├── script_prueba_demostracion.m # Simulacion completa del sistema +│ ├── simulacion_3d_laser.m # Visualizacion 3D animada +│ └── diagrama_circuito.m # Esquematico del circuito +├── Imagenes/ +│ ├── Sistema Laser-Fotosensor — Resultados Completos.png +│ ├── Analisis SVD — Espacios Vectoriales.png +│ ├── Reconstruccion FFT.png +│ ├── Simulacion 3D — Microfono Laser.png +│ └── Diagrama de Circuito — Microfono Laser.png +└── LICENSE +``` + +### Uso + +```matlab +% 1. Simulacion matematica completa (no requiere hardware) +run('Scripts/script_prueba_demostracion.m') + +% 2. Simulacion 3D animada del montaje (presionar Q para detener) +run('Scripts/simulacion_3d_laser.m') + +% 3. Diagrama de circuito esquematico +run('Scripts/diagrama_circuito.m') +% Guardar en alta resolucion: +print(gcf, '-dpng', '-r300', 'diagrama_circuito.png') +``` + +**Requisitos:** MATLAB (base) + Signal Processing Toolbox +No requiere Simulink ni Simscape. + +--- + +## Metodo + +### Pipeline optico-electronico + +``` +1. Audio dentro de la caja → vibra el vidrio (Δx ~ µm) +2. Vidrio vibrante modula la intensidad del reflejo del laser + P_luz(t) = P_laser × [1 + m × audio(t)] (m = profundidad de modulacion) +3. BPW34 convierte luz en corriente: + I_foto = R × P_luz (R = 0.3 A/W) +4. TIA LM358 convierte corriente en voltaje: + V_TIA = I_foto × Rf (Rf = 10 kΩ) +5. C_ac elimina el offset DC +6. MAX9814 amplifica con AGC automatico (40 dB) +7. Jack PC → MATLAB captura la senal digitalizada +``` + +### Reconstruccion por FFT + +```matlab +Y = fft(senal_capturada); +umbral = max(abs(Y)) * 0.1; % conservar componentes > 10% +mascara = abs(Y) > umbral; % filtro espectral +mascara = mascara | flipud(mascara); % simetria hermitiana +senal_rec = real(ifft(Y .* mascara)); % reconstruccion +``` + +### Analisis SVD + +La matriz de trayectoria M ∈ ℝ^(ventana × cols) captura la estructura temporal de la senal. Su descomposicion M = UΣVᵀ revela cuantos modos son necesarios para representar el contenido espectral — directamente relacionado con el numero de frecuencias presentes. + +--- + +## Licencia + +Distribuido bajo los terminos del archivo [LICENSE](LICENSE). + +--- + +*Proyecto integrador — Fisica 2do Semestre · Ondas, Oscilaciones y Espacios Vectoriales* \ No newline at end of file blob - c578a92abb852e7ed90dbc89daf0ec4004ff5b1c (mode 644) blob + /dev/null --- diagrama_circuito.m +++ /dev/null @@ -1,416 +0,0 @@ -%% DIAGRAMA DE CIRCUITO — Microfono Laser -% BPW34 → TIA (LM358) → C_ac → MAX9814 → Jack PC -% -% Autor: Alejandro B. E. — Fisica 2do Semestre - -clear; close all; clc; - -fig = figure('Name','Diagrama de Circuito — Microfono Laser', ... - 'NumberTitle','off','Position',[40 40 1600 900], ... - 'Color',[0.07 0.07 0.10]); - -ax = axes('Position',[0 0 1 1],'Color',[0.07 0.07 0.10]); -hold(ax,'on'); axis(ax,'off'); -xlim(ax,[0 160]); ylim(ax,[0 95]); - -%% ─── HELPERS ──────────────────────────────────────────────────── - - function wire(ax,x1,y1,x2,y2,col,lw) - if nargin<6, col=[0.85 0.85 0.85]; end - if nargin<7, lw=1.4; end - plot(ax,[x1 x2],[y1 y2],'Color',col,'LineWidth',lw); - end - - function node(ax,x,y,col) - if nargin<4, col=[0.85 0.85 0.85]; end - plot(ax,x,y,'o','MarkerFaceColor',col,'MarkerEdgeColor',col,'MarkerSize',5); - end - - function dibujar_R(ax,xc,yc,W,H,lbl_txt,val_txt) - xs = xc - W/2; - xx = linspace(xs, xs+W, 9); - yy = yc + H/2 * [0 1 -1 1 -1 1 -1 1 0]; - plot(ax,xx,yy,'Color',[0.9 0.6 0.2],'LineWidth',1.5); - plot(ax,[xc-W/2-1.5 xc-W/2],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); - plot(ax,[xc+W/2 xc+W/2+1.5],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); - text(ax,xc,yc+H*0.9+0.3,lbl_txt,'Color',[0.9 0.7 0.3],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); - text(ax,xc,yc-H*0.9-0.5,val_txt,'Color',[0.65 0.65 0.65],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); - end - - function dibujar_C(ax,xc,yc,gap,H,lbl_txt,val_txt) - g = gap/2; - plot(ax,[xc-g xc-g],[yc-H/2 yc+H/2],'Color',[0.3 0.75 1.0],'LineWidth',2.2); - plot(ax,[xc+g xc+g],[yc-H/2 yc+H/2],'Color',[0.3 0.75 1.0],'LineWidth',2.2); - plot(ax,[xc-g-2 xc-g],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); - plot(ax,[xc+g xc+g+2],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); - text(ax,xc,yc+H/2+0.9,lbl_txt,'Color',[0.3 0.85 1.0],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); - text(ax,xc,yc-H/2-1.2,val_txt,'Color',[0.55 0.55 0.65],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); - end - - function gnd(ax,x,y) - plot(ax,[x x],[y y-1.2],'Color',[0.55 0.55 0.55],'LineWidth',1.3); - w = [2.2 1.5 0.7]; - for i=1:3 - plot(ax,[x-w(i) x+w(i)],[y-1.2-(i-1)*0.7 y-1.2-(i-1)*0.7], ... - 'Color',[0.55 0.55 0.55],'LineWidth',1.2); - end - end - - function vcc(ax,x,y,lbl_txt) - if nargin<4, lbl_txt='+5V'; end - plot(ax,[x x],[y y+1.5],'Color',[0.9 0.35 0.35],'LineWidth',1.3); - plot(ax,[x-1.2 x+1.2],[y+1.5 y+1.5],'Color',[0.9 0.35 0.35],'LineWidth',2); - text(ax,x,y+2.8,lbl_txt,'Color',[0.95 0.4 0.4],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); - end - -%% ─── LAYOUT: el circuito ocupa y=30..92, tabla y=2..17 ───────── -% GND rail en y=30 (antes 18) — deja espacio para tabla abajo -Y_GND = 30; % rail GND -Y_VCC = 82; % rail +5V -Y_UP = 12; % desplazamiento vertical respecto a version anterior (+12) - -%% ═══════════════════════════════════════════════════════════════ -% TITULO -%% ═══════════════════════════════════════════════════════════════ -text(ax,80,93,'Diagrama de Circuito — Microfono Laser', ... - 'Color',[1 0.75 0.15],'FontSize',14,'HorizontalAlignment','center', ... - 'FontWeight','bold','FontName','Courier New'); -text(ax,80,90,'BPW34 → TIA LM358 → C_{ac} → MAX9814 → Jack PC → MATLAB FFT', ... - 'Color',[0.6 0.6 0.6],'FontSize',9,'HorizontalAlignment','center', ... - 'FontName','Courier New'); -plot(ax,[3 157],[87.5 87.5],'Color',[0.25 0.25 0.3],'LineWidth',0.8); - -%% ═══════════════════════════════════════════════════════════════ -% RAILS -%% ═══════════════════════════════════════════════════════════════ -plot(ax,[5 155],[Y_VCC Y_VCC],'Color',[0.7 0.2 0.2],'LineWidth',1,'LineStyle','--'); -text(ax,4,Y_VCC+0.6,'+5V','Color',[0.9 0.4 0.4],'FontSize',7,'FontName','Courier New'); -plot(ax,[5 155],[Y_GND Y_GND],'Color',[0.4 0.4 0.4],'LineWidth',1,'LineStyle','--'); -text(ax,4,Y_GND-0.8,'GND','Color',[0.55 0.55 0.55],'FontSize',7,'FontName','Courier New'); - -% Separador entre circuito y tabla -plot(ax,[3 157],[27.5 27.5],'Color',[0.2 0.2 0.25],'LineWidth',1.2); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 1: SENSOR OPTICO (y += 12 respecto a version anterior) -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[5 42 28 30],'EdgeColor',[0.4 0.4 0.5], ... - 'LineWidth',0.8,'LineStyle',':'); -text(ax,19,73.5,'SENSOR OPTICO','Color',[0.5 0.5 0.6],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -% Laser KY-008 -rectangle(ax,'Position',[7 44 8 6],'EdgeColor',[0.3 0.9 0.3], ... - 'FaceColor',[0.05 0.15 0.05],'LineWidth',1.3,'Curvature',0.2); -text(ax,11,47.2,'LASER','Color',[0.3 1.0 0.3],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); -text(ax,11,45.8,'KY-008','Color',[0.3 0.7 0.3],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,11,44.6,'650 nm','Color',[0.5 0.5 0.5],'FontSize',6, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -% Haz laser -x_beam = linspace(15,25,60); -y_beam = 47 + 0.15*sin(linspace(0,6*pi,60)); -plot(ax,x_beam,y_beam,'Color',[1 0.2 0.2],'LineWidth',1.8); -text(ax,20,48.3,'haz 650nm','Color',[1 0.4 0.4],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -% Vidrio -plot(ax,[26 26],[40 56],'Color',[0.4 0.75 1.0],'LineWidth',3); -plot(ax,[26.8 26.8],[40 56],'Color',[0.3 0.6 0.9],'LineWidth',1); -text(ax,26,57.2,'VIDRIO','Color',[0.4 0.85 1.0],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); -text(ax,26,56.0,'(vibra con','Color',[0.4 0.7 0.85],'FontSize',6.2, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,26,55.0,'el sonido)','Color',[0.4 0.7 0.85],'FontSize',6.2, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -% Reflexion -x_ref = linspace(27,22,30); -y_ref = linspace(47,62,30); -plot(ax,x_ref,y_ref,'Color',[1 0.4 0.4],'LineWidth',1.5,'LineStyle','--'); -text(ax,23.5,56,'reflexion','Color',[1 0.5 0.5],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -% BPW34 -xd = 20; yd = 65; -patch(ax,[xd-1.5 xd+1.5 xd-1.5],[yd-1.8 yd yd+1.8], ... - [0.2 0.2 0.2],'FaceColor',[0.15 0.15 0.25], ... - 'EdgeColor',[1 0.8 0.2],'LineWidth',1.5); -plot(ax,[xd+1.5 xd+1.5],[yd-1.8 yd+1.8],'Color',[1 0.8 0.2],'LineWidth',2); -plot(ax,[xd-3 xd-1.5],[yd yd],'Color',[0.85 0.85 0.85],'LineWidth',1.4); -plot(ax,[xd+1.5 xd+3],[yd yd],'Color',[0.85 0.85 0.85],'LineWidth',1.4); -for ang = [-25 0 25] - dx_p = 1.8*cosd(ang+180); dy_p = 1.8*sind(ang+180); - plot(ax,[xd+dx_p xd-0.2],[yd+dy_p yd], ... - 'Color',[1 0.9 0.3],'LineWidth',1,'LineStyle','--'); -end -text(ax,xd,yd+4.2,'BPW34','Color',[1.0 0.85 0.15],'FontSize',8.5, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); -text(ax,xd,yd+2.8,'Fotodiodo PIN','Color',[0.7 0.7 0.0],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,xd-3.8,yd+0.3,'K','Color',[0.65 0.65 0.65],'FontSize',7,'FontName','Courier New'); -text(ax,xd+2.5,yd+0.3,'A','Color',[0.65 0.65 0.65],'FontSize',7,'FontName','Courier New'); - -wire(ax,xd-3,yd,xd-3,Y_VCC); vcc(ax,xd-3,Y_VCC,'+5V'); -wire(ax,xd+3,yd,xd+3,Y_GND); gnd(ax,xd+3,Y_GND); -text(ax,xd,yd-3.5,'polariz. inversa','Color',[0.5 0.5 0.5],'FontSize',6, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -wire(ax,xd+3,yd,35,yd); -node(ax,35,yd); -text(ax,32,yd+1.5,'I_{foto}','Color',[1.0 0.85 0.2],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 2: TIA — LM358 -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[35 40 42 36],'EdgeColor',[0.3 0.5 0.8], ... - 'LineWidth',0.8,'LineStyle',':'); -text(ax,56,77.5,'TIA — LM358','Color',[0.4 0.6 0.9],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -xop=58; yop=56; sz=7; -patch(ax,[xop-sz xop-sz xop+sz],[yop-sz yop+sz yop], ... - [0.1 0.1 0.2],'FaceColor',[0.08 0.08 0.18], ... - 'EdgeColor',[0.4 0.6 1.0],'LineWidth',1.8); -text(ax,xop-1,yop,'LM358','Color',[0.5 0.7 1.0],'FontSize',7, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); - -xin=xop-sz; yin_n=yop+3.5; yin_p=yop-3.5; yout=yop; -text(ax,xin-0.6,yin_n,'−','Color',[0.7 0.7 0.9],'FontSize',10,'FontName','Courier New'); -text(ax,xin-0.6,yin_p,'+','Color',[0.7 0.7 0.9],'FontSize',10,'FontName','Courier New'); - -xout_node = xop+sz+2; -wire(ax,xop+sz,yout,xout_node,yout); - -wire(ax,35,yd,35,yin_n); -wire(ax,35,yin_n,xin,yin_n); -node(ax,35,yin_n); - -% Retroalimentacion Rf -wire(ax,xout_node,yout,xout_node,yop+12); -wire(ax,xout_node,yop+12,xin-2,yop+12); -wire(ax,xin-2,yop+12,xin-2,yin_n); -node(ax,xin-2,yin_n); -node(ax,xout_node,yout); -dibujar_R(ax,(xout_node+xin-2)/2,yop+12,14,1.8,'R_f','1 MOhm'); - -% Cf paralelo con Rf -wire(ax,xout_node,yop+15.5,xin-2,yop+15.5); -wire(ax,xout_node,yop+12,xout_node,yop+15.5); -wire(ax,xin-2,yop+12,xin-2,yop+15.5); -dibujar_C(ax,(xout_node+xin-2)/2,yop+15.5,1.5,2.5,'C_f','100pF'); - -% Divisor Vref -wire(ax,xin,yin_p,xin-4,yin_p); -dibujar_R(ax,xin-8,yin_p,6,1.5,'R1','100k'); -wire(ax,xin-11,yin_p,xin-11,Y_VCC); vcc(ax,xin-11,Y_VCC,'+5V'); -wire(ax,xin-4,yin_p,xin-4,yin_p-3); -dibujar_R(ax,xin-4,yin_p-6,6,1.5,'R2','100k'); -wire(ax,xin-4,yin_p-9,xin-4,Y_GND); gnd(ax,xin-4,Y_GND); -node(ax,xin-4,yin_p); -text(ax,xin-5.5,yin_p+2,'V_{ref}','Color',[0.8 0.5 0.5],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,xin-5.5,yin_p+0.7,'2.5V','Color',[0.6 0.4 0.4],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -wire(ax,xop,yop+sz,xop,Y_VCC); vcc(ax,xop,Y_VCC,'+5V'); -wire(ax,xop,yop-sz,xop,Y_GND); gnd(ax,xop,Y_GND); - -text(ax,xout_node+1,yout+1.5,'V_{TIA}','Color',[0.4 0.7 1.0],'FontSize',7.5, ... - 'HorizontalAlignment','left','FontName','Courier New','FontWeight','bold'); -text(ax,xout_node+1,yout-1.5,'= I x R_f','Color',[0.35 0.55 0.8],'FontSize',6.5, ... - 'HorizontalAlignment','left','FontName','Courier New'); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 3: ACOPLAMIENTO AC -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[78 48 18 16],'EdgeColor',[0.3 0.6 0.6], ... - 'LineWidth',0.8,'LineStyle',':'); -text(ax,87,65.5,'C_{ac} (bloqueo DC)','Color',[0.35 0.7 0.7],'FontSize',6.8, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -wire(ax,xout_node,yout,79,yout); -wire(ax,79,yout,79,56); -wire(ax,79,56,82,56); -dibujar_C(ax,87,56,1.8,3.5,'C_{ac}','10 uF'); -wire(ax,89,56,93,56); -wire(ax,93,56,93,52); -dibujar_R(ax,93,49,5,1.5,'R_{in}','10k'); -wire(ax,93,46,93,Y_GND); gnd(ax,93,Y_GND); -node(ax,93,56); -wire(ax,93,56,96,56); -text(ax,87,53.5,'elimina V_{DC}','Color',[0.35 0.65 0.65],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,87,52.3,'pasa V_{AC}','Color',[0.35 0.65 0.65],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 4: MAX9814 -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[96 42 30 36],'EdgeColor',[0.7 0.3 0.9], ... - 'FaceColor',[0.08 0.04 0.12],'LineWidth',1.8,'Curvature',0.08); -text(ax,111,79.5,'MAX9814','Color',[0.9 0.5 1.0],'FontSize',10, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); -text(ax,111,77.5,'HiLetgo Module','Color',[0.65 0.35 0.75],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -pins_y = [74 69 64 59 54 49 44]; -pins_lbl = {'VCC','GND','OUT','GAIN','AR','MIC\_IN','MIC\_BIAS'}; -pins_col = {[0.9 0.35 0.35],[0.55 0.55 0.55],[0.3 0.9 0.6], ... - [0.8 0.8 0.3],[0.7 0.6 0.5],[0.9 0.6 0.3],[0.6 0.5 0.7]}; -for i = 1:length(pins_y) - plot(ax,[96 99],[pins_y(i) pins_y(i)],'Color',pins_col{i},'LineWidth',1.5); - plot(ax,97,pins_y(i),'s','MarkerFaceColor',pins_col{i}, ... - 'MarkerEdgeColor',pins_col{i},'MarkerSize',5); - text(ax,100.5,pins_y(i),pins_lbl{i},'Color',pins_col{i},'FontSize',7, ... - 'VerticalAlignment','middle','FontName','Courier New','FontWeight','bold'); -end - -wire(ax,96,74,88,74); wire(ax,88,74,88,Y_VCC); vcc(ax,88,Y_VCC,'+5V'); -wire(ax,96,69,88,69); wire(ax,88,69,88,Y_GND); gnd(ax,88,Y_GND); -wire(ax,96,56,96,49); node(ax,96,56); -wire(ax,96,59,94,59); -text(ax,93,59,'NC','Color',[0.5 0.5 0.5],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,91,57.5,'(float=40dB)','Color',[0.55 0.55 0.35],'FontSize',6.2, ... - 'HorizontalAlignment','center','FontName','Courier New'); -wire(ax,96,54,94,54); -dibujar_C(ax,92,54,1.5,2.5,'C_{AR}','4.7uF'); -wire(ax,89.5,54,89.5,Y_GND); gnd(ax,89.5,Y_GND); -plot(ax,[123 127],[64 64],'Color',[0.3 0.9 0.6],'LineWidth',1.8); -plot(ax,126.5,64,'s','MarkerFaceColor',[0.3 0.9 0.6], ... - 'MarkerEdgeColor',[0.3 0.9 0.6],'MarkerSize',5); -text(ax,122,64,'OUT','Color',[0.3 0.9 0.6],'FontSize',7, ... - 'HorizontalAlignment','right','FontName','Courier New','FontWeight','bold'); -wire(ax,126,64,131,64); - -text(ax,113,59,'AGC','Color',[0.8 0.5 0.9],'FontSize',8.5, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); -text(ax,113,57.5,'auto-ganancia','Color',[0.6 0.35 0.7],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,113,56.2,'40 / 50 / 60 dB','Color',[0.6 0.35 0.7],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 5: CAPACITOR DE SALIDA -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[130 56 12 14],'EdgeColor',[0.3 0.5 0.6], ... - 'LineWidth',0.8,'LineStyle',':'); -text(ax,136,71,'C_{sal}','Color',[0.35 0.6 0.7],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); -wire(ax,131,64,133,64); -dibujar_C(ax,136,64,1.8,3.5,'C_{sal}','47 uF'); -wire(ax,139,64,142,64); -wire(ax,139,64,139,60); -dibujar_R(ax,139,57,5,1.5,'R_L','10k'); -wire(ax,139,54,139,Y_GND); gnd(ax,139,Y_GND); -node(ax,139,64); -text(ax,136,61.5,'bloquea offset','Color',[0.35 0.55 0.65],'FontSize',6.2, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,136,60.3,'1.25V MAX9814','Color',[0.35 0.55 0.65],'FontSize',6.2, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 6: JACK 3.5mm -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[142 56 16 16],'EdgeColor',[0.3 0.7 0.4], ... - 'FaceColor',[0.04 0.1 0.06],'LineWidth',1.5,'Curvature',0.1); -xj=150; yj=64; -th=linspace(0,2*pi,60); -plot(ax,xj+2*cos(th),yj+2*sin(th),'Color',[0.4 0.8 0.4],'LineWidth',1.5); -plot(ax,xj+1*cos(th),yj+1*sin(th),'Color',[0.6 0.9 0.6],'LineWidth',1); -plot(ax,[xj-2 xj+2],[yj yj],'Color',[0.4 0.8 0.4],'LineWidth',1.5); -plot(ax,[xj xj],[yj-2 yj+2],'Color',[0.4 0.8 0.4],'LineWidth',1.5); -wire(ax,142,64,148,64); -text(ax,150,69.8,'JACK 3.5mm','Color',[0.35 0.85 0.45],'FontSize',7.5, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); -text(ax,150,68.5,'Microfono PC','Color',[0.3 0.65 0.35],'FontSize',6.8, ... - 'HorizontalAlignment','center','FontName','Courier New'); -wire(ax,150,yj-2,150,Y_GND); gnd(ax,150,Y_GND); - -%% ═══════════════════════════════════════════════════════════════ -% BLOQUE 7: PC + MATLAB -%% ═══════════════════════════════════════════════════════════════ -rectangle(ax,'Position',[154 47 5 26],'EdgeColor',[0.2 0.6 0.8], ... - 'FaceColor',[0.03 0.08 0.12],'LineWidth',1.5,'Curvature',0.05); -wire(ax,152,64,154,64); -plot(ax,[153.5 154.5],[64.4 64],'Color',[0.3 0.75 0.95],'LineWidth',1.5); -plot(ax,[153.5 154.5],[63.6 64],'Color',[0.3 0.75 0.95],'LineWidth',1.5); -text(ax,156.5,67,'PC','Color',[0.3 0.75 0.95],'FontSize',8, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); -text(ax,156.5,63,'+','Color',[0.25 0.6 0.8],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,156.5,60,'MAT','Color',[0.25 0.6 0.8],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,156.5,58,'LAB','Color',[0.25 0.6 0.8],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -text(ax,156.5,55,'FFT','Color',[0.2 0.5 0.7],'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -%% ═══════════════════════════════════════════════════════════════ -% FLUJO DE SENAL — debajo del separador (y < 27) -%% ═══════════════════════════════════════════════════════════════ -y_flow = 23.5; -puntos_x = [20 35 58 87 111 136 150 156]; -nombres = {'I_{foto}','->V_{TIA}','V_{TIA}','V_{AC}','V_{amp}','V_{out}','V_{PC}','AUDIO'}; -colores = {[1.0 0.85 0.2],[0.4 0.7 1.0],[0.4 0.7 1.0],[0.3 0.8 0.8], ... - [0.85 0.5 1.0],[0.85 0.5 1.0],[0.35 0.85 0.45],[0.3 0.75 0.95]}; -for i = 1:length(puntos_x)-1 - plot(ax,[puntos_x(i)+0.5 puntos_x(i+1)-0.5],[y_flow y_flow], ... - 'Color',[0.3 0.3 0.35],'LineWidth',1.2); - plot(ax,[puntos_x(i+1)-1.2 puntos_x(i+1)-0.3 puntos_x(i+1)-1.2], ... - [y_flow+0.5 y_flow y_flow-0.5], ... - 'Color',[0.3 0.3 0.35],'LineWidth',1.2); -end -for i = 1:length(puntos_x) - plot(ax,puntos_x(i),y_flow,'o','MarkerFaceColor',colores{i}, ... - 'MarkerEdgeColor',colores{i},'MarkerSize',4); - text(ax,puntos_x(i),y_flow+1.5,nombres{i},'Color',colores{i},'FontSize',6.5, ... - 'HorizontalAlignment','center','FontName','Courier New'); -end -text(ax,80,y_flow-1.2,'← Flujo de senal →','Color',[0.4 0.4 0.45],'FontSize',7, ... - 'HorizontalAlignment','center','FontName','Courier New'); - -%% ═══════════════════════════════════════════════════════════════ -% TABLA DE VALORES — bien separada abajo del flujo -%% ═══════════════════════════════════════════════════════════════ -xT = 20; yT = 11; % y=10..21, debajo del flujo (y=23.5) -rectangle(ax,'Position',[xT yT-1 120 11],'EdgeColor',[0.25 0.25 0.3], ... - 'FaceColor',[0.07 0.07 0.09],'LineWidth',0.8); -text(ax,xT+60,yT+9.5,'Valores del circuito','Color',[0.75 0.75 0.8],'FontSize',8.5, ... - 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); - -datos = { - 'BPW34', 'Responsividad:', '0.3 A/W @ 650 nm', [1.0 0.85 0.2]; - 'LM358 TIA', 'Rf = 1 MOhm,', 'Cf = 100 pF', [0.4 0.7 1.0]; - 'C_ac', '10 uF fc =', '1.6 Hz (paso AC)', [0.3 0.8 0.8]; - 'MAX9814', 'Av = 40 dB,', 'AGC automatico', [0.85 0.5 1.0]; - 'C_sal', '47 uF fc =', '0.34 Hz', [0.35 0.7 0.45]; - 'Alimentacion', '+5V + GND,', 'VCC LM358 + laser', [0.9 0.4 0.4]; -}; -col_x = [xT+2, xT+28, xT+60]; -for i = 1:size(datos,1) - yi = yT + 8.0 - (i-1)*1.55; - text(ax,col_x(1),yi,datos{i,1},'Color',datos{i,4},'FontSize',7.5, ... - 'FontWeight','bold','FontName','Courier New'); - text(ax,col_x(2),yi,datos{i,2},'Color',[0.65 0.65 0.65],'FontSize',7.5,'FontName','Courier New'); - text(ax,col_x(3),yi,datos{i,3},'Color',[0.5 0.5 0.55],'FontSize',7.5,'FontName','Courier New'); -end - -%% ─── Pie ────────────────────────────────────────────────────── -plot(ax,[3 157],[9.5 9.5],'Color',[0.2 0.2 0.25],'LineWidth',0.8); -text(ax,80,1.8, ... - 'Fisica 2do Semestre | Ondas y Oscilaciones | BPW34 + LM358 + MAX9814 + MATLAB FFT', ... - 'Color',[0.35 0.35 0.4],'FontSize',7.5,'HorizontalAlignment','center', ... - 'FontName','Courier New'); - -fprintf(' Diagrama generado.\n'); -fprintf(' Para guardar: print(gcf,''-dpng'',''-r300'',''diagrama_circuito.png'')\n'); \ No newline at end of file blob - 72cd55127b1234dc0d40605c3807500ef7cb728e (mode 644) blob + /dev/null --- script_prueba_demostracion.m +++ /dev/null @@ -1,422 +0,0 @@ -%% SCRIPT DE PRUEBA Y DEMOSTRACIÓN -% 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('║ Fisica 2do Semestre - Ondas, Oscilaciones y Espacios Vect. ║\n'); -fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); - -%% ======================================================================== -% PARÁMETROS DEL SISTEMA -%% ======================================================================== -fprintf('CONFIGURANDO PARÁMETROS DEL SISTEMA...\n'); - -fs = 44100; % Hz — frecuencia de muestreo -duracion = 3; % s -t = (0:1/fs:duracion-1/fs)'; - -% ── 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 = 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 = 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 = pipeline_sensor(senial_chirp, P_laser, mod_depth, ... - R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); - -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 = pipeline_sensor(senial_compleja, P_laser, mod_depth, ... - R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); - -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); -[f4, mag4, ~] = calcular_fft_sistema(senial_compleja_ruidosa, fs); - -fprintf(' Identificando componentes principales:\n\n'); - -[~, idx] = findpeaks(mag1, 'MinPeakHeight', max(mag1)*0.2); -fprintf(' Tono puro (1000 Hz):\n'); -fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f1(idx))); - -[~, idx] = findpeaks(mag2, 'MinPeakHeight', max(mag2)*0.2); -fprintf(' Acorde (262, 330, 392 Hz):\n'); -fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f2(idx))); - -fprintf('╰─ Completado: FFT calculado para todas las senales\n\n'); - -%% ======================================================================== -% PRUEBA 3: DESCOMPOSICIÓN EN VALORES SINGULARES (SVD) -%% ======================================================================== -fprintf('╭─ PRUEBA 3: ANÁLISIS SVD (ESPACIOS VECTORIALES)\n'); - -[U1, S1, V1, var1] = analizar_svd(senial_pura_ruidosa); -[U2, S2, V2, var2] = analizar_svd(senial_acorde_ruidosa); -[U3, S3, V3, var3] = analizar_svd(senial_chirp_ruidosa); -[U4, S4, V4, var4] = analizar_svd(senial_compleja_ruidosa); - -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', ... - rank(U2*S2*V2'), var2(min(5, length(var2)))); -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', ... - rank(U4*S4*V4'), var4(min(5, length(var4)))); - -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 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 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 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 = %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 Laser-Fotosensor — Resultados Completos', ... - 'Position',[100 100 1400 1000]); - -t_zoom = t(1:2000); - -% ── TONO PURO ───────────────────────────────────────────────────────────── -subplot(4,4,1); -plot(t_zoom, senial_pura(1:2000), 'b-', 'LineWidth', 1.5); -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 — 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 (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\nSNR = %.1f dB', snr1),'FontWeight','bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; - -% ── ACORDE ──────────────────────────────────────────────────────────────── -subplot(4,4,5); -plot(t_zoom, senial_acorde(1:2000), 'r-', 'LineWidth', 1.5); -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 — 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 (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 (Do Mayor)\nSNR = %.1f dB', snr2),'FontWeight','bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; - -% ── BARRIDO ─────────────────────────────────────────────────────────────── -subplot(4,4,9); -plot(t_zoom, senial_chirp(1:2000), 'm-', 'LineWidth', 1.5); -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 — 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 (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 100-1000Hz\nSNR = %.1f dB', snr3),'FontWeight','bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; - -% ── SEÑAL COMPLEJA ──────────────────────────────────────────────────────── -subplot(4,4,13); -plot(t_zoom, senial_compleja(1:2000), 'c-', 'LineWidth', 1.5); -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 — 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 (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 (5 armonicos)\nSNR = %.1f dB', snr4),'FontWeight','bold'); -xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; - -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'); - -figure('Name','Analisis SVD — Espacios Vectoriales'); - -subplot(2,2,1); -semilogy(diag(S1), 'bo-', 'LineWidth', 2, 'MarkerSize', 6); -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 \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 \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 \sigma_i'); -title('SVD — Compleja (muchos armonicos)','FontWeight','bold'); grid on; - -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 FINAL -%% ======================================================================== -fprintf('╔════════════════════════════════════════════════════════════════╗\n'); -fprintf('║ RESUMEN DE RESULTADOS ║\n'); -fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); - -tabla = array2table(... - [1000, err1, snr1, cor1; ... - 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'}); - -disp(tabla); - -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'); -fprintf('║ ║\n'); -fprintf('║ Sistema listo para usar con datos reales del fotosensor ║\n'); -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(' Metricas de validacion calculadas\n'); - -%% ======================================================================== -% FUNCIONES LOCALES (siempre al final del script) -%% ======================================================================== - -function [f, mag, Y] = calcular_fft_sistema(senial, fs) - N = length(senial); - Y = fft(senial); - mag = abs(Y(1:N/2)) / N; - f = fs * (0:N/2-1) / N; -end - -function [U, S, V, varianza_ac] = analizar_svd(senial) - ventana = max(2, round(length(senial) / 100)); - cols = length(senial) - ventana + 1; - M = zeros(ventana, cols); - for i = 1:ventana - M(i,:) = senial(i : i + cols - 1)'; - end - [U, S, V] = svd(M, 'econ'); - sv = diag(S); - varianza_ac = cumsum(sv.^2) / sum(sv.^2) * 100; -end - -function senial_rec = reconstruir_por_fft(senial_ruidosa) - N = length(senial_ruidosa); - Y = fft(senial_ruidosa); - mag_pos = abs(Y(1 : floor(N/2) + 1)); - umbral = max(mag_pos) * 0.1; - - 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))); - - senial_rec = real(ifft(Y .* mascara)); -end - -function [error_rms, snr_val, correlacion] = calcular_metricas(original, reconstruida) - factor = (original' * reconstruida) / (reconstruida' * reconstruida); - rec_scaled = reconstruida * factor; - - error_rms = sqrt(mean((original - rec_scaled).^2)); - pot = mean(original.^2); - - if pot > 0 && error_rms > 0 - snr_val = 10 * log10(pot / error_rms^2); - else - snr_val = Inf; - end - - correlacion = (original' * rec_scaled) / (norm(original) * norm(rec_scaled)); -end \ No newline at end of file blob - /dev/null blob + c578a92abb852e7ed90dbc89daf0ec4004ff5b1c (mode 644) --- /dev/null +++ Scripts/diagrama_circuito.m @@ -0,0 +1,416 @@ +%% DIAGRAMA DE CIRCUITO — Microfono Laser +% BPW34 → TIA (LM358) → C_ac → MAX9814 → Jack PC +% +% Autor: Alejandro B. E. — Fisica 2do Semestre + +clear; close all; clc; + +fig = figure('Name','Diagrama de Circuito — Microfono Laser', ... + 'NumberTitle','off','Position',[40 40 1600 900], ... + 'Color',[0.07 0.07 0.10]); + +ax = axes('Position',[0 0 1 1],'Color',[0.07 0.07 0.10]); +hold(ax,'on'); axis(ax,'off'); +xlim(ax,[0 160]); ylim(ax,[0 95]); + +%% ─── HELPERS ──────────────────────────────────────────────────── + + function wire(ax,x1,y1,x2,y2,col,lw) + if nargin<6, col=[0.85 0.85 0.85]; end + if nargin<7, lw=1.4; end + plot(ax,[x1 x2],[y1 y2],'Color',col,'LineWidth',lw); + end + + function node(ax,x,y,col) + if nargin<4, col=[0.85 0.85 0.85]; end + plot(ax,x,y,'o','MarkerFaceColor',col,'MarkerEdgeColor',col,'MarkerSize',5); + end + + function dibujar_R(ax,xc,yc,W,H,lbl_txt,val_txt) + xs = xc - W/2; + xx = linspace(xs, xs+W, 9); + yy = yc + H/2 * [0 1 -1 1 -1 1 -1 1 0]; + plot(ax,xx,yy,'Color',[0.9 0.6 0.2],'LineWidth',1.5); + plot(ax,[xc-W/2-1.5 xc-W/2],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); + plot(ax,[xc+W/2 xc+W/2+1.5],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); + text(ax,xc,yc+H*0.9+0.3,lbl_txt,'Color',[0.9 0.7 0.3],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); + text(ax,xc,yc-H*0.9-0.5,val_txt,'Color',[0.65 0.65 0.65],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); + end + + function dibujar_C(ax,xc,yc,gap,H,lbl_txt,val_txt) + g = gap/2; + plot(ax,[xc-g xc-g],[yc-H/2 yc+H/2],'Color',[0.3 0.75 1.0],'LineWidth',2.2); + plot(ax,[xc+g xc+g],[yc-H/2 yc+H/2],'Color',[0.3 0.75 1.0],'LineWidth',2.2); + plot(ax,[xc-g-2 xc-g],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); + plot(ax,[xc+g xc+g+2],[yc yc],'Color',[0.85 0.85 0.85],'LineWidth',1.4); + text(ax,xc,yc+H/2+0.9,lbl_txt,'Color',[0.3 0.85 1.0],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); + text(ax,xc,yc-H/2-1.2,val_txt,'Color',[0.55 0.55 0.65],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); + end + + function gnd(ax,x,y) + plot(ax,[x x],[y y-1.2],'Color',[0.55 0.55 0.55],'LineWidth',1.3); + w = [2.2 1.5 0.7]; + for i=1:3 + plot(ax,[x-w(i) x+w(i)],[y-1.2-(i-1)*0.7 y-1.2-(i-1)*0.7], ... + 'Color',[0.55 0.55 0.55],'LineWidth',1.2); + end + end + + function vcc(ax,x,y,lbl_txt) + if nargin<4, lbl_txt='+5V'; end + plot(ax,[x x],[y y+1.5],'Color',[0.9 0.35 0.35],'LineWidth',1.3); + plot(ax,[x-1.2 x+1.2],[y+1.5 y+1.5],'Color',[0.9 0.35 0.35],'LineWidth',2); + text(ax,x,y+2.8,lbl_txt,'Color',[0.95 0.4 0.4],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); + end + +%% ─── LAYOUT: el circuito ocupa y=30..92, tabla y=2..17 ───────── +% GND rail en y=30 (antes 18) — deja espacio para tabla abajo +Y_GND = 30; % rail GND +Y_VCC = 82; % rail +5V +Y_UP = 12; % desplazamiento vertical respecto a version anterior (+12) + +%% ═══════════════════════════════════════════════════════════════ +% TITULO +%% ═══════════════════════════════════════════════════════════════ +text(ax,80,93,'Diagrama de Circuito — Microfono Laser', ... + 'Color',[1 0.75 0.15],'FontSize',14,'HorizontalAlignment','center', ... + 'FontWeight','bold','FontName','Courier New'); +text(ax,80,90,'BPW34 → TIA LM358 → C_{ac} → MAX9814 → Jack PC → MATLAB FFT', ... + 'Color',[0.6 0.6 0.6],'FontSize',9,'HorizontalAlignment','center', ... + 'FontName','Courier New'); +plot(ax,[3 157],[87.5 87.5],'Color',[0.25 0.25 0.3],'LineWidth',0.8); + +%% ═══════════════════════════════════════════════════════════════ +% RAILS +%% ═══════════════════════════════════════════════════════════════ +plot(ax,[5 155],[Y_VCC Y_VCC],'Color',[0.7 0.2 0.2],'LineWidth',1,'LineStyle','--'); +text(ax,4,Y_VCC+0.6,'+5V','Color',[0.9 0.4 0.4],'FontSize',7,'FontName','Courier New'); +plot(ax,[5 155],[Y_GND Y_GND],'Color',[0.4 0.4 0.4],'LineWidth',1,'LineStyle','--'); +text(ax,4,Y_GND-0.8,'GND','Color',[0.55 0.55 0.55],'FontSize',7,'FontName','Courier New'); + +% Separador entre circuito y tabla +plot(ax,[3 157],[27.5 27.5],'Color',[0.2 0.2 0.25],'LineWidth',1.2); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 1: SENSOR OPTICO (y += 12 respecto a version anterior) +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[5 42 28 30],'EdgeColor',[0.4 0.4 0.5], ... + 'LineWidth',0.8,'LineStyle',':'); +text(ax,19,73.5,'SENSOR OPTICO','Color',[0.5 0.5 0.6],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +% Laser KY-008 +rectangle(ax,'Position',[7 44 8 6],'EdgeColor',[0.3 0.9 0.3], ... + 'FaceColor',[0.05 0.15 0.05],'LineWidth',1.3,'Curvature',0.2); +text(ax,11,47.2,'LASER','Color',[0.3 1.0 0.3],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); +text(ax,11,45.8,'KY-008','Color',[0.3 0.7 0.3],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,11,44.6,'650 nm','Color',[0.5 0.5 0.5],'FontSize',6, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +% Haz laser +x_beam = linspace(15,25,60); +y_beam = 47 + 0.15*sin(linspace(0,6*pi,60)); +plot(ax,x_beam,y_beam,'Color',[1 0.2 0.2],'LineWidth',1.8); +text(ax,20,48.3,'haz 650nm','Color',[1 0.4 0.4],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +% Vidrio +plot(ax,[26 26],[40 56],'Color',[0.4 0.75 1.0],'LineWidth',3); +plot(ax,[26.8 26.8],[40 56],'Color',[0.3 0.6 0.9],'LineWidth',1); +text(ax,26,57.2,'VIDRIO','Color',[0.4 0.85 1.0],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); +text(ax,26,56.0,'(vibra con','Color',[0.4 0.7 0.85],'FontSize',6.2, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,26,55.0,'el sonido)','Color',[0.4 0.7 0.85],'FontSize',6.2, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +% Reflexion +x_ref = linspace(27,22,30); +y_ref = linspace(47,62,30); +plot(ax,x_ref,y_ref,'Color',[1 0.4 0.4],'LineWidth',1.5,'LineStyle','--'); +text(ax,23.5,56,'reflexion','Color',[1 0.5 0.5],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +% BPW34 +xd = 20; yd = 65; +patch(ax,[xd-1.5 xd+1.5 xd-1.5],[yd-1.8 yd yd+1.8], ... + [0.2 0.2 0.2],'FaceColor',[0.15 0.15 0.25], ... + 'EdgeColor',[1 0.8 0.2],'LineWidth',1.5); +plot(ax,[xd+1.5 xd+1.5],[yd-1.8 yd+1.8],'Color',[1 0.8 0.2],'LineWidth',2); +plot(ax,[xd-3 xd-1.5],[yd yd],'Color',[0.85 0.85 0.85],'LineWidth',1.4); +plot(ax,[xd+1.5 xd+3],[yd yd],'Color',[0.85 0.85 0.85],'LineWidth',1.4); +for ang = [-25 0 25] + dx_p = 1.8*cosd(ang+180); dy_p = 1.8*sind(ang+180); + plot(ax,[xd+dx_p xd-0.2],[yd+dy_p yd], ... + 'Color',[1 0.9 0.3],'LineWidth',1,'LineStyle','--'); +end +text(ax,xd,yd+4.2,'BPW34','Color',[1.0 0.85 0.15],'FontSize',8.5, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); +text(ax,xd,yd+2.8,'Fotodiodo PIN','Color',[0.7 0.7 0.0],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,xd-3.8,yd+0.3,'K','Color',[0.65 0.65 0.65],'FontSize',7,'FontName','Courier New'); +text(ax,xd+2.5,yd+0.3,'A','Color',[0.65 0.65 0.65],'FontSize',7,'FontName','Courier New'); + +wire(ax,xd-3,yd,xd-3,Y_VCC); vcc(ax,xd-3,Y_VCC,'+5V'); +wire(ax,xd+3,yd,xd+3,Y_GND); gnd(ax,xd+3,Y_GND); +text(ax,xd,yd-3.5,'polariz. inversa','Color',[0.5 0.5 0.5],'FontSize',6, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +wire(ax,xd+3,yd,35,yd); +node(ax,35,yd); +text(ax,32,yd+1.5,'I_{foto}','Color',[1.0 0.85 0.2],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontName','Courier New','FontWeight','bold'); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 2: TIA — LM358 +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[35 40 42 36],'EdgeColor',[0.3 0.5 0.8], ... + 'LineWidth',0.8,'LineStyle',':'); +text(ax,56,77.5,'TIA — LM358','Color',[0.4 0.6 0.9],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +xop=58; yop=56; sz=7; +patch(ax,[xop-sz xop-sz xop+sz],[yop-sz yop+sz yop], ... + [0.1 0.1 0.2],'FaceColor',[0.08 0.08 0.18], ... + 'EdgeColor',[0.4 0.6 1.0],'LineWidth',1.8); +text(ax,xop-1,yop,'LM358','Color',[0.5 0.7 1.0],'FontSize',7, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); + +xin=xop-sz; yin_n=yop+3.5; yin_p=yop-3.5; yout=yop; +text(ax,xin-0.6,yin_n,'−','Color',[0.7 0.7 0.9],'FontSize',10,'FontName','Courier New'); +text(ax,xin-0.6,yin_p,'+','Color',[0.7 0.7 0.9],'FontSize',10,'FontName','Courier New'); + +xout_node = xop+sz+2; +wire(ax,xop+sz,yout,xout_node,yout); + +wire(ax,35,yd,35,yin_n); +wire(ax,35,yin_n,xin,yin_n); +node(ax,35,yin_n); + +% Retroalimentacion Rf +wire(ax,xout_node,yout,xout_node,yop+12); +wire(ax,xout_node,yop+12,xin-2,yop+12); +wire(ax,xin-2,yop+12,xin-2,yin_n); +node(ax,xin-2,yin_n); +node(ax,xout_node,yout); +dibujar_R(ax,(xout_node+xin-2)/2,yop+12,14,1.8,'R_f','1 MOhm'); + +% Cf paralelo con Rf +wire(ax,xout_node,yop+15.5,xin-2,yop+15.5); +wire(ax,xout_node,yop+12,xout_node,yop+15.5); +wire(ax,xin-2,yop+12,xin-2,yop+15.5); +dibujar_C(ax,(xout_node+xin-2)/2,yop+15.5,1.5,2.5,'C_f','100pF'); + +% Divisor Vref +wire(ax,xin,yin_p,xin-4,yin_p); +dibujar_R(ax,xin-8,yin_p,6,1.5,'R1','100k'); +wire(ax,xin-11,yin_p,xin-11,Y_VCC); vcc(ax,xin-11,Y_VCC,'+5V'); +wire(ax,xin-4,yin_p,xin-4,yin_p-3); +dibujar_R(ax,xin-4,yin_p-6,6,1.5,'R2','100k'); +wire(ax,xin-4,yin_p-9,xin-4,Y_GND); gnd(ax,xin-4,Y_GND); +node(ax,xin-4,yin_p); +text(ax,xin-5.5,yin_p+2,'V_{ref}','Color',[0.8 0.5 0.5],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,xin-5.5,yin_p+0.7,'2.5V','Color',[0.6 0.4 0.4],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +wire(ax,xop,yop+sz,xop,Y_VCC); vcc(ax,xop,Y_VCC,'+5V'); +wire(ax,xop,yop-sz,xop,Y_GND); gnd(ax,xop,Y_GND); + +text(ax,xout_node+1,yout+1.5,'V_{TIA}','Color',[0.4 0.7 1.0],'FontSize',7.5, ... + 'HorizontalAlignment','left','FontName','Courier New','FontWeight','bold'); +text(ax,xout_node+1,yout-1.5,'= I x R_f','Color',[0.35 0.55 0.8],'FontSize',6.5, ... + 'HorizontalAlignment','left','FontName','Courier New'); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 3: ACOPLAMIENTO AC +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[78 48 18 16],'EdgeColor',[0.3 0.6 0.6], ... + 'LineWidth',0.8,'LineStyle',':'); +text(ax,87,65.5,'C_{ac} (bloqueo DC)','Color',[0.35 0.7 0.7],'FontSize',6.8, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +wire(ax,xout_node,yout,79,yout); +wire(ax,79,yout,79,56); +wire(ax,79,56,82,56); +dibujar_C(ax,87,56,1.8,3.5,'C_{ac}','10 uF'); +wire(ax,89,56,93,56); +wire(ax,93,56,93,52); +dibujar_R(ax,93,49,5,1.5,'R_{in}','10k'); +wire(ax,93,46,93,Y_GND); gnd(ax,93,Y_GND); +node(ax,93,56); +wire(ax,93,56,96,56); +text(ax,87,53.5,'elimina V_{DC}','Color',[0.35 0.65 0.65],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,87,52.3,'pasa V_{AC}','Color',[0.35 0.65 0.65],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 4: MAX9814 +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[96 42 30 36],'EdgeColor',[0.7 0.3 0.9], ... + 'FaceColor',[0.08 0.04 0.12],'LineWidth',1.8,'Curvature',0.08); +text(ax,111,79.5,'MAX9814','Color',[0.9 0.5 1.0],'FontSize',10, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); +text(ax,111,77.5,'HiLetgo Module','Color',[0.65 0.35 0.75],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +pins_y = [74 69 64 59 54 49 44]; +pins_lbl = {'VCC','GND','OUT','GAIN','AR','MIC\_IN','MIC\_BIAS'}; +pins_col = {[0.9 0.35 0.35],[0.55 0.55 0.55],[0.3 0.9 0.6], ... + [0.8 0.8 0.3],[0.7 0.6 0.5],[0.9 0.6 0.3],[0.6 0.5 0.7]}; +for i = 1:length(pins_y) + plot(ax,[96 99],[pins_y(i) pins_y(i)],'Color',pins_col{i},'LineWidth',1.5); + plot(ax,97,pins_y(i),'s','MarkerFaceColor',pins_col{i}, ... + 'MarkerEdgeColor',pins_col{i},'MarkerSize',5); + text(ax,100.5,pins_y(i),pins_lbl{i},'Color',pins_col{i},'FontSize',7, ... + 'VerticalAlignment','middle','FontName','Courier New','FontWeight','bold'); +end + +wire(ax,96,74,88,74); wire(ax,88,74,88,Y_VCC); vcc(ax,88,Y_VCC,'+5V'); +wire(ax,96,69,88,69); wire(ax,88,69,88,Y_GND); gnd(ax,88,Y_GND); +wire(ax,96,56,96,49); node(ax,96,56); +wire(ax,96,59,94,59); +text(ax,93,59,'NC','Color',[0.5 0.5 0.5],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,91,57.5,'(float=40dB)','Color',[0.55 0.55 0.35],'FontSize',6.2, ... + 'HorizontalAlignment','center','FontName','Courier New'); +wire(ax,96,54,94,54); +dibujar_C(ax,92,54,1.5,2.5,'C_{AR}','4.7uF'); +wire(ax,89.5,54,89.5,Y_GND); gnd(ax,89.5,Y_GND); +plot(ax,[123 127],[64 64],'Color',[0.3 0.9 0.6],'LineWidth',1.8); +plot(ax,126.5,64,'s','MarkerFaceColor',[0.3 0.9 0.6], ... + 'MarkerEdgeColor',[0.3 0.9 0.6],'MarkerSize',5); +text(ax,122,64,'OUT','Color',[0.3 0.9 0.6],'FontSize',7, ... + 'HorizontalAlignment','right','FontName','Courier New','FontWeight','bold'); +wire(ax,126,64,131,64); + +text(ax,113,59,'AGC','Color',[0.8 0.5 0.9],'FontSize',8.5, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); +text(ax,113,57.5,'auto-ganancia','Color',[0.6 0.35 0.7],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,113,56.2,'40 / 50 / 60 dB','Color',[0.6 0.35 0.7],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 5: CAPACITOR DE SALIDA +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[130 56 12 14],'EdgeColor',[0.3 0.5 0.6], ... + 'LineWidth',0.8,'LineStyle',':'); +text(ax,136,71,'C_{sal}','Color',[0.35 0.6 0.7],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); +wire(ax,131,64,133,64); +dibujar_C(ax,136,64,1.8,3.5,'C_{sal}','47 uF'); +wire(ax,139,64,142,64); +wire(ax,139,64,139,60); +dibujar_R(ax,139,57,5,1.5,'R_L','10k'); +wire(ax,139,54,139,Y_GND); gnd(ax,139,Y_GND); +node(ax,139,64); +text(ax,136,61.5,'bloquea offset','Color',[0.35 0.55 0.65],'FontSize',6.2, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,136,60.3,'1.25V MAX9814','Color',[0.35 0.55 0.65],'FontSize',6.2, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 6: JACK 3.5mm +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[142 56 16 16],'EdgeColor',[0.3 0.7 0.4], ... + 'FaceColor',[0.04 0.1 0.06],'LineWidth',1.5,'Curvature',0.1); +xj=150; yj=64; +th=linspace(0,2*pi,60); +plot(ax,xj+2*cos(th),yj+2*sin(th),'Color',[0.4 0.8 0.4],'LineWidth',1.5); +plot(ax,xj+1*cos(th),yj+1*sin(th),'Color',[0.6 0.9 0.6],'LineWidth',1); +plot(ax,[xj-2 xj+2],[yj yj],'Color',[0.4 0.8 0.4],'LineWidth',1.5); +plot(ax,[xj xj],[yj-2 yj+2],'Color',[0.4 0.8 0.4],'LineWidth',1.5); +wire(ax,142,64,148,64); +text(ax,150,69.8,'JACK 3.5mm','Color',[0.35 0.85 0.45],'FontSize',7.5, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); +text(ax,150,68.5,'Microfono PC','Color',[0.3 0.65 0.35],'FontSize',6.8, ... + 'HorizontalAlignment','center','FontName','Courier New'); +wire(ax,150,yj-2,150,Y_GND); gnd(ax,150,Y_GND); + +%% ═══════════════════════════════════════════════════════════════ +% BLOQUE 7: PC + MATLAB +%% ═══════════════════════════════════════════════════════════════ +rectangle(ax,'Position',[154 47 5 26],'EdgeColor',[0.2 0.6 0.8], ... + 'FaceColor',[0.03 0.08 0.12],'LineWidth',1.5,'Curvature',0.05); +wire(ax,152,64,154,64); +plot(ax,[153.5 154.5],[64.4 64],'Color',[0.3 0.75 0.95],'LineWidth',1.5); +plot(ax,[153.5 154.5],[63.6 64],'Color',[0.3 0.75 0.95],'LineWidth',1.5); +text(ax,156.5,67,'PC','Color',[0.3 0.75 0.95],'FontSize',8, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); +text(ax,156.5,63,'+','Color',[0.25 0.6 0.8],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,156.5,60,'MAT','Color',[0.25 0.6 0.8],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,156.5,58,'LAB','Color',[0.25 0.6 0.8],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +text(ax,156.5,55,'FFT','Color',[0.2 0.5 0.7],'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +%% ═══════════════════════════════════════════════════════════════ +% FLUJO DE SENAL — debajo del separador (y < 27) +%% ═══════════════════════════════════════════════════════════════ +y_flow = 23.5; +puntos_x = [20 35 58 87 111 136 150 156]; +nombres = {'I_{foto}','->V_{TIA}','V_{TIA}','V_{AC}','V_{amp}','V_{out}','V_{PC}','AUDIO'}; +colores = {[1.0 0.85 0.2],[0.4 0.7 1.0],[0.4 0.7 1.0],[0.3 0.8 0.8], ... + [0.85 0.5 1.0],[0.85 0.5 1.0],[0.35 0.85 0.45],[0.3 0.75 0.95]}; +for i = 1:length(puntos_x)-1 + plot(ax,[puntos_x(i)+0.5 puntos_x(i+1)-0.5],[y_flow y_flow], ... + 'Color',[0.3 0.3 0.35],'LineWidth',1.2); + plot(ax,[puntos_x(i+1)-1.2 puntos_x(i+1)-0.3 puntos_x(i+1)-1.2], ... + [y_flow+0.5 y_flow y_flow-0.5], ... + 'Color',[0.3 0.3 0.35],'LineWidth',1.2); +end +for i = 1:length(puntos_x) + plot(ax,puntos_x(i),y_flow,'o','MarkerFaceColor',colores{i}, ... + 'MarkerEdgeColor',colores{i},'MarkerSize',4); + text(ax,puntos_x(i),y_flow+1.5,nombres{i},'Color',colores{i},'FontSize',6.5, ... + 'HorizontalAlignment','center','FontName','Courier New'); +end +text(ax,80,y_flow-1.2,'← Flujo de senal →','Color',[0.4 0.4 0.45],'FontSize',7, ... + 'HorizontalAlignment','center','FontName','Courier New'); + +%% ═══════════════════════════════════════════════════════════════ +% TABLA DE VALORES — bien separada abajo del flujo +%% ═══════════════════════════════════════════════════════════════ +xT = 20; yT = 11; % y=10..21, debajo del flujo (y=23.5) +rectangle(ax,'Position',[xT yT-1 120 11],'EdgeColor',[0.25 0.25 0.3], ... + 'FaceColor',[0.07 0.07 0.09],'LineWidth',0.8); +text(ax,xT+60,yT+9.5,'Valores del circuito','Color',[0.75 0.75 0.8],'FontSize',8.5, ... + 'HorizontalAlignment','center','FontWeight','bold','FontName','Courier New'); + +datos = { + 'BPW34', 'Responsividad:', '0.3 A/W @ 650 nm', [1.0 0.85 0.2]; + 'LM358 TIA', 'Rf = 1 MOhm,', 'Cf = 100 pF', [0.4 0.7 1.0]; + 'C_ac', '10 uF fc =', '1.6 Hz (paso AC)', [0.3 0.8 0.8]; + 'MAX9814', 'Av = 40 dB,', 'AGC automatico', [0.85 0.5 1.0]; + 'C_sal', '47 uF fc =', '0.34 Hz', [0.35 0.7 0.45]; + 'Alimentacion', '+5V + GND,', 'VCC LM358 + laser', [0.9 0.4 0.4]; +}; +col_x = [xT+2, xT+28, xT+60]; +for i = 1:size(datos,1) + yi = yT + 8.0 - (i-1)*1.55; + text(ax,col_x(1),yi,datos{i,1},'Color',datos{i,4},'FontSize',7.5, ... + 'FontWeight','bold','FontName','Courier New'); + text(ax,col_x(2),yi,datos{i,2},'Color',[0.65 0.65 0.65],'FontSize',7.5,'FontName','Courier New'); + text(ax,col_x(3),yi,datos{i,3},'Color',[0.5 0.5 0.55],'FontSize',7.5,'FontName','Courier New'); +end + +%% ─── Pie ────────────────────────────────────────────────────── +plot(ax,[3 157],[9.5 9.5],'Color',[0.2 0.2 0.25],'LineWidth',0.8); +text(ax,80,1.8, ... + 'Fisica 2do Semestre | Ondas y Oscilaciones | BPW34 + LM358 + MAX9814 + MATLAB FFT', ... + 'Color',[0.35 0.35 0.4],'FontSize',7.5,'HorizontalAlignment','center', ... + 'FontName','Courier New'); + +fprintf(' Diagrama generado.\n'); +fprintf(' Para guardar: print(gcf,''-dpng'',''-r300'',''diagrama_circuito.png'')\n'); \ No newline at end of file blob - /dev/null blob + 72cd55127b1234dc0d40605c3807500ef7cb728e (mode 644) --- /dev/null +++ Scripts/script_prueba_demostracion.m @@ -0,0 +1,422 @@ +%% SCRIPT DE PRUEBA Y DEMOSTRACIÓN +% 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('║ Fisica 2do Semestre - Ondas, Oscilaciones y Espacios Vect. ║\n'); +fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); + +%% ======================================================================== +% PARÁMETROS DEL SISTEMA +%% ======================================================================== +fprintf('CONFIGURANDO PARÁMETROS DEL SISTEMA...\n'); + +fs = 44100; % Hz — frecuencia de muestreo +duracion = 3; % s +t = (0:1/fs:duracion-1/fs)'; + +% ── 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 = 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 = 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 = pipeline_sensor(senial_chirp, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); + +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 = pipeline_sensor(senial_compleja, P_laser, mod_depth, ... + R_bpw34, Rf_TIA, Av_MAX, ruido_fotosensor); + +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); +[f4, mag4, ~] = calcular_fft_sistema(senial_compleja_ruidosa, fs); + +fprintf(' Identificando componentes principales:\n\n'); + +[~, idx] = findpeaks(mag1, 'MinPeakHeight', max(mag1)*0.2); +fprintf(' Tono puro (1000 Hz):\n'); +fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f1(idx))); + +[~, idx] = findpeaks(mag2, 'MinPeakHeight', max(mag2)*0.2); +fprintf(' Acorde (262, 330, 392 Hz):\n'); +fprintf(' Picos detectados: %s Hz\n', sprintf('%.0f ', f2(idx))); + +fprintf('╰─ Completado: FFT calculado para todas las senales\n\n'); + +%% ======================================================================== +% PRUEBA 3: DESCOMPOSICIÓN EN VALORES SINGULARES (SVD) +%% ======================================================================== +fprintf('╭─ PRUEBA 3: ANÁLISIS SVD (ESPACIOS VECTORIALES)\n'); + +[U1, S1, V1, var1] = analizar_svd(senial_pura_ruidosa); +[U2, S2, V2, var2] = analizar_svd(senial_acorde_ruidosa); +[U3, S3, V3, var3] = analizar_svd(senial_chirp_ruidosa); +[U4, S4, V4, var4] = analizar_svd(senial_compleja_ruidosa); + +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', ... + rank(U2*S2*V2'), var2(min(5, length(var2)))); +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', ... + rank(U4*S4*V4'), var4(min(5, length(var4)))); + +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 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 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 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 = %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 Laser-Fotosensor — Resultados Completos', ... + 'Position',[100 100 1400 1000]); + +t_zoom = t(1:2000); + +% ── TONO PURO ───────────────────────────────────────────────────────────── +subplot(4,4,1); +plot(t_zoom, senial_pura(1:2000), 'b-', 'LineWidth', 1.5); +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 — 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 (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\nSNR = %.1f dB', snr1),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; + +% ── ACORDE ──────────────────────────────────────────────────────────────── +subplot(4,4,5); +plot(t_zoom, senial_acorde(1:2000), 'r-', 'LineWidth', 1.5); +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 — 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 (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 (Do Mayor)\nSNR = %.1f dB', snr2),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; + +% ── BARRIDO ─────────────────────────────────────────────────────────────── +subplot(4,4,9); +plot(t_zoom, senial_chirp(1:2000), 'm-', 'LineWidth', 1.5); +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 — 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 (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 100-1000Hz\nSNR = %.1f dB', snr3),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; + +% ── SEÑAL COMPLEJA ──────────────────────────────────────────────────────── +subplot(4,4,13); +plot(t_zoom, senial_compleja(1:2000), 'c-', 'LineWidth', 1.5); +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 — 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 (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 (5 armonicos)\nSNR = %.1f dB', snr4),'FontWeight','bold'); +xlabel('Frecuencia (Hz)'); ylabel('|Y(f)|'); grid on; + +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'); + +figure('Name','Analisis SVD — Espacios Vectoriales'); + +subplot(2,2,1); +semilogy(diag(S1), 'bo-', 'LineWidth', 2, 'MarkerSize', 6); +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 \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 \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 \sigma_i'); +title('SVD — Compleja (muchos armonicos)','FontWeight','bold'); grid on; + +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 FINAL +%% ======================================================================== +fprintf('╔════════════════════════════════════════════════════════════════╗\n'); +fprintf('║ RESUMEN DE RESULTADOS ║\n'); +fprintf('╚════════════════════════════════════════════════════════════════╝\n\n'); + +tabla = array2table(... + [1000, err1, snr1, cor1; ... + 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'}); + +disp(tabla); + +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'); +fprintf('║ ║\n'); +fprintf('║ Sistema listo para usar con datos reales del fotosensor ║\n'); +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(' Metricas de validacion calculadas\n'); + +%% ======================================================================== +% FUNCIONES LOCALES (siempre al final del script) +%% ======================================================================== + +function [f, mag, Y] = calcular_fft_sistema(senial, fs) + N = length(senial); + Y = fft(senial); + mag = abs(Y(1:N/2)) / N; + f = fs * (0:N/2-1) / N; +end + +function [U, S, V, varianza_ac] = analizar_svd(senial) + ventana = max(2, round(length(senial) / 100)); + cols = length(senial) - ventana + 1; + M = zeros(ventana, cols); + for i = 1:ventana + M(i,:) = senial(i : i + cols - 1)'; + end + [U, S, V] = svd(M, 'econ'); + sv = diag(S); + varianza_ac = cumsum(sv.^2) / sum(sv.^2) * 100; +end + +function senial_rec = reconstruir_por_fft(senial_ruidosa) + N = length(senial_ruidosa); + Y = fft(senial_ruidosa); + mag_pos = abs(Y(1 : floor(N/2) + 1)); + umbral = max(mag_pos) * 0.1; + + 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))); + + senial_rec = real(ifft(Y .* mascara)); +end + +function [error_rms, snr_val, correlacion] = calcular_metricas(original, reconstruida) + factor = (original' * reconstruida) / (reconstruida' * reconstruida); + rec_scaled = reconstruida * factor; + + error_rms = sqrt(mean((original - rec_scaled).^2)); + pot = mean(original.^2); + + if pot > 0 && error_rms > 0 + snr_val = 10 * log10(pot / error_rms^2); + else + snr_val = Inf; + end + + correlacion = (original' * rec_scaled) / (norm(original) * norm(rec_scaled)); +end \ No newline at end of file blob - /dev/null blob + 72e6e079375bb030552e2d4c12b4dbc53bf8e8d5 (mode 644) --- /dev/null +++ Scripts/simulacion_3d_laser.m @@ -0,0 +1,404 @@ +%% SIMULACION 3D — MICROFONO LASER +% Visualizacion 3D animada del experimento completo: +% Caja insonorizada → vidrio vibrante → laser → BPW34 → +% TIA (LM358) → MAX9814 → PC → FFT → reconstruccion +% +% Autor: Alejandro B. E. — Fisica 2do Semestre + +clear; close all; clc; + +fprintf('╔══════════════════════════════════════════════════════╗\n'); +fprintf('║ SIMULACION 3D — Microfono Laser ║\n'); +fprintf('╚══════════════════════════════════════════════════════╝\n\n'); +fprintf(' Presiona Q en la figura 3D para detener la animacion.\n\n'); + +%% ═══════════════════════════════════════════════════════ +% PARAMETROS +%% ═══════════════════════════════════════════════════════ + +% Audio simulado (acorde La mayor: 440 + 880 + 660 Hz) +f1 = 440; f2 = 880; f3 = 660; +fs = 8000; % Hz +duracion = 3.0; % s + +t = (0 : 1/fs : duracion - 1/fs)'; +N = length(t); + +% Senal de audio dentro de la caja (normalizada -1 a 1) +audio_original = 0.5*sin(2*pi*f1*t) + ... + 0.3*sin(2*pi*f2*t) + ... + 0.2*sin(2*pi*f3*t); +audio_original = audio_original / max(abs(audio_original)); % normalizar + +% Parametros fisicos +R_bpw34 = 0.3; % A/W — responsividad BPW34 @ 650nm +P_laser = 1e-3; % W — potencia laser +mod_depth = 0.15; % antes 0.4, — — profundidad de modulacion del vidrio +Rf_TIA = 10e3; % Ω — resistencia TIA +Av_MAX = 1; % antes 3, V/V — ganancia MAX9814 + +%% ─── PIPELINE DE SENAL (CORREGIDO) ───────────────────── + +% 1. Modulacion optica: vibracion del vidrio modula P_laser +P_luz = P_laser * (1 + mod_depth * audio_original); +% P_luz oscila entre P_laser*(1-m) y P_laser*(1+m) — nunca negativo + +% 2. BPW34: P_luz → I_foto (corriente) +I_foto = R_bpw34 * P_luz + 1e-8 * randn(N,1); +% I_foto_DC = R * P_laser = 0.3 * 1e-3 = 300 µA (offset DC) +% I_foto_AC = R * P_laser * mod_depth * audio = ±120 µA (señal util) + +% 3. TIA: I_foto → V_tia, luego ELIMINAR DC por resta de media +% (en hardware esto lo hace el capacitor de acoplamiento C_ac) +V_tia_total = I_foto * Rf_TIA; % V = I * Rf → offset DC + señal AC +V_tia = V_tia_total - mean(V_tia_total); % solo componente AC +% V_tia_AC pico = mod_depth * R * P_laser * Rf = 0.4*0.3*1e-3*10e3 = 1.2 mV +% Nota: señal pequeña — el MAX9814 la amplifica + +% 4. MAX9814: amplificar y saturar +V_max = Av_MAX * V_tia; +V_max = max(-1.65, min(1.65, V_max)); % saturacion ±1.65V + +% 5. FFT sobre la señal capturada +Y = fft(V_max); +mag_Y = abs(Y); + +% Filtrado: umbral de magnitud (conservar picos principales) +umbral = max(mag_Y) * 0.08; +mascara = mag_Y > umbral; +% Simetria conjugada obligatoria para ifft real +mascara = mascara | flipud(mascara); +Y_filt = Y .* mascara; + +% 6. Reconstruccion (IFFT) +V_rec = real(ifft(Y_filt)); + +% Escalar V_rec para comparar con audio_original (minimos cuadrados) +factor = (audio_original' * V_rec) / (V_rec' * V_rec + 1e-12); +V_rec_escalado = V_rec * factor; + +% Correlacion +cc = corrcoef(audio_original, V_rec_escalado); +rho = cc(1,2); + +fprintf(' Senal simulada:\n'); +fprintf(' Frecuencias: %.0f + %.0f + %.0f Hz\n', f1, f2, f3); +fprintf(' I_foto DC: %.0f uA\n', mean(I_foto)*1e6); +fprintf(' V_TIA AC pico: %.4f V\n', max(abs(V_tia))); +fprintf(' V_MAX pico: %.4f V\n', max(abs(V_max))); +fprintf(' Correlacion: %.4f\n\n', rho); + +%% ═══════════════════════════════════════════════════════ +% FIGURA PRINCIPAL +%% ═══════════════════════════════════════════════════════ +fig = figure('Name','Simulacion 3D — Microfono Laser', ... + 'NumberTitle','off', ... + 'Position',[30 30 1500 900], ... + 'Color',[0.05 0.05 0.08], ... + 'KeyPressFcn', @(s,e) setappdata(s,'salir', strcmp(e.Key,'q'))); +setappdata(fig, 'salir', false); + +%% ═══════════════════════════════════════════════════════ +% SUBPLOT 3D +%% ═══════════════════════════════════════════════════════ +ax3d = subplot('Position', [0.02 0.35 0.55 0.62]); +set(ax3d,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','ZColor','w'); +hold(ax3d,'on'); grid(ax3d,'on'); +view(ax3d, 35, 22); +xlabel(ax3d,'X (cm)','Color','w'); +ylabel(ax3d,'Y (cm)','Color','w'); +zlabel(ax3d,'Z (cm)','Color','w'); +title(ax3d,'Montaje experimental 3D','Color',[1 0.7 0.1],'FontWeight','bold','FontSize',12); +ax3d.GridColor = [0.2 0.2 0.2]; +xlim(ax3d,[-2 58]); ylim(ax3d,[-3 38]); zlim(ax3d,[-1 33]); +lighting(ax3d,'gouraud'); +light(ax3d,'Position',[60 60 60],'Style','infinite'); + +% Helper: dibujar caja + function dibujar_caja(ax,x0,y0,z0,Lx,Ly,Lz,col,al) + verts = [x0 y0 z0; + x0+Lx y0 z0; + x0+Lx y0+Ly z0; + x0 y0+Ly z0; + x0 y0 z0+Lz; + x0+Lx y0 z0+Lz; + x0+Lx y0+Ly z0+Lz; + x0 y0+Ly z0+Lz]; + faces = [1 2 6 5; 2 3 7 6; 3 4 8 7; + 4 1 5 8; 1 2 3 4; 5 6 7 8]; + patch(ax,'Vertices',verts,'Faces',faces, ... + 'FaceColor',col,'FaceAlpha',al, ... + 'EdgeColor',[0.55 0.55 0.55],'LineWidth',0.7); + end + +Lc = 20; % tamaño caja (cm) + +% Caja insonorizada +dibujar_caja(ax3d, 0,0,0, Lc,Lc,Lc, [0.35 0.25 0.15], 0.22); +text(ax3d, Lc/2, Lc/2, Lc+1.5,'Caja insonorizada', ... + 'Color',[0.85 0.65 0.3],'FontSize',9,'HorizontalAlignment','center'); + +% Vidrio (cara x=Lc) +[yv,zv] = meshgrid(linspace(0.5,Lc-0.5,12), linspace(0.5,Lc-0.5,12)); +xv0 = Lc * ones(size(yv)); +h_vidrio = surf(ax3d, xv0, yv, zv, ... + 'FaceColor',[0.5 0.8 1.0],'FaceAlpha',0.28, ... + 'EdgeColor',[0.4 0.7 0.9],'EdgeAlpha',0.12); +text(ax3d, Lc+0.3, Lc/2, Lc+0.8,'Vidrio', ... + 'Color',[0.5 0.9 1.0],'FontSize',9); + +% Audifono dentro de la caja +th = linspace(0,2*pi,40); +for lado = [-1 1] + yc = Lc/2 + lado*5; + fill3(ax3d, Lc/2-0.3+zeros(1,40), ... + yc + 3*cos(th), ... + Lc/2 + 3*sin(th), ... + [0.2 0.2 0.2],'FaceAlpha',0.85,'EdgeColor',[0.5 0.5 0.5]); +end +text(ax3d, Lc/2-5, Lc/2, Lc/2+5.5,'Audifono', ... + 'Color',[0.7 0.7 0.7],'FontSize',8); + +% Modulo laser KY-008 +laser_pos = [35, 4, 10]; +[xl,yl,zl] = cylinder(0.8,20); +surf(ax3d, xl*3+laser_pos(1), yl+laser_pos(2), zl+laser_pos(3), ... + 'FaceColor',[0.15 0.65 0.15],'EdgeColor','none','FaceAlpha',0.92); +text(ax3d, laser_pos(1)+0.5, laser_pos(2)-0.5, laser_pos(3)-2.2,'Laser KY-008', ... + 'Color',[0.3 1.0 0.3],'FontSize',8,'FontWeight','bold'); + +% Punto de impacto en vidrio +P_imp = [Lc, 10, 10]; + +% Haz laser (rojo solido) +h_haz_ida = plot3(ax3d, ... + [laser_pos(1) P_imp(1)], ... + [laser_pos(2) P_imp(2)], ... + [laser_pos(3) P_imp(3)], ... + 'r-','LineWidth',2.5); + +% Reflexion hacia BPW34 +v_inc = (P_imp - laser_pos) / norm(P_imp - laser_pos); +n_vid = [-1 0 0]; +v_ref = v_inc - 2*dot(v_inc,n_vid)*n_vid; +bpw34_pos = P_imp + 12*v_ref; + +h_haz_ref = plot3(ax3d, ... + [P_imp(1) bpw34_pos(1)], ... + [P_imp(2) bpw34_pos(2)], ... + [P_imp(3) bpw34_pos(3)], ... + 'r--','LineWidth',1.8); + +% Punto de impacto +plot3(ax3d, P_imp(1),P_imp(2),P_imp(3),'y*','MarkerSize',12,'LineWidth',2); + +% BPW34 (caja negra) +dibujar_caja(ax3d, bpw34_pos(1)-1.2, bpw34_pos(2)-1.2, bpw34_pos(3)-1.2, ... + 2.4, 2.4, 2.4, [0.08 0.08 0.08], 0.92); +text(ax3d, bpw34_pos(1), bpw34_pos(2), bpw34_pos(3)+3.2,'BPW34', ... + 'Color',[1.0 0.85 0.1],'FontSize',9,'FontWeight','bold','HorizontalAlignment','center'); + +% Tubo negro (proteccion de luz ambiente) +[xt,yt,zt] = cylinder(1.5,20); +surf(ax3d, xt+bpw34_pos(1), yt+bpw34_pos(2), zt*5+bpw34_pos(3)-2.5, ... + 'FaceColor',[0.07 0.07 0.07],'EdgeColor','none','FaceAlpha',0.55); + +% Protoboard + LM358 TIA +proto = [37, 14, 4]; +dibujar_caja(ax3d, proto(1), proto(2), proto(3), 9, 5, 0.6, [0.1 0.5 0.1], 0.85); +text(ax3d, proto(1)+4.5, proto(2)+2.5, proto(3)+2,'LM358 TIA', ... + 'Color',[0.4 1.0 0.4],'FontSize',8,'HorizontalAlignment','center'); + +% Cable BPW34 → TIA +plot3(ax3d,[bpw34_pos(1) proto(1)+4], ... + [bpw34_pos(2) proto(2)+2], ... + [bpw34_pos(3) proto(3)+0.5], ... + 'Color',[1 0.55 0.1],'LineWidth',1.5,'LineStyle',':'); + +% MAX9814 +maxp = [37, 21, 4]; +dibujar_caja(ax3d, maxp(1), maxp(2), maxp(3), 7, 4, 1.2, [0.45 0.1 0.55], 0.88); +text(ax3d, maxp(1)+3.5, maxp(2)+2, maxp(3)+2.8,'MAX9814', ... + 'Color',[0.9 0.5 1.0],'FontSize',8,'HorizontalAlignment','center'); + +% Cable TIA → MAX9814 +plot3(ax3d,[proto(1)+4 maxp(1)+3], ... + [proto(2)+5 maxp(2)], ... + [proto(3)+0.5 maxp(3)+0.6], ... + 'Color',[1 0.55 0.1],'LineWidth',1.5,'LineStyle',':'); + +% Laptop +pcp = [46, 14, 4]; +% Pantalla +fill3(ax3d,[pcp(1) pcp(1)+9 pcp(1)+9 pcp(1)], ... + [pcp(2) pcp(2) pcp(2) pcp(2)], ... + [pcp(3) pcp(3) pcp(3)+8 pcp(3)+8], ... + [0.1 0.1 0.16],'EdgeColor',[0.5 0.5 0.5],'FaceAlpha',0.92); +fill3(ax3d,[pcp(1)+0.5 pcp(1)+8.5 pcp(1)+8.5 pcp(1)+0.5], ... + [pcp(2)-0.1 pcp(2)-0.1 pcp(2)-0.1 pcp(2)-0.1], ... + [pcp(3)+0.5 pcp(3)+0.5 pcp(3)+7.5 pcp(3)+7.5], ... + [0.05 0.3 0.4],'EdgeColor','none','FaceAlpha',0.85); +% Base +fill3(ax3d,[pcp(1) pcp(1)+9 pcp(1)+9 pcp(1)], ... + [pcp(2) pcp(2) pcp(2)+4 pcp(2)+4], ... + [pcp(3) pcp(3) pcp(3) pcp(3)], ... + [0.2 0.2 0.2],'EdgeColor',[0.5 0.5 0.5],'FaceAlpha',0.92); +text(ax3d, pcp(1)+4.5, pcp(2)-1.2, pcp(3)+4,'PC + MATLAB', ... + 'Color',[0.3 0.85 1.0],'FontSize',9,'FontWeight','bold','HorizontalAlignment','center'); + +% Cable MAX9814 → PC +plot3(ax3d,[maxp(1)+7 pcp(1)], ... + [maxp(2)+2 pcp(2)+2], ... + [maxp(3)+0.6 pcp(3)+0.5], ... + 'Color',[0.7 0.7 0.7],'LineWidth',2); + +% Leyenda +legend(ax3d,[h_haz_ida,h_haz_ref], ... + {'Haz laser (650nm)','Reflexion hacia BPW34'}, ... + 'Location','northeast','TextColor','w', ... + 'Color',[0.1 0.1 0.15],'EdgeColor',[0.4 0.4 0.4]); + +%% ═══════════════════════════════════════════════════════ +% SUBPLOTS INFERIORES DE SENAL +%% ═══════════════════════════════════════════════════════ +c_audio = [1.0 0.7 0.1]; +c_foto = [1.0 0.4 0.3]; +c_tia = [0.3 0.8 1.0]; +c_rec = [0.4 1.0 0.4]; + +ax_audio = subplot('Position',[0.02 0.03 0.22 0.28]); +ax_ifoto = subplot('Position',[0.26 0.03 0.22 0.28]); +ax_tia = subplot('Position',[0.50 0.03 0.22 0.28]); +ax_fft = subplot('Position',[0.74 0.03 0.24 0.28]); + +function setup_ax(ax, ttl, col) + set(ax,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w', ... + 'GridColor',[0.15 0.15 0.15],'FontSize',8); + grid(ax,'on'); + title(ax, ttl,'Color',col,'FontWeight','bold','FontSize',9); + xlabel(ax,'Tiempo (s)','Color','w','FontSize',8); +end + +setup_ax(ax_audio,'Audio en la caja', c_audio); +setup_ax(ax_ifoto,'BPW34 — I_{foto} (uA)', c_foto); +setup_ax(ax_tia, 'V_{TIA} + MAX9814 (mV)', c_tia); +setup_ax(ax_fft, 'FFT — Espectro', c_rec); + +n_win = round(fs * 0.012); % ventana de 12 ms +t_win = t(1:n_win); + +h_l_audio = plot(ax_audio, t_win, audio_original(1:n_win), 'Color',c_audio,'LineWidth',1.2); +h_l_ifoto = plot(ax_ifoto, t_win, I_foto(1:n_win)*1e6, 'Color',c_foto, 'LineWidth',1.2); +h_l_tia = plot(ax_tia, t_win, V_tia(1:n_win)*1e3, 'Color',c_tia, 'LineWidth',1.2); + +ylim(ax_audio,[-1.3 1.3]); +ylim(ax_ifoto,[min(I_foto)*1e6*1.05 max(I_foto)*1e6*1.05]); +ylim(ax_tia, [min(V_tia)*1e3*1.1 max(V_tia)*1e3*1.1]); + +% FFT estatica +f_vec = (0:floor(N/2)) * fs / N; +mag = abs(Y(1:floor(N/2)+1)) / N; +mag(2:end-1) = 2*mag(2:end-1); +plot(ax_fft, f_vec, mag,'Color',c_rec,'LineWidth',0.9); +xlim(ax_fft,[0 2000]); +set(ax_fft,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); +grid(ax_fft,'on'); +title(ax_fft,'FFT — Espectro','Color',c_rec,'FontWeight','bold','FontSize',9); +xlabel(ax_fft,'Frecuencia (Hz)','Color','w','FontSize',8); +hold(ax_fft,'on'); +for fi = [f1 f2 f3] + [~,idx_fi] = min(abs(f_vec - fi)); + plot(ax_fft, fi, mag(idx_fi),'w^','MarkerSize',7,'MarkerFaceColor','w'); + text(ax_fft, fi, mag(idx_fi)*1.12, sprintf('%.0fHz',fi), ... + 'Color','w','FontSize',7,'HorizontalAlignment','center'); +end + +%% ═══════════════════════════════════════════════════════ +% ANIMACION +%% ═══════════════════════════════════════════════════════ +fprintf(' Iniciando animacion (presiona Q para salir)...\n\n'); + +paso = round(fs/30); % ~30 fps +n_frm = floor(N / paso); +amp_v = 0.25; % cm vibracion max del vidrio + +for k = 1:n_frm + + if ~ishandle(fig) || getappdata(fig,'salir'), break; end + + i0 = (k-1)*paso + 1; + i1 = min(i0 + n_win - 1, N); + idx = i0:i1; + + if length(idx) < n_win, break; end + + % Vibracion del vidrio + desp = amp_v * audio_original(i0); + set(h_vidrio,'XData',(Lc + desp)*ones(size(yv))); + + % Haz laser sigue el punto de impacto + P_imp_k = [Lc + desp, P_imp(2), P_imp(3)]; + set(h_haz_ida,'XData',[laser_pos(1) P_imp_k(1)], ... + 'YData',[laser_pos(2) P_imp_k(2)], ... + 'ZData',[laser_pos(3) P_imp_k(3)]); + set(h_haz_ref,'XData',[P_imp_k(1) bpw34_pos(1)], ... + 'YData',[P_imp_k(2) bpw34_pos(2)], ... + 'ZData',[P_imp_k(3) bpw34_pos(3)]); + + % Actualizar graficas + tw = t(idx); + set(h_l_audio,'XData',tw,'YData',audio_original(idx)); + set(h_l_ifoto,'XData',tw,'YData',I_foto(idx)*1e6); + set(h_l_tia, 'XData',tw,'YData',V_tia(idx)*1e3); + xlim(ax_audio,[tw(1) tw(end)]); + xlim(ax_ifoto,[tw(1) tw(end)]); + xlim(ax_tia, [tw(1) tw(end)]); + + title(ax3d, sprintf('Montaje 3D — t = %.3f s | P_{laser} = %.5f W', ... + t(i0), P_luz(i0)), ... + 'Color',[1 0.7 0.1],'FontWeight','bold','FontSize',11); + + drawnow limitrate; +end + +%% ═══════════════════════════════════════════════════════ +% FIGURA FINAL: RECONSTRUCCION +%% ═══════════════════════════════════════════════════════ +fprintf(' Animacion terminada.\n\n'); + +figure('Name','Reconstruccion FFT','NumberTitle','off', ... + 'Position',[80 80 1300 750],'Color',[0.05 0.05 0.08]); + +subplot(3,1,1); +plot(t, audio_original,'Color',c_audio,'LineWidth',0.8); +set(gca,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); +grid on; +title('Audio original dentro de la caja','Color',c_audio,'FontWeight','bold','FontSize',11); +xlabel('Tiempo (s)','Color','w'); ylabel('Amplitud','Color','w'); +xlim([0 duracion]); + +subplot(3,1,2); +plot(t, V_max,'Color',c_tia,'LineWidth',0.8); +set(gca,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); +grid on; +title('Senal capturada (MAX9814 out)','Color',c_tia,'FontWeight','bold','FontSize',11); +xlabel('Tiempo (s)','Color','w'); ylabel('V (V)','Color','w'); +xlim([0 duracion]); + +subplot(3,1,3); +plot(t, V_rec_escalado,'Color',c_rec,'LineWidth',0.8); +set(gca,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); +grid on; +title(sprintf('Senal reconstruida (IFFT) — correlacion: %.4f', rho), ... + 'Color',c_rec,'FontWeight','bold','FontSize',11); +xlabel('Tiempo (s)','Color','w'); ylabel('Amplitud','Color','w'); +xlim([0 duracion]); + +V_play = V_rec_escalado / max(abs(V_rec_escalado) + 1e-10); +fprintf(' Reproduciendo senal reconstruida...\n'); +sound(V_play, fs); + +fprintf('\n╔══════════════════════════════════════════════════════╗\n'); +fprintf('║ Simulacion completada ║\n'); +fprintf('║ Correlacion original / reconstruido: %.4f ║\n', rho); +fprintf('╚══════════════════════════════════════════════════════╝\n'); \ No newline at end of file blob - 72e6e079375bb030552e2d4c12b4dbc53bf8e8d5 (mode 644) blob + /dev/null --- simulacion_3d_laser.m +++ /dev/null @@ -1,404 +0,0 @@ -%% SIMULACION 3D — MICROFONO LASER -% Visualizacion 3D animada del experimento completo: -% Caja insonorizada → vidrio vibrante → laser → BPW34 → -% TIA (LM358) → MAX9814 → PC → FFT → reconstruccion -% -% Autor: Alejandro B. E. — Fisica 2do Semestre - -clear; close all; clc; - -fprintf('╔══════════════════════════════════════════════════════╗\n'); -fprintf('║ SIMULACION 3D — Microfono Laser ║\n'); -fprintf('╚══════════════════════════════════════════════════════╝\n\n'); -fprintf(' Presiona Q en la figura 3D para detener la animacion.\n\n'); - -%% ═══════════════════════════════════════════════════════ -% PARAMETROS -%% ═══════════════════════════════════════════════════════ - -% Audio simulado (acorde La mayor: 440 + 880 + 660 Hz) -f1 = 440; f2 = 880; f3 = 660; -fs = 8000; % Hz -duracion = 3.0; % s - -t = (0 : 1/fs : duracion - 1/fs)'; -N = length(t); - -% Senal de audio dentro de la caja (normalizada -1 a 1) -audio_original = 0.5*sin(2*pi*f1*t) + ... - 0.3*sin(2*pi*f2*t) + ... - 0.2*sin(2*pi*f3*t); -audio_original = audio_original / max(abs(audio_original)); % normalizar - -% Parametros fisicos -R_bpw34 = 0.3; % A/W — responsividad BPW34 @ 650nm -P_laser = 1e-3; % W — potencia laser -mod_depth = 0.15; % antes 0.4, — — profundidad de modulacion del vidrio -Rf_TIA = 10e3; % Ω — resistencia TIA -Av_MAX = 1; % antes 3, V/V — ganancia MAX9814 - -%% ─── PIPELINE DE SENAL (CORREGIDO) ───────────────────── - -% 1. Modulacion optica: vibracion del vidrio modula P_laser -P_luz = P_laser * (1 + mod_depth * audio_original); -% P_luz oscila entre P_laser*(1-m) y P_laser*(1+m) — nunca negativo - -% 2. BPW34: P_luz → I_foto (corriente) -I_foto = R_bpw34 * P_luz + 1e-8 * randn(N,1); -% I_foto_DC = R * P_laser = 0.3 * 1e-3 = 300 µA (offset DC) -% I_foto_AC = R * P_laser * mod_depth * audio = ±120 µA (señal util) - -% 3. TIA: I_foto → V_tia, luego ELIMINAR DC por resta de media -% (en hardware esto lo hace el capacitor de acoplamiento C_ac) -V_tia_total = I_foto * Rf_TIA; % V = I * Rf → offset DC + señal AC -V_tia = V_tia_total - mean(V_tia_total); % solo componente AC -% V_tia_AC pico = mod_depth * R * P_laser * Rf = 0.4*0.3*1e-3*10e3 = 1.2 mV -% Nota: señal pequeña — el MAX9814 la amplifica - -% 4. MAX9814: amplificar y saturar -V_max = Av_MAX * V_tia; -V_max = max(-1.65, min(1.65, V_max)); % saturacion ±1.65V - -% 5. FFT sobre la señal capturada -Y = fft(V_max); -mag_Y = abs(Y); - -% Filtrado: umbral de magnitud (conservar picos principales) -umbral = max(mag_Y) * 0.08; -mascara = mag_Y > umbral; -% Simetria conjugada obligatoria para ifft real -mascara = mascara | flipud(mascara); -Y_filt = Y .* mascara; - -% 6. Reconstruccion (IFFT) -V_rec = real(ifft(Y_filt)); - -% Escalar V_rec para comparar con audio_original (minimos cuadrados) -factor = (audio_original' * V_rec) / (V_rec' * V_rec + 1e-12); -V_rec_escalado = V_rec * factor; - -% Correlacion -cc = corrcoef(audio_original, V_rec_escalado); -rho = cc(1,2); - -fprintf(' Senal simulada:\n'); -fprintf(' Frecuencias: %.0f + %.0f + %.0f Hz\n', f1, f2, f3); -fprintf(' I_foto DC: %.0f uA\n', mean(I_foto)*1e6); -fprintf(' V_TIA AC pico: %.4f V\n', max(abs(V_tia))); -fprintf(' V_MAX pico: %.4f V\n', max(abs(V_max))); -fprintf(' Correlacion: %.4f\n\n', rho); - -%% ═══════════════════════════════════════════════════════ -% FIGURA PRINCIPAL -%% ═══════════════════════════════════════════════════════ -fig = figure('Name','Simulacion 3D — Microfono Laser', ... - 'NumberTitle','off', ... - 'Position',[30 30 1500 900], ... - 'Color',[0.05 0.05 0.08], ... - 'KeyPressFcn', @(s,e) setappdata(s,'salir', strcmp(e.Key,'q'))); -setappdata(fig, 'salir', false); - -%% ═══════════════════════════════════════════════════════ -% SUBPLOT 3D -%% ═══════════════════════════════════════════════════════ -ax3d = subplot('Position', [0.02 0.35 0.55 0.62]); -set(ax3d,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','ZColor','w'); -hold(ax3d,'on'); grid(ax3d,'on'); -view(ax3d, 35, 22); -xlabel(ax3d,'X (cm)','Color','w'); -ylabel(ax3d,'Y (cm)','Color','w'); -zlabel(ax3d,'Z (cm)','Color','w'); -title(ax3d,'Montaje experimental 3D','Color',[1 0.7 0.1],'FontWeight','bold','FontSize',12); -ax3d.GridColor = [0.2 0.2 0.2]; -xlim(ax3d,[-2 58]); ylim(ax3d,[-3 38]); zlim(ax3d,[-1 33]); -lighting(ax3d,'gouraud'); -light(ax3d,'Position',[60 60 60],'Style','infinite'); - -% Helper: dibujar caja - function dibujar_caja(ax,x0,y0,z0,Lx,Ly,Lz,col,al) - verts = [x0 y0 z0; - x0+Lx y0 z0; - x0+Lx y0+Ly z0; - x0 y0+Ly z0; - x0 y0 z0+Lz; - x0+Lx y0 z0+Lz; - x0+Lx y0+Ly z0+Lz; - x0 y0+Ly z0+Lz]; - faces = [1 2 6 5; 2 3 7 6; 3 4 8 7; - 4 1 5 8; 1 2 3 4; 5 6 7 8]; - patch(ax,'Vertices',verts,'Faces',faces, ... - 'FaceColor',col,'FaceAlpha',al, ... - 'EdgeColor',[0.55 0.55 0.55],'LineWidth',0.7); - end - -Lc = 20; % tamaño caja (cm) - -% Caja insonorizada -dibujar_caja(ax3d, 0,0,0, Lc,Lc,Lc, [0.35 0.25 0.15], 0.22); -text(ax3d, Lc/2, Lc/2, Lc+1.5,'Caja insonorizada', ... - 'Color',[0.85 0.65 0.3],'FontSize',9,'HorizontalAlignment','center'); - -% Vidrio (cara x=Lc) -[yv,zv] = meshgrid(linspace(0.5,Lc-0.5,12), linspace(0.5,Lc-0.5,12)); -xv0 = Lc * ones(size(yv)); -h_vidrio = surf(ax3d, xv0, yv, zv, ... - 'FaceColor',[0.5 0.8 1.0],'FaceAlpha',0.28, ... - 'EdgeColor',[0.4 0.7 0.9],'EdgeAlpha',0.12); -text(ax3d, Lc+0.3, Lc/2, Lc+0.8,'Vidrio', ... - 'Color',[0.5 0.9 1.0],'FontSize',9); - -% Audifono dentro de la caja -th = linspace(0,2*pi,40); -for lado = [-1 1] - yc = Lc/2 + lado*5; - fill3(ax3d, Lc/2-0.3+zeros(1,40), ... - yc + 3*cos(th), ... - Lc/2 + 3*sin(th), ... - [0.2 0.2 0.2],'FaceAlpha',0.85,'EdgeColor',[0.5 0.5 0.5]); -end -text(ax3d, Lc/2-5, Lc/2, Lc/2+5.5,'Audifono', ... - 'Color',[0.7 0.7 0.7],'FontSize',8); - -% Modulo laser KY-008 -laser_pos = [35, 4, 10]; -[xl,yl,zl] = cylinder(0.8,20); -surf(ax3d, xl*3+laser_pos(1), yl+laser_pos(2), zl+laser_pos(3), ... - 'FaceColor',[0.15 0.65 0.15],'EdgeColor','none','FaceAlpha',0.92); -text(ax3d, laser_pos(1)+0.5, laser_pos(2)-0.5, laser_pos(3)-2.2,'Laser KY-008', ... - 'Color',[0.3 1.0 0.3],'FontSize',8,'FontWeight','bold'); - -% Punto de impacto en vidrio -P_imp = [Lc, 10, 10]; - -% Haz laser (rojo solido) -h_haz_ida = plot3(ax3d, ... - [laser_pos(1) P_imp(1)], ... - [laser_pos(2) P_imp(2)], ... - [laser_pos(3) P_imp(3)], ... - 'r-','LineWidth',2.5); - -% Reflexion hacia BPW34 -v_inc = (P_imp - laser_pos) / norm(P_imp - laser_pos); -n_vid = [-1 0 0]; -v_ref = v_inc - 2*dot(v_inc,n_vid)*n_vid; -bpw34_pos = P_imp + 12*v_ref; - -h_haz_ref = plot3(ax3d, ... - [P_imp(1) bpw34_pos(1)], ... - [P_imp(2) bpw34_pos(2)], ... - [P_imp(3) bpw34_pos(3)], ... - 'r--','LineWidth',1.8); - -% Punto de impacto -plot3(ax3d, P_imp(1),P_imp(2),P_imp(3),'y*','MarkerSize',12,'LineWidth',2); - -% BPW34 (caja negra) -dibujar_caja(ax3d, bpw34_pos(1)-1.2, bpw34_pos(2)-1.2, bpw34_pos(3)-1.2, ... - 2.4, 2.4, 2.4, [0.08 0.08 0.08], 0.92); -text(ax3d, bpw34_pos(1), bpw34_pos(2), bpw34_pos(3)+3.2,'BPW34', ... - 'Color',[1.0 0.85 0.1],'FontSize',9,'FontWeight','bold','HorizontalAlignment','center'); - -% Tubo negro (proteccion de luz ambiente) -[xt,yt,zt] = cylinder(1.5,20); -surf(ax3d, xt+bpw34_pos(1), yt+bpw34_pos(2), zt*5+bpw34_pos(3)-2.5, ... - 'FaceColor',[0.07 0.07 0.07],'EdgeColor','none','FaceAlpha',0.55); - -% Protoboard + LM358 TIA -proto = [37, 14, 4]; -dibujar_caja(ax3d, proto(1), proto(2), proto(3), 9, 5, 0.6, [0.1 0.5 0.1], 0.85); -text(ax3d, proto(1)+4.5, proto(2)+2.5, proto(3)+2,'LM358 TIA', ... - 'Color',[0.4 1.0 0.4],'FontSize',8,'HorizontalAlignment','center'); - -% Cable BPW34 → TIA -plot3(ax3d,[bpw34_pos(1) proto(1)+4], ... - [bpw34_pos(2) proto(2)+2], ... - [bpw34_pos(3) proto(3)+0.5], ... - 'Color',[1 0.55 0.1],'LineWidth',1.5,'LineStyle',':'); - -% MAX9814 -maxp = [37, 21, 4]; -dibujar_caja(ax3d, maxp(1), maxp(2), maxp(3), 7, 4, 1.2, [0.45 0.1 0.55], 0.88); -text(ax3d, maxp(1)+3.5, maxp(2)+2, maxp(3)+2.8,'MAX9814', ... - 'Color',[0.9 0.5 1.0],'FontSize',8,'HorizontalAlignment','center'); - -% Cable TIA → MAX9814 -plot3(ax3d,[proto(1)+4 maxp(1)+3], ... - [proto(2)+5 maxp(2)], ... - [proto(3)+0.5 maxp(3)+0.6], ... - 'Color',[1 0.55 0.1],'LineWidth',1.5,'LineStyle',':'); - -% Laptop -pcp = [46, 14, 4]; -% Pantalla -fill3(ax3d,[pcp(1) pcp(1)+9 pcp(1)+9 pcp(1)], ... - [pcp(2) pcp(2) pcp(2) pcp(2)], ... - [pcp(3) pcp(3) pcp(3)+8 pcp(3)+8], ... - [0.1 0.1 0.16],'EdgeColor',[0.5 0.5 0.5],'FaceAlpha',0.92); -fill3(ax3d,[pcp(1)+0.5 pcp(1)+8.5 pcp(1)+8.5 pcp(1)+0.5], ... - [pcp(2)-0.1 pcp(2)-0.1 pcp(2)-0.1 pcp(2)-0.1], ... - [pcp(3)+0.5 pcp(3)+0.5 pcp(3)+7.5 pcp(3)+7.5], ... - [0.05 0.3 0.4],'EdgeColor','none','FaceAlpha',0.85); -% Base -fill3(ax3d,[pcp(1) pcp(1)+9 pcp(1)+9 pcp(1)], ... - [pcp(2) pcp(2) pcp(2)+4 pcp(2)+4], ... - [pcp(3) pcp(3) pcp(3) pcp(3)], ... - [0.2 0.2 0.2],'EdgeColor',[0.5 0.5 0.5],'FaceAlpha',0.92); -text(ax3d, pcp(1)+4.5, pcp(2)-1.2, pcp(3)+4,'PC + MATLAB', ... - 'Color',[0.3 0.85 1.0],'FontSize',9,'FontWeight','bold','HorizontalAlignment','center'); - -% Cable MAX9814 → PC -plot3(ax3d,[maxp(1)+7 pcp(1)], ... - [maxp(2)+2 pcp(2)+2], ... - [maxp(3)+0.6 pcp(3)+0.5], ... - 'Color',[0.7 0.7 0.7],'LineWidth',2); - -% Leyenda -legend(ax3d,[h_haz_ida,h_haz_ref], ... - {'Haz laser (650nm)','Reflexion hacia BPW34'}, ... - 'Location','northeast','TextColor','w', ... - 'Color',[0.1 0.1 0.15],'EdgeColor',[0.4 0.4 0.4]); - -%% ═══════════════════════════════════════════════════════ -% SUBPLOTS INFERIORES DE SENAL -%% ═══════════════════════════════════════════════════════ -c_audio = [1.0 0.7 0.1]; -c_foto = [1.0 0.4 0.3]; -c_tia = [0.3 0.8 1.0]; -c_rec = [0.4 1.0 0.4]; - -ax_audio = subplot('Position',[0.02 0.03 0.22 0.28]); -ax_ifoto = subplot('Position',[0.26 0.03 0.22 0.28]); -ax_tia = subplot('Position',[0.50 0.03 0.22 0.28]); -ax_fft = subplot('Position',[0.74 0.03 0.24 0.28]); - -function setup_ax(ax, ttl, col) - set(ax,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w', ... - 'GridColor',[0.15 0.15 0.15],'FontSize',8); - grid(ax,'on'); - title(ax, ttl,'Color',col,'FontWeight','bold','FontSize',9); - xlabel(ax,'Tiempo (s)','Color','w','FontSize',8); -end - -setup_ax(ax_audio,'Audio en la caja', c_audio); -setup_ax(ax_ifoto,'BPW34 — I_{foto} (uA)', c_foto); -setup_ax(ax_tia, 'V_{TIA} + MAX9814 (mV)', c_tia); -setup_ax(ax_fft, 'FFT — Espectro', c_rec); - -n_win = round(fs * 0.012); % ventana de 12 ms -t_win = t(1:n_win); - -h_l_audio = plot(ax_audio, t_win, audio_original(1:n_win), 'Color',c_audio,'LineWidth',1.2); -h_l_ifoto = plot(ax_ifoto, t_win, I_foto(1:n_win)*1e6, 'Color',c_foto, 'LineWidth',1.2); -h_l_tia = plot(ax_tia, t_win, V_tia(1:n_win)*1e3, 'Color',c_tia, 'LineWidth',1.2); - -ylim(ax_audio,[-1.3 1.3]); -ylim(ax_ifoto,[min(I_foto)*1e6*1.05 max(I_foto)*1e6*1.05]); -ylim(ax_tia, [min(V_tia)*1e3*1.1 max(V_tia)*1e3*1.1]); - -% FFT estatica -f_vec = (0:floor(N/2)) * fs / N; -mag = abs(Y(1:floor(N/2)+1)) / N; -mag(2:end-1) = 2*mag(2:end-1); -plot(ax_fft, f_vec, mag,'Color',c_rec,'LineWidth',0.9); -xlim(ax_fft,[0 2000]); -set(ax_fft,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); -grid(ax_fft,'on'); -title(ax_fft,'FFT — Espectro','Color',c_rec,'FontWeight','bold','FontSize',9); -xlabel(ax_fft,'Frecuencia (Hz)','Color','w','FontSize',8); -hold(ax_fft,'on'); -for fi = [f1 f2 f3] - [~,idx_fi] = min(abs(f_vec - fi)); - plot(ax_fft, fi, mag(idx_fi),'w^','MarkerSize',7,'MarkerFaceColor','w'); - text(ax_fft, fi, mag(idx_fi)*1.12, sprintf('%.0fHz',fi), ... - 'Color','w','FontSize',7,'HorizontalAlignment','center'); -end - -%% ═══════════════════════════════════════════════════════ -% ANIMACION -%% ═══════════════════════════════════════════════════════ -fprintf(' Iniciando animacion (presiona Q para salir)...\n\n'); - -paso = round(fs/30); % ~30 fps -n_frm = floor(N / paso); -amp_v = 0.25; % cm vibracion max del vidrio - -for k = 1:n_frm - - if ~ishandle(fig) || getappdata(fig,'salir'), break; end - - i0 = (k-1)*paso + 1; - i1 = min(i0 + n_win - 1, N); - idx = i0:i1; - - if length(idx) < n_win, break; end - - % Vibracion del vidrio - desp = amp_v * audio_original(i0); - set(h_vidrio,'XData',(Lc + desp)*ones(size(yv))); - - % Haz laser sigue el punto de impacto - P_imp_k = [Lc + desp, P_imp(2), P_imp(3)]; - set(h_haz_ida,'XData',[laser_pos(1) P_imp_k(1)], ... - 'YData',[laser_pos(2) P_imp_k(2)], ... - 'ZData',[laser_pos(3) P_imp_k(3)]); - set(h_haz_ref,'XData',[P_imp_k(1) bpw34_pos(1)], ... - 'YData',[P_imp_k(2) bpw34_pos(2)], ... - 'ZData',[P_imp_k(3) bpw34_pos(3)]); - - % Actualizar graficas - tw = t(idx); - set(h_l_audio,'XData',tw,'YData',audio_original(idx)); - set(h_l_ifoto,'XData',tw,'YData',I_foto(idx)*1e6); - set(h_l_tia, 'XData',tw,'YData',V_tia(idx)*1e3); - xlim(ax_audio,[tw(1) tw(end)]); - xlim(ax_ifoto,[tw(1) tw(end)]); - xlim(ax_tia, [tw(1) tw(end)]); - - title(ax3d, sprintf('Montaje 3D — t = %.3f s | P_{laser} = %.5f W', ... - t(i0), P_luz(i0)), ... - 'Color',[1 0.7 0.1],'FontWeight','bold','FontSize',11); - - drawnow limitrate; -end - -%% ═══════════════════════════════════════════════════════ -% FIGURA FINAL: RECONSTRUCCION -%% ═══════════════════════════════════════════════════════ -fprintf(' Animacion terminada.\n\n'); - -figure('Name','Reconstruccion FFT','NumberTitle','off', ... - 'Position',[80 80 1300 750],'Color',[0.05 0.05 0.08]); - -subplot(3,1,1); -plot(t, audio_original,'Color',c_audio,'LineWidth',0.8); -set(gca,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); -grid on; -title('Audio original dentro de la caja','Color',c_audio,'FontWeight','bold','FontSize',11); -xlabel('Tiempo (s)','Color','w'); ylabel('Amplitud','Color','w'); -xlim([0 duracion]); - -subplot(3,1,2); -plot(t, V_max,'Color',c_tia,'LineWidth',0.8); -set(gca,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); -grid on; -title('Senal capturada (MAX9814 out)','Color',c_tia,'FontWeight','bold','FontSize',11); -xlabel('Tiempo (s)','Color','w'); ylabel('V (V)','Color','w'); -xlim([0 duracion]); - -subplot(3,1,3); -plot(t, V_rec_escalado,'Color',c_rec,'LineWidth',0.8); -set(gca,'Color',[0.05 0.05 0.08],'XColor','w','YColor','w','GridColor',[0.15 0.15 0.15]); -grid on; -title(sprintf('Senal reconstruida (IFFT) — correlacion: %.4f', rho), ... - 'Color',c_rec,'FontWeight','bold','FontSize',11); -xlabel('Tiempo (s)','Color','w'); ylabel('Amplitud','Color','w'); -xlim([0 duracion]); - -V_play = V_rec_escalado / max(abs(V_rec_escalado) + 1e-10); -fprintf(' Reproduciendo senal reconstruida...\n'); -sound(V_play, fs); - -fprintf('\n╔══════════════════════════════════════════════════════╗\n'); -fprintf('║ Simulacion completada ║\n'); -fprintf('║ Correlacion original / reconstruido: %.4f ║\n', rho); -fprintf('╚══════════════════════════════════════════════════════╝\n'); \ No newline at end of file