ほぼ昨日のソースと同様、違うのは主に関数でデータを取り込む代わりに
data[i] = (analogRead(mic) >> 2) - 128;としているところ。
マイクは秋月の「高感度マイクアンプキット 500円」。まずこれを組み立てたのですが…ハンダがランドに乗ってくれなくてまたしても苦戦。「こんだけ熱が回っちゃうとマイク壊れているかもしれないなぁ…」と思いつつ、オシロにつないでみると一応声を拾っている。良かった良かった。
FFTは昨日も使った8bit fft。で、結果なのですが…ピークtoピークのアナログ波形でも出力は0-50程度、どうも今ひとつダイナミックレンジが狭い感じ。また、人間の声についてはそれなりに拾っていますが、ビープ音についてはレンジを越えてしまう様子。128点のサンプリングに約15mSかかっているので約8500回/秒、その半分として4.2Khzは拾っているはずなのですが。うーん。
さて、今回は芸無くSerialへの出力でしたが、次回は何かもっと見やすく表示してみます。
#include <fix_fft.h>
#include <Time.h>
#define N_SAMPLES 128
char im[N_SAMPLES]; // 虚数部
char data[N_SAMPLES]; // 入力/実数部
char buf[20]; // 文字出力バッファ
int mic = 0; // マイク接続ポート
int cnt = 0; // ループカウンタ
int prevSec = 0; // 秒カウント
void setup() {
Serial.begin(115200);
analogReference(DEFAULT);
prevSec = -1;
}
void loop(){
int i;
unsigned long mil;
cnt ++;
mil = millis();
for (i = 0; i < N_SAMPLES; i++) {
// 音声を読み込み
data[i] = (analogRead(mic) >> 2) - 128;
// 虚数部をクリア
im[i] = 0;
}
// 128個の読み込み時間を計測
mil = millis() - mil;
// FFT
fix_fft(data, im, 7, 0); // full scale 2^7=128, FFT mode
for (i = 0; i < N_SAMPLES / 2; i++) {
data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);
}
// 1秒ごとのループ回数と128個の読み込み時間(mSec)を表示
int s = second();
if (prevSec != s) {
prevSec = s;
data[0] = cnt; // 0をcnt出力に流用
data[1] = mil; // 1をmil出力に流用
dispData("Results : ", data, N_SAMPLES / 2); // 結果出力
Serial.println("");
cnt = 0; // カウンタをクリア
}
}
void dispData(char *inMsg, char *inData, int inN) {
Serial.print(inMsg);
for (int i = 0; i < inN; i++) {
sprintf(buf, "%5d", inData[i]);
Serial.print(buf);
}
}
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。