viernes, 19 de enero de 2024

ADC Lectura de corriente AC con ACS712

 Medir consumo de corriente AC220V

Fig1. Modulo ACS712



Este sitio fue creado para compartir el mutuo interés en la electrónica y en especial la programación de microcontroladores PIC. Descrita la introducción te agradezco por visitar mi blog recordando que siempre estamos abiertos a cualquier critica constructiva relacionada con esta publicación.

En esta ocasión veremos como medir el consumo de corriente alterna haciendo uso de un modulo muy accesible en cuanto a disponibilidad en el comercio y precio, este modulo se basa en el circuito integrado ACS712.
El propósito que se busca en esta oportunidad es el de medir con un microcontrolador PIC16F887, la corriente de consumo que tiene una carga conectada al suministro eléctrico domiciliario 220V/50Hz, y mostrar el valor de consumo en amperios (A) mediante mensajes de texto enviados al puerto serial UART de una PC. para llevar a cabo las pruebas se recomienda tomar las debidas precauciones de seguridad sobre todo en la interconexión del sensor AC712 con la carga.

La programación se realizara utilizando MPLABX y el compilador XC8 ambos disponibles en la pagina de microchip. Aquí dejo los enlaces de las versiones utilizadas para nuestro ejemplo:

 <<MPLABX v6.15>>   <<XC8 v2.45>>

La configuración del entorno se utiliza el pack PIC16Fxxx_DFP(1.5.151)
Mencionar también que es necesario contar con conocimientos mínimos sobre programación en lenguaje C y el uso de microcontroladores PIC16.

Acerca del efecto HALL 

Se conoce como efecto Hall a la aparición de un campo eléctrico por separación de cargas en el interior de un conductor por el que circula una corriente en presencia de un campo magnético con componente perpendicular al movimiento de las cargas(Wikipedia).

Haciendo referencia a la nota de aplicación del fabricante de sensores Honeywell (Hall Effect Sensing and Application). ilustraremos con mayor claridad este efecto en la tecnología de medición.

Imaginemos una pequeña lamina semiconductora(elemento Hall interno de un sensor) por la que atraviesa una corriente eléctrica; si medimos el voltaje eléctrico en los extremos perpendiculares al flujo de corriente notaremos que ante la ausencia de un campo magnético este voltaje es 0 debido a que la distribución de corriente es uniforme en toda superficie de la lamina.

Fig2. Efecto Hall en ausencia de un campo magnético 

Ahora con la presencia de un campo magnético se produce una fuerza conocida como fuerza de Lorentz que perturba el flujo de corriente ocasionando un diferencia de potencial eléctrico en los extremos, esta diferencia es el voltaje Hall.
 
Fig3. Efecto Hall en presencia de un campo magnético


Entonces podemos deducir que el voltaje Hall es proporcional al producto de la corriente que circula por el elemento y el campo magnético que lo atraviesa, siendo necesario amplificar este valor para que pueda ser capturado por el microcontrolador.


Modulo sensor ACS712

En el sensor de corriente ACS712, se incorpora internamente un camino o pista de cobre superficial por donde circula la corriente de carga, esta corriente de paso genera un campo magnético que a la vez deriva en una diferencia de potencial en los extremos de la sección de pista, esta diferencia es estabilizada y optimizada internamente para conseguir una salida con voltaje proporcional a la corriente. Este sensor posee poca perdida debido a que la resistencia interna de la pista de cobre es muy baja. Algo muy importante de mencionar que el circuito integrado ACS712 a fecha esta descontinuado y por lo tanto no esta recomendado para nuevos diseños, pero el fabricante dispone de nuevos modelo que ofrecen mejores prestaciones.
Como mencione previamente la razón de utilizar este sensor pese a estar descontinuo, es la disponibilidad que hay a un bajo costo económico, en cualquier caso tanto el hardware y software elaborado en este ejemplo adaptable a los modelos actuales del sensor.
Seguidamente listo alguna de las características mas relevantes del sensor ACS712 extraídos de la hoja de datos:
  • Resistencia interna de 1.2 milésimas de Ohm;
  • Error total en salida del 1.5% a 25°C;
  • Aislamiento mínima de 2.1kV RMS;
  • Voltaje de salida proporcional para AC y DC;
  • Voltaje de operación a 5V;
  • Sensibilidad en salida de 66 a 185mV/A.
Las variantes con respecto al sensor ACS712 se listan a continuación:
  • ACS712ELCTR-05B-T ±5A 185mV/A (Hasta 5A);
  • ACS712ELCTR-20A-T ±20A 100mV/A (Hasta 20A);
  • ACS712ELCTR-30A-T ±30A 66mV/A (Hasta 30A).
Fig4. Variantes del modulo ACS
La siguiente gráfica nos ilustra el comportamiento proporcional que tiene el voltaje de salida con respecto a la corriente que se mide con la variante 05B, las gráficas correspondientes a los demás modelos se encuentran en la hoja de datos del fabricante.

Fig5. Voltaje de salida / corriente medida ACS712-05B
Como detalle adicional en referencia a la fig5. notara que la salida del sensor sera de 2.5V sin consumo, por lo tanto el rango de salida considerando la relación de 185mV por amperio, sera de 1.57V — 3.42V. Esto se deduce considerando que el valor máximo de 5 A representa 0.925V (0.185 * 5), siendo el rango 2.5 ± 0.925V.

La siguiente figura muestra el esquema de circuito para el modulo de pruebas ACS-712, el cual posee los elementos esenciales para la operación y conexión al microcontrolador.

Fig6. Esquema de circuito del modulo sensor ACS712
 
Como ya vimos, la salida OUT, proporciona una señal de voltaje en el rango 2.5 ± 0.925V. según la corriente que circula por la pista IN+/ IN-, esta dependencia se visualiza en la figura 5. 
Como el voltaje aplicado a la carga es una onda sinusoidal alterna 220V con frecuencia de 50Hz en el caso de mi país, la salida del sensor también oscilara, manteniendo el periodo de 20ms. (t=1/f).
La medición que se realizara utilizando el modulo ADC del PIC16F dentro de un periodo de tiempo posibilitara calcular la corriente de consumo, aplicando uno de los siguientes métodos:
 
Método 1) Determinar los valores pico VPK de la señal alterna en un periodo de tiempo, y calcular el valor RMS(Root Mean Square), con el producto VRMS = VPK * 0.707 tal como se se muestra en la figura 7, este calculo es valido únicamente con señales sinusoidales.

Fig7. Calculo de Valor RMS

Método 2) Esta técnica es aplicable a cualquier tipo de señal y consiste en tomar una muestra de los valores absolutos en cada semi-ciclo para determinar un promedio,. Entonces el valor RMS se obtiene aplicando la formula que se muestra en la figura 8.
 
Fig8. Calculo de valor RMS
Si se integra la función seno para un semi-ciclo, se encuentra que el voltaje promedio VPM = VPK * (2/π ).

Una vez calculado el valor RMS(Root Mean Square) la corriente podrá determinarse por la relación de salida Voltaje / Corriente del sensor. En nuestro caso utilizaremos el modulo ACS-712-05B el cual según la hoja de datos posee una sensibilidad de 185mV/A. 
 
Esquema de conexión PIC16F y ACS712
La figura 9 muestra el esquema de conexión del microcontrolador PIC16F al modulo ACS712. El circuito se alimenta con +5V y la salida OUT del modulo ACS712 se conecta de forma directa al canal AN0 del PIC16F.
Fig9. Diagrama de conexión del circuito
El conversor ADC del PIC16F posee una resolución de 10-bits, y el rango de voltaje para la conversion sera de 2.5 ± 0.925V(ACS712-05), con el fin de mejorar la sensibilidad de cambio, se utilizara como voltaje de referencia positivo el pin AN3/Vref+, mismo que se conectara al divisor de tensión formado por las resistencias. El voltaje del divisor sera 3.75V (+5 * 10k/(10k+3.3k). 
Con esta configuracion podemos determinar que la sensibilidad en mV por cada bit sera:

(Vref+ - Vref-) / 2^10-bits = (3.75V - 0V) / 1024 = 3.66 mV.

Conociendo este resultado, la relación de cambio en bits por cada amperio sera 185mV/3.66mV = 50.5 bits. (ACS712-05)
 
Por otro lado la comunicación serial con la PC, utiliza un convertidor USB a UART, en nuestro caso es un CP-2102, pero puede ser cualquier otro conversor, porque solo se requiere un par de conexiones a los pines TXD y RXD del PIC16F, finalmente existe un diodo LED conectado al pin RE2 que destellara para indicar la actividad del programa.
 
Programa del Microcontrolador PIC
El objetivo de este programa es medir la corriente de consumo para una carga alterna de 100W utilizando el modulo sensor ACS712, el valor determinado por el PIC16F, se enviara cada segundo por el puerto serie como un mensaje de texto a 9600bps. El método aplicado para el calculo de la corriente es la medición del valor pico Ipk y división por raíz cuadrada como se observa en la figura 7.
El PIC16F opera con un cristal de 20MHz, siendo esta la base de calculo para la configuracion del tiempo de adquisición del convertidor ADC, modulo USART y el temporizador TMR0. Para mayores referencias sobre la operación del convertidor ADC del PIC16F puedes ir al siguiente enlace de una publicación previa de este blog:

En cuanto a los procedimiento y funciones utilizadas en el programa, todo se resume en el código principal main.c con sus respectivos comentarios. En la parte final dejo el enlace para descarga del proyecto MPLABX que contiene todos lo archivos utilizados.
 
void main(void)
{
    setup();
//Configuración de puertos y periféricos
    while(1)
    {
        if(tick1ms)
//Bandera activa cada 1ms
        {
            tick1ms = 0;
//Limpia bandera
          
  taskAPP(); //Ejecuta cada 1ms
        }
        taskADC();
//Ejecuta la tarea continuamente
    }

void setup(void)
{
   
//Oscilador Externo HS=20MHz Tcy = 0.2us
    ANSEL = 0;     
//Pines AN0-AN7 en modo digital
    ANSELH = 0;    
//Pines AN8-AN13 en modo digital
    TRISA = 0xFF;
    ANSELbits.ANS0 = 1;
//Habilita el canal AN0
    ANSELbits.ANS3 = 1;
//Habilita Vref+ AN3
    TRISEbits.TRISE2 = 0;
//Pin de salida LED
   
/* CONFIGURACION UART 9600 BPS*/
    BAUDCTLbits.BRG16 = 0;
//8-bit BaudGen
    TXSTAbits.BRGH = 1;
    TXSTAbits.TXEN = 1;
    RCSTAbits.SPEN = 1;
    SPBRG = 129;
//Formula [20M/(16 * 9600)] - 1
   
/* CONFIGURACION ADC VRAF+*/
    ADCON0bits.ADCS = 0b10; //TAD Fosc/32 = 1.6uS a 20MHz
    ADCON0bits.CHS = 0b0000; //Canal AN0
    ADCON1bits.VCFG0 = 1; //Activa Vref+ = pin AN3/RA3
    ADCON0bits.ADON = 1; //Activa modulo ADC.
   
/* CONFIGURACION TIMER0 1MS*/
    OPTION_REGbits.T0CS = 0;
//Modo temporizador
    OPTION_REGbits.PSA = 0;
//Con prescala
    OPTION_REGbits.PS = 0b100;
//Prescala 1:32
    TMR0 = 100;
//256-(time/[(pre)*(4/Fosc)]) time=0.001 seg
    INTCONbits.T0IF = 0;
//Limpia bandera
    INTCONbits.T0IE = 1;
//Activa interrupción del TMR0
    INTCONbits.GIE = 1;
//Habilita las interrupciones
}

void __interrupt() isr()
{
    if(INTCONbits.T0IF)
//Activa cada 1ms
     {
        INTCONbits.T0IF = 0;
//Limpia bandera
        TMR0 += 100;
//Reinicia contador
        tick1ms = 1;
//Activa bandera 1ms
        if(tickcnt++ > 999)
//Control 0-999 ms
            tickcnt = 0;
//Reinicia contador 1s
    }
}

void taskADC(void) //Procedimiento para lectura ADC
{
    static uint8_t cnt = 0;
    static uint16_t valmax, valmin;
    uint16_t val;
    switch(adst)
    {
        case ADSTART:
//Activa ADC, inicia variables
            ADCON0bits.ADON = 1;
            valmax = 0x0000;
            valmin = 0xFFFF;
            adst = ADREAD;
            break;
        case ADREAD:
//Inicia la lectura
            ADCON0bits.GO = 1;
            adst = ADWAIT;
            break;
        case ADWAIT:
//Espera conversion ADC
            if(ADCON0bits.GO == 0)
            {
                val = ADRESH;
                val = val << 8;
                val = val | ADRESL;
                val = val >> 6;
                if(val > valmax) valmax = val;
                if(val < valmin) valmin = val;
                if(adst == ADWAIT) adst = ADREAD;
            }
            break;
        case ADSTOP:
//Desactiva el ADC
            ADCON0bits.ADON = 0;
            if(valmax > valmin) adraw = valmax - valmin;
            else adraw = 0;
            adst = ADIDLE;
        break;
        case ADIDLE:
//Estado de reposo
            _nop();
    }
}


Luego de llevar a cabo la configuración de los pines y periféricos con el procedimiento setup(), el programa principal debe llevar a cabo las siguientes tareas por cada segundo transcurrido: 
  • Muestreo de señal, por 50m;
  • Enviar mensaje con valor de corriente;
  • Destello de LED de actividad.
Estas tres tareas se llevan cabo con el procedimiento taskAPP() en intervalos de 1ms. mismos que se controlar por la bandera de interrupción del TMR0.

void taskAPP(void)
{
    if(tickcnt == 0)
//Inicia captura ADC en 0ms
        adst = ADSTART;
    if(tickcnt == 50)
        adst = ADSTOP;
//Fin de captura ADC en 50ms
    if(tickcnt == 600) 
//Procesa y muestra datos
    {
        current = (1000UL * adraw) / 50;
//valor en ma
        current = (50UL * current) / 142;
//[100*(current/2)]/142
        printf("AMP=%lu\r\n", current);
    }
    if(tickcnt == 700) LEDpin = 1;
//Activa led en 700ms
    if(tickcnt == 900) LEDpin = 0;
//Desactiva led en 900ms
}


Pruebas de funcionamiento
Antes de abrir el proyecto en MPLABX, asegúrate de tener instalado la ultima versión del compilador XC8, una vez abierto el proyecto, en la ventana del explorador veremos los archivos del programa. Luego de revisar el codigo procedemos a compilar, y si no hay errores todo estara lista para cargar el código al microcontrolador utilizando un programador de PIC. En este punto para llevar a cabo las pruebas de funcionamiento deberás contar con un circuito montado, en mi caso utilice el circuito que se observa en la siguiente imagen.


Fig10. Circuito de pruebas PIC16F
Ya con el programa cargado en memoria del PIC16F y con el suminitro conectado, notara que el led destella una vez por segundo, indicando la correcta ejecución del programa.
Luego debemos conectar una carga a las terminales INA/INB del modulo ADC712, el valor de corriente se mostrara en el ordenador utilizando una terminal serial asociado a un puerto COM del ordenador, yo utilice en este caso HTerm, un programa gratuito y multi-plataforma que puedes descargar con el siguiente enlace: <<HTERM>>.

Para comprender mejor los valores calculados en el microcontrolador, he realizado varias capturas en cada etapa del medición dentro del programa. estos se muestran a continuación.

Fig11. Referencia AN0 con GND/VCC (valmax-valmin)
Considerar que la captura que se muestra en la figura 11, solo es referencial para comprobar el procedimiento de muestreo, dado que en ambas situaciones el voltaje de entrada es constante GND=0V y VCC=5V, la deferencia de los valores picos muestreados deberia ser idealmente 0V, aquí se puede notar que cuando AN0 va conectado directamente a GND, muestra una diferencia de 3 a 6 puntos, que asumo su origen a la improvisación de las conexiones en el protoboard y el ruido propio del sensor
que según la hoja de datos es de ±20mV. A posterior con unas pruebas adicionales sobre el circuito, veré detallar mas esta diferentes que representa un error para la medición.

Fig12. AN0 Conectado al ACS712 (valmax-valmin)

Ya con la entrada AN0 conectado al sensor ACS712, cuando no hay consumo(sin carga), el resultado ya nos muestra un valor debido al error descrito previamente, y con el consumo de 100W (con carga), el resultado aproximado es 62 bits, este valor es pico a pico, es decir la diferencia entre el valor máximo y mínimo registrado, por lo tanto si consideramos solo un semi-ciclo, representaría a la mitad de valor mostrado, esto es Vpk≈31 bits. Para obtener el valor eficaz de estos bits multiplicamos 31 * 0.701 ≈ 22 bits.  
 
Recordemos que la relación de cambio es igual a 50 bits/A, y para una carga de 100W, la corriente eficaz calculara sera 0.45A (100W/220V), entonces el valor en bits considerando la relación de cambio seria 50 * 0.45A ≈ 22 bits. 
 
La captura que se observa en la figura 13, muestra el valor de corriente pico a pico (Ipp) calculado en miliamperios, este calculo se aplico utilizando la regla de tres simple a la diferencia (valmax-valmin) y la relación de cambio de 50bits/A.

Fig13. Valor pico a pico (Ipp) en mA

Como resultado final de la medición, la captura en la figura 14, muestra el calculo del valor eficaz para el valor pico a pico de corriente, lo cual nos arroja un promedio de Irms=420mA, considerando las siete lecturas observadas.

Fig14. Valor eficaz Irms en mA
 
Para contrastar este resultado teórico con la carga de 100W, se conecto un amperímetro en serie con la carga y se procedió a medir la corriente de consumo, misma que se muestra en la figura 15.
Fig15. Valores registrados con Amperímetro
El valor promedio registrado con el instrumento fue de 0.363A es decir 363mA, que representa un valor pico de 570mA (Ipk = Ipm / (2/π )), siendo su valor eficaz  Irms ≈ 403 mA.

Recomendación y Conclusión
Si bien se ha completado la meta de medir la corriente de consumo en alterna para una carga de 100W, el ruido que se presenta en las lecturas incluso si no hay consumo, es un punto a considerar en la aplicación final, recordar este sensor ya fue descontinuado por el fabricante, recomendándose usar el ACS723.
La técnica empleada para medir la corriente eficaz consistió en medir los valores picos de la señal y calcular su valor eficaz, si bien es una manera simple para implementar, es también la mas susceptible al ruido y cambios en la forma sinusoidal de la señal alterna, por eso como una alternativa seria llevar a cabo los calculo basado en el segundo método, lo que requiere a su vez añadir al circuito un rectificador. 
Recomendar nuevamente que la conexión de carga 220VAC a los pines INA / INB del modulo ACS712 debe efectuarse con mucha precaución, considerando todas la medidas de seguridad posible, una mala conexión puede provocar severos daños personales y materiales.

Aquí dejo los enlaces para que puedas descargar el proyecto MPLABX, se encuentra en formato gzip recordando que soy usuario de linux y es probable que necesites modificar algunas referencias para compilar con windows.


Proyecto <<MPLABX ac712p16f>>

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.
Atte. Pablo Zárate Arancibia
email: pablinza@me.com / pablinzte@gmail.com
@pablinzar
Santa Cruz de la Sierra - Bolivia

No hay comentarios.:

Publicar un comentario