Bueno, ya creé mi subfunción para calcular el valor rms de cualquier arreglo de números flotantes. La integral la hice con el método de los trapecios múltiples.
Su prototipo es:
float ValorRMS(float *arreglo, int samples);Se le entrega un apuntador al arreglo de flotantes y en samples el número de elementos del arreglo y listo, entrega el valor en flotante a la salida.
La subfunción se declara así:
//Subfunción Calcula Valor RMS de un arreglo flotante de n muestras
float ValorRMS(float *arreglo, int samples)
{
int i;
float suma=0;
for(i=0;i<samples;i++)
arreglo[i]*=arreglo[i];
for(i=1;i<samples-1;i++)
suma+=arreglo[i];
suma+=(arreglo[0]+arreglo[samples-1])/2.0;
return sqrt(suma/samples);
}
Si alguien la llega a implementar en un PIC16, no olvidar que int samples deberá ser capaz de apuntar a todas las muestras de arreglo.
Ah y los valores en arreglo son modificados (elevados al cuadrado). Si es necesario dejarlos intactos entonces hay que clonar el arreglo con un realloc o algo por el estilo.
La probé con una onda senoidal a 60Hz y Vpico de 180V. El programa de prueba es éste:
//Programa para calcular el valor RMS de una señal discreta
#include "stdafx.h"
#include "math.h"
#include "malloc.h"
#include "conio.h"
//Constantes
#define dospi 6.283185
//Variables
float vpico=180.0;
int muestras=22050; //muestras totales del arreglo
float frec=60.0;
int fsample=22050;
float *seno;
int i,j;
float vrms;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//Subfunción Calcula Valor RMS de un arreglo flotante de n muestras
float ValorRMS(float *arreglo, int samples)
{
int i;
float suma=0;
for(i=0;i<samples;i++)
arreglo[i]*=arreglo[i];
for(i=1;i<samples-1;i++)
suma+=arreglo[i];
suma+=(arreglo[0]+arreglo[samples-1])/2.0;
return sqrt(suma/samples);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//Función principal
int main(int argc, char* argv[])
{
printf("Programa para calcular el valor RMS de una señal discreta");
printf("\nVoltaje pico = %f",vpico);
printf("\nGenerando onda senoidal %fHz @ %dsps",frec,fsample);
//Genera el arreglo senoidal
seno=(float *)malloc(sizeof(float)*muestras);
for(i=0;i<muestras;i++)
seno[i]=vpico*sin((float)dospi*frec*i/fsample);
//Sobre el arreglo senoidal se calcula el valor rms usando el método del trapecio múltiple
vrms=ValorRMS(seno,muestras);
printf("\nValor RMS %f",vrms);
printf("\nPresione enter");
getch();
return 0;
}