lunes, 5 de mayo de 2014

Bootloader para PIC en GNU/Linux

Para crear y compilar programas para PIC en Linux, disponemos de varias herramientas, algunas de ellas las mismas que en Windows, haciendo uso de Wine.

A continuación enumero algunas de las herramientas que se disponen:

Piklab-> Editor
Mplab->Editor + compiladores (con wine)
Mplabx ->Editor +  compiladores
CCS->Editor y compilador de C (con wine), pero también existe una versión sin IDE para Linux.
SDCC->Compilador para Lenguaje C.
GPUtils_>Conjunto de herramientas para pics (Compilador, simulador)



Personalmente yo recomiendo Piklab como IDE para programar, ya que es altamente personalizable y es compatible con casi todos los lenguajes y compiladores que se usan con PIC, y como Lenguaje/Compilador, pues con el que uno se sienta mas a gusto.

Para programar la memoria flash del PIC en Linux, existen muchas herramientas de Hardware/Software, prácticamente las mismas que en Windows, para el caso del Pickit2, se usa el paquete PK2CMD, coloco un link con un tutorial del blog desdelinux, de como usar PK2CMD:

http://blog.desdelinux.net/como-grabar-microcontroladores-pic-desde-linux-pk2cmd/

Para Windows casi todos los fabricantes de compiladores para PIC incluyen su propio bootloader, por ejemplo Mikroelectronica y CCS, en el caso de Linux una buena opción es el "Tiny Bootloader for Linux" de Ferezvi que es una versión de "Tiny PIC bootloader" de Claudiu Chiculita que ya existía para Windows.

Ahora describiré como usar el Tiny Bootloader en Linux, antes de ello debemos disponer de un circuito con PIC y un programador (solo se usa una vez para grabar el bootloader)

1) Descargar y descomprimir : http://www.etc.ugal.ro/cchiculita/software/tinybld198.zip

2) Acceder a la carpeta "picsource", en ella encontraremos el código fuente en assembler y los archivos "HEX" para diferentes combinaciones de PIC/Frecuencia de Reloj, si nuestro caso coincide con alguno de los archivos listados saltar al paso 7), de no ser el caso, toca modificar alguno de los archivos "ASM" que resulte mas compatible, en mi caso era un PIC16f877a @ 12MHZ, que si observamos las imágenes, no se encuentra listado.

Lista de archivos para la serie 16f


Lista de archivos para la serie 18f

4) Instalar MPLAB, se puede descargar de aquí:
http://download.informer.com/win-1192947495-b5455fc8-5c3f1fdb/mplab_ide_8_91.zip, se ejecuta usando wine.

3) Abrir y modificar el código fuente a nuestra necesidad (en caso de no estar el hex disponible en las listas de arriba), para mi caso (16f877a @ 12MHZ) yo usare el archivo "tinybld16f.asm", en este archivo debemos modificar las siguientes lineas:

Linea 2 (Escoger PIC):     LIST      P=16F877A, F=INHX8M  
Linea 3 (Frecuencia de Reloj):xtal EQU 12000000  
Linea 4 (Baud Rate): baud EQU 9600 

Modificar linea de código  Fuses de configuración:
    __CONFIG  _HS_OSC & _CP_OFF & _WRT_OFF & _BODEN_ON & _PWRTE_ON & _LVP_OFF & _DEBUG_OFF

Añadir la directiva include (de acuerdo al PIC):
#include "p16f877A.inc"

4) Copiar los siguientes archivos en una carpeta nueva, podemos nombrarla "Bootloader":
bankswitch.inc 
icdpictypes.inc
spbrgselect.inc

Estos archivos también se encuentran en la carpeta "picsources".
 tinybld16f.asm (Con las modificaciones hechas)


5) Crear un proyecto en MPLAB de acuerdo al PIC que se usara, usar la carpeta Bootloader y añadir todos los archivos que ella contiene al proyecto.

6) Compilar el proyecto, y si no hay errores se generara un archivo "tinybld16f.hex"

7) Grabar el archivo "tinybld16f.hex" en el pic, usando cualquier grabador, en mi caso tengo un pickit2 con pk2cmd.

8) Instalar  el bootloader para Linux, en el PC.

http://sourceforge.net/projects/tinybldlin/files/tinybldlin/tinybldlin-0.6/

En sourceforge disponemos de archivos de instalación, por código fuente y por paquete .deb.


Hasta aquí ya tenemos el bootloader grabado en el PIC y podemos montar el pic en nuestro circuito y proceder a probar el bootloader.

Para ello después de instalar,  abrimos TinyPIC bootloader for GNU/Linux, conectamos y energizamos nuestro circuito.
Con el boton "Browse ubicamos nuestro hex"
Con el boton "check pic" verificamos que el bootloader y el pic son reconocidos
Con el boton "write flash" escribimos el hex en el pic.
Tener en cuenta que inmediatamente antes de pulsar  en "check PIC" o en "write flash" se debe inducir un reset en el PIC.
Tener en cuenta también que al escribir nuestro programa la frecuencia de reloj es la misma a la que trabaja el bootloader, la velocidad de la comunicación serial si puede variar.


Pulsando "Check PIC"

 El resultado de pulsar check PIC debe ser "Found 16f876A/877A" (obviamente de acuerdo al tipo de PIC), es decir que la detección fue exitosa.

En la siguiente captura se muestra el resultado de grabar un archivo al PIC, por medio del Bootloader.



Por ahora es todo, como ventaja del bootloader debo decir que facilita bastante el proceso de depuración y evita el uso de un grabador.

Saludos y hasta una próxima entrada.

miércoles, 19 de febrero de 2014

Notebook de IPython

El notebook de IPython es una interfaz  web para IPython y hace posible ejecutar código python  de una manera interactiva y bastante atractiva.
En IPython la documentación y el código interactúan en la interfaz web, luego se puede exportar a diferentes formatos como html o pdf para su publicación
Coloco un vídeo realizado por el equipo de Pybonacci que muestra de una manera breve un ejemplo de como usar IPython.


Para instalar ipython en Windows, GNU/Linux o MAC, consultar el siguiente enlace: Instalación de IPython


A manera de prueba, coloco un notebook que contiene el código de la entrada referente a Modelado de un Panel Fotovoltaico:

-Notebook IPython Panel Fotovoltaico 

En este Link se puede visualizar el notebook con el código para analizar un panel fotovoltaico, proporcionado en la entrada anterior de este blog.

Para probar IPython sin tener que instalar nada, se puede recurrir a la web https://cloud.sagemath.com, además se puede probar también SageMath, para  usar SageMath Cloud con todos sus servicios, te debes registrar primero en su web y podrás acceder a muchos ejemplos, cuenta también con un editor de LaTeX oncloud

Saludos y hasta la próxima.

martes, 18 de febrero de 2014

Otra de fotovoltaicos

Estoy desarrollando  un modelo en python de un panel fotovoltaico, es análogo al que puse en una entrada anterior, pero esta vez explotaremos mas el modelo y lo usaremos para analizar la interacción entre el panel fotovoltaico con los siguientes casos:

-Punto de operación, panel fotovoltaico - carga resistiva,
-Punto de operación, panel fotovoltaico - batería

Definiremos una clase con métodos que nos permitan simular el comportamiento de un panel fotovoltaico.


import numpy as np
from scipy.special import lambertw

El código anterior importa los módulos necesarios.

Ahora declaramos la clase y algunos valores necesarios para la implementación


class pv:
    """CLASE PARA ANALIZAR PANELES FOTOVOLTAICOS"""
          
    ################################################    
    # constantes fisicas
    K=1.3806503e-23 #constante de boltzman
    q=1.60217646e-19 # carga del electron
    Egap=1.124*q    #Para silicio cristalino: Egap = 1.124 eV = 1.8⋅10−19 J.

    ################################################
    # modelado de un panel fotovoltaico
    ###############################################
    #condiciones estandar de prueba (STC)
    Gstc=1.0    #valor de Irradiacion en Kw/m^2
    Tstc=273.0+25.0 #Temperatura ambiente en °K
    NOCT=46.0 # [°C] temperatura nominal de operación del modulo
    VT_stc=K*Tstc/q # Voltaje Termico en temperatura STC  ec(1.5)
    

Método de inicialización de los objetos de la clase "pv", cada vez que creemos un objeto pv, debemos asignarle los parámetros listados, caso contrario se usaran los parámetros por default.

$V_{OC_{STC}}[V]$: Voltaje de circuito abierto del modulo fotovoltaico, medido en  condiciones estandard de prueba (STC: del ingles Standard Test Condition).

$I_{SC_{STC}}$[A]: Corriente de cortocircuito del modulo fotovoltaico, en STC.

$V_{mpp_{STC}}$[V] : Voltaje en el punto de máxima potencia, en STC.

$I_{mpp_{STC}}$[A]: Corriente en el punto de máxima potencia para STC.

$\alpha_I$[A/°C]: Coeficiente de Temperatura de $I_{SC}$.

$\alpha_V$[V/°C]: Coeficiente de Temperatura de $V_{OC}$.

$N_S$: Numero de células solares en serie que forman el arreglo.

$N_P$: Numero de ramas en paralelo de que esta formado el arreglo.


    def __init__(self,Voc_stc=10.8,Isc_stc=7.7,Vmpp_stc=8.6,
                 Impp_stc=7.2,alfa_i=5.39e-3,alfa_v=-0.0378,Ns=18.0,Np=1.0):
        self.Voc_stc=Voc_stc
        self.Isc_stc=Isc_stc
        self.Vmpp_stc=Vmpp_stc
        self.Impp_stc=Impp_stc
        self.alfa_i=alfa_i
        self.alfa_v=alfa_v
        self.Ns=Ns
        self.Np=Np

A continuación el método ipanel(Va,Ga,Ta)para encontrar la corriente en el panel, a este método se le deben pasar tres parámetros,:
$V_a$: Es la tensión en los bornes del panel, para laque se desea hallar la corriente correspondiente.
$G_a$: Es el valor de la irradiación normalizado, donde una irradiación de $1000\frac{W}{m^2}$ corresponde a $G_a=1$
$T_a$: Es el valor de la temperatura ambiente, para calcular la temperatura de la celula/modulo, se usa una formula aproximada, definida dentro del método ipanel

El procedimiento para encontrar la corriente se encuentra documentado en el libro "Power Electronics and Control Techniques for Maximum Harvesting in Photovoltaics Systems". de los autores: Femia, Petrone, Spagnuolo, Vitelli.
En este  libro se muestra una forma para definir la corriente en el panel como una función explicita de  la tensión para ello se hace uso de la función Lambertw definida en scipy.
 
    def ipanel(self,Va,Ga,Ta):
        # Va [V], contiene el valor de la tension en los bornes del panel
        # Ga, el valor  de la Iradiación solar
        # Ta[°C], Temperatura  ambiente
        # ipanel:  esta función devuelve la corriente en el panel,
        #   dados el valor de Ga, Ta, Va
        ###############################################################
        T=Ta+(self.NOCT-20.0)/800.0*Ga # [°C]Temperatura del modulo
        T=273.0+T #[°K]
        VT=self.K*T/self.q # Voltaje Termico a la Temperatura del modulo
        # Cálculo de parámetros de del modelo
        Iph_stc=self.Isc_stc 
        aux1=self.alfa_v-self.Voc_stc/self.Tstc
        aux2=self.alfa_i/Iph_stc-3/self.Tstc-self.Egap/(self.K*self.Tstc**2)
        aux3=self.Ns*self.VT_stc
        n=aux1/(aux2*aux3) # Factor de idealidad
        Isat_stc=Iph_stc*np.exp(-self.Voc_stc/(n*self.Ns*self.VT_stc))
        C=Isat_stc/(self.Tstc**3*np.exp(-self.Egap/(self.K*self.Tstc))) 
        Isat=C*T**3*np.exp(-self.Egap/(self.K*T)) 
        Iph=Iph_stc*(Ga/self.Gstc)*(1.0+self.alfa_i*(T-self.Tstc))
        aux1=self.Vmpp_stc*(2.0*self.Impp_stc-Iph-Isat_stc) 
        aux2=n*Isat_stc*self.Ns*self.VT_stc
        aux3=np.exp((self.Vmpp_stc-2.0*n*self.Ns*self.VT_stc)*self.Vmpp_stc/(self.Ns**2*n**2*self.VT_stc**2))
        aux4=2.0*self.Vmpp_stc/(n*self.Ns*self.VT_stc)-self.Vmpp_stc**2/(self.Ns**2*n**2*self.VT_stc**2)
        x=np.abs(lambertw(aux1*aux3/aux2))+aux4  # ec(1.45)
        Rs=(x*n*self.Ns*self.VT_stc-self.Vmpp_stc)/self.Impp_stc
        Rp=x*n*self.Ns*self.VT_stc/(Iph_stc-self.Impp_stc-Isat*(np.exp(x)-1.0))
        aux1=(Rp*Rs)/(Rp+Rs) 
        aux2=np.exp((Rp*Rs*(Iph+Isat)+Rp*Va)/(n*self.Ns*VT*(Rp+Rs)))
        theta=aux1*Isat/(n*self.Ns*VT)*aux2
        ##############################################################
        # ecuación de salida
        I=(Rp*(Iph+Isat)-Va)/(Rs+Rp)-n*self.Ns*VT*np.abs(lambertw(theta))/Rs 
        # la siguiente ecuacion restringe I a valres mayores a 0
        #I=0.5*np.abs(I+np.abs(I))
        return I

Hasta aquí tenemos definido un método para inicializar la clase y asignar valores a los parámetros del modelo, y un método  que encuentra el valor de la corriente en el panel para un conjunto de condiciones dadas.


Lo siguiente que haremos sera analizar la interaccion entre el panel fotovoltaico y una Carga Resistiva, las condiciones de operación serán: $G=1.0$(Irradiación solar de $1000\frac{W}{m^2}$ y temperatura ambiente de $25^°C$


 
Circuito 1


Si tratáramos de solucionar el problema de manera gráfica, el punto de operación, es decir la corriente y la tensión en el conjunto panel fotovoltaico - resistencia, lo podemos encontrar por la intersección de ambas curvas I-V. Para solucionar el problema y encontrar los valores numéricos, plantearemos el problema de la siguiente forma:
Ecuación de la Resistencia :
(A):
$$V_{PV}=I_{PV}\cdot R$$     
Corriente en el modulo fotovoltaico como función de la tensión:
(B):
$$I_{PV}=F(V_{PV})$$        
Dado que la función que define la corriente $I_{PV}$ es no lineal, se hace necesaria la implementación de un método numérico que aproxime la solución. Para el presente caso emplearemos el método de la secante, a continuación muestro su implementación en python.


def secante(funcion,a,b,rel_tol,maxiter=100):
    fa=funcion(a)
    for i in xrange(maxiter):
        fb=funcion(b)
        x=b-fb*(b-a)/(fb-fa)
        a=b
        b=x
        fa=fb
        error=abs((b-a)/b)
        if error<rel_tol:
            return x
            break
    raise RuntimeError("No hubo convergencia después de {} \
                        iteraciones".format(maxiter))


Teniendo ya lo necesario, encontrar la solución del Circuito 1 se reduce a plantear las ecuaciones (A) y (B) a la forma $G(V)=0$, lo cual quedaría asi
$V_{PV}-I_{PV}\cdot R=0$
$V_{PV}-F(V_{PV})\cdot R=0$

Antes de seguir con la solucion, coloco la definición de una función auxiliar que usare para imprimir resultados:


def print_resultados(titulo,v,i):
    print "==============================="
    print "Resultados:", titulo
    print "Tension en panel Fotovoltaico",v
    print "Corriente panel fotovoltaico",i

Ahora el código necesario para resolver el circuito, usando las herramientas definidas hasta ahora.

################################################
#Resolver el circuito
#               R   
#   _________/\/\/\_____
#   |                   |
#   |                   |
#   PV                  |
#   |                   |
#   |___________________|
panel=pv()#creamos un objeto pv, con 
# parametros de inicializacion por defecto 
#(observar codigo de definicion de la clase pv)
G=1.0 #irradiacion
T=25.0#temperatura
v=np.arange(0,10.8,0.0001)#vector de tensión, lo usaremos
# para hacer un barrido
i=panel.ipanel(v,G,T)#barrido de la corriente para el
#vector de tensiones definido arriba

#La funcion pv_r(V), define el comportamiento del circuito
# PV-R
def pv_r(V):
    R=1.0
    I=panel.ipanel(V,G,T)
    return V-I*R#al pasar por el metodo secante(..)
    #debe encontrar la raiz de G(V)=V-I*R=0
  
Vpv=secante(pv_r,0,10.8,0.00001)#llamamos al metodo secante,
# notese que se pasa la funcion pv_r como parametro es decir
# encontrara el valor de "V" que haga que pv_r=0,
I=panel.ipanel(Vpv,G,T) #valor de corriente correspondiente a V
# (Hallado por el metodo de la secante) 
print_resultados("Circuito Panel-Carga",Vpv,I) 
#ahora graficamos la solucion, para verificar
plt.hold(True)
plt.plot(v,i)
R=1.0
i2=v/R
plt.plot(v,i2)
plt.xlim(0.0,10.8)
plt.ylim(0.0,8)
plt.title("Circuito 1")
plt.show()
#################################################

Ejecutando el código anterior, obtenemos la figura:


Y en la terminal obtenemos de salida lo siguiente:

jcristhian@pc-otba-01:~$ python pv_r.py
===============================
Resultados: Circuito Panel-Carga
Tension en panel Fotovoltaico 7.55679593541
Corriente panel fotovoltaico 7.55679593176

Notar que como la resistencia de carga para la que efectuamos el análisis tiene el valor de $1.0\Omega$ entonces la tensión y corriente resultantes presentan el mismo valor.

Ahora plantearemos un segundo problema que consistirá en encontrar el flujo de corriente de un modulo fotovoltaico a una batería, para propósitos didácticos modelaremos la batería como una fuente de tensión de $5$V en serie con una resistencia de $0.5\Omega$

Circuito 2



Implementación de la solucion:


#################################################
#Resolver el circuito
#               R   
#   _________/\/\/\_____
#   |                   |
#  _|_                __|__
#   PV                 Vdc
#   |                   |
#   |___________________|
#definimos la  funcion que define el problema,
#que sera pasada a la implementacion del metodo de la secante
#para encontrar la tensión que resuelve el problema
def pv_r_v(V):
    R=0.5
    Vdc=5.0
    I=pv().ipanel(V,1.0,25)
    return V-I*R-Vdc
    
Vpv=secante(pv_r_v,0,10.8,0.00001)
I=panel.ipanel(Vpv,G,T)
print_resultados("Circuito Panel-Bateria",Vpv,I)
#ahora graficamos las curvas I-V para ambos elementos
#plt.subplot(1,2,2)
plt.hold(True)
plt.plot(v,i)
plt.xlim(0.0,10.8)
plt.ylim(0.0,8)
R=0.5
Vdc=5.0
i2=(v-Vdc)/R
plt.plot(v,i2)
plt.title("Circuito 2")
plt.show()

El script anterior da como salida lo sgte:


===============================
Resultados: Circuito Panel-Bateria
Tension en panel Fotovoltaico 8.60072641912
Corriente panel fotovoltaico 7.2014528405




miércoles, 12 de febrero de 2014

Control de Potencia en AC con triac y microcontrolador PIC 16F628A

El Triac
El Triac es un dispositivo capaz conducir en ambas direcciones,  es útil para usarlo en control potencia de corriente alterna, posee un pin a través del cual se controla la conducción.

Símbolo esquemático del triac

La conducción  empieza cuando se ingresa una corriente de magnitud mínima $I_{GT}$   positiva o negativa por la compuerta (Pin G), una vez que el triac entra en conducción, la compuerta pierde el control  y el triac permanecerá conduciendo hasta que la corriente que circula entre A1 y A2 sea menor a una corriente de mantenimiento $I_H$, si necesitamos que el triac vuelva a conducir debemos lanzar otro pulso de corriente en el gate, aun cuando existen mas formas de disparar el triac, para el propósito presente solo usaremos la que hemos mencionado.

Control de Fase
 Si conectamos la fuente Vac directamente a la carga y suponiendo que la carga "LOAD" es puramente resistiva, la potencia en la carga viene dada por:

$$P=\frac{V_{AC}^2}{R}$$

Donde:
$V_{AC}$: es el voltaje efectivo de la onda senoidal
$R$: Es el valor en $\Omega$ de la carga resistiva.

Ahora, que pasa si permitimos que se transfiera corriente a la carga solo a partir de un cierto ángulo de disparo al cual llamaremos "$\alpha$", la tensión que llega a la carga tendría la forma de la onda de color verde como muestra la siguiente figura.

Control de fase

El ángulo $\alpha$ puede tomar cualquier valor entre $0$ y $\pi$ radianes, la potencia promedio  que recibe la carga en función del ángulo de disparo $\alpha$, estará dada por la fórmula:
$$P =\frac{1}{\pi} \int_{\alpha}^{ \pi} \frac{[A \cdot sin(\alpha)]^2}{R} \cdot d\alpha$$
$$P=\frac{A^2}{2\pi R}[{\pi-\alpha +\frac{1}{2} \sin(2\alpha})]$$
Donde $A$ es la amplitud de la onda senoidal.
Por simetría del problema solo es necesario integrar hasta $pi$ .

De la misma manera si queremos calcular el voltaje efectivo de la nueva onda "senoidal troceada" , en función del ángulo $\alpha$ tenemos:
$$V_{rms}=\frac{A}{\sqrt{2\pi}}\sqrt{[{\pi-\alpha +\frac{1}{2} \sin(2\alpha})]}$$

A continuación graficamos la dependencia entre el ángulo "$\alpha$", la potencia promedio "$P$" y el voltaje efectivo de la onda troceada "$V_{rms}$"


Gráfica de Ángulo de disparo, Potencia y Tensión Eficaz


El anterior gráfico, muestra como variando el ángulo de disparo (eje $X$) del triac, podemos variar la potencia que se suministra a la carga. EN el grafico, $V_{max}$ es el valor efectivo máximo que corresponde al valor efectivo de una senoidal completa es decir $\frac{A}{\sqrt{2}}$

Un circuito típico para manejar cargas en AC es como el de la figura siguiente:


Circuito 1, para variación de potencia con triac


El proceso que llevara a cabo el microcontrolador  para variar potencia mediante el triac consta de los siguientes pasos:

1:  - Detectar inicio de un nuevo medio ciclo de onda  
2:  - Esperar un tiempo t correspondiente al ángulo alfa
3:  - Enviar la señal de disparo al circuito de control  
4:  - Volver al paso 1  

Para detectar el principio de un medio ciclo de onda, usaremos este circuito cuya salida conectaremos al pin de Interrupción externa.


Circuito 2, para detectar cruce por cero de la onda senoidal.


En el Circuito 2 muestran  las formas de onda generadas en cada etapa del circuito conformador, este circuito se encarga de acondicionar la señal de la red para que el PIC16f628A detecte cada medio ciclo de la red, por medio de la interrupción externa (pin B0).

Circuito 3, circuito completo para probar el ejemplo.


 El código usado para probar el circuito es el siguiente, se usa esta usando el oscilador interno a 4MHz:


1:  #include"16f628a.h"  
2:  #use delay(clock=4000000)  
3:  #use standard_io(a)  
4:  #use standard_io(b)  
5:  #FUSES NOWDT              //No Watch Dog Timer  
6:  #FUSES INTRC_IO            //Internal RC Osc, no CLKOUT  
7:  #FUSES PUT               //Power Up Timer  
8:  #FUSES PROTECT             //Code protected from reads  
9:  #FUSES NOBROWNOUT           //No brownout reset  
10:  #FUSES MCLR              //Master Clear pin enabled  
11:  #FUSES NOLVP              //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O  
12:  #FUSES NOCPD              //No EE protection  
13:  #FUSES RESERVED            //Used to set the reserved FUSE bits  
14:  #DEFINE PIN_TTRIAC1 PIN_A3  
15:  #DEFINE PIN_TTRIAC2 PIN_b2  
16:  // El programa funciona de la siguiente manera:  
17:  // El circuito de conformacion de onda, conectado al pin de INT0  
18:  // hace que se genere una interrupcion en cada inicio de medio ciclo de la onda senoidal  
19:  // de la red, asi para 60Hz, se generara una interrupcion cada 1/(2*60Hz)=8.33ms  
20:  // Cuando se produzca la interrupcion, desde la rutina EXT_ISR   
21:  // se habilitara la interrupcion INT_T0 y se cargara el registro TIMER0 con un valor "k"  
22:  // Luego vendra la interrupcion por desbordamiento de Timer0, y disparara el triac,  
23:  // el valor de "k" se hara variar continuamente para conseguir un efecto de destello  
24:  #int_TIMER0  
25:  void INT_T0(void)   
26:  {  
27:    output_high(PIN_TTRIAC1);  
28:    output_high(PIN_TTRIAC2);  
29:    delay_us(10);   
30:    output_low(PIN_TTRIAC1);  
31:    output_low(PIN_TTRIAC2);  
32:    disable_interrupts(INT_TIMER0);  
33:  }  
34:  int k=0;  
35:  #int_EXT  
36:  void EXT_isr(void)   
37:  {  
38:     set_timer0(k--);  
39:     enable_interrupts(INT_TIMER0);  
40:  }  
41:  void config (void)  
42:  {  
43:    setup_timer_1(T1_DISABLED);  
44:    setup_timer_2(T2_DISABLED,0,1);  
45:    setup_ccp1(CCP_OFF);  
46:    setup_comparator(NC_NC_NC_NC);  
47:    setup_vref(FALSE);  
48:    enable_interrupts(INT_EXT);  
49:    ext_int_edge(l_to_h);// interrupcion externa por flanco de subida  
50:    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);//timer con desbordamiento maximo de t=1/(2*60Hz)=8.33ms  
51:    enable_interrupts(GLOBAL);  
52:    disable_interrupts(Int_Timer0);//deshabilitamos interrupcion de timer 0  
53:    set_tris_b(1);  
54:    set_tris_a(0);  
56:  }  
57:  void main (void)  
58:  {  
59:   config();  
61:   while(true)  
62:   {  
63:    //  
64:   }  
65:  }  



Vídeo de demostración



Este ensayo puede servir como base para implementar un controlador de temperatura o de cualquier variable, directamente en AC.
Los PCB que se muestran el vídeo contienen los circuitos expuestos, me despido hasta una próxima entrada.

domingo, 26 de enero de 2014

Graficar los datos de un archivo csv

 Un archivo csv=Comma Separated Values es un formato de archivo en que los datos de interés están separados por comas (u otros separadores), estos datos de interés pueden ser datos numéricos, o cadenas de caracteres.
En la presente entrada, solo nos interesan los datos numéricos, que pueden provenir de un archivo de hoja de calculo como Libre Office Calc,  MS Excel o pueden guardar resultados de simulaciones.

Este es un script de python que  procesa y grafica un archivo csv, se necesitan las librerias "pylab" y "csv".

 # procesar_csv.py  
 import pylab as pl  
 import csv  
 #  
 entrada = open('test.csv')  
 tabla = []  
 for fila in csv.reader(entrada):  
   tabla.append(fila)  
 entrada.close()  
 x=[0]  
 y=[0]  
 for fila in range(1, len(tabla)):  
     x.append(float(tabla[fila][0]))  
     y.append(float(tabla[fila][1]))  
 pl.plot(x,y)  
 pl.xlabel('Tiempo[s]')  
 pl.ylabel('Tension[V]')  
 pl.title('Ejemplo de grafica de un archivo csv')  
 pl.savefig('imagen.png')  
 pl.show()  


Este será el contenido del archivo csv de prueba, guardar como "test.csv", en el mismo directorio del script "procesar_csv.py"

 "TIME","?"  
 0,0  
 8.888888889e-05,10.4198  
 0.0001777777777,20.8278  
 0.0003555555555,41.5621  
 0.0007111111111,82.3786  
 0.001266666666,142.929  
 0.001822222222,197.233  
 0.002377777777,242.917  
 0.002933333333,277.985  
 0.003488888888,300.903  
 0.004044444444,310.67  
 0.0046,306.859  
 0.005155555555,289.638  
 0.005711111111,259.757  
 0.006266666666,218.524  
 0.006822222222,167.741  
 0.007377777777,109.626  
 0.007933333333,46.7202  
 0.008488888888,-18.2275  
 0.009044444444,-82.3786  
 0.0096,-142.929  
 0.01015555555,-197.233  
 0.01071111111,-242.917  
 0.01126666666,-277.985  
 0.01182222222,-300.903  
 0.01237777777,-310.67  
 0.01293333333,-306.859  
 0.01348888888,-289.638  
 0.01404444444,-259.757  
 0.0146,-218.524  
 0.01515555555,-167.741  
 0.01571111111,-109.626  
 0.01626666666,-46.7202  
 0.01682222222,18.2275  

Al ejecutar el script sobre el archivo csv anterior se obtiene la siguiente figura:

Panel fotovoltaico en python


Anteriormente publicamos como simular un panel fotovoltaico con GNU Octave, en la presente entrada haremos lo mismo para python, haciendo uso de las librerías numpy y matplotlib.


 import numpy as np  
 import matplotlib.pyplot as plt  
 def ipanel(V,T,G,Voc):  
   Isc=3.76  
   Ns=36.0  
   Np=1.0  
   A=1.3  
   Ki=3e-3  
   Eg=1.15  
   k=1.38e-23  
   q=1.6e-19  
   Tref=273.0+25.0  
   Tc=273.0+T  
   Irs=Isc/(np.exp(q*Voc/(Ns*k*A*Tc))-1)  
   Is=Irs*(Tc/Tref)**3*np.exp(q*Eg*(1/Tref-1/Tc)/(k*A))  
   Iph1=(Isc+Ki*(Tc-Tref))*G  
   iVTG1=Np*Iph1-Np*Is*(np.exp(q*V/(Ns*k*Tc*A))-1)  
   iVTG1=0.5*(iVTG1+np.abs(iVTG1))  
   return iVTG1  
 Vfv=np.arange(0,30.1,0.1)  
 # respuesta de la corriente cuando variamos temperatura   
 # y mantenemos la irraradiación "G" constante  
 T=np.array([25.0,40.0,60.0])  
 IT1=ipanel(Vfv,T[0],0.75,21.7)  
 IT2=ipanel(Vfv,T[1],0.75,21.7)  
 IT3=ipanel(Vfv,T[2],0.75,21.7)  
 plt.figure(1)  
 p1,=plt.plot(Vfv,IT1)  
 p2,=plt.plot(Vfv,IT2)  
 p3,=plt.plot(Vfv,IT3)  
 plt.legend([p3, p2, p1], ["T=60","T=40", "T=25"])  
 plt.ylabel("Corriente[A]")  
 plt.xlabel("Tension[V]")  
 plt.show()     
 plt.savefig('img1.png')  
 #grafica de potencia, pára las condiciones anteriores  
 plt.figure(2)  
 p1,=plt.plot(Vfv,IT1*Vfv)  
 p2,=plt.plot(Vfv,IT2*Vfv)  
 p3,=plt.plot(Vfv,IT3*Vfv)  
 plt.legend([p3, p2, p1], ["T=60","T=40", "T=25"])  
 plt.ylabel("Potencia[W]")  
 plt.xlabel("Tension[V]")  
 plt.show()   
 plt.savefig('img2.png')  
 # respuesta de la corriente cuando variamos G  
 # y mantenemos la temperatura constante  
 G=np.array([0.5,0.75,1])  
 IG1=ipanel(Vfv,T[0],G[0],21.7)  
 IG2=ipanel(Vfv,T[0],G[1],21.7)  
 IG3=ipanel(Vfv,T[0],G[2],21.7)  
 plt.figure(3)  
 p1,=plt.plot(Vfv,IG1)  
 p2,=plt.plot(Vfv,IG2)  
 p3,=plt.plot(Vfv,IG3)  
 plt.legend([p3, p2, p1], ["G=1.0","G=0.75", "G=0.5"])  
 plt.xlabel("Tension[V]")  
 plt.ylabel("Corriente[A]")  
 plt.show()   
 plt.savefig('img3.png')  
 #grafica de potencia, pára las condiciones anteriores  
 plt.figure(4)  
 p1,=plt.plot(Vfv,IG1*Vfv)  
 p2,=plt.plot(Vfv,IG2*Vfv)  
 p3,=plt.plot(Vfv,IG3*Vfv)  
 plt.legend([p3, p2, p1], ["G=1.0","G=0.75", "G=0.5"])  
 plt.xlabel("Potencia[W]")  
 plt.ylabel("Corriente[A]")  
 plt.show()   
 plt.savefig('img4.png')  







Creacion de Script para Instalar Lamp en CentOS y uso de SCP

Creacion de Script para Instalar Lamp en CentOS y uso de SCP

BASH es un shell de Unix (intérprete de comandos de Unix) escrito para el proyecto GNU. Su nombre es un acrónimo de bourne-again shell (otro shell bourne); haciendo un juego de palabras (born-again significa renacimiento) sobre el Bourne shell (sh), que fue uno de los primeros shells importantes de Unix.
Bash es el shell por defecto de la mayoria de sistemas GNU/Linux
Por eso es que un script bash es el tiene manejo de la consola del servidor,este post veremos la creación de un script para la instalación de un entorno LAMP(Linux, Apache,Mysql y Php) para un servidor CentOS,aunque algunos ya empiezan a llamar GLAMP a este entorno, dándole el crédito que merece GNU, poniendo de manera mas notoria que GNU no es igual a Linux. Lo expuesto aquí respecto a la creación de script puede ser implementado para servidor Debian, Ubuntu,Opensuse cambiando la sintaxis de su manejo de paquetes de instalación y actualizaciones Un script posee la siguiente base, lo cual lo identifica como tal para el interprete bash de la consola Linux, estas etiquetas son: 

#!/bin/bash  
# -*- ENCODING: UTF-8 -*-  

Estas dos etiquetas van al inicio del script, para crear y ejecutar un script simplemente habría que hacer los dos siguientes pasos
  • Crear y editar un archivo para script, con la característica que termine el nombre del archivo con .sh
  • Otorgar permisos y ejecutar el archivo

Creación y edición 

La creación de un archivo en consola de un sistema GNU/Linux se realiza : 
#touch script.sh  
El comando Touch creara un archivo en blanco, aqui vemos que nuestro script (el cual podria tener cualquier nombre) utiliza la terminación .sh, el cual lo identificara del resto de archivos como script shell también podríamos ahorrarnos este paso usando un editor de texto,pues un editor de texto crear el archivo si este no existe, en nuestro caso utilizare el script sera nano 
#nano script.sh 

miércoles, 22 de enero de 2014

Modelado de Motores DC

 Para poder usar adecuadamente un motor es necesario conocer sus características y estudiar su comportamiento en las condiciones en que será usado, en esta entrada se propone el uso de LTspice para el análisis, procurando integrar el comportamiento mecánico y térmico del motor. LTspice, es un software de simulación, aunque gratuito, no es libre, esta basado en Spice, y es desarrollado por Linear Technology, incluye mejoras que lo hacen recomendable para simular circuitos que trabajen en modo de conmutación, aunque bien sirve para cualquier tipo de simulación análogica.Para descargarlo, acceder al siguiente enlace: Descargar LTspice Para modelar un motor se debe recurrir a parámetros proporcionados en hojas de datos de fabricantes, o en su defecto recurrir a mediciones y captura de datos, que permitan obtener los parámetros de un modelo dado y posteriormente, estudiar el comportamiento del motor. Un motor DC esta constituido de dos partes, el rotor y el estátor, en el rotor encontramos un bobinado, el cual presenta un comportamiento Resistivo que se debe a la resistencia del cable bobinado, mas un comportamiento inductivo, este debido a la bobina arrollada sobre el núcleo, adicionalmente , se tiene una caída de tensión interna conocida como fuerza contraelectromotriz.


Figura 1: Modelo Basico de un Motor DC
$v=Ri+L\dfrac{di}{dt}+v_e$.............................(1)

Donde: $v$ es el voltaje aplicado. $R$ y $L$ son la resistencia e inductancia del bobinado, respectivamente. $i$ es la corriente en el motor. $v_e$ es la fuerza contraelectromotriz.

La ecuación (1) se complementa con otra que relaciona el torque y la velocidad angular en el eje del motor:
 $T_M=J\dfrac{d\omega}{dt}+B\omega+T_L$..............................(2)

Donde: $J$ es la inercia del rotor. $B$ es el coeficiente de fricción. $T_M$ es el torque Entregado + Pérdidas. $T_L$ es el torque en la carga. Con la ecuación (2), se puede crear un circuito eléctrico que modele, la relación entre $T_M$, $T_L$ y $\omega$, de tal manera que se pueda estudiar la relación entre ese conjunto de variables.

Figura 2: Circuito que modela el comportamiento mecánico
Este circuito representa una analogía eléctrica de la ecuación (2) $I1=C\dfrac{dv}{dt}+(\frac{1}{R})v+I2$ Esta ecuación representa al circuito de la Figura 2, notar que la tensión es la misma para todos los elementos, por estar en paralelo, y representa a la velocidad angular en el motor. Este es un paralelo entre la ecuación mecánica y su circuito eléctrico equivalente: $I1$ representa a $T_M$ $R$ representa a $1/B$, es decir la inversa del valor de la fricción. $C$ representa a $J$, la inercia del rotor $I2$ representa al torque de carga aplicado al eje del motor. $v$ que llamaremos a la tensión en los nodos marcados como salidas, representa a la velocidad angular. Debido a que ambos circuitos modelan las relaciones entre las variables eléctricas y mecánicas del motor, pero lo hacen por separado, es necesario, juntarlas en un mismo modelo y en base a este crear una simulación. Las ecuaciones que generan la interacción entre ambos circuitos se obtienen de la relación entre $T_M$ e $i$ y entre $v_e$ y $\omega$: Entre el torque y la corriente existe una proporcionalidad, determinada por una llamada constante de torque $K_i$.
$T_M=K_ii$.............................(3)

 Entre la velocidad angular del motor y la fuerza contraelectromotriz la relación es. $v_e=K_e\omega$..............................(4)

 De tal manera que en la Figura1 la fuente de tensión $v_e$ no es una fuente independiente sino una fuente dependiente del valor de $\omega$, de la misma manera en la Figura 2, la fuente de Intensidad $I1$ es dependiente del valor de la corriente en el primer circuito, en LTspice, como en otros simuladores estos comportamientos se modelan usando fuentes dependientes "e" que son fuentes de tensión controladas por tensión y fuentes "f" que son fuentes de corriente controladas por corriente.

Figura 3: Modelo que interacciona el comportamiento eléctrico y mecánico

En la Figura 3, se puede observar que la fuente $Ke$ es una fuente "e" y depende de la tensión en el Nodo W (con respecto al nodo de Tierra o GND)la fuente $Ki$ es una fuente "f" cuya tensión de control es la corriente $i$ que recorre a todos los elementos del primer circuito, la salida de $K_i$ representa al torque y la salida de la fuente $K_e$ representa a la fuerza contralectromotriz. El circuito de la Figura 3, será usado para modelar el comportamiento de un motor MAXON RE30, el cual viene disponible en 5 diferentes tensiones nominales: 12V, 18V 24V, 36V, 48V. Los datos técnicos para este tipo de motor, lo encontramos en: Motor Maxon RE30

 
Figura 4: Datos técnicos del motor Maxon RE30
A modo de ejemplo, el modelado se llevara a cabo con el motor de $12V$, para este motor, los parámetros a usar son:

Tabla 1: Datos técnicos Necesarios para el Modelado
Terminal Resistance Terminal Inductance Rotor Inertia Torque ConstantSpeed ConstantNo Load Current No Load Speed
$0.198 \Omega$ $0.0345 mH$ $33.5gcm^2$ $13.9 mN m/A$$685 rpm/V$$300 mA$$8170 rpm$
Antes de proseguir, se debe establecer las unidades, de las variables involucradas.

Tabla 2: Unidades SI
Variable:Tensión Corriente TorqueVelocidad Angular
Unidad: $V$ $A$ $N m$$rad/s$

Convirtiendo los valores de la tabla anterior a las unidades convenidas:


Tabla 3: Datos de la tabla 1 convertidos al SI
Terminal Resistance Terminal Inductance Rotor Inertia Torque ConstantSpeed ConstantNo Load Current No Load Speed
$0.198 \Omega$ $34.5 \mu H$ $3.35\mu Kg.m^2$ $13.9m \frac{Nm }{A}$$71.73\frac{rad/s}{V}$ $0.3A$ $855.6\frac{rad}{s}$


La contante $B$ modela las perdidas por fricción, para obtenerla analicemos el circuito de la Figura 3 en estado estacionario y para condiciones en que el torque de carga es nulo, con lo cual se anulan el efecto del inductor y el capacitor (inercia del rotor), con esto el modelo se reduce a la Figura 5.


Figura 5: Equivalente del modelo del motor, en estado permanente en condiciones sin carga

De la Figura 5, podemos deducir: $K_ii=B\omega$. Con lo que $B=K_ii/\omega$, donde $i$ es la corriente en condiciones sin carga (en la tabla es :"No Load Current") y $\omega$ es velocidad angular en condiciones sin carga (en la tabla es: "No Load Speed"), usando los valores de la Tabla 3 tenemos $B=4.874x10^-6\frac{Nm}{rad/s}$ El valor de $K_e$, es el inverso de la "Speed Constant", consignada en la Tabla 3, notar que es prácticamente igual a $K_i$, por lo que en caso de no ser consignada una de las dos se puede usar el mismo valor para ambas. Con esto, se tiene que los parámetros deben tener los siguientes valores:


Tabla 4: Valores de los Parámetros
$R$ $L$ $J$ $K_i$$K_e$$B$
$0.198 \Omega$ $34.5 \mu H$ $3.35\mu Kg.m^2$ $13.9m \frac{Nm }{A}$$13.94m\frac{V}{rad/s}$ $4.874\mu\frac{Nm}{rad/s}$


Hasta aquí ya se calcularon todos los valores de los parámetros necesarios para el modelo propuesto, la mayoría se obtienen directamente de la hoja de datos, otros se deben convertir a unidades Estándar, y solo uno calcularlo en base a datos de la hoja técnica.lo que sigue, sería, ingresarlos en LTspice.


Figura 6: Modelo para el motor Maxon

Los Valores de $R1$, $L1$, $C1$ y $V1$, se ingresan directamente La fuente E1 se configura así:


Figura 8: Configuración de la fuente E1

La fuente F1 se configura así:

Figura 8: Configuración de la fuente F1

El valor de $R2$ que se debe ingresar corresponde al inverso de $B$, es decir $R2=1/B=205.17k$. Como debe ser obvio, la equivalencia del circuito propuesto para analizar el comportamiento del motor es a nivel numérico, a nivel de unidades de medida cada magnitud mecánica estará según le corresponda en la Tabla 2, es decir el Torque en $Nm$ (en el simulador aparecerá en $A$), y la velocidad angular en $rad/s$ (en el simulador aparecerá en $V$).  

Testeando el modelo:
 
Figura 9: Curvas de Torque vs Velocidad angular, a diferentes tensiones
Estas curvas muestran la relación entre el torque y la velocidad angular, el punto de trabajo exacto, lo determinaran la carga mecánica acoplada al motor, si lo que queremos es estudiar el desempeño del motor con una cierta carga, es necesario realizar un modelado de la carga e ingresarlo a Ltspice y estudiar la respuesta.


Figura 10: Respuesta transitoria de velocidad a diferentes tensiones
.
Figura 11: Curvas de Torque vs Potencia, en varios valores de tensión
La Figura 11, muestra la potencia mecánica que puede suministrar el motor, en función del torque, observar que en la Figura 4 (Datos de Maxon), el valor nominal de potencia es $60W$ y el valor nominal de torque es de $51.7mNm$, esto significa que aunque el motor puede sobrepasar estos valores, no es saludable para su vida útil, que lo haga por mucho tiempo.


Figura 12: Curvas de Torque vs Eficiencia, en varios valores de tensión
Hasta aquí se ha logrado construir un modelo que emula el comportamiento eléctrico y mecánico del motor, además de lo que se muestra, se puede támbien graficar el diagrama de Bode de la respuesta en frecuencia del motor, se pueden también estudiar los efectos de diversas cargas, respuesta a una señal PWM, mostrar el desempeño en un sistema de control, en fin, bastantes posibilidades adicionales. Si bien el presente análisis se ha llevado a cabo con datos ya proporcionados por el fabricante, en caso de no disponer de ellos, se puede modelar experimentalmente el motor y la carga y adecuarlo al modelo propuesto, para llevar a cabo diferentes análisis. El mismo análisis se puede llevar a cabo usando algún otro simulador de circuitos, con similares resultados, se pueden realizar cálculos referentes al transitorio, como referentes al estado permanente (por ejemplo curvas de torque y velocidad).