#define SAMPLEN 512 #include #include #include #include "fftfloat.c" LiquidCrystal lcd(4,5,6,7,2,9,3); float calkshindo(float (*fx)[2],float (*fy)[2],float (*fz)[2],float ftime); float dummycal(float (*fx)[2],float (*fy)[2],float (*fz)[2],float ftime); void rsort(float arr[], int left, int right); void adsconv(); int up=0;//upサンプルの現在位置 int uf=0;//uf最大位置 float ref[]={0xc05900,0xc07800,0xd94b00};//基準値 float u[SAMPLEN][3];//測定値をSAMPLEN個保存 float wx[SAMPLEN][2]; float wy[SAMPLEN][2]; float wz[SAMPLEN][2]; float XX[SAMPLEN][2]; float synthe[SAMPLEN]; char adcsel=0;//変換中の軸 float k[3];//3軸の測定値が揃うまで一時保存 int kt[3];//テンポラリ char p[3];//3軸の測定値が揃ったかどうかのフラグ unsigned long stmp;//サンプリングを開始した時刻 unsigned long st;//SAMPLEN個のサンプリングに要した秒数 float (*fx)[2];//時間軸サンプル float (*fy)[2]; float (*fz)[2]; void timer_interrupt() { int rch0,rch1,rch2; static char intflag=0; static float lc[]={-0.6,-0.1,0.4,0.9}; if(intflag==1){return;} intflag=1; if (digitalRead(PIN_P20)) { intflag=0; return; } for(int i=0;i<4;i++){ lc[i]+=0.002; if(lc[i]>0.99){lc[i]=-1;} } analogWrite(PIN_LED0, pow(lc[0],4)*255); analogWrite(PIN_LED1, pow(lc[1],4)*255); analogWrite(PIN_LED2, pow(lc[2],4)*255); analogWrite(PIN_LED3, pow(lc[3],4)*255); SPI.transfer(0x10); // Data Read Command rch0 = SPI.transfer(0xff); // NOP:ffh rch1 = SPI.transfer(0xff); rch2 = SPI.transfer(0xff); if(rch0>0x7f){ rch0-=0x80; }else{ rch0+=0x80; } k[adcsel]=(float)((rch0<<16)|(rch1<<8)|rch2); kt[adcsel]=(rch0<<8)|rch1; p[adcsel]=1;//軸フラグセット if(p[0]&&p[1]&&p[2]){ k[0]=(k[0]-ref[0])*980.0/(ref[2]-ref[0]);//galに変換 k[1]=(k[1]-ref[1])*980.0/(ref[2]-ref[1]); k[2]=(k[2]-(ref[0]+ref[1])/2.0)*980.0/(ref[2]-(ref[0]+ref[1])/2.0)-980.0; up++;//現在位置を進める if(up>=SAMPLEN){up=0;st=timer_get_ms()-stmp;stmp=timer_get_ms();}//超えたら0に戻る u[up][0]=k[0];u[up][1]=k[1];u[up][2]=k[2];//測定値を入れる if(uf=SAMPLEN ){ for(i = 0; i < SAMPLEN-up; i++){//ループになってる配列を整形する fx[i][0]=u[i+up][0];fx[i][1]=0; fy[i][0]=u[i+up][1];fy[i][1]=0; fz[i][0]=u[i+up][2];fz[i][1]=0; } for(i = SAMPLEN-up; i < SAMPLEN; i++){ fx[i][0]=u[i+up-SAMPLEN][0];fx[i][1]=0; fy[i][0]=u[i+up-SAMPLEN][1];fy[i][1]=0; fz[i][0]=u[i+up-SAMPLEN][2];fz[i][1]=0; } kshindo=calkshindo(fx,fy,fz,((float)st)/1000);//震度計算 if(kshindo>=0.5){ digitalWrite(PIN_P21, 1); }else{ digitalWrite(PIN_P21, 0); } p=str; p += sprintf(p,"X:%04X Y:%04X ",kt[0],kt[1]); lcd.setCursor(0,0); lcd.print(str); p=str; p += sprintf(p,"Z:%04X k%1.1f",kt[2],kshindo); lcd.setCursor(0,1); lcd.print(str); } } float calkshindo(float (*fx)[2],float (*fy)[2],float (*fz)[2],float ftime){ float hz_i,avex,avey,avez,kshindo,a; float y,f,filter; int i; hz_i=1/ftime;//1番目の要素の周波数 avex=0;avey=0;avez=0; //平均を減算 for(i = 0; i < SAMPLEN; i++){ avex+=fx[i][0]; avey+=fy[i][0]; avez+=fz[i][0]; } avex/=SAMPLEN; avey/=SAMPLEN; avez/=SAMPLEN; for(i = 0; i < SAMPLEN; i++){ fx[i][0]-=avex; fy[i][0]-=avey; fz[i][0]-=avez; } fft(SAMPLEN,fx,wx,XX);//fft変換 fft(SAMPLEN,fy,wy,XX); fft(SAMPLEN,fz,wz,XX); for(i = 0; i < SAMPLEN; i++){ if(SAMPLEN/2 pivot) i++; while (arr[j] < pivot) j--; if (i <= j) { tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; i++; j--; } }; /* recursion */ if (left < j) rsort(arr, left, j); if (i < right) rsort(arr, i, right); }