# ============================================================ # COMUNICACIONES 1 # Unidad 6: Fibra óptica # Resolución de ejercicios propuestos # Google Colab / Python # ============================================================ import math # ------------------------------------------------------------ # FUNCIONES AUXILIARES # ------------------------------------------------------------ def mostrar_titulo(titulo): print("\n" + "=" * 72) print(titulo) print("=" * 72) def validar_positivo(valor, nombre): if valor <= 0: raise ValueError(f"{nombre} debe ser mayor que cero.") def validar_no_negativo(valor, nombre): if valor < 0: raise ValueError(f"{nombre} no puede ser negativo.") # ============================================================ # CONVERSIONES ÓPTICAS # ============================================================ def mw_a_dbm(P_mW): """ Convierte potencia óptica desde mW a dBm. Fórmula: P_dBm = 10 * log10(P_mW / 1 mW) """ validar_positivo(P_mW, "P_mW") return 10 * math.log10(P_mW) def dbm_a_mw(P_dBm): """ Convierte potencia óptica desde dBm a mW. Fórmula: P_mW = 10^(P_dBm / 10) """ return 10 ** (P_dBm / 10) # ============================================================ # EJERCICIO 1: ATENUACIÓN TOTAL POR FIBRA # ============================================================ # Fórmula: # A_fibra = alpha * L # # Donde: # A_fibra = pérdida por fibra en dB # alpha = atenuación en dB/km # L = longitud en km def calcular_atenuacion_fibra(alpha_db_km, longitud_km): """ Calcula la atenuación total de una fibra óptica. Parámetros: alpha_db_km : atenuación de la fibra en dB/km longitud_km : longitud del enlace en km """ validar_no_negativo(alpha_db_km, "alpha_db_km") validar_no_negativo(longitud_km, "longitud_km") A_fibra = alpha_db_km * longitud_km return A_fibra # ============================================================ # EJERCICIO 2: PRESUPUESTO ÓPTICO # ============================================================ # Fórmulas: # A_fibra = alpha * L # A_conectores = N_c * A_c # A_empalmes = N_e * A_e # A_total = A_fibra + A_conectores + A_empalmes + M def calcular_presupuesto_optico( longitud_km, alpha_db_km, cantidad_conectores, perdida_conector_db, cantidad_empalmes, perdida_empalme_db, margen_db ): """ Calcula la pérdida total de un enlace óptico. Incluye: - pérdida por fibra; - pérdida por conectores; - pérdida por empalmes; - margen de diseño. """ validar_no_negativo(longitud_km, "longitud_km") validar_no_negativo(alpha_db_km, "alpha_db_km") validar_no_negativo(cantidad_conectores, "cantidad_conectores") validar_no_negativo(perdida_conector_db, "perdida_conector_db") validar_no_negativo(cantidad_empalmes, "cantidad_empalmes") validar_no_negativo(perdida_empalme_db, "perdida_empalme_db") validar_no_negativo(margen_db, "margen_db") A_fibra = alpha_db_km * longitud_km A_conectores = cantidad_conectores * perdida_conector_db A_empalmes = cantidad_empalmes * perdida_empalme_db A_total = A_fibra + A_conectores + A_empalmes + margen_db return A_fibra, A_conectores, A_empalmes, A_total # ============================================================ # EJERCICIO 3: POTENCIA RECIBIDA # ============================================================ # Fórmula: # P_RX = P_TX - A_total # # Donde: # P_RX = potencia recibida en dBm # P_TX = potencia transmitida en dBm # A_total = pérdida total en dB def calcular_potencia_recibida(P_TX_dBm, A_total_dB): """ Calcula la potencia óptica recibida en dBm. """ validar_no_negativo(A_total_dB, "A_total_dB") P_RX_dBm = P_TX_dBm - A_total_dB return P_RX_dBm # ============================================================ # EJERCICIO 4: MARGEN RESPECTO DE SENSIBILIDAD # ============================================================ # Fórmula: # Margen = P_RX - S_RX # # Donde: # P_RX = potencia recibida en dBm # S_RX = sensibilidad mínima del receptor en dBm def calcular_margen_enlace(P_RX_dBm, sensibilidad_RX_dBm): """ Calcula el margen del enlace respecto de la sensibilidad del receptor. """ margen_db = P_RX_dBm - sensibilidad_RX_dBm return margen_db def evaluar_margen(margen_db): """ Evalúa si el enlace tiene margen positivo, justo o negativo. """ if margen_db > 3: return "Enlace con margen adecuado." elif margen_db >= 0: return "Enlace funcional, pero con margen reducido." else: return "Enlace no recomendado: la potencia recibida queda por debajo de la sensibilidad." # ============================================================ # EJERCICIO 5: APERTURA NUMÉRICA # ============================================================ # Fórmula: # NA = sqrt(n1^2 - n2^2) # # Donde: # n1 = índice de refracción del núcleo # n2 = índice de refracción del revestimiento def calcular_apertura_numerica(n1, n2): """ Calcula la apertura numérica de una fibra óptica. Condición física: n1 debe ser mayor que n2. """ validar_positivo(n1, "n1") validar_positivo(n2, "n2") if n1 <= n2: raise ValueError("Para guiar luz en la fibra debe cumplirse n1 > n2.") NA = math.sqrt(n1**2 - n2**2) return NA def calcular_angulo_aceptacion(NA, n0=1.0): """ Calcula el ángulo máximo de aceptación en grados. Fórmula: theta_max = asin(NA / n0) n0 = índice del medio externo, aproximadamente 1 para aire. """ validar_positivo(n0, "n0") validar_no_negativo(NA, "NA") if NA / n0 > 1: raise ValueError("NA/n0 no puede ser mayor que 1 para calcular arcsen.") theta_rad = math.asin(NA / n0) theta_grados = math.degrees(theta_rad) return theta_grados def calcular_angulo_critico(n1, n2): """ Calcula el ángulo crítico para reflexión interna total. Fórmula: theta_c = asin(n2 / n1) """ validar_positivo(n1, "n1") validar_positivo(n2, "n2") if n1 <= n2: raise ValueError("Debe cumplirse n1 > n2.") theta_c_rad = math.asin(n2 / n1) theta_c_grados = math.degrees(theta_c_rad) return theta_c_grados # ============================================================ # EJERCICIO 6: RETARDO DE PROPAGACIÓN # ============================================================ # Fórmulas: # v = c / n # t_p = L / v # # Donde: # v = velocidad de propagación en la fibra # c = velocidad de la luz en el vacío # n = índice de refracción efectivo # L = longitud en metros # t_p = retardo de propagación def calcular_velocidad_fibra(n): """ Calcula la velocidad de propagación en la fibra. """ validar_positivo(n, "n") c = 3e8 # m/s v = c / n return v def calcular_retardo_fibra(longitud_km, n): """ Calcula el retardo de propagación en una fibra óptica. """ validar_no_negativo(longitud_km, "longitud_km") validar_positivo(n, "n") longitud_m = longitud_km * 1000 v = calcular_velocidad_fibra(n) t_s = longitud_m / v return t_s, v # ============================================================ # EJERCICIO 7: DISPERSIÓN CROMÁTICA # ============================================================ # Fórmula: # Delta_t = D * Delta_lambda * L # # Donde: # Delta_t = ensanchamiento temporal en ps # D = coeficiente de dispersión en ps/(nm*km) # Delta_lambda = ancho espectral en nm # L = longitud en km def calcular_dispersion_cromatica(D_ps_nm_km, delta_lambda_nm, longitud_km): """ Calcula el ensanchamiento temporal por dispersión cromática. """ validar_no_negativo(D_ps_nm_km, "D_ps_nm_km") validar_no_negativo(delta_lambda_nm, "delta_lambda_nm") validar_no_negativo(longitud_km, "longitud_km") delta_t_ps = D_ps_nm_km * delta_lambda_nm * longitud_km return delta_t_ps # ============================================================ # FUNCIÓN OPCIONAL: FRECUENCIA ÓPTICA # ============================================================ # Fórmula: # f = c / lambda def calcular_frecuencia_optica(longitud_onda_nm): """ Calcula la frecuencia óptica a partir de la longitud de onda. Parámetro: longitud_onda_nm : longitud de onda en nanómetros Retorna: frecuencia en Hz y en THz """ validar_positivo(longitud_onda_nm, "longitud_onda_nm") c = 3e8 longitud_onda_m = longitud_onda_nm * 1e-9 f_hz = c / longitud_onda_m f_thz = f_hz / 1e12 return f_hz, f_thz # ============================================================ # RESOLUCIÓN DE LOS EJERCICIOS PROPUESTOS # ============================================================ # ------------------------------------------------------------ # EJERCICIO 1 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 1: Cálculo de atenuación total") L_km_ej1 = 25 alpha_ej1 = 0.35 A_fibra_ej1 = calcular_atenuacion_fibra(alpha_ej1, L_km_ej1) print(f"Longitud del enlace : {L_km_ej1} km") print(f"Atenuación de la fibra : {alpha_ej1} dB/km") print(f"Pérdida por fibra : {A_fibra_ej1:.2f} dB") # ------------------------------------------------------------ # EJERCICIO 2 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 2: Presupuesto óptico") longitud_km = 20 alpha_db_km = 0.35 cantidad_conectores = 4 perdida_conector_db = 0.5 cantidad_empalmes = 6 perdida_empalme_db = 0.1 margen_db = 3 A_fibra, A_conectores, A_empalmes, A_total = calcular_presupuesto_optico( longitud_km, alpha_db_km, cantidad_conectores, perdida_conector_db, cantidad_empalmes, perdida_empalme_db, margen_db ) print(f"Longitud del enlace : {longitud_km} km") print(f"Atenuación de fibra : {alpha_db_km} dB/km") print(f"Pérdida por fibra : {A_fibra:.2f} dB") print(f"Cantidad de conectores : {cantidad_conectores}") print(f"Pérdida por conector : {perdida_conector_db} dB") print(f"Pérdida por conectores : {A_conectores:.2f} dB") print(f"Cantidad de empalmes : {cantidad_empalmes}") print(f"Pérdida por empalme : {perdida_empalme_db} dB") print(f"Pérdida por empalmes : {A_empalmes:.2f} dB") print(f"Margen de diseño : {margen_db:.2f} dB") print(f"Pérdida total del enlace : {A_total:.2f} dB") # ------------------------------------------------------------ # EJERCICIO 3 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 3: Potencia recibida") P_TX_dBm = 0 P_RX_dBm = calcular_potencia_recibida(P_TX_dBm, A_total) print(f"Potencia transmitida : {P_TX_dBm:.2f} dBm") print(f"Pérdida total : {A_total:.2f} dB") print(f"Potencia recibida : {P_RX_dBm:.2f} dBm") print(f"Potencia recibida : {dbm_a_mw(P_RX_dBm):.6f} mW") # ------------------------------------------------------------ # EJERCICIO 4 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 4: Margen respecto de sensibilidad") sensibilidad_RX_dBm = -18 margen_enlace = calcular_margen_enlace(P_RX_dBm, sensibilidad_RX_dBm) print(f"Potencia recibida : {P_RX_dBm:.2f} dBm") print(f"Sensibilidad del receptor : {sensibilidad_RX_dBm:.2f} dBm") print(f"Margen del enlace : {margen_enlace:.2f} dB") print(f"Evaluación : {evaluar_margen(margen_enlace)}") # ------------------------------------------------------------ # EJERCICIO 5 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 5: Apertura numérica") n1 = 1.48 n2 = 1.46 NA = calcular_apertura_numerica(n1, n2) theta_max = calcular_angulo_aceptacion(NA, n0=1.0) theta_c = calcular_angulo_critico(n1, n2) print(f"Índice del núcleo n1 : {n1}") print(f"Índice del cladding n2 : {n2}") print(f"Apertura numérica NA : {NA:.4f}") print(f"Ángulo máximo aceptación : {theta_max:.2f} grados") print(f"Ángulo crítico : {theta_c:.2f} grados") # ------------------------------------------------------------ # EJERCICIO 6 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 6: Retardo de propagación") L_km = 50 n = 1.5 t_s, v = calcular_retardo_fibra(L_km, n) print(f"Longitud del enlace : {L_km} km") print(f"Índice de refracción n : {n}") print(f"Velocidad en la fibra : {v:.2e} m/s") print(f"Retardo de propagación : {t_s:.3e} s") print(f"Retardo de propagación : {t_s * 1e6:.2f} us") print(f"Retardo de propagación : {t_s * 1e3:.4f} ms") # ------------------------------------------------------------ # EJERCICIO 7 # ------------------------------------------------------------ mostrar_titulo("EJERCICIO 7: Dispersión cromática") D = 17 delta_lambda = 0.1 L_km_disp = 80 delta_t_ps = calcular_dispersion_cromatica(D, delta_lambda, L_km_disp) print(f"Coeficiente D : {D} ps/(nm·km)") print(f"Ancho espectral Δλ : {delta_lambda} nm") print(f"Longitud del enlace : {L_km_disp} km") print(f"Ensanchamiento temporal : {delta_t_ps:.2f} ps") print(f"Ensanchamiento temporal : {delta_t_ps * 1e-12:.3e} s") # ------------------------------------------------------------ # EJERCICIO OPCIONAL # ------------------------------------------------------------ mostrar_titulo("EJERCICIO OPCIONAL: Frecuencia óptica para ventanas típicas") for lambda_nm in [850, 1310, 1550, 1625]: f_hz, f_thz = calcular_frecuencia_optica(lambda_nm) print(f"λ = {lambda_nm:4.0f} nm -> f = {f_thz:.2f} THz") # ============================================================ # RESUMEN FINAL # ============================================================ mostrar_titulo("RESUMEN DE RESULTADOS") print(f"Ejercicio 1 - Pérdida por fibra : {A_fibra_ej1:.2f} dB") print(f"Ejercicio 2 - Pérdida total enlace : {A_total:.2f} dB") print(f"Ejercicio 3 - Potencia recibida : {P_RX_dBm:.2f} dBm") print(f"Ejercicio 4 - Margen de enlace : {margen_enlace:.2f} dB") print(f"Ejercicio 5 - Apertura numérica : {NA:.4f}") print(f"Ejercicio 6 - Retardo propagación : {t_s * 1e6:.2f} us") print(f"Ejercicio 7 - Dispersión cromática : {delta_t_ps:.2f} ps")