main
commit 4cc60c4882

162
.gitignore vendored

@ -0,0 +1,162 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
Codigo/lib

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,143 @@
import numpy as np
import rtlsdr
import matplotlib.pyplot as plt
from scipy.signal import welch, windows, freqz
# -------------------------- RTL-SDR Configuration -------------------------------------------
sdr = rtlsdr.RtlSdr() # Inicializar el dispositivo RTL-SDR
sample_rate = 2.4e6 # Tasa de muestreo en muestras por segundo (3MHz)
# The maximum sample rate is 3.2 MS/s (mega samples per second).
# However, the RTL-SDR is unstable at this rate and may drop samples.
# The maximum sample rate that does not drop samples is 2.56 MS/s.
# Configurar parámetros
# Rafael Micro R820T/2/R860 24 1766 MHz (Can be improved to ~13 - 1864 MHz with experimental drivers)
# Experimentalmente capta desde 12MHz
sdr.sample_rate = sample_rate # Tasa de muestreo en muestras por segundo
sdr.center_freq = 99.9e6 # Frecuencia central en Hz (99.9 MHz)
sdr.gain = 42 # Ganancia del receptor
output_file = "fm999.bin" # Nombre del archivo de salida con las muestras capturadas
block_size = 1024 * 1024 # Tamaño de cada bloque de muestras (tasa de muestreo * duracion de la muestra)
samples_buffer = [] # Buffer para almacenar las muestras
# ------------------------ Captura y procesamiento de muestras en bloques ---------------------------------
num_blocks = 1 # Capturar 1 bloques de muestras
for _ in range(num_blocks):
samples = sdr.read_samples(block_size) # Capturar bloque de muestras
np.save(output_file, samples, allow_pickle=False) # Guardar las muestras en el archivo binario
samples_buffer.extend(samples) # Agregar las muestras al buffer
# Mantener el buffer dentro del tamaño deseado
if len(samples_buffer) > block_size * num_blocks:
samples_buffer = samples_buffer[-block_size * num_blocks:]
sdr.close() # Cerrar el dispositivo RTL-SDR
signal_energy = np.sum(np.abs(samples_buffer)**2) / len(samples_buffer) # Calcular la energía de la señal
threshold = 1e-8 # Umbral de energía de la señal
information_present = signal_energy > threshold # Verificar si hay información en las muestras
if information_present:
print("Se detectó información en las muestras.")
else:
print("No se detectó información en las muestras.")
# -------------------------------------- Procesamiento para generar el espectro de potencia con Welch ---------------------------------------------------------
# Parámetros de Welch
m = 256 # Tamaño de cada segmento de datos
k = 128 # Superposición entre segmentos
ventana = np.bartlett(m) # Ventana de Bartlett
# Cálculo del espectro de potencia mediante Welch
N = len(samples_buffer)
S = int(np.floor((N-m) / (m-k))) + 1 # Número total de segmentos
Pxx_segments = np.zeros((S, m)) # Inicializar arreglo para almacenar los espectros de potencia de cada segmento
# Calcular el espectro de potencia para cada segmento
for i in range(S-1):
start = i* (m-k) +1
end = start + m
segment = samples_buffer[start:end] * ventana
Pxx_segments[i, :] = np.abs(np.fft.fft(segment))**2 / (np.sum(ventana**2) * sample_rate)
PSD = np.mean(Pxx_segments, axis=0) # Promediar los espectros de potencia de todos los segmentos
frecuencias_welch = np.fft.fftfreq(m, d=1/sample_rate) # Frecuencias correspondientes a los segmentos de datos
# -------------------------------------- Ploteos ---------------------------------------------------------
# Muestras capturadas
plt.plot(samples_buffer)
plt.xlabel('Muestras')
plt.ylabel('Amplitud')
plt.title('Muestras capturadas')
plt.show()
# Muestras capturadas
plt.plot(np.abs(samples_buffer))
plt.xlabel('Muestras')
plt.ylabel('Amplitud')
plt.title('Muestras capturadas absolutas')
plt.show()
# Transformada de Fourier y frecuencias correspondiente de las muestras en el dominio de la frecuencia
fft_result = np.fft.fft(samples_buffer)
magnitud_fft = np.abs(fft_result)
frecuencias = np.fft.fftfreq(len(samples_buffer), d=1/sample_rate)
# Grafica de la transformada de Fourier
plt.figure(figsize=(10, 6))
plt.plot(frecuencias, magnitud_fft)
plt.title('Transformada de Fourier')
plt.xlabel('Frecuencia (Hz)')
plt.ylabel('Magnitud')
plt.show()
# Espectro de frecuencia
frequencies, spectrum = plt.psd(samples_buffer, NFFT=1024, Fs=sample_rate, scale_by_freq=True)
plt.xlabel('Frecuencia (Hz)')
plt.ylabel('Densidad espectral de potencia')
plt.title('Espectro de frecuencia')
plt.show()
# Calcular la respuesta en frecuencia
w, h = freqz(np.sqrt(PSD), worN=8000) # Utilizar la raíz cuadrada para obtener la magnitud
w_normalized = w / np.pi # Convertir la frecuencia a radianes por segundo normalizada por pi
magnitude_db = 20 * np.log10(np.abs(h)) # Calcular la magnitud en decibelios
# Graficar la respuesta en magnitud
plt.figure(figsize=(10, 6))
plt.plot(w_normalized, magnitude_db)
plt.title('Estimación de la Respuesta en Magnitud')
plt.xlabel('Frecuencia Normalizada (xπ rad/muestras)')
plt.ylabel('Magnitud (dB)')
plt.grid(True)
plt.show()
# Calcular las frecuencias normalizadas en unidades de omega/pi
frecuencias_normalizadas = frecuencias_welch / np.pi
# Graficar el espectro de potencia promedio en función de omega/pi
plt.figure(figsize=(10, 6))
plt.semilogy(frecuencias_normalizadas, PSD)
plt.text(0.5, 0.9, "Ventaneo con Bartlett", horizontalalignment='center', verticalalignment='center', transform=plt.gca().transAxes, bbox=dict(facecolor='white', alpha=0.8))
plt.title('Espectro de Potencia usando Welch')
plt.xlabel('Frecuencia Normalizada (ω/π)')
plt.ylabel('Densidad espectral de potencia')
plt.grid(True)
plt.show()

@ -0,0 +1,3 @@
home = /usr/bin
include-system-site-packages = false
version = 3.10.12
Loading…
Cancel
Save