チーム16A3

課題名

アベレージング・フィルタ

研究者名

3年14組19番 杭田知樹
3年14組21番 駒﨑淳

概要

PSoCのLCDディスプレイ上に矩形波を表示させる。
スイッチ2を押すとアベレージング・フィルタがかかる。
スイッチ3を押すとフーリエ変換によってスペクトルが表示される。

アベレージング・フィルタ

LCDディスプレイを16分割し、
[0,0,0,0,16,16,16,16,0,0,0,0,16,16,16,16]
の矩形波を作った。
スイッチ2を押すと、左から順に隣り合う4項の平均をとる操作を1つずつずらしながら進めていく。
そしてLCDディスプレイにその計算結果を出力する。

フーリエ変換

スイッチ3を押すと、もとの矩形波やアベレージング・フィルタにかけた後の波の係数列を分析する。
そしてフーリエ変換を行い、波のスペクトルを表示する。
アベレージング・フィルタを通した後の波のスペクトルが正しく表示されるときとされない時がある。
スペクトル表示後に時間が経つと元の波を表示する。

ソースコード

main.c

...

#include<device.h>
#include<stdio.h>
#include <math.h>

void average(double a[16],double b[16]){
 int i;
  for(i=0;i<16;i++){
      b[i]=(a[i]+a[(i+1)%16]+a[(i+2)%16]+a[(i+3)%16])/4;
  }}

void display(double a[16]){
 int i;
  for(i=0;i<16;i++){
      LCD_Char_1_DrawVerticalBG(1,i,1,a[i]);
      if(a[i]>8){
          LCD_Char_1_DrawVerticalBG(0,i,1,a[i]-8);
      }
  }}

void main()
{

 double a[16] = {1,1,1,1,16,16,16,16,1,1,1,1,16,16,16,16};//矩形波
   double b[16];
  double c[16];
  int i;
  int j;
  unsigned t;
  
  LCD_Char_1_Start();
  LCD_Char_1_ClearDisplay();

  for(;;)
   {
      //SW2 AVE
      if(!SW2_Read()){
          LCD_Char_1_ClearDisplay();
          for(i=0;i<16;i++){
              b[i]=a[i];
          }
          average(b,a);
          while(!SW2_Read()){
              display(a);
          }
      }
      
      //SW3 FFT
      else if(!SW3_Read()){
          for(j =0;j<16;j++)
            c[j] = a[j];
          LCD_Char_1_ClearDisplay();
          FFT(1,4,a,b);
          for(j=0;j<8;j++) {
              LCD_Char_1_DrawVerticalBG(1,j,2,a[j]*16);
          }
          for(t = 0; t < 1600000; t++);
          LCD_Char_1_ClearDisplay();
          for(j = 0; j < 16; j++)
            a[j] = c[j];
      }
      
      else{
          display(a);
      }

  }
}

/* [] END OF FILE */
fft.c

...

#include <math.h>
#define N_points 64 //number of points 
#define exponent log(64)/log(2) //log2(N_points); for N_points=64 -> exponent=6

double mod[N_points]={0}; //arrays
double data_re[N_points]={0};
double data_imm[N_points]={0};

void FFT(int dir,long m,double *x,double *y)
{
// dir: forward (=1) o inverse (!=1) transform; 
// m exponent;

long n,i,i1,j,k,i2,l,l1,l2;
double c1,c2,tx,ty,t1,t2,u1,u2,z;

/* Calculate the number of points */
n = 1;
for (i=0;i<m;i++) 
n *= 2;

/* Do the bit reversal */
i2 = n >> 1;
j = 0;
for (i=0;i<n-1;i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}

/* Compute the FFT */
c1 = -1.0; 
c2 = 0.0;
l2 = 1;
for (l=0;l<m;l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0; 
u2 = 0.0;
for (j=0;j<l1;j++) {
for (i=j;i<n;i+=l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1; 
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1) 
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}

/* Scaling factor for forward transform */
if (dir == 1) {
for (i=0;i<n;i++) {
x[i] /= n;
y[i] /= n;
}
}
}

/* [] END OF FILE */

考察

アベレージング・フィルタは足して割るだけなので簡単に実装できた。
しかしフーリエ変換の実装は完全に上手くはいかなかった。
もとの波を関数ではなく配列に数値を代入して作ったので、フーリエ変換に当てはめるのが難しかった。

  • 最終更新:2016-05-09 16:52:23

このWIKIを編集するにはパスワード入力が必要です

認証パスワード