Medidor de Potencia AC sin Amplificador Operacional

Esta es una versión simplificada del medidor de Potencia AC que he presentado anteriormente, esta versión no posee la etapa de amplificadores operacionales para realizar el rectificado de onda completa de precisión, lo cual reduce al máximo la calibración y complejidad del mismo, también eleva un poco el nivel de error ya que posee menos instancias de acondicionado de señal.

Esta es la versión con acondicionado de señal:
http://electgpl.blogspot.com.ar/2016/06/medidor-de-potencia-truerms-para-220vac.html

El método que utilizaremos para nuestro medidor sera basado en montar la señal alterna a medir en una continua a 2.5V (el punto medio de representación del ADC del MCU con 5V).
Para ello agregaremos el offset mediante un divisor resistivo y un atenuador de tensión para ingresar la alterna con offset al ADC con una amplitud reducida, ya que no podemos ingresar con los 220Vac.
Esto sera para el caso de la medición de tensión, ya que en corriente utilizaremos un circuito integrado dedicado ACS712 (en mi caso de 5A, pero los hay en 20 y 30A).

Esta es la nota donde hablamos de medición de señales simétricas:
https://electgpl.blogspot.com.ar/2016/06/medicion-de-senales-simetricas-con-adc.html

En esta otra nota vamos a encontrar diversas maneras de sensar corriente, una de ellas sera la del ACS712 que podremos leer para expandir y acompañarla del vídeo de youtube como en todas las notas:
http://electgpl.blogspot.com.ar/2017/01/sensado-de-corriente-alterna.html

El circuito empleado sera el siguiente:


El modulo ACS712 esta representado dentro del cuadro de linea punteada, en la realidad podremos comprar el modulo ya armado y solo hay que alimentarlo con 5V y conectar su salida directa a la entrada del ADC del microcontrolador.

El programa utilizado para este proyecto:


  1. #include <16F883.h>
  2. #device adc=10
  3. #use delay(int=4000000)
  4. #define LCD_ENABLE_PIN  PIN_B2
  5. #define LCD_RS_PIN      PIN_B0
  6. #define LCD_RW_PIN      PIN_B1
  7. #define LCD_DATA4       PIN_B4
  8. #define LCD_DATA5       PIN_B5
  9. #define LCD_DATA6       PIN_B6
  10. #define LCD_DATA7       PIN_B7
  11. #include <LCD.C>
  12. #include <math.h>
  13. #define CONST_CORRIENTE 5
  14. #define CONST_TENSION   310
  15. void main(){
  16.    setup_adc_ports(sAN0|sAN1|VSS_VDD);
  17.    setup_adc(ADC_CLOCK_DIV_2);
  18.    int16 i, adcZ=0;
  19.    float adc1=0, valorMax1=0, adc2=0, valorMax2=0;
  20.    float tension, corriente, potencia;
  21.    lcd_init();
  22.    while(true){
  23.       do{
  24.          set_adc_channel(0);
  25.          adcZ=read_adc()-512;
  26.          delay_us(20);
  27.       }while(adcZ<10);
  28.       for(i=0;i<300;i++){
  29.          set_adc_channel(0);
  30.          adc1=(read_adc()*5.0/1023.0)-2.5;
  31.          delay_us(33);
  32.          valorMax1=adc1*adc1+valorMax1;
  33.          set_adc_channel(1);
  34.          adc2=(read_adc()*5.0/1023.0)-2.5;
  35.          delay_us(33);
  36.          valorMax2=adc2*adc2+valorMax2;
  37.       }  
  38.       tension=sqrt(valorMax1/300)*CONST_TENSION;
  39.       corriente=sqrt(valorMax2/300)*CONST_CORRIENTE;
  40.       potencia=tension*corriente;
  41.       if(tension<50.0||corriente<0.03){
  42.          lcd_gotoxy(1,1);
  43.          printf(lcd_putc,"     W:000.0    ");
  44.          lcd_gotoxy(1,2);
  45.          printf(lcd_putc,"V:000.0   A:0.00");
  46.       }else{
  47.          lcd_gotoxy(1,1);
  48.          printf(lcd_putc,"     W:%3.1f    ",potencia);
  49.          lcd_gotoxy(1,2);
  50.          printf(lcd_putc,"V:%3.1f   A:%1.2f",tension, corriente);
  51.       }
  52.       valorMax1=0;
  53.       valorMax2=0;
  54.    }
  55. }




NOTA: se ha implementado una mejora al nivel de ruido del sensor ACS712 mediante un filtro RC de 1k y 1uF.
Podemos ver la diferencia notable en el osciloscopio, aunque el algoritmo de medición realiza una integración mediante la discretizacion de la señal, podemos mejorar aun mas la relación señal ruido del amperimetro, este reduce el ruido para niveles bajos de corriente.



Código para Arduino:

  1. #include <math.h>
  2. #include <LiquidCrystal.h>
  3. LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //( RS, EN, d4, d5, d6, d7)
  4. #define CONST_CORRIENTE 2
  5. #define CONST_TENSION   530
  6. int i, adcZ=0;
  7. float adc1=0, valorMax1=0, adc2=0, valorMax2=0;
  8. float tension, corriente, potencia;
  9. void setup(){
  10.    lcd.begin(16, 2);
  11.    lcd.clear();
  12. }
  13. void loop(){
  14.    do{
  15.       adcZ=analogRead(A0)-512;
  16.       delayMicroseconds(20);
  17.    }while(adcZ<10);
  18.    for(i=0;i<500;i++){
  19.       adc1=(analogRead(A0)*5.0/1023.0)-2.5;
  20.       delayMicroseconds(33);
  21.       valorMax1=adc1*adc1+valorMax1;
  22.       adc2=(analogRead(A1)*5.0/1023.0)-2.5;
  23.       delayMicroseconds(33);
  24.       valorMax2=adc2*adc2+valorMax2;
  25.    }  
  26.    tension=sqrt(valorMax1/500)*CONST_TENSION;
  27.    corriente=sqrt(valorMax2/500)*CONST_CORRIENTE;
  28.    potencia=tension*corriente;
  29.    delay(2000);
  30.    if(tension<50.0||corriente<0.03){
  31.       lcd.setCursor(0,0);
  32.       lcd.print("     W:000.0    ");
  33.       lcd.setCursor(0,1);
  34.       lcd.print("V:000.0   A:0.00");
  35.    }else{
  36.       lcd.setCursor(5,0);
  37.       lcd.print("W:");
  38.       lcd.setCursor(7,0);
  39.       lcd.print(potencia);
  40.       lcd.setCursor(0,1);
  41.       lcd.print("V:");
  42.       lcd.setCursor(2,1);
  43.       lcd.print(tension);
  44.       lcd.setCursor(10,1);
  45.       lcd.print("A:");
  46.       lcd.setCursor(12,1);
  47.       lcd.print(corriente);
  48.    }
  49.    valorMax1=0;
  50.    valorMax2=0;
  51. }


Reemplazar los potenciometros por la etapa de sensado que se ve en el primer circuito, El resto corre igual se utilizan dos canales ADC al igual que en el primer circuito.
Se ha utilizado potenciometros para la simulación.
Aquí dejare el link a Circuits.io para la simulación del proyecto.

ACTUALIZACIÓN (ARDUINO):