Baumkuchen’s Workshop

バイオリンと電子工作、DIY、ジョギングなど。

バイオリンタイマーの製作#3-時計IC DS1302とFFT

LCDモジュールを壊してしまったので、再度、秋月で注文しました。

部品が届くまで、出来ることをちまちまやっていきます。

baum-kuchen.hatenablog.com

時計IC制御 DS1302の確認

時計ICの作動確認です。DS1302は、2~5V作動ができるので、Aruduinoに直接接続しました。インターフェースは、I2Cもどきの独自シリアル規格なので、プログラムを自作します。

f:id:Baum_kuchen:20220110104103j:plain

ネットを探すと、

GitHub - msparks/arduino-ds1302: Arduino library for the DS1302 Real Time Clock chip

というのがありましたが、作動確認だけが目的なので、簡単なデータ読み書きプログラムを書き、年、月、日、時、分、秒をターミナルに表示させてみました。

f:id:Baum_kuchen:20220110103903p:plain

ADサンプリングとFFT処理

MICアンプの出力をAruduinoにつなげてADサンプリングしたら、結構なサンプリングレートでとれたので、FFT処理も実装してみました。

ADサンプリングのスケッチ(一部)はこれだけ(Aruduinoのサンプルスケッチを流用)。

#define MAXDATA 128
float ar[MAXDATA];
float ai[MAXDATA]; 

a= millis(); // read the analog in value: for(i=0;i<MAXDATA;i++){ sensorValue = analogRead(analogInPin); ar[i]=sensorValue; ai[i]=0.0; // map it to the range of the analog out: outputValue = map(sensorValue, 0, 1023, 0, 255); // change the analog out value: analogWrite(analogOutPin, outputValue); } b= millis();

これで、走らせたら大体20mS掛かりましたので(b-aで計算)、約6KHzのサンプリングで出来たことになりますので、まずは、十分です。

FFT処理は、Aruduinoでは厳しいのかなと思って、実装してみたら、128データだと約70mSで処理できました。意外と速いですね。データを増やせばもっと時間はかかりますが、音の認識なら1秒単位位で十分ですし、ArduinoにしろPICにしろ、スタティックRAMの容量からすると、128が限界ですので。なお、コードはこんな感じ。(theta = 2*PI/N;を入れてcallする)

void fft(int n, float theta, float ar[], float ai[])
{
    int m, mh, i, j, k;
    float wr, wi, xr, xi;

    for (m = n; (mh = m >> 1) >= 1; m = mh) {
        for (i = 0; i < mh; i++) {
            wr = cos(theta * i);
            wi = sin(theta * i);
            for (j = i; j < n; j += m) {
                k = j + mh;
                xr = ar[j] - ar[k];          
                xi = ai[j] - ai[k];
                ar[j] += ar[k];
                ai[j] += ai[k];
                ar[k] = wr * xr - wi * xi;
                ai[k] = wr * xi + wi * xr;
            }
        }
        theta *= 2;
    }
    /* ---- unscrambler ---- */
    i = 0;
    for (j = 1; j < n - 1; j++) {
        for (k = n >> 1; k > (i ^= k); k >>= 1);
        if (j < i) {
            xr = ar[j];
            xi = ai[j];
            ar[j] = ar[i];
            ai[j] = ai[i];
            ar[i] = xr;
            ai[i] = xi;
        }
    }  
}

ADサンプルとFFT処理の結果

試しに取得してみたバイオリンの各開放弦でのサンプリングとFFT処理の結果は、こんな感じになりました。 

まずは、生波形。(縦軸200=1V、横軸単位ms)

f:id:Baum_kuchen:20220110180651p:plain

f:id:Baum_kuchen:20220110180714p:plain

A線、D線、E線は、基本周波数が良くわかりやすいですが、G線はよく見ないと分りずらいです。単に弾き方が悪いのか、楽器が安いせいかもしれませんが。
次は、FFT処理をした結果です。(縦軸は、fft()関数からの実部、虚部、横軸はHz)

f:id:Baum_kuchen:20220110181234p:plain

f:id:Baum_kuchen:20220110181301p:plain

やはり、A線、D線、E線は、スペクトルのピークが分かりやすいです。ただし、どれも高調波成分に比べ、基本周波数のレベルが小さいということが分かりました。また、サンプリング数=128だと、今回の設定であは周波数分解能=50Hz(6K÷128≒50Hz)となるので、ピーク周波数が生データの値とも異なります。(当然、窓関数処理なども入れてないので、データの端の影響もあるかと)

一方、G線は、やはりスペクトルとしても分りずらいですね。一応、250Hzのところに僅かなピークがありますが、G線の音と分かっていなければ無視するでしょうね。ここら辺は、もう少し、正確なデータ取得、処理をして確認していくことにします。

いずれにしろ、Aruduinoレベルで、バイオリンの音のサンプリング及びFFT処理がそれなりの時間でできるということと、ある程度、スペクトルも分析できそうだということが分かっただけでも良かったです。

今後の計画

残りの作業。次は、ADサンプリングとFFT処理バイオリンの音判別をトライします。また、大体の要素がそろってきたので改めて全体の設計もしていこうかと。あと、制御基板をどうするかですが、念のためSeeeduinoもポチって置きました。

  • AD&サンプリング
  • FFT処理(信号処理をもう少し工夫)
  • 制御基板作成
  • 省電力化検討(スリープ機能など)
  • 簡易オシロ(波形、レベル)
  • 簡易スペアナ
  • 音判別(簡易版、精細版)
  • 練習時間タイマー(本命)
  • 簡易チューナー(おまけ)
  • 時計(おまけ)(時刻設定)

よろしければ、お付き合いください。

(2022.1.10 更新)