En comunicaciones analógicas se manejan algunos parámetros con el fin de simplificar el modelado de componentes, los parámetros mas relevantes son: parámetros de admitancia y parámetros de reflexión; los fabricantes suelen facilitar al usuario archivos para simular estos componentes, usualmente archivos .S2P (archivos con la información de los parámetros de reflexión), estos archivos son aceptados por gran cantidad de simuladores ya que son sencillos de trabajar y mas fáciles de encontrar, pero también nos vamos a topar con archivos .Y2P (archivos con la información de los parámetros de admitancia), o bien encontraremos datasheets con esta información, estos archivos no son aceptados por los simuladores así que si deseamos simular dicho componente se puede volver algo tedioso ya que debemos realizar cálculos para pasar de unos parámetros a otros, este post tiene como propósito facilitar este trabajo y dejar que la maquina lo haga por nosotros.

Utilizando Python realizaremos la lectura y modificación de un archivo .Y2P dado por el fabricante de un transistor y generaremos un .S2P; Pero primero… que son estos parámetros y como se realiza la conversión?

  • Parámetros de reflexión

Estos parámetros nos dicen como es el comportamiento básico de redes eléctricas lineales cuando se someten a varios estímulos de régimen permanente, estos parámetros varían según la frecuencia de operación por lo que debe tener información para cualquier frecuencia, en esta se debe encontrar.

Muchas propiedades eléctricas útiles de las redes o de componentes pueden expresarse por medio de los parámetros-S, como por ejemplo la ganancia, pérdida por retorno, relación de onda estacionaria de tensión, coeficiente de reflexión y estabilidad de amplificación.

Dispersión se refiere a la forma en que las corrientes y tensiones que se desplazan en una línea de transmisión son afectadas cuando se encuentran con una discontinuidad debida por la introducción de una red en una línea de transmisión. Esto equivale a la onda encontrándose con una impedancia diferente de la impedancia característica de la línea.

Selección_009.png

Con:

S11= \frac{b1}{a1}|a2=0
S12= \frac{b1}{a2}|a1=0
S21= \frac{b2}{a1}|a2=0
S22= \frac{b2}{a2}|a1=0

Donde:

  1. S11= Coeficiente de reflexión de entrada
  2. S12= Coeficiente de reflexión de transmisión inversa
  3. S21= Coeficiente de reflexión de transmisión directa
  4. S22= Coeficiente de reflexión de salida
  • Parámetros de admitancia

Contiene básicamente la misma información que los parámetros S pero analizadas desde su admitancia, la admitancia de un circuito es la facilidad que este ofrece al paso de la corriente.

Selección_010

Con:

Yi=\frac{I1}{V1}|V2=0
Yr=\frac{I1}{V2}|V1=0
Yf=\frac{I2}{V1}|V2=0
Yo=\frac{I2}{V2}|V1=0
I1=YiV1+YrV2
I2=YfV1+YoV2

Donde:

  1. Yi= Admitancia de entrada de corto circuito
  2. Yr= Admitancia de transferencia inversa de corto circuito
  3. Yf= Admitancia de transferencia directa de corto circuito
  4. Yo= Admitancia de salida de corto circuito

Con todo esto en mente… como hacemos para pasar de unos parámetros a los otros?

  • Conversión de parámetros

Selección_011.png

Donde Zo es la impedancia de acoplamiento de la red de dos puertos, normalmente de 50Ω.

Lo que realizaremos es un ejecutable en Python el cual nos pida la dirección del archivo para lograr la conversión de todos los parámetros Y a parámetros S.

  • Creando nuestro ejecutable

Lo primero que haremos es pedirle al usuario la dirección del archivo .Y2P dado por el fabricante:

donde = raw_input("Ingrese la direccion del archivo: ").replace(" ", "")
print "\nLa ruta es:", donde,"\n\n\n"
l=len(donde)
a=".y2p"

Se realiza también la limpieza de esta dirección eliminado espacios si es que el usuario los ingresa, también se mira que tan larga es la dirección y se crea una variable “a” con el fin de realizar una validación que veremos continuación:

if donde[l-4:l]==a:
    f=open(donde, 'rb')    #Se abre el archivo .y2p
    ls=f.readlines()            #Se lee el archivo
    linea=0
    archi=open('resultado.s2p','w')    #Se crea el archivo .s2p
    #Escritura de lineas fijas
    archi.write('#Archivo .S2P a partir de .Y2P\n')
    archi.write('#Autor: Jonnathan Sebastian Sanchez Sanabria\n')
    archi.write('#Grupo de trabajo GNU/Linux Universidad Distrital (GLUD)\n')
    archi.write('#License: GPLv3\n')
    archi.write('#Year:2017\n')

    archi.write('!Freq.(MHz) S11(Real) S11(Imag) S21(Real) S21(Imag) S12(Real) S12(Imag) S22(Real) S22(Imag)\n')

Se realiza una comparación para asegurar el ingreso de un archivo .Y2P, de ser así iniciamos el proceso de creación de nuestro archivo .S2P, ingresando unas lineas predefinidas.

for i,j in zip (ls,range(len(ls))):
        if i[0:5]=='! Mhz':
            linea=j
    print "Archivo creado exitosamente:\nNombre del archivo:resultado.s2p\nUbicacion:Esta carpeta"
    #print linea,len(ls)
    compi = []
    for i in range(linea+1,len(ls)):
        datos =  filter(None, (ls[i].replace(" ","\t")).split("\t"))
        clean_data = filter(None, [i.replace("\r\n",'') for i in datos])
        freq=float(clean_data[0])#*1000000
        archi.write(str(freq))
        archi.write(" ")

Ahora se realiza la lectura linea a linea del archivo, buscando la linea que inicie en “! Mhz”, esta linea viene por defecto en los archivos dados por los fabricantes y después de esta inicia la información con la que realizaremos nuestro cálculos; Se realiza una limpieza de esta información con el fin de facilitar su lectura, para poder realizar los cálculos debemos saber como esta dispuesta la información, para esto miramos el archivo del fabricante:

! Mhz    gi    bi    gf    bf    gr    br    go    bo

Donde g es la parte real de nuestro parámetro y b la parte imaginaria de este, la información viene en el siguiente orden: Yi, Yf, Yr, Yo.
Lo siguiente que se debe realizar es generar un numero imaginario compuesto por g+b, para cada uno de nuestros parámetros:

        Yi = complex(float(clean_data[1]),float(clean_data[2]))
        Yf = complex(float(clean_data[3]),float(clean_data[4]))
        Yr = complex(float(clean_data[5]),float(clean_data[6]))
        Yo = complex(float(clean_data[7]),float(clean_data[8]))
        vares = [Yi,Yf,Yr,Yo]
        compi.append(vares)

Con esto ya estamos listos para realizar los cálculos necesarios:

        S11=((1-Yi)*(1+Yo)+(Yr*Yf))/((1-Yi)*(1+Yo)-(Yr*Yf))       #S11
        s11real=S11.real
        s11imag=S11.imag
        archi.write(str(s11real))
        archi.write(" ")
        archi.write(str(s11imag))
        S12=((-2*Yr)/((1+Yi)*(1+Yo)-(Yr*Yf)))                     #S12
        s12real=S12.real
        s12imag=S12.imag
        archi.write(str(s12real))
        archi.write(" ")
        archi.write(str(s12imag))
        archi.write(" ")
        S21=((-2*Yf)/((1+Yi)*(1+Yo)-(Yr*Yf)))                     #S21
        s21real=S21.real
        s21imag=S21.imag
        archi.write(str(s21real))
        archi.write(" ")
        archi.write(str(s21imag))
        archi.write(" ")
        S22=(((1+Yi)*(1-Yo)+(Yr*Yf))/((1+Yi)*(1+Yo)-(Yr*Yf)))     #S22
        s22real=S22.real
        s22imag=S22.imag
        archi.write(str(s22real))
        archi.write(" ")
        archi.write(str(s22imag))
        archi.write("\n")

Como la lectura es linea por linea, a medida que se lee se van realizando las operaciones necesarias y la escritura en nuestro archivo .S2P, cabe aclarar que este código ha sido uno de mis primeros acercamientos a Python así que este se puede optimizar bastante, si desea realizar la  optimización del código la comunidad estará agradecida con usted, cualquier sugerencia o cambio lo puede dejar en los comentarios de este post.

Para finalizar mostramos un mensaje de error en caso de ingresar un archivo distinto a .Y2P

else:
    print "La ruta no llega a un archivo .y2p\nError de capa 8"

Con esto esta listo el archivo .S2P el cual podremos utilizar para simular el componente deseado, este archivo se encontrara en la carpeta de localización del archivo leer.py

Selección_012.png

Archivos creados en este post con archivo .Y2P para pruebas: https://github.com/GLUD/Y2P-to-S2P