Versão do protegemed que calcula o tempo em ms da fuga, calcula o numero de onverflow (valores muito baixo) e underflow (valores muito altos). Além disso, calcula um valor médio a partir dos valores capturados e não apenas pela fft.

Dependencies:   EthernetInterface mbed-rtos mbed

Committer:
rebonatto
Date:
Mon Jul 21 00:58:34 2014 +0000
Revision:
2:86c3cb25577b
Parent:
1:917ca6b5d9d9
Problemas com objeto para aquisi??o da rfid (serial)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rebonatto 0:c64e1194230b 1 /*
rebonatto 0:c64e1194230b 2 * SignalProcessor.cpp
rebonatto 0:c64e1194230b 3 *
rebonatto 0:c64e1194230b 4 * Created on:
rebonatto 0:c64e1194230b 5 * Author:
rebonatto 0:c64e1194230b 6 */
rebonatto 0:c64e1194230b 7
rebonatto 0:c64e1194230b 8 #include <math.h>
rebonatto 0:c64e1194230b 9 #include <stdlib.h>
rebonatto 0:c64e1194230b 10 #include <stdio.h>
rebonatto 0:c64e1194230b 11 #include <string.h>
rebonatto 0:c64e1194230b 12
rebonatto 0:c64e1194230b 13 #include "SignalProcessor.h"
rebonatto 2:86c3cb25577b 14 #include "limites.h"
rebonatto 0:c64e1194230b 15
rebonatto 0:c64e1194230b 16 #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
rebonatto 0:c64e1194230b 17 #define PI 3.14159265358979323846F
rebonatto 0:c64e1194230b 18 // 3.141597653564793332212487132
rebonatto 0:c64e1194230b 19 // 3.14159265358979323846
rebonatto 0:c64e1194230b 20
rebonatto 0:c64e1194230b 21
rebonatto 0:c64e1194230b 22 /* Elementos vm2, under, over adicionados em 20/05/2014 por Rebonatto */
rebonatto 0:c64e1194230b 23 /* vm2 eh o calculo do valor medio, under eh a cotagem dos valores do AD com 0 */
rebonatto 0:c64e1194230b 24 /* over e a contagem do AD com 4095 */
rebonatto 0:c64e1194230b 25 /* over e under sao para verificar se o processo de ajuste dos dados esta Ok e vm2 para conferir o vm da fft */
rebonatto 0:c64e1194230b 26 void SignalProcessor::CalculateRMSBulk(float *result, float *vm2, int *under, int *over)
rebonatto 0:c64e1194230b 27 {
rebonatto 0:c64e1194230b 28 int nChannel,nSample;
rebonatto 0:c64e1194230b 29
rebonatto 0:c64e1194230b 30 for(nChannel=0;nChannel<Settings::get_MaxChannels();nChannel++)
rebonatto 0:c64e1194230b 31 result[nChannel] = vm2[nChannel] = under[nChannel] = over[nChannel] = 0;
rebonatto 0:c64e1194230b 32
rebonatto 0:c64e1194230b 33 for(nChannel=0;nChannel<Settings::get_MaxChannels();nChannel++)
rebonatto 0:c64e1194230b 34 {
rebonatto 0:c64e1194230b 35 for(nSample=0;nSample<Settings::get_Samples();nSample++)
rebonatto 0:c64e1194230b 36 {
rebonatto 0:c64e1194230b 37 unsigned short int v = Capture::GetValue(nSample, nChannel);
rebonatto 0:c64e1194230b 38 /* novos calculos */
rebonatto 0:c64e1194230b 39 vm2[nChannel] += v;
rebonatto 0:c64e1194230b 40 if (v <= 20)
rebonatto 0:c64e1194230b 41 under[nChannel] = under[nChannel] + 1;
rebonatto 0:c64e1194230b 42 if (v >= 4075)
rebonatto 0:c64e1194230b 43 over[nChannel] = over[nChannel] + 1;
rebonatto 0:c64e1194230b 44 float val = (float)v;
rebonatto 0:c64e1194230b 45
rebonatto 0:c64e1194230b 46 val -= Settings::get_Offset(nChannel);
rebonatto 0:c64e1194230b 47 val /= Settings::get_Gain(nChannel);
rebonatto 0:c64e1194230b 48 val *= val;
rebonatto 0:c64e1194230b 49 result[nChannel] += val;
rebonatto 0:c64e1194230b 50 }
rebonatto 0:c64e1194230b 51 result[nChannel] /= (float)Settings::get_Samples();
rebonatto 0:c64e1194230b 52 result[nChannel] = sqrt(result[nChannel]);
rebonatto 0:c64e1194230b 53
rebonatto 0:c64e1194230b 54 /* novos calculos */
rebonatto 0:c64e1194230b 55 vm2[nChannel] /= (float)Settings::get_Samples();
rebonatto 0:c64e1194230b 56 }
rebonatto 0:c64e1194230b 57 }
rebonatto 0:c64e1194230b 58
rebonatto 0:c64e1194230b 59 float SignalProcessor::CalculateRMS(unsigned short int *buffer,int nChannel)
rebonatto 0:c64e1194230b 60 {
rebonatto 0:c64e1194230b 61 float result=0;
rebonatto 0:c64e1194230b 62 int nSample;
rebonatto 0:c64e1194230b 63
rebonatto 0:c64e1194230b 64 for(nSample=0;nSample<Settings::get_Samples();nSample++)
rebonatto 0:c64e1194230b 65 {
rebonatto 0:c64e1194230b 66
rebonatto 0:c64e1194230b 67 unsigned short int v = buffer[nSample];
rebonatto 0:c64e1194230b 68 float val = (float)v;
rebonatto 0:c64e1194230b 69 // cada ponto
rebonatto 0:c64e1194230b 70 val -= Settings::get_Offset(nChannel); // diminui o offset
rebonatto 0:c64e1194230b 71 val /= Settings::get_Gain(nChannel); // divide pelo ganhp
rebonatto 0:c64e1194230b 72 val *= val; // eleva ao quadrado
rebonatto 0:c64e1194230b 73 result += val; // soma
rebonatto 0:c64e1194230b 74 }
rebonatto 0:c64e1194230b 75 result /= (float)Settings::get_Samples(); // divide pelo numero de amostras (256)
rebonatto 0:c64e1194230b 76 result = sqrt(result);
rebonatto 0:c64e1194230b 77 return result;
rebonatto 0:c64e1194230b 78 }
rebonatto 0:c64e1194230b 79
rebonatto 0:c64e1194230b 80 void SignalProcessor::CalculateFFT(unsigned short int *buffer,float *sen,float *cos,float *vm,int sign, int ch)
rebonatto 0:c64e1194230b 81 {
rebonatto 0:c64e1194230b 82 int i;
rebonatto 0:c64e1194230b 83 //float value[256];
rebonatto 0:c64e1194230b 84 /*
rebonatto 0:c64e1194230b 85 printf("Tamanho float %lu\n", sizeof(float));
rebonatto 0:c64e1194230b 86 printf("Tamanho double %lu\n", sizeof(double));
rebonatto 0:c64e1194230b 87 printf("Tamanho unsigned short int %lu\n", sizeof(unsigned short int));
rebonatto 0:c64e1194230b 88 printf("Tamanho unsigned long %lu\n", sizeof(unsigned long));
rebonatto 0:c64e1194230b 89 printf("Tamanho unsigned long long %lu\n", sizeof(unsigned long long));
rebonatto 0:c64e1194230b 90 */
rebonatto 0:c64e1194230b 91
rebonatto 0:c64e1194230b 92 /*
rebonatto 0:c64e1194230b 93 for(int i=0; i < Settings::get_Samples(); i++)
rebonatto 0:c64e1194230b 94 printf("%d*",buffer[i]);
rebonatto 0:c64e1194230b 95 printf("\n");
rebonatto 0:c64e1194230b 96 */
rebonatto 0:c64e1194230b 97
rebonatto 0:c64e1194230b 98 //printf("[0] %d %d %d %d\n", buffer[0], buffer[100], buffer[200], buffer[255]);
rebonatto 0:c64e1194230b 99 /*
rebonatto 0:c64e1194230b 100 for(i=0; i<Settings::get_Samples();i++)
rebonatto 0:c64e1194230b 101 value[i]= (float) ( (buffer[i] - Settings::get_Offset(ch)) / Settings::get_Gain(ch) );
rebonatto 0:c64e1194230b 102 */
rebonatto 2:86c3cb25577b 103
rebonatto 0:c64e1194230b 104 float* fft = ComplexFFT(buffer,1, ch); //deve desalocar memoria do ptr retornado
rebonatto 2:86c3cb25577b 105
rebonatto 0:c64e1194230b 106
rebonatto 0:c64e1194230b 107 /*
rebonatto 0:c64e1194230b 108 Mapa do vetor fft.
rebonatto 0:c64e1194230b 109 O vetor tem 2 vezes o no. de amostras. Cada par de valores (portanto n e n+1), representam, respectivamente
rebonatto 0:c64e1194230b 110 COS e SEN.
rebonatto 0:c64e1194230b 111 Os dois primeiros valores reprensetam a frequencia 0Hz, portanto sao atribuidas ao valor medio.
rebonatto 0:c64e1194230b 112 Os demais pares de valores representam a fundamental e suas harmonicas,
rebonatto 0:c64e1194230b 113 sendo que se a fundamental for 60Hz, teremos: 60,120,180,240...
rebonatto 0:c64e1194230b 114 Para a nossa aplicacao apenas as 12 primeiras harmonicas serao utilizadas (720Hz)
rebonatto 0:c64e1194230b 115 */
rebonatto 0:c64e1194230b 116
rebonatto 0:c64e1194230b 117 //*vm = DFT(value, sen, cos);
rebonatto 0:c64e1194230b 118 *vm = fft[0];
rebonatto 0:c64e1194230b 119
rebonatto 0:c64e1194230b 120 for(int i=1;i<Settings::get_MaxHarmonics()+1;i++)
rebonatto 0:c64e1194230b 121 {
rebonatto 0:c64e1194230b 122 cos[i-1] = fft[i*2];
rebonatto 0:c64e1194230b 123 sen[i-1] = fft[i*2+1];
rebonatto 0:c64e1194230b 124 }
rebonatto 0:c64e1194230b 125
rebonatto 2:86c3cb25577b 126 /*
rebonatto 0:c64e1194230b 127 for(int i=0;i<Settings::get_MaxHarmonics();i++)
rebonatto 0:c64e1194230b 128 {
rebonatto 0:c64e1194230b 129 printf("[%dHz]\tsen %.4f\tcos %.4f\n", (i+1)*60, sen[i], cos[i]);
rebonatto 0:c64e1194230b 130 }
rebonatto 2:86c3cb25577b 131 */
rebonatto 0:c64e1194230b 132 free(fft);
rebonatto 0:c64e1194230b 133 //printf("[3] %d %d %d %d\n", buffer[0], buffer[100], buffer[200], buffer[255]);
rebonatto 0:c64e1194230b 134 }
rebonatto 0:c64e1194230b 135
rebonatto 0:c64e1194230b 136
rebonatto 0:c64e1194230b 137 float* SignalProcessor::ComplexFFT(unsigned short int* data, int sign, int ch)
rebonatto 0:c64e1194230b 138 {
rebonatto 0:c64e1194230b 139
rebonatto 0:c64e1194230b 140 //variables for the fft
rebonatto 0:c64e1194230b 141 unsigned long n,mmax,m,j,istep,i;
rebonatto 0:c64e1194230b 142 //double wtemp,wr,wpr,wpi,wi,theta,tempr,tempi;
rebonatto 0:c64e1194230b 143 float wtemp,wr,wpr,wpi,wi,theta,tempr,tempi;
rebonatto 0:c64e1194230b 144 float *vector;
rebonatto 0:c64e1194230b 145 //the complex array is real+complex so the array
rebonatto 0:c64e1194230b 146 //as a size n = 2* number of complex samples
rebonatto 0:c64e1194230b 147 //real part is the data[index] and
rebonatto 0:c64e1194230b 148 //the complex part is the data[index+1]
rebonatto 0:c64e1194230b 149
rebonatto 0:c64e1194230b 150 //new complex array of size n=2*sample_rate
rebonatto 0:c64e1194230b 151 //if(vector==0)
rebonatto 0:c64e1194230b 152 //vector=(float*)malloc(2*SAMPLE_RATE*sizeof(float)); era assim, define estava em Capture.h
rebonatto 1:917ca6b5d9d9 153
rebonatto 1:917ca6b5d9d9 154 printf("Antes malloc\n");
rebonatto 0:c64e1194230b 155 vector=(float*)malloc(2*Settings::get_Samples()*sizeof(float));
rebonatto 0:c64e1194230b 156 memset(vector,0,2*Settings::get_Samples()*sizeof(float));
rebonatto 1:917ca6b5d9d9 157 printf("DEpois malloc\n");
rebonatto 2:86c3cb25577b 158
rebonatto 2:86c3cb25577b 159
rebonatto 2:86c3cb25577b 160 DisplayRAMBanks();
rebonatto 2:86c3cb25577b 161
rebonatto 0:c64e1194230b 162 //put the real array in a complex array
rebonatto 0:c64e1194230b 163 //the complex part is filled with 0's
rebonatto 0:c64e1194230b 164 //the remaining vector with no data is filled with 0's
rebonatto 0:c64e1194230b 165 //for(n=0; n<SAMPLE_RATE;n++)era assim, define estava em Capture.h
rebonatto 0:c64e1194230b 166
rebonatto 0:c64e1194230b 167 for(n=0; n<Settings::get_Samples();n++)
rebonatto 0:c64e1194230b 168 {
rebonatto 0:c64e1194230b 169 if(n<Settings::get_Samples()){
rebonatto 0:c64e1194230b 170 //vector[2*n]= (float) ( (data[n] - Settings::get_Offset(ch)) / Settings::get_Gain(ch) );
rebonatto 0:c64e1194230b 171 vector[2*n]= (float) data[n] ;
rebonatto 0:c64e1194230b 172 // printf("%.4f$", vector[2*n]);
rebonatto 0:c64e1194230b 173 }
rebonatto 0:c64e1194230b 174 else
rebonatto 0:c64e1194230b 175 vector[2*n]=0;
rebonatto 0:c64e1194230b 176 vector[2*n+1]=0;
rebonatto 0:c64e1194230b 177 }
rebonatto 0:c64e1194230b 178
rebonatto 0:c64e1194230b 179 //printf("\n");
rebonatto 0:c64e1194230b 180
rebonatto 0:c64e1194230b 181 //printf("[1] %d %d %d %d\n", data[0], data[100], data[200], data[255]);
rebonatto 0:c64e1194230b 182
rebonatto 0:c64e1194230b 183 //binary inversion (note that the indexes
rebonatto 0:c64e1194230b 184 //start from 0 witch means that the
rebonatto 0:c64e1194230b 185 //real part of the complex is on the even-indexes
rebonatto 0:c64e1194230b 186 //and the complex part is on the odd-indexes)
rebonatto 0:c64e1194230b 187 //n=SAMPLE_RATE << 1; //multiply by 2era assim, define estava em Capture.h
rebonatto 0:c64e1194230b 188 n=Settings::get_Samples() << 1; //multiply by 2
rebonatto 0:c64e1194230b 189 j=0;
rebonatto 0:c64e1194230b 190 for (i=0;i<n/2;i+=2) {
rebonatto 0:c64e1194230b 191 if (j > i) {
rebonatto 0:c64e1194230b 192 SWAP(vector[j],vector[i]);
rebonatto 0:c64e1194230b 193 SWAP(vector[j+1],vector[i+1]);
rebonatto 0:c64e1194230b 194 if((j/2)<(n/4)){
rebonatto 0:c64e1194230b 195 SWAP(vector[(n-(i+2))],vector[(n-(j+2))]);
rebonatto 0:c64e1194230b 196 SWAP(vector[(n-(i+2))+1],vector[(n-(j+2))+1]);
rebonatto 0:c64e1194230b 197 }
rebonatto 0:c64e1194230b 198 }
rebonatto 0:c64e1194230b 199 m=n >> 1;
rebonatto 0:c64e1194230b 200 while (m >= 2 && j >= m) {
rebonatto 0:c64e1194230b 201 j -= m;
rebonatto 0:c64e1194230b 202 m >>= 1;
rebonatto 0:c64e1194230b 203 }
rebonatto 0:c64e1194230b 204 j += m;
rebonatto 0:c64e1194230b 205 }
rebonatto 0:c64e1194230b 206 //end of the bit-reversed order algorithm
rebonatto 0:c64e1194230b 207
rebonatto 0:c64e1194230b 208 //Danielson-Lanzcos routine
rebonatto 0:c64e1194230b 209 mmax=2;
rebonatto 0:c64e1194230b 210 while (n > mmax) {
rebonatto 0:c64e1194230b 211 istep=mmax << 1;
rebonatto 0:c64e1194230b 212 theta=sign*(2*PI/mmax);
rebonatto 0:c64e1194230b 213 wtemp=sin(0.5*theta);
rebonatto 0:c64e1194230b 214 wpr = -2.0*wtemp*wtemp;
rebonatto 0:c64e1194230b 215 wpi=sin(theta);
rebonatto 0:c64e1194230b 216 wr=1.0;
rebonatto 0:c64e1194230b 217 wi=0.0;
rebonatto 0:c64e1194230b 218 for (m=1;m<mmax;m+=2) {
rebonatto 0:c64e1194230b 219 for (i=m;i<=n;i+=istep) {
rebonatto 0:c64e1194230b 220 j=i+mmax;
rebonatto 0:c64e1194230b 221 tempr=wr*vector[j-1]-wi*vector[j];
rebonatto 0:c64e1194230b 222 tempi=wr*vector[j]+wi*vector[j-1];
rebonatto 0:c64e1194230b 223 vector[j-1]=vector[i-1]-tempr;
rebonatto 0:c64e1194230b 224 vector[j]=vector[i]-tempi;
rebonatto 0:c64e1194230b 225 vector[i-1] += tempr;
rebonatto 0:c64e1194230b 226 vector[i] += tempi;
rebonatto 0:c64e1194230b 227 }
rebonatto 0:c64e1194230b 228 wr=(wtemp=wr)*wpr-wi*wpi+wr;
rebonatto 0:c64e1194230b 229 wi=wi*wpr+wtemp*wpi+wi;
rebonatto 0:c64e1194230b 230 }
rebonatto 0:c64e1194230b 231 mmax=istep;
rebonatto 0:c64e1194230b 232 }
rebonatto 0:c64e1194230b 233 //end of the algorithm
rebonatto 0:c64e1194230b 234
rebonatto 0:c64e1194230b 235 /*
rebonatto 0:c64e1194230b 236 // Ajustes a FFT
rebonatto 0:c64e1194230b 237 for(i = 0; i < Settings::get_Samples()*2; i++ ){
rebonatto 0:c64e1194230b 238 vector[i] = (float) ((2 * vector[i]) / Settings::get_Samples() );
rebonatto 0:c64e1194230b 239 /*
rebonatto 0:c64e1194230b 240 if (i % 2 == 1)
rebonatto 0:c64e1194230b 241 vector[i] = vector[i] * -1;
rebonatto 0:c64e1194230b 242
rebonatto 0:c64e1194230b 243 }
rebonatto 0:c64e1194230b 244 */
rebonatto 0:c64e1194230b 245 //printf("[2] %d %d %d %d\n", data[0], data[100], data[200], data[255]);
rebonatto 0:c64e1194230b 246
rebonatto 0:c64e1194230b 247 return vector;
rebonatto 0:c64e1194230b 248 }
rebonatto 0:c64e1194230b 249
rebonatto 0:c64e1194230b 250 /*
rebonatto 0:c64e1194230b 251 float SignalProcessor::DFT(float *data, float *seno, float *coss){
rebonatto 0:c64e1194230b 252 int i, j;
rebonatto 0:c64e1194230b 253
rebonatto 0:c64e1194230b 254 for(i=0; i < Settings::get_MaxHarmonics()+1; i++)
rebonatto 0:c64e1194230b 255 seno[i] = coss[i] = 0;
rebonatto 0:c64e1194230b 256
rebonatto 0:c64e1194230b 257 for(i=0; i < Settings::get_Samples(); i++){
rebonatto 0:c64e1194230b 258 for(j = 0; j < Settings::get_MaxHarmonics()+1; j++ ){
rebonatto 0:c64e1194230b 259 coss[j] += (data[i] * (cos( (2 * PI * i * j) / Settings::get_Samples() ) ) ) ;
rebonatto 0:c64e1194230b 260 seno[j] += (data[i] * (sin( (2 * PI * i * j) / Settings::get_Samples() ) ) ) ;
rebonatto 0:c64e1194230b 261 }
rebonatto 0:c64e1194230b 262 }
rebonatto 0:c64e1194230b 263
rebonatto 0:c64e1194230b 264 for(j = 1; j < Settings::get_MaxHarmonics()+1; j++ ){
rebonatto 0:c64e1194230b 265 coss[j] = 2 * coss[j] / Settings::get_Samples();
rebonatto 0:c64e1194230b 266 seno[j] = 2 * seno[j] / Settings::get_Samples() ;
rebonatto 0:c64e1194230b 267 }
rebonatto 0:c64e1194230b 268 return (float) (coss[0] / Settings::get_Samples()) + (seno[0] / Settings::get_Samples());
rebonatto 0:c64e1194230b 269 }
rebonatto 0:c64e1194230b 270 */