miércoles, 31 de julio de 2024

TMR0 Control de Potencia AC220

Control de Potencia AC220V

Te doy la bienvenida a este sitio, que fue creado para compartir el mutuo interés en la electrónica y en especial la programación de microcontroladores PIC. Agradecido por visitar mi blog quiero recordarte que estoy atento a cualquier consulta o critica constructiva relacionada con esta publicación. 
En esta oportunidad vamos a ver como controlar la potencia o energía que consume una carga resistiva, considerando que el suministro eléctrico es la linea AC220 de una instalación domiciliaria.
La programación del ejemplo se realizara utilizando el software  de diseño  MPLABX  y el compilador de lenguaje C para PIC XC8 ambos disponibles en la pagina de microchip de forma gratuita. Aquí dejo los enlaces de las versiones utilizadas para nuestro ejemplo:  <<MPLABX v6.20>>   <<XC8 v2.45>>
Mencionar también que es necesario contar con conocimientos mínimos sobre programación en lenguaje C y el uso de microcontroladores PIC16.

Introducción al Tema

De manera breve describiremos que la señal de onda que se muestra en la figura 1, es el resultado de la rotación continua y constante de un <fasor> dentro de un campo magnético, donde la longitud del <fasor> determina la amplitud de la señal, y la velocidad de rotación determina su frecuencia, esta explicación corresponde a una señal alterna como la suministrada en una instalación domiciliaria, en mi país, la red de baja tensión posee un voltaje eficaz de E=220V y frecuencia de f=50Hz, La figura 1 muestra la relación amplitud y tiempo.

Fig1.  Ciclo de Señal en linea AC220V, Voltaje (V) / Tiempo(S)

Observe que la tensión maxima es Em=311V, y el tiempo total del ciclo T=0.02 segundos, esto se determina fácilmente aplicando las ecuaciones básicas: 

Cuando consideramos el uso de cargas resistivas consideramos que la onda sinusoidal del voltaje siempre estará en fase con la onda de corriente, eso si con magnitudes diferentes, entonces para controlar la energía suministrada a la carga resistiva, el circuito de control debe ser capaz de abrir y cerrar el circuito eléctrico de manera sincronizada con la fase de onda, este circuito se representa en la figura 2,

Fig2. Circuito básico para control de Carga

Comentaremos dos maneras para realizar el control de potencia en un carga, ambos sincronizados con la fase de onda. 

Forma 1: Control de Potencia por Ciclos activos

En este caso la llave de control, opera en función de la cantidad de semi-ciclos de la onda sinusoidal, abriendo o cerrando el circuito solo en los puntos de cruce por cero, de esta forma  se determina la cantidad energía que consume la carga en un lapso de tiempo, como notara en la figura 3.

Fig3. Control de Potencia por Ciclos

El lapso de tiempo mencionado que viene a ser el periodo (Tpwm) para el control es fijo, y el tiempo de activación (td) es variable, su valor sera siempre un múltiplo del periodo que tiene cada semi-ciclo (THALF), por ejemplo, si la frecuencia de onda es F=50Hz, se pueden calculan los siguientes valores considerando la figura 3:
El consumo de energía se determina por el ciclo de trabajo en porcentaje, aplicando la siguiente ecuación:
Este tipo de control de potencia se utiliza bastante para controlar la temperatura de las resistencias eléctricas de una gran variedad de equipos(horno, plancha, calefactor, etc).

Forma 2: Control de Potencia por Fase de disparo
En este caso, la llave de control se sincroniza con el inicio de cada semi-ciclo, para abrir el circuito y luego cerrarlo en función del ángulo de fase (θ) que tiene la onda, en la practica en ángulo de fase se controla por un tiempo de espera (td) que es variable, y el periodo de control (Tpwm) fijo es el tiempo que dura el semi-ciclo (THALF), tal como se observa en la figura 4. 

Fig4. Control de Potencia por Fase
Para una frecuencia de onda F=50Hz, el periodo de control sera:
TPWM = THALF = 0.001s
El ángulo de fase para cerrar el circuito en función del tiempo se determina por la siguiente ecuación y siendo la figura 5 una tabla con valores de tiempo(td) para un determinado ángulo de fase (θ).
Fig5. Tiempo de espera por ángulo de fase
  
Notara que el tiempo de espera necesario para el disparo, no debe exceder al periodo de control, y que su relación con la potencia entrada a la carga es inversamente proporcional, es decir que a mayor tiempo de espera (td), menor es la  potencia en la carga (dt%)

De la mima manera que el caso anterior, el consumo de energía se determina por el ciclo de trabajo en porcentaje, aplicando la siguiente ecuación:

Vamos a implementar un circuito de control de potencia considerando la forma 2, y para este fin utilizaremos una lampara incandescente de 100W, un circuito de potencia con tiristor (TRIAC) y un microcontrolador (PIC16F887).
 
Circuito de Control AC
En esta parte, ya con los conceptos vistos al inicio, analizaremos el control de fase que se implementara con un <TRIAC> y en la que utilizaremos las siguientes señales que se relacionas con la onda sinusoidal del voltaje AC, la figura 6, ilustra la representación en colores, donde: 
PWM = Representa la Energía que consume la carga en cada semi-ciclo
ZCD = Pulso de entrada para indicar el cruce por cero de la onda sinusoidal
TDT = Pulso de salida para activar el disparo que cerrara el circuito
Fig6. Control de disparo de Fase
Una característica que tiene un TRIAC, es la capacidad de conducir la corriente eléctrica en ambos semi-ciclos positivo y negativo de la onda sinusoidal. Para que este dispositivo cierre el circuito entre sus terminales T1 y T2 una de sus entrada conocida como puerta (G) debe activarse, una vez que este entra en conducción, el circuito se mantendrá cerrado hasta que la corriente que pasa por las terminales T1 y T2, caiga por debajo del valor conocido como corriente de mantenimiento, con lo cual las terminales T1 y T2 dejaran de conducir quedando el circuito abierto. Esta condición ocurre cuando la señal sinusoidal cruza por cero, donde teóricamente la corriente por las terminales T1 y T2 es 0.

Fig7. Simbología de un TRIAC

En la figura 8, se muestra el circuito de control utilizado para nuestro ejemplo, donde se separan dos bloques distinguidas por el color, la zona roja corresponde al bloque AC que trabaja con el suministro eléctrico 220V / 50Hz, la zona verde es el bloque DC cuyas señales operan con niveles lógicos digitales, es importante mantener esta separación de forma física en el circuito que va implementarse, y proteger del contacto humano los elementos que están en el bloque AC. Recordar también que el circuito que se muestra en la figura 6, tiene fines educativos, por lo cual se excluyen varios elementos de protección adicionales necesarias para un producto final.  
Fig8. Circuito de Control con TRIAC
Desde un punto de referencia en el bloque DC, la señal para indicar el cruce por cero, es generado por la polarización de los diodos que posee el opto-acoplador U1 en ambos ciclos, donde la corriente AC que circula se reduce al orden de los miliamperios debido a las resistencias R1 y R2. Cuando la onda sinusoidal pasa por el punto cero, ninguno de los diodos de U1 esta polarizado y por lo tanto el colector y emisor del transistor quedara abierto, conforme la onda pase el punto cero y vaya incrementándose, el voltaje aplicado a los diodos se incrementara hasta que uno de ellos se polarice haciendo que el transistor se cierre; Considerando esto podemos deducir que el nivel logico en el colector de U1, sera 1 solo cuando la señal AC cruce por cero y el resto de tiempo permanecerá con valor 0, esto se representa con el pulso ZCD de la figura 6.
Para controlar la puerta (G) del TRIAC, y mantener aislado el bloque AC del circuito, se utiliza un opto-acoplador tipo triac U2, con esto la activación dependerá de la polarización del diodo en U2, en la figura 6 este evento se representa con la señal TDT. Finalmente el Microcontrolador utilizara como entrada la señal ZCD para detectar el instante donde se produce el cruce por cero y la salida TDT para disparar el TRIAC.
Lista de componentes que muestra el circuito de la figura 8, es la siguiente:
  • Fusible F1 0.5A / 220V
  • Resistencia R1,R2 100kΩ / 1.0W
  • Resistencia R3 220Ω / 0.5W
  • Resistencia R4 10kΩ / 0.25W
  • Resistencia R5 1kΩ / 0.25W
  • Triac T1 BT-136 600V
  • Opto-Acoplador U1 PC-814
  • Opto-Acoplador U2 MOC-3022
En el lado del Microcontrolador, emplearemos un circuito bastante simple utilizando el PIC16F887, observe la figura 9. La señal de entrada ZCD que proviene del circuito de control se conectara al pin de interrupción externa INT, y la señal de salida TDT al circuito de control sera el pin RB1, además se utilizara una resistencia variable para dividir la tensión y hacer lectura de su valor analógico en el pin AN0, finalmente un diodo conectado al pin RE2 indicar con un destello que el programa del PIC esta en funcionamiento.
Fig9. Circuito PIC16F887

Programación del PIC

Ya en esta sección trataremos la programación del microcontrolador PIC, como sabrán no es sencillo describir el funcionamiento de un programa en pocas palabras y que sea fácil de entender,  me disculpo si no he sido claro en alguna parte, por eso para ir entrando en contexto, la figura 10 ilustra el flujo que sigue el programa principal y también la rutina de servicio a la interrupción.
Fig10. Flujo-grama Programa principal e ISR
 
Programa Principal: Posterior a la configuracion de los puertos, el modulo ADC, el temporizador y las interrupciones, el programa principal ingresa en un bucle continuo para ejecutar tres tareas cada milisegundo, estas tres tareas son: destellar el LED, hacer lectura del canal analógico ADC y ajustar el tiempo de disparo. Cabe resaltar que ninguna de estas tareas representa un proceso bloqueante, la codificación utiliza una técnica de programación por estados, si quieres conocer mas detalles al respecto puedes revisar la siguiente publicación. <Programación por estados con Temporizador>
Rutina de Servicio a la Interrupción ISR: El código de esta rutina atiende a dos eventos, la interrupción del temporizador T0IF que permite ejecutar las tareas del programa principal cada milisegundo, y la interrupción externa INT que indica el cruce por cero ZCD, con la que sincronizara el tiempo de disparo TDT basado en un contador. Este contador se incrementa con cada interrupción del temporizador.
Si bien los comentarios en la codificación del programa describen el propósito de cada linea, se ha establecido la configuracion de variables considerando lo siguiente:
  • La interrupción del temporizador se ajusto a 0.0002 segundos, con este tiempo para cada semi-ciclo de onda, la rutina ISR atiende hasta 50 interrupciones T0IF (0.010 / 0.0002 = 50). Un registro contador CNT se inicia en 0 cada vez que ocurre la interrupción externa INT(Cruce por cero) y se incrementa con cada interrupción T0IF,  el control del disparo se da cuando el contador CNT alcanza el valor del tiempo TDT (Pulso de disparo).
  • El valor para el tiempo TDT estará en función de la lectura ADC al canal AN0, cuya voltaje analógico es ajustable por un potenciómetro, entonces para que el resultado de la conversion de 10-bit, permanezca en el rango 0 a 49, se divide entre 21, y con ello se actualiza al valor del tiempo TDT. 
A continuación se muestra el código del programa para el PIC16F887, considerando que la frecuencia del oscilador es Fosc=8MHz.
 
#include <xc.h>
#include <stdio.h>
#define ZCDpin PORTBbits.RB0 //Entrada para indicar Cruce por cero
#define TDTpin PORTBbits.RB1 //Salida para el pulso de disparo TRIAC
#define LEDpin PORTEbits.RE2 //Salida para destellar el LED
volatile uint8_t tick1ms = 0;
volatile uint8_t TDTval = 0; //Variable de control para disparo 0-49
void setupMCU(void);
void taskLED(void);
void taskADC(void);
void main(void)
{
    setupMCU(); //Configuración
    while(1)
    {
        if(tick1ms) //Valida en cada milisegundo
        {
            tick1ms = 0; //Limpia bandera
            taskLED();   //Tarea para destello
            taskADC();   //Tarea de lectura ADC
        }
    }
}
void __interrupt() isr(void) //Rutina ISR
{
    static uint8_t cnt0, cnt1, toffset;
    if(INTCONbits.INTF) //pulso ZCD
    {
        INTCONbits.INTF = 0;
        toffset = 0; //Reinicia corrección del contador
    }    
    if(INTCONbits.T0IF) //Activa cada 0.0002s
    {
        INTCONbits.T0IF = 0;  //Limpia bandera
        TMR0 += 156; //Reinicia contador T0
        if(cnt0++ > 4) //Valida 5 x 0.0002 = 0.001s
        {
           tick1ms = 1; //Activa cada 0.001s
           cnt0 = 0;
        }
        if(toffset == 6) //Valida corrección ZCD
        {
            cnt1 = 0; //Reinicia contador TDT
            toffset++;
        }
        if(toffset < 6) toffset++;
        if(cnt1 == TDTval) TDTpin = 1; //Valida y activa disparo
        else TDTpin = 0;
        if(cnt1 < 50)  cnt1++; //t=50*0.2m = 10m
    }
    
}
void setupMCU(void)
{
    OSCCONbits.IRCF = 0b111; //Ajusta Fosc=8MHz, Tcy=0.5u
    while(OSCCONbits.HTS == 0) {}
    /* CONFIGURACION PUERTOS*/
    ANSEL = 0;
    ANSELH = 0;
    TRISEbits.TRISE2 = 0; //Salida LED
    TRISBbits.TRISB1 = 0; //Salida control TDT
    LEDpin = 0; //Apaga el LED
    TDTpin = 0; //Nivel bajo en pulso TDT
    TRISBbits.TRISB0 = 1; //Entrada ZCD
    OPTION_REGbits.nRBPU = 0; //Pull-up en ZCD
    OPTION_REGbits.INTEDG = 1; //Flanco Ascendente
    INTCONbits.INTF = 0; //Limpia bandera INT
    INTCONbits.INTE = 1; //Activa interrupcion externa
    /* CONFIGURACION TIMER0 0.2MS */
    OPTION_REGbits.T0CS = 0;//Modo Termporizador
    OPTION_REGbits.PSA = 0; //Con prescala
    OPTION_REGbits.PS = 0b001; //Prescala 1:4
    TMR0 = 156; //256-[(time*Fosc)/(pre*4)] time=0.0002 seg
    INTCONbits.T0IF = 0; //Limpia bandera
    INTCONbits.T0IE = 1; //Activa interrupcion del TMR0
    /* CONFIGURACION ADC-10 Canal0*/
    ANSELbits.ANS0 = 1; //Activa canal AN0
    ADCON0bits.ADCS = 0b10; //TAD=4us > 1.6us (8MHz/32)
    ADCON0bits.CHS = 0; //Selecciona Canal 0
    ADCON0bits.ADON = 0; //Desactiva el modulo ADC
    INTCONbits.GIE = 1; //Habilita las interrupciones
}
void taskADC(void) //Ciclo 1ms, Lectura ADC de 10Hz
{
    static uint8_t state = 0, cnt = 0;
    static uint16_t adcraw;
    cnt++;
    switch(state)
    {
        case 0: //Activa ADC para captura
            ADCON0bits.ADON = 1;
            cnt = 0;
            state = 1;
            break;
        case 1: //Inicia conversion AN0
            ADCON0bits.GO = 1;
            state = 2;
            break;
        case 2://Espera fin de conversion AN0
            if(ADCON0bits.GO == 0)
            {
                adcraw = ADRESL; //ADRESL First
                adcraw |= (uint16_t) (ADRESH << 8);
                adcraw >>= 6; //Corrige alineacion de ADH:ADL
                ADCON0bits.ADON = 0;
                state = 3;
            }
            break;
        case 3: //Espera fin de ciclo
            if(cnt++ > 99) //valida 100 x 1ms = 100ms
            {
                TDTval = (uint8_t) (adcraw / 22U); //Ajusta a TDT
                state = 0;
            }
    }
}
void taskLED(void) //Destella led ciclo 1ms
{
    static uint16_t tcnt = 0;
    if(tcnt++ > 999)
    {
        tcnt = 0;
        LEDpin = 1;
    }
    if(tcnt == 200) LEDpin = 0;
}

Pruebas de Funcionamiento

Se ensayo el código inicial en el microcontrolador para llevar a cabo las pruebas de funcionamiento utilice una placa de control TRIAC que disponía de un proyecto anterior, en esta placa de cuatro salidas, solo se utilizo uno de los canales.
 
Fig11. Circuito de control y PIC
En la primera prueba sin considerar la corrección del tiempo de disparo TDT, la lampara comenzó a oscilar cuando se realizo el ajuste total del potenciómetro para entregar toda la potencia. Esto se debe a que el pulso detector ZCD tiene un tiempo de duración,  que se extiende antes y después del cruce por cero, por lo que fue necesario agregar un tiempo offset para corregir el disparo, finalmente con un valor de ajuste igual a 7 (7x0.0002 = 0.0014), se corrige el problema de oscilación. Una forma practica para determinar este valor de corrección, es medir con un instrumento el porcentaje de nivel alto en la señal ZCD, en mi caso registre 28%, del cual la mitad corresponde al instante en que el detector de cruce se activa, esto es 14% del semi-ciclo (0.010 x 0.14 = 0.0014)
 
Abajo dejo un breve vídeo que muestra el funcionamiento de este circuito y el código del proyecto MPLABX.

 
Aquí dejo los enlaces para que puedas descargar el proyecto, se encuentra en formato gzip, debes descomprimir y abrir con MPLABX 
Si quieres ver como compilar e implementar los proyectos de este blog, elaborados con MPLABX mira este vídeo.<Compilando proyectos MPLABX>

Conclusiones

Se ha demostrado el funcionamiento adecuado del circuito de control de potencia, con el microcontrolador PIC16F887, los valores de tiempo que utilice pueden modificarse en base a requisitos propios de cada proyecto, Si estas en planes de poner en practica este tipo de control como recomendación debe considerar los siguiente puntos: 
  • Este circuito como se menciona al inicio, considera el uso de una carga puramente resistivas, donde no habrá desface entre el voltaje y la corriente AC.
  • El control de intensidad de de la luz que se muestra en el ejemplo es solo para lamparas incandescentes, y no se aplica a las luces tipo LED ya que operan con otro principio.
  • Puede incrementar la resolución para el control de energía en la carga a mas pasos de los que se trato en el ejemplo, pero debe saber que la relación del tiempo de disparo con la cantidad de energía que se entrega no es lineal debido a la magnitud variable que la tensión eléctrica. 
  • Por ultimo el punto mas importante de todo: Si no sabe lo que esta conectando en este circuito, deje de armarlo y no continué hasta comprender su funcionamiento. Una mala conexión o manipulación del mismo puede provocar serios daños material y personal(riesgo de muerte).
Sin mas que mencionar agradezco tu visita al blog y espero que el ejemplo visto pueda ser útil en tu formación y el proyecto que desarrollas.

Atentamente, Pablo Zárate Arancibia  email: pablinza@me.com / pablinzte@gmail.com, @pablinzar

Santa Cruz de la Sierra - Bolivia



No hay comentarios.:

Publicar un comentario