Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SDFileSystem TextLCD mbed
main.cpp
00001 /* 00002 -------------------------------------------------------------- 00003 Universidade Luterana do Brasil 00004 Departamento de Engenharia Elétrica 00005 Trabalho de Conclusão de Curso de Engenharia Elétrica 00006 MCSA - Motor Current Signature Analysis - Diagnóstico por Análise Espectral de Corrente de Motor 00007 Aluno: Flávio Dutra Lencina 00008 Orientador: Prof. Eng. Eletricista João Daniel de Oliveira Klein 00009 Data: 20/03/2016 00010 Dispositivo de Coleta e envio de dados espectrais de Corrente 00011 Desenvolvido para plataforma NXP FRDM-K64F co processador ARM Cortex-M4 MK64FN1M0VLL12 MCU 00012 utilizando Kinetis Devlopment Studio da NXP 00013 ADC0 :coleta de dados de corrente 00014 FFT para análise em frequência dos 4096 pontos 00015 Envio dos dados de |FFT| x freq[k] pela serial em 115200bps 00016 Grava dados no SD card \sd\Estreito\EE_Coletaxx.csv ou \sd\Estreito\EA_Coletaxx.csv 00017 ou envia para serial 00018 Leitura da AN0 para o teclado. 00019 Teste com LCD 20x4 00020 00021 -------------------------------------------------------------- */ 00022 00023 // 15-04-2016: 00024 // Mudança de estratégia de interrupções para utilização do teclado com LCD Shield do Arduino. 00025 // Colocar Interrupção para a porta serial e retirar das teclas SW2 e SW3. Utilização do teclado do Shield. 00026 // 15-06-2016: 00027 // Revisado para AN2 - Coleta a 4096 SPS e AN1 - 512 SPS 00028 // 03-08-2016: Revisão para adicionar PGA com CD4066 e controle com CD4028 BCD para decimal 00029 // 21-08-2016: Ajuste de RTC. 00030 00031 #include "mbed.h" 00032 #include "SDFileSystem.h" 00033 #include "math.h" 00034 #include "mbed_debug.h" 00035 #include "TextLCD.h" 00036 #include <complex> 00037 00038 #define ZRef 0.5 // Eleva para metade 00039 #define Ts 244.14062 //4096Hz 00040 00041 // SD-CARD Interface 00042 #define SD_MOSI PTE3 00043 #define SD_MISO PTE1 00044 #define SD_SCLK PTE2 00045 #define SD_CS PTE4 00046 #define SD_DETECT PTE6 00047 00048 // Interface LCD 20x04 - 4bits de dados 00049 #define RS PTC12 //D8 // instead PTA0 pin 34, we have to use PTC12 - pin 84 00050 //#define RW GND-3 00051 #define EN PTC4 //D9 00052 #define DB7 PTC3 //D7 00053 #define DB6 PTC2 //D6 00054 #define DB5 PTA2 //D5 00055 #define DB4 PTB23 //D4 00056 00057 // Teclas do Teclado Shield 00058 #define btn1 1 00059 #define btn2 2 00060 #define btn3 3 00061 #define btn4 4 00062 #define btn5 5 00063 #define btnNONE 0 00064 00065 00066 // modos de envio de dados 00067 00068 #define SERIAL 01 00069 #define SDCARD 02 00070 00071 // Canais analógicos 00072 AnalogIn kbd(A0); // Teclado funcional 00073 AnalogIn ainc(A1); // Entrada analógica espectro curto 00074 AnalogIn ainl(A2); // Entrada analógica espectro longo 00075 DigitalIn SD_OK(SD_DETECT,PullDown); // Card Detect 00076 //Saídas Digitais 00077 DigitalOut GV0(PTA1); //A 00078 DigitalOut GV1(PTB9); //B 00079 DigitalOut GV2(PTC17); //C 00080 00081 // Tipo Complexo 00082 typedef complex<float> Complex; 00083 00084 // Protótipos de Funções 00085 void Coleta(uint8_t mult); 00086 uint16_t reverse(uint16_t x); 00087 void fft(uint16_t N_FFT_); 00088 void gravar(uint8_t mult); 00089 uint16_t Countfile(uint8_t n); 00090 uint8_t le_teclado(void); 00091 00092 // Inicializa SD card 00093 SDFileSystem sd(SD_MOSI, SD_MISO, SD_SCLK, SD_CS, "sd"); 00094 // Inicializa LCD 00095 TextLCD lcd(RS, EN, DB4, DB5, DB6, DB7,TextLCD::LCD20x4); // rs, e, d4-d7 00096 // Inicializa Serial 00097 Serial pc(USBTX, USBRX); // tx, rx 00098 00099 // Variáveis 00100 const long N=4096; 00101 const unsigned int m = 12; 00102 //float t[N] 00103 float f[N/2+1]; 00104 double x0[N]; 00105 Complex y2[N/2+1]; 00106 bool sdsel=false; 00107 bool conectado = true;//false; 00108 char buffer[32]; // para o rtc 00109 // Interrupção de leitura da serial 00110 void SerialRecInt(void) 00111 { 00112 00113 if (sdsel==false) 00114 { 00115 unsigned char msg; 00116 uint32_t tempo=0; 00117 char UTS[11]; 00118 time_t seconds = time(NULL); 00119 strftime(buffer,32,"%d/%m/%Y %H:%M:%S\n",localtime(&seconds)); 00120 msg=pc.getc(); 00121 while(!pc.writeable()){} 00122 switch (msg){ 00123 case 'C':// Iniciar conexão 00124 { 00125 pc.printf("OK\n"); 00126 conectado = true; 00127 break; 00128 } 00129 case 'D':// Terminar conexão 00130 { 00131 pc.printf("OK\n"); 00132 conectado = false; 00133 break; 00134 } 00135 case 'E': // Espectro Estreito 00136 { 00137 // Envia espectro Curto via Serial. 00138 if (conectado) 00139 { 00140 Coleta(4); 00141 for(int n=0;n<N/2;n++) 00142 pc.printf("%8.4f;%8.4f\n",f[n],x0[n]); 00143 } 00144 break; 00145 } 00146 case 'L': // Espectro Longo 00147 { 00148 // Envia espectro Amplo via Serial. 00149 if (conectado) 00150 { 00151 Coleta(1); 00152 for(int n=0;n<N/2;n++) 00153 pc.printf("%8.4f;%8.4f\n",f[n],x0[n]); 00154 } 00155 break; 00156 } 00157 case 'R': // Relógio 00158 { 00159 pc.gets(UTS,11); // Recebe o valor de Timestamp 00160 for(int n=0;n<10;n++) 00161 { 00162 tempo = tempo * 10 + (UTS[n] -48); 00163 00164 } 00165 set_time(tempo); 00166 pc.printf("%s",buffer); 00167 break; 00168 } 00169 case 'T': // Teste 00170 { 00171 pc.printf("%s",buffer); 00172 if (SD_OK.read()) 00173 debug("Cartao SD Ok-> %d\n",SD_OK.read()); 00174 else 00175 debug("Cartao SD NOk-> %d\n",SD_OK.read()); 00176 break; 00177 } 00178 default: 00179 break; 00180 } 00181 //tm.start(); 00182 } 00183 00184 //msg = ' '; 00185 } 00186 // Leitura do teclado 00187 uint8_t le_teclado(void) 00188 { 00189 uint16_t tecla = kbd.read_u16(); 00190 if (tecla > 60000) return btnNONE; //sem tecla 00191 if (tecla > 40000) return btn5; 00192 if (tecla > 30000) return btn4; 00193 if (tecla > 15000) return btn3; 00194 if (tecla > 5000) return btn2; 00195 if (tecla >= 0) return btn1; 00196 return btnNONE; 00197 } 00198 00199 int main() 00200 { 00201 //Timer tm0; 00202 uint8_t tecla; 00203 pc.baud(115200); 00204 pc.attach(&SerialRecInt,pc.RxIrq); // Chamada de IRQ para Serial 00205 lcd.cls(); 00206 lcd.printf("TCC - MCSA - ULBRA\n"); // linha 0 00207 // debug("MCSA - Aquisição de Motor.\n\r"); 00208 // tm0.start(); 00209 while(1) { 00210 // Comando via teclado 00211 tecla=le_teclado(); 00212 lcd.locate(0,3); // aponta para linha 3 00213 lcd.printf("1- Amplo / 2- Curto"); 00214 //lcd.printf("%d",tecla); // tecla pressionada 00215 switch(tecla){ 00216 case btn1: // Espectro Longo 00217 { 00218 sdsel=true; 00219 Coleta(1); 00220 gravar(1); 00221 sdsel=false; 00222 break; 00223 } 00224 case btn2: // Espectro Curto 00225 { 00226 sdsel=true; 00227 Coleta(4); 00228 gravar(4); 00229 sdsel=false; 00230 break; 00231 } 00232 case btn3: // Limpa comando 00233 { 00234 lcd.locate(0,1); 00235 lcd.printf(" "); 00236 break; 00237 } 00238 case btn4: // Créditos 00239 { 00240 lcd.cls(); 00241 lcd.printf("ULBRA ENG. ELETRICA\n"); 00242 lcd.printf(" TCC - MCSA \n "); 00243 lcd.printf("Flavio Dutra Lencina\n"); 00244 lcd.printf("Prof. Joao D. Klein \n"); 00245 while(1) 00246 { 00247 tecla=le_teclado(); 00248 if tecla(<> btnNONE) 00249 break; 00250 wait_ms(200); 00251 } 00252 lcd.cls(); 00253 lcd.printf("TCC - MCSA - ULBRA\n"); // linha 0 00254 break; 00255 } 00256 default: 00257 break; 00258 } 00259 wait_ms(300); 00260 // tm0.reset(); 00261 // while(tm0.read_ms()<500); 00262 lcd.locate(0,2); 00263 // Verifica se há cartão SD 00264 if (SD_OK.read()) 00265 lcd.printf(" "); 00266 else 00267 lcd.printf(" Insira o Cartao SD"); 00268 00269 } 00270 } 00271 // Coleta de dados 00272 void Coleta(uint8_t mult) 00273 { 00274 Timer tm; 00275 tm.stop(); 00276 double max,z; 00277 uint8_t Ganho =0; 00278 float fs,df;//,dt; 00279 // multiplicador 00280 if(mult<1) 00281 mult=1; 00282 else 00283 mult=4; 00284 00285 // Informações para LCD 00286 00287 lcd.locate(0,1); 00288 lcd.printf(" "); 00289 lcd.locate(0,1); 00290 lcd.printf("Ajustando Ganho..."); 00291 00292 // Fazer Ajuste de ganho 00293 00294 tm.start(); // Ativa Timer 00295 while(1)//Ganho < 5) // de 0 até 5 00296 { 00297 tm.reset(); 00298 max = ainl.read(); 00299 for (int n=1;n<137;n++) 00300 { 00301 while (tm.read_us()<(Ts)); 00302 tm.reset(); 00303 z=ainl.read(); 00304 if (max < z) max=z; 00305 } 00306 // tm.stop(); 00307 //debug 00308 lcd.locate(0,2); 00309 lcd.printf("Max: %4.2f",max); 00310 if (max < 0.632) 00311 { 00312 Ganho++; 00313 if (Ganho > 5) // Ganho máx 00314 { 00315 Ganho = 5; 00316 break; 00317 } 00318 ///Saidas para PGA 00319 GV0 = Ganho & 0x01; 00320 GV1 = (Ganho & 0x02)>>1; 00321 GV2 = (Ganho & 0x04)>>2; 00322 //debug 00323 lcd.printf("%d %d %d\n", (uint8_t)GV0,(uint8_t)GV1,(uint8_t)GV2); 00324 } 00325 else 00326 break; 00327 // tm.start(); 00328 } 00329 tm.stop(); 00330 lcd.locate(0,1); 00331 lcd.printf("Coletando dados..."); 00332 // Cálculo de espectro de frequência 00333 fs= (float)1000/(Ts*mult); // frequência de amostragem 4098kHz~4096 00334 df= 1000*(fs/N); // delta de frequência 00335 f[0]=0.0001; 00336 for (int n=1;n<N/2;n++) 00337 f[n]= f[n-1]+df; 00338 tm.start(); // Retiva Timer 00339 for (long int n=0;n<N;n++){ 00340 tm.reset(); 00341 // Por enquanto Espectro longo e curto no mesmo 00342 //if (mult==1) 00343 x0[n]= ainl.read(); // espetro longo 00344 // else 00345 // x0[n]= ainc.read(); // espectro curto 00346 while (tm.read_us()<(Ts*mult)); // freq de amostragem: 4096 Hz ou 512 Hz 00347 for (int i=0;i<mult;i++) 00348 { __NOP(); 00349 __NOP(); 00350 __NOP(); 00351 //__NOP(); 00352 } 00353 } 00354 tm.stop(); // Para o Timer 00355 // Reseta Ganho 00356 GV0=0; 00357 GV1=0; 00358 GV2=0; 00359 // Ajuste de zero 00360 for (long int n=0;n<N;n++){ 00361 00362 x0[n]=x0[n]-ZRef; 00363 } 00364 //debug("Foi ate o N:%d\n ",N); 00365 00366 00367 fft(N); 00368 // Módulo da FFT 00369 for(long int n=0;n<N/2;n++) 00370 x0[n]=(double)sqrt(y2[n].real()*y2[n].real()+y2[n].imag()*y2[n].imag()); 00371 // encontra maior valor 00372 max=x0[0]; 00373 for (int n=1;n<N/2;n++) 00374 if (x0[n] > max) max =x0[n]; 00375 // Normaliza valores a 1 máx (linear) 00376 // for (int n=0;n<N/2;n++){ 00377 // x0[n]= x0[n]/max; 00378 // } 00379 00380 00381 00382 // Normaliza valores 00383 for (int n=0;n<N/2;n++){ 00384 x0[n]= 20* log10(x0[n]/max); 00385 } 00386 lcd.locate(0,1); 00387 lcd.printf(" "); 00388 00389 } 00390 00391 // A FFT por decimação de frequência 00392 void fft(uint16_t N_FFT_) 00393 { 00394 Complex u_[N_FFT_],wTable_[N_FFT_]; 00395 Complex uTmp; 00396 uint16_t bTable_[N_FFT_]; 00397 uint16_t nHalf = N_FFT_/2; 00398 Complex arg = Complex(0, -6.283185f/N_FFT_); 00399 00400 uint16_t nShift = __clz(N_FFT_) + 1; // Apenas no mbed 00401 for (uint16_t k=0; k<N_FFT_; k++){ 00402 wTable_[k] = exp(arg*(float)k); 00403 bTable_[k] = __rbit(k) >> nShift; // Apenas no mbed 00404 //bTable_[k] = reverse(k); 00405 u_[k]=x0[k]; 00406 //debug("%d ",k); 00407 } 00408 for (uint16_t stg=1; stg<N_FFT_/2; stg*=2) 00409 { 00410 uint16_t nHalf2 = nHalf*2; 00411 for (uint16_t kp=0; kp<N_FFT_; kp+=nHalf2) 00412 { 00413 uint16_t kx = 0; 00414 for (uint16_t k=kp; k<kp+nHalf; k++) 00415 { 00416 // Butterfly operation 00417 Complex uTmp = u_[k+nHalf]; 00418 u_[k+nHalf] = (u_[k] - uTmp)*wTable_[kx]; 00419 u_[k] = u_[k] + uTmp; 00420 kx = kx + stg; 00421 } 00422 } 00423 nHalf = nHalf/2; 00424 } 00425 // Last stage 00426 y2[0] = u_[0] + u_[1]; 00427 y2[0] = u_[0] + u_[1]; 00428 y2[N_FFT_/2] = u_[0] - u_[1]; 00429 for (uint16_t k=2; k<N_FFT_; k+=2) 00430 u_[k] = u_[k] + u_[k+1]; 00431 // Reorder to bit reversal 00432 for (uint16_t k=1; k<N_FFT_/2; k++) 00433 y2[k] = u_[bTable_[k]]; 00434 } 00435 // Bit reverso 00436 uint16_t reverse(uint16_t x) 00437 { 00438 uint16_t NO_OF_BITS = sizeof(x) * 8; 00439 uint16_t reverse_num = 0; 00440 for (uint16_t i = 0; i < NO_OF_BITS; i++) 00441 { 00442 if((x & (1 << i))) 00443 reverse_num |= 1 << ((NO_OF_BITS - 1) - i); 00444 } 00445 return (reverse_num >> (NO_OF_BITS-m)); 00446 } 00447 // Grava em SD Card 00448 void gravar(uint8_t x) 00449 { 00450 char arquivo[64]; 00451 if (SD_OK.read()) 00452 { 00453 // debug("Gravando em cartao SD\n\r"); 00454 lcd.locate(0,1); 00455 lcd.printf("Gravando dados..."); 00456 if (x==1) // Amplo 00457 { 00458 mkdir("/sd/Amplo", 0777); 00459 sprintf(arquivo, "/sd/Amplo/EA_Coleta%03d.csv", Countfile(1)); 00460 // pc.printf("Arquivo: %s\n\r",arquivo); 00461 } 00462 else // Estreito 00463 { 00464 mkdir("/sd/Estreito", 0777); 00465 sprintf(arquivo, "/sd/Estreito/EE_Coleta%03d.csv", Countfile(2)); 00466 } 00467 FILE *fp =fopen(arquivo,"w"); 00468 fprintf(fp,"Freq[Hz];Amplitude[dB]\r\n"); 00469 00470 for(int n=0;n<N/2;n++){ 00471 //fputc(0x0A,fp); 00472 // 00473 fprintf(fp,"%8.4f;%8.4f\r\n",f[n],x0[n]); 00474 } 00475 00476 //fputc(0x0D,fp); 00477 fclose(fp); 00478 lcd.locate(0,1);// (0,1); 00479 lcd.printf(" "); 00480 } 00481 else 00482 { 00483 //debug("Sem cartao SD.\n\r"); 00484 lcd.locate(0,1); 00485 lcd.printf("Sem cartao SD.\n"); 00486 } 00487 //tm.start(); 00488 } 00489 // Manipulação de arquivos 00490 uint16_t Countfile(uint8_t n) 00491 { 00492 struct dirent *p; 00493 uint16_t numFiles = 0; 00494 DIR * sdDir; 00495 if (n==1){ 00496 sdDir = opendir("/sd/Amplo"); 00497 } 00498 else 00499 sdDir = opendir("/sd/Estreito"); 00500 while ((p = readdir( sdDir )) != NULL) 00501 numFiles++; 00502 closedir(sdDir); 00503 return numFiles; 00504 } 00505 00506 00507 00508 00509
Generated on Sat Jul 16 2022 20:05:54 by
1.7.2