Medición de Tensión Alterna TrueRMS v2

Basándonos en la versión 1 de esta nota: http://electgpl.blogspot.com.ar/2016/04/medicion-de-tension-alterna-truerms.html
Vamos a realizar algunas mejoras en el firmware que van a hacer el código mas preciso y luego seguiremos con otro nuevo post sobre la medición de corriente para realizar el medidor de energía eléctrica.
Las mejoras son las siguientes:

1) Eliminamos el renglón del LCD donde mostramos el falso valor Pico (falso porque estábamos tomando el valor TrueRMS calculado y multiplicándolo por Raiz de 2, cosa que es falso ya que Raiz de 2 es un valor correspondiente al RMS para una señal seno, no aplica a otra forma de onda.

2) Cambio el valor del delay en la iteración del lazo for, que en el post anterior lo tenia en 10ms pero en la practica tras pruebas lo deje en 60us, esto es porque tenemos que medir tanto el hemiciclo positivo como el negativo que luego pasa a ser positivo por el rectificador de onda completa, entonces la medición debe ser de los 100Hz de señal. Para ello calculamos 300 iteraciónes por 60us, nos dará unos 18ms de delay (esto si no tomamos en cuenta la demora que tiene el resto de las instrucciones que si bien son pocos ciclos, existe), de esta forma podremos recorrer las 300 iteraciónes por los dos hemiciclos.

3) El cruce por cero, el método que tenemos para saber cuando la señal es cero y una vez que es así comenzamos la medición para que sea mas exacta y sincronizada, para ello usamos un Do While que lee el ADC y permanece dentro del mismo lazo hasta que pase por Cero y luego sale del lazo Do While dando lugar a entrar al lazo for de medición.

4) Por ultimo podremos ver en renglón donde se muestra el valor de tensión donde se multiplica por 75 y se suma a 44, esto es porque se ha realizado una regresión lineal de valores para llegar a la ecuación que responde a nuestra curva que por suerte es bastante lineal.
El procedimiento es medir la tensión RMS que nos da el ADC (entre 0 y 5V) y mediante un Variac vamos variando la tensión de entrada en el transformador de medición entre 150 y 240Vac (ese es el rango que he utilizado), se toman mediciones en distintos valores de tensión dentro de ese rango, Ej: 150, 160, 170, ... ,230 y 240Vac, a cada valor le corresponde un valor que sera el que entrega el transformador reductor, rectificado y atenuado en el ADC. A cada valor de tensión alterna variada entre 150 y 240Vac le corresponde un valor de ADC, entonces tomamos esas dos columnas de valores, las ingresamos en la planilla de calculo y luego se aplica un gráfico de dispersión xy donde una vez graficado se aplica la regresión estadística y nos muestra la ecuación. 
Esta ecuación es útil para mi sistema, es decir, el transformador que use de 220 a 12V el puente rectificador, atenuador, etc... Es un proceso que tendremos que hacer según el hardware que estemos configurando (es parte de la calibración, ya que luego se puede poner un preset en el atenuador resistivo del ADC para ajustar de forma fina).

El programa:


  1. #include <16F883.h>
  2. #device adc=10
  3. #use delay(int=4000000)
  4. #include <LCD.C>
  5. #include <math.h>
  6. void main(){
  7.    setup_adc_ports(sAN0|VSS_VDD);
  8.    setup_adc(ADC_CLOCK_DIV_2);
  9.    int16 i;
  10.    float adc1, valorMax=0;
  11.    lcd_init();
  12.    while(true){
  13.       do{
  14.          set_adc_channel(0);
  15.          adc1=read_adc()*5.0/1023.0;
  16.          delay_us(20);
  17.       }while(adc1!=0);
  18.       for(i=0;i<300;i++){
  19.          set_adc_channel(0);
  20.          adc1=read_adc()*5.0/1023.0;
  21.          delay_us(60);
  22.          valorMax=adc1*adc1+valorMax;
  23.       }  
  24.       lcd_gotoxy(1,1);
  25.       printf(lcd_putc,"Voltimetro Trms");
  26.       lcd_gotoxy(1,2);
  27.       printf(lcd_putc,"Val RMS: %3.0f ",(sqrt(valorMax/300)*75)+44);
  28.       valorMax=0;
  29.    }
  30. }

Linea 13 a 17, aquí podremos ver el Do While, recordemos que el Do While es igual al While pero con la diferencia que la primera vez ejecutara su código sin importar la condición que tenga y luego de la primera vez ejecutara según su condición.
En este caso hacemos una lectura del ADC la pasamos a un nivel entre 0 y 5V, la condición del Do While sera que el valor del adc sea distinto de cero, entonces mientras que el valor sea distinto de cero el Do While sera verdadero y el programa quedara loopeado dentro de ese lazo, una vez que el valor sea igual a cero, la condición sera falsa y saldrá del Do While, entonces seguirá con la instrucción siguiente que es el for, de esa forma el Do While cumple la función de esperar que la señal sea 0 o pase por 0.

Linea 18 a 23, Este sera el for que genera las 300 iteraciónes donde realizaremos la sumatoria de los cuadrados de cada valor cada 60us como hemos mencionado anteriormente.

Linea 27, Aquí tal vez podríamos realizar un paso anterior y pre-calcular los valores para mostrarlos en una variable nueva, pero el funcionamiento es el mismo y lo he dejado asi, pero es sencillo realizar el calculo antes de mostrar el valor en el LCD y luego enviarlo a una variable. El calculo que se realiza en la misma linea del LCD es tomar el valor sumado de los cuadrados y dividirlo por las 300 muestras para sacar el promedio de la suma y luego aplicar la raíz cuadrada. Por ultimo he agregado la multiplicación por 75 y la suma de 44 porque es el valor de la regresión que me ha dado el gráfico de dispersión de la planilla de calculo.

En resumen, hemos desarrollado un muy simple medidor de tensión TrueRMS con 16.7ksps. 



11 comentarios:

  1. Excelentes tus aportes, he podido aprender y recordar muchas cosas. Muchos saludos y ojalá sigas compartiendo tu conocimiento.

    ResponderBorrar
  2. Leer esto fue de gran ayuda. Soy brasileño y necesiti hacer un proyecto semejante. Muchas gracias estimado.

    ResponderBorrar
  3. Buenas tardes, este post me aclaro varios conocimientos, solo tengo una duda. Es indistinta la corriente que circule en la entrada (220v AC)? Osea si circulan 2500A no sufre el trafo?
    Espero una respuesta. Gracias.

    ResponderBorrar
    Respuestas
    1. Hola, que transformador es el que vas a hacer circular 2.5kA?, saludos

      Borrar
  4. Hola, desde hace tiempo sigo tu canal en Youtube y me gusta mucho tu contenido. solo tengo una pregunta
    ¿como calcularía el tiempo del delay si fuera una frecuencia de 60Hz?

    ResponderBorrar
    Respuestas
    1. Hola tenes que cambiar la linea 21: delay_us(60); por delay_us(55);
      Saludos.

      Borrar
  5. Saludos, muy bueno tu información, disculpa quisiera saber, como obtuviste el valor de 75 y 44 linea 27 de programa, Por favor explicar.

    ResponderBorrar
  6. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  7. Hay varios detalles en tu programa: 1ro No es necesario seleccionar el canal del adc cada vez antes de leer, además, luego de seleccionar el canal tienes que esperar un determinado tiempo. 2do- En la parte del "for" luego de leer el ADC esperas 60us y luego haces una operación, podrías hacer la operación primero y lo que tarda la operación, descontarlo a los 60uS.

    ResponderBorrar