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:
- #include <16F883.h>
- #device adc=10
- #use delay(int=4000000)
- #include <LCD.C>
- #include <math.h>
- void main(){
- setup_adc_ports(sAN0|VSS_VDD);
- setup_adc(ADC_CLOCK_DIV_2);
- int16 i;
- float adc1, valorMax=0;
- lcd_init();
- while(true){
- do{
- set_adc_channel(0);
- adc1=read_adc()*5.0/1023.0;
- delay_us(20);
- }while(adc1!=0);
- for(i=0;i<300;i++){
- set_adc_channel(0);
- adc1=read_adc()*5.0/1023.0;
- delay_us(60);
- valorMax=adc1*adc1+valorMax;
- }
- lcd_gotoxy(1,1);
- printf(lcd_putc,"Voltimetro Trms");
- lcd_gotoxy(1,2);
- printf(lcd_putc,"Val RMS: %3.0f ",(sqrt(valorMax/300)*75)+44);
- valorMax=0;
- }
- }
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.