やはり、気になることは気になるもので、VUメーターのスケッチのなかのFFT(オーディオFFT)が動作しなかったので、少し調べてみることにしました。OLEDMeter.inoの中に記載されているFFTは全く同じ物が、https://github.com/GadgetReboot/Arduino/tree/master/Uno/Spectrum_Analyzer ArduinoサンプルとしてUPされていました。99%全く同じスケッチの様です。まずはこれで動くのかを確かめました。既にOLEDMeter.inoにてFFT用のインクルードファイルはインストール済みです。(#include "fix_fft.h")
単に接続もOLEDMeter.inoと全く同じで大丈夫です。コンパイルも問題なくすみ、書き込みです。問題なくスペクトラムアナライザーが動きました。ということは、OLEDMeter.inoの中に記載されているものはほぼ同じスケッチです。となると、各メーターモード選択はできていて、スペクトラムアナライザーだけが上手く選択できないのは、選択するルーチンが上手くないということが疑わしくなります。それで、スケッチを調べて見ました。選択はvoid select_dspMode() で行っています。すぐ分かりました。選択子にスペクトラムアナライザーが無いのです。これでは、絶対スペクトラムアナライザーが選択されません。
void select_dspMode() {
if (digitalRead(RecXmt_select) == LOW) {
if (digitalRead(Xmt_Mode_select) == LOW)dsp_Mode = _SWR;
else dsp_Mode = _POWER;
}
else if (digitalRead(Rec_Mode_select) == LOW){
dsp_Mode = _VU_MTR;
else dsp_Mode = _S_MTR;
}
if (digitalRead(Xmt_Mode_select) == LOW)dsp_Mode = _SWR;
else dsp_Mode = _POWER;
}
else if (digitalRead(Rec_Mode_select) == LOW){
dsp_Mode = _VU_MTR;
else dsp_Mode = _S_MTR;
}
上記では上手くありませんので、仕様を少し変えます。トランシーバーを想定しての仕様変更です。通常は、受信状態から始まるので、スタート時はSメーター表示です。(もとはVUメーター)ここで、スペアナも受信状態で使いたい(相手の受信音から帯域を確認したりする。勿論送信時もありますが、送信時のスペアナは先ず今は考え無いことにします。)ので、SメーターとスペクトラムアナライザーはSWで切り替え出来るようにする。VUメータは元のスペアナSWと入れ替える。この時はSメーターとSWがONでVUメーターという具合です。受信信号の入力レベルをVUメーターで確認する感じです。スペクトラムアナライザーの入力はVUメーターと一緒になっている仕様なので、丁度うまい具合になります。
これをvoid select_dspMode() に反映させます。次のようにスペクトラムアナライザーも選択されるようにして、書き換えました。
void select_dspMode() {
if (digitalRead(RecXmt_select) == LOW) {
if (digitalRead(Xmt_Mode_select) == LOW)dsp_Mode = _SWR;
else dsp_Mode = _POWER;
}
//else if (digitalRead(Rec_Mode_select) == LOW){
else if (digitalRead(Alt_Mode_select) == LOW)
dsp_Mode = _VU_MTR;
else if (digitalRead(Rec_Mode_select) == LOW)
dsp_Mode = _ALT;
else
dsp_Mode = _S_MTR;
}
if (digitalRead(RecXmt_select) == LOW) {
if (digitalRead(Xmt_Mode_select) == LOW)dsp_Mode = _SWR;
else dsp_Mode = _POWER;
}
//else if (digitalRead(Rec_Mode_select) == LOW){
else if (digitalRead(Alt_Mode_select) == LOW)
dsp_Mode = _VU_MTR;
else if (digitalRead(Rec_Mode_select) == LOW)
dsp_Mode = _ALT;
else
dsp_Mode = _S_MTR;
}
void setup()も追加が若干ありました。//add の部分です。
void setup() {
Serial.begin(9600); //add
// analog input for outside source
pinMode(s_meter_input, INPUT); //A0
pinMode(vu_meter_input, INPUT); //A1
pinMode(fwd_pwr_input, INPUT); //A2
pinMode(rev_pwr_input, INPUT); //A3
pinMode(RecXmt_select, INPUT_PULLUP); //10
pinMode(Xmt_Mode_select, INPUT_PULLUP); //11
pinMode(Rec_Mode_select, INPUT_PULLUP); //12
pinMode(Alt_Mode_select, INPUT_PULLUP); //13
display.begin(SH1106_SWITCHCAPVCC, 0x3C); // needed for SH1106 display
//display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // needed for SSD1306 display
display.setTextSize(1); //add
display.setTextColor(WHITE); //add
display.clearDisplay(); // clears display from any library info displayed
analogReference(DEFAULT); //add
//display.invertDisplay(1); // option to invert display to black on white
//dsp_Mode = _VU_MTR; // start with default vu meter
dsp_Mode = _S_MTR;
//dsp_Mode = _ALT;
}
Serial.begin(9600); //add
// analog input for outside source
pinMode(s_meter_input, INPUT); //A0
pinMode(vu_meter_input, INPUT); //A1
pinMode(fwd_pwr_input, INPUT); //A2
pinMode(rev_pwr_input, INPUT); //A3
pinMode(RecXmt_select, INPUT_PULLUP); //10
pinMode(Xmt_Mode_select, INPUT_PULLUP); //11
pinMode(Rec_Mode_select, INPUT_PULLUP); //12
pinMode(Alt_Mode_select, INPUT_PULLUP); //13
display.begin(SH1106_SWITCHCAPVCC, 0x3C); // needed for SH1106 display
//display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // needed for SSD1306 display
display.setTextSize(1); //add
display.setTextColor(WHITE); //add
display.clearDisplay(); // clears display from any library info displayed
analogReference(DEFAULT); //add
//display.invertDisplay(1); // option to invert display to black on white
//dsp_Mode = _VU_MTR; // start with default vu meter
dsp_Mode = _S_MTR;
//dsp_Mode = _ALT;
}
下記のOLEDMeter.ino中のスケッチのvoid dsp_FFT()ルーチンでの変更箇所です。あくまでもオリジナルのspectrum.inoと同じにしただけです。元のプログラムで問題ないかは、確認してません。オリジナルといっしょであればいいので!
void dsp_FFT() {
int min = 1024, max = 0; //set minumum & maximum ADC values
for (i = 0; i < 128; i++) { //take 128 samples
val = analogRead(vu_meter_input); //get audio from Analog 1
//data[i] = val / 2 - 128; //each element of array is val/4-128
data[i] = val / 4 - 128; //each element of array is val/4-128
im[i] = 0; //
if (val > max) max = val; //capture maximum level
if (val < min) min = val; //capture minimum level
};
fix_fft(data, im, 7, 0); //perform the FFT on data
display.clearDisplay(); //clear display
for (i = 1; i < 64; i++) { // In the current design, 60Hz and noise
// int dat = 3 * sqrt(data[i] * data[i] + im[i] * im[i]); //filter out noise and hum
int dat = sqrt(data[i] * data[i] + im[i] * im[i]);//filter out noise and hum
display.drawLine(i * 2 + x, ylim, i * 2 + x, ylim - dat, WHITE); // draw bar graphics for freqs above 500Hz to buffer
};
//display.setTextColor(WHITE);//コメント化
display.setCursor(0, 0); //set cursor to top of screen
display.print(" Audio Spectrum"); //print title to buffer
display.display(); //show the buffer
}
int min = 1024, max = 0; //set minumum & maximum ADC values
for (i = 0; i < 128; i++) { //take 128 samples
val = analogRead(vu_meter_input); //get audio from Analog 1
//data[i] = val / 2 - 128; //each element of array is val/4-128
data[i] = val / 4 - 128; //each element of array is val/4-128
im[i] = 0; //
if (val > max) max = val; //capture maximum level
if (val < min) min = val; //capture minimum level
};
fix_fft(data, im, 7, 0); //perform the FFT on data
display.clearDisplay(); //clear display
for (i = 1; i < 64; i++) { // In the current design, 60Hz and noise
// int dat = 3 * sqrt(data[i] * data[i] + im[i] * im[i]); //filter out noise and hum
int dat = sqrt(data[i] * data[i] + im[i] * im[i]);//filter out noise and hum
display.drawLine(i * 2 + x, ylim, i * 2 + x, ylim - dat, WHITE); // draw bar graphics for freqs above 500Hz to buffer
};
//display.setTextColor(WHITE);//コメント化
display.setCursor(0, 0); //set cursor to top of screen
display.print(" Audio Spectrum"); //print title to buffer
display.display(); //show the buffer
}
上記の変更を行い、コンパイルしました。変なことはしていないので、問題なくパスが通ります。書き込みも問題なく終わりました。さて結果は、受信状態のSメーター表示時にSWでオーディオ帯域のスペクトラムアナライザーがちゃんと表示されました。成功です。SメーターとFFTがSWで切り替わります。受診時の信号をFFTできる仕様通りに動いてくれました。VUメーターもSWで受診時のみ受信信号レベル確認(FFT入力と同じ)が出来るように表示されます。送信時は今までどおり、Powerメーターが表示され、送信時のみSWでVSWRメーターが表示され動きます。各表示動作を動画に撮りました。
スケッチ修正後のOLEDMeter.ino の切り替え動作確認
気になっていた所が解決しました。マーティーの工房日記にもありましたが、ArduinoUNOは大きいので次は、ということで マーティーさんとは違い、私のは少し大きいですが、ArduinoNANOでやってみましょうか?といったところです。ESP32 DivKitCでもいずれ対応してみたい気はあります。
つづく?