Buenas tardes a todos y gracias de antemano por las posibles respuestas. Estoy realizando un sensor de voltaje alterno,con Arduino Uno el cual recitifico con diodo a media onda para introducir en arduino. El algoritmo que utilizo se basa en tomar cuantas más muestras posibles en el periodo T de la señal, e ir integrando, utilizando la definición de Vrms, que es la siguiente:
Por tanto, voy tomando los valores instantáneos de V y multiplicando por el diferencial de t, el cual calculo usando micros. Una vez ha transcurrido el tiempo T, calculo el valor de Vrms, haciendo la raiz y multiplicando por 1/T, o f.
Repito la operación 50 veces y extraigo la media.
Bien, el valor que obtengo tiene un error relativo del 7% aprox respecto a dos múltimetros de alta calidad, algo que es demasiado, ya que tengo que medir voltajes del orden de 230 V y este error es demasiado.
Teniendo en cuenta que la frecuencia con la que estoy midiendo es de 4,32 KHz, no debería ser mucho más preciso el valor? Podría optimizar el código sin necesidad de tocar la velocidad de lectura del A/D y que fuera más preciso?
El número de muestras que me toma por periodo de la señal es de unas 86-87.
long tiempo;
double valor, f=50,V_rms = 0,V_rms_medio=0, matrix,t_muestreo = 0;
double endit=0, prvTime = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
double sum = 0;//Variable Integrador
int i=0;
for(int k=0;k<50;k++)//Bucle que repite 50 veces el proceso obtención de Vrms para sacar una media
{
i=0;
double init = micros();//Inicio la cuenta
endit = init;
while((endit-init) < 20000)//Mientras no se alcanza el periodo de la señal en microsegundos(20000 us, equivalente a una frecuencia de 50 Hz) se van tomando muestras
{
prvTime = micros(); //Toma el tiempo antes de leer la señal
valor = analogRead(0);//Lee el voltaje
endit = micros();//Toma el tiempo justo despues de leer la señal
matrix=valor*5/(1024);//Convierte el valor del ACD en voltios
sum = (matrix*matrix)*((endit-prvTime)/1000000)+sum; //Integrado de la señal. El voltaje al cuadrado por el diferencial de t, en segundos más el valor acumulado
i++;
}
V_rms = sqrt(f*sum)+V_rms; //voltaje VRMS es igual a la raiz de la frecuencia por la integral de V2*dt, calculada previamente en sum, más el valor de voltaje calculado
t_muestreo = endit-init;
//en la iteración previa de k.
sum=0;
//Reinicio el valor sum para la siguiente iteración del for loop.
}
V_rms_medio = V_rms/50;//Calculo la media de los valores finales de Vrms calculados
V_rms=0;//Reinicio V_rms para el siguiente void loop.
Serial.print("Vrms: ");
Serial.println(V_rms_medio,DEC);
Serial.print("Numero de Itereaciones: ");
Serial.println(i);
Serial.print("Tiempo de muestreo us: ");
Serial.println(t_muestreo);
Serial.print("Frecuencia de muestreo KHz: ");
Serial.println(i/(t_muestreo*1000/1000000));//Frecuencia de muestreo es igual al número de muestras por segundo, dividido entre 1000 para pasar a KHz
Serial.println("");
}