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:
- #include <16F883.h>
- #device adc=10
- #use delay(int=4000000)
- #define LCD_ENABLE_PIN PIN_B2
- #define LCD_RS_PIN PIN_B0
- #define LCD_RW_PIN PIN_B1
- #define LCD_DATA4 PIN_B4
- #define LCD_DATA5 PIN_B5
- #define LCD_DATA6 PIN_B6
- #define LCD_DATA7 PIN_B7
- #include <LCD.C>
- #include <math.h>
- #define CONST_CORRIENTE 5
- #define CONST_TENSION 310
- void main(){
- setup_adc_ports(sAN0|sAN1|VSS_VDD);
- setup_adc(ADC_CLOCK_DIV_2);
- int16 i, adcZ=0;
- float adc1=0, valorMax1=0, adc2=0, valorMax2=0;
- float tension, corriente, potencia;
- lcd_init();
- while(true){
- do{
- set_adc_channel(0);
- adcZ=read_adc()-512;
- delay_us(20);
- }while(adcZ<10);
- for(i=0;i<300;i++){
- set_adc_channel(0);
- adc1=(read_adc()*5.0/1023.0)-2.5;
- delay_us(33);
- valorMax1=adc1*adc1+valorMax1;
- set_adc_channel(1);
- adc2=(read_adc()*5.0/1023.0)-2.5;
- delay_us(33);
- valorMax2=adc2*adc2+valorMax2;
- }
- tension=sqrt(valorMax1/300)*CONST_TENSION;
- corriente=sqrt(valorMax2/300)*CONST_CORRIENTE;
- potencia=tension*corriente;
- if(tension<50.0||corriente<0.03){
- lcd_gotoxy(1,1);
- printf(lcd_putc," W:000.0 ");
- lcd_gotoxy(1,2);
- printf(lcd_putc,"V:000.0 A:0.00");
- }else{
- lcd_gotoxy(1,1);
- printf(lcd_putc," W:%3.1f ",potencia);
- lcd_gotoxy(1,2);
- printf(lcd_putc,"V:%3.1f A:%1.2f",tension, corriente);
- }
- valorMax1=0;
- valorMax2=0;
- }
- }
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:
- #include <math.h>
- #include <LiquidCrystal.h>
- LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //( RS, EN, d4, d5, d6, d7)
- #define CONST_CORRIENTE 2
- #define CONST_TENSION 530
- int i, adcZ=0;
- float adc1=0, valorMax1=0, adc2=0, valorMax2=0;
- float tension, corriente, potencia;
- void setup(){
- lcd.begin(16, 2);
- lcd.clear();
- }
- void loop(){
- do{
- adcZ=analogRead(A0)-512;
- delayMicroseconds(20);
- }while(adcZ<10);
- for(i=0;i<500;i++){
- adc1=(analogRead(A0)*5.0/1023.0)-2.5;
- delayMicroseconds(33);
- valorMax1=adc1*adc1+valorMax1;
- adc2=(analogRead(A1)*5.0/1023.0)-2.5;
- delayMicroseconds(33);
- valorMax2=adc2*adc2+valorMax2;
- }
- tension=sqrt(valorMax1/500)*CONST_TENSION;
- corriente=sqrt(valorMax2/500)*CONST_CORRIENTE;
- potencia=tension*corriente;
- delay(2000);
- if(tension<50.0||corriente<0.03){
- lcd.setCursor(0,0);
- lcd.print(" W:000.0 ");
- lcd.setCursor(0,1);
- lcd.print("V:000.0 A:0.00");
- }else{
- lcd.setCursor(5,0);
- lcd.print("W:");
- lcd.setCursor(7,0);
- lcd.print(potencia);
- lcd.setCursor(0,1);
- lcd.print("V:");
- lcd.setCursor(2,1);
- lcd.print(tension);
- lcd.setCursor(10,1);
- lcd.print("A:");
- lcd.setCursor(12,1);
- lcd.print(corriente);
- }
- valorMax1=0;
- valorMax2=0;
- }
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.