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
Codes/SignalProcessor.cpp@2:86c3cb25577b, 2014-07-21 (annotated)
- 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?
User | Revision | Line number | New 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 | */ |