2026年3月1日日曜日

WaveGene > WaveSpectra - フィルタ特性確認

ESP32によるFIRフィルタをWaveGene・WaveSpectra 使って特性確認行いました。 WaveGeneから1・2・4KHz又はスイープ信号出力→FIRフイルタ→WaveSpectra FFT表示による特性確認。下記サイトのFIRフィルタ(カットオフ周波数3kHz)を使用しました。 







参考サイト
●github.com/JR3XNW



ブロック図








回路図
















WaveGene 1・2・4KHz信号出力























WaveSpectra (ESP32によるFIRフィルタ無)




















WaveSpectra (ESP32によるFIRフィルタ有)





















WaveGene スイープ信号出力






















WaveSpectra - ESP32によるFIRフィルタ無)


























WaveSpectra - ESP32によるFIRフィル有




















プログラム Arduino IDE【ボード:ESP32 Dev Module】

#include <Arduino.h>

const int dac_Pin = 25; //Audio DAC output
const int adc_Pin= 32; //I Signal ADC

//FIR Cutoff-3KHz LPF
// https://github.com/JR3XNW/pico-Program-Lab/blob/main/Filter_sweep_test_SpectrumDisplay_FIR.inoD
const int filterLength = 31; // Number of filter taps.
float filterBuffer[filterLength] = {0.0};
float firCoeffs[filterLength] = { // Put the FIR filter coefficients here.
   0.001695,0.001201,-0.000905,-0.004228,-0.005427,0.0,
   0.011365,0.018584,0.00825,-0.021236,-0.048939,-0.03959,
   0.029858,0.145107,0.254511,0.299507,0.254511,0.145107,
   0.029858,-0.03959,-0.048939,-0.021236,0.00825,0.018584,
   0.011365,0.0,-0.005427,-0.004228,-0.000905,0.001201,0.001695
};

int bufferIndex = 0;

// Update to FIR filter function
float firFilter(float input) {
  filterBuffer[bufferIndex] = input; //result = I_signal - Q_signal;
  bufferIndex = (bufferIndex + 1) % filterLength;
  float sum = 0.0;
  for (int i = 0; i < filterLength; i++) {
    int index = (bufferIndex - i + filterLength) % filterLength;
    sum += filterBuffer[index] * firCoeffs[i];
  }
  return sum;
}

//IIR Cutoff-3KHz LPF
//https://github.com/JR3XNW/pico-Program-Lab/blob/main/Filter_sweep_test_SpectrumDisplay_IIR.ino
// フィルターの係数 (2次のバターワースフィルター)

const int filterOrder = 2;
double b[filterOrder + 1] = { 0.03478604, 0.06957207, 0.03478604 }; // 係数b
double a[filterOrder + 1] = { 1.0, -1.40750534, 0.54664949 }; // 係数a

double filterBufferX[filterOrder + 1] = {0.0};
double filterBufferY[filterOrder + 1] = {0.0};

// IIRフィルターの実装
double iirFilter(double input) {
  // 入力をバッファに追加
  for (int i = filterOrder; i > 0; i--) {
    filterBufferX[i] = filterBufferX[i - 1];
    filterBufferY[i] = filterBufferY[i - 1];
  }
  filterBufferX[0] = input;

  // フィルター出力の計算
  double output = 0.0;
  for (int i = 0; i <= filterOrder; i++) {
    output += b[i] * filterBufferX[i];
    if (i > 0) {
      output -= a[i] * filterBufferY[i];
    }
  }
  filterBufferY[0] = output;

  return output;
}

void setup(){    
  Serial.begin(115200);    
  pinMode(dac_Pin, OUTPUT);
  pinMode(adc_Pin, INPUT);
}
void loop(){  
  float adc=0;  
  adc = analogRead(adc_Pin);  
  adc = (adc / 2047.5)- 1.0; //adc信号変換 -1~1  
  //Serial.println(adc);  //シリアルプロッタ
  adc = firFilter(adc);   //firフィルタ
  //adc = iirFilter(adc); //iirフィルタ
  uint8_t audio = (uint8_t)((adc + 1.0)* 127.5); //audio信号変換 0~256
  //Serial.println(audio);  
  dacWrite(dac_Pin, audio); //dac Audio 出力
  }


0 件のコメント:

コメントを投稿

WaveGene - 多機能 高精度 テスト信号発生ソフト

 WaveGene - 多機能 高精度 テスト信号発生ソフトを使ってみました。  ●サイン波、矩形波、三角波、ノコギリ波、パルス列、パルス列(+-)、ホワイトノイズ、ピンクノイズ、M系列ノイズ(MLS) ●変調(AM、DSB、FM、PM、PWM) ●スイープ(周波数、振幅、位相)...