● 実験テーマ98
「dsPIC33F_簡易OLEDオーディオFFTアナライザの実験」
(OLEDを使った小型の、簡易オーディオFFTアナライザの実験です。)
※ 2017.11.10
→ 1回目の更新です。
小型OLED_オーディオ・FFTアナライザとして使える形にまとめました。
11月3日からの記事を参照してください。
以下、この実験の顛末記です。
■ 2017.10.28
・前回のテーマで、PIC24Fでの、OLED表示テストは上手く行った。
今回は、以前作った、dsPIC33F_簡易オーディオ・FFTアナライザ(実験テーマ76及び、実験テーマ77参照のこと)
のハードを流用し、液晶表示用コネクタの部分に、OLED冶具ケーブルを接続して、0.96"OLEDによる、小型の
簡易オーディオ・FFTアナライザを目指しての実験をしてみました。
・ソフトは、過去の自作ソースがあるので、それを基に作成してみた。
HEX書込んで、デバッグ開始。
目盛とメッセージは表示するが、FFT表示の動きがメチャクチャ。
調査を始める。
FFT表示は、dot描画関数と、line描画関数を使っている。
現在のOLEDライブラリでの、SRAM(SegmentBffer)上の原点は、表示RAM(GDDRAM)と同じ左上としてある。
一方、過去のモノクロ液晶ライブラリでは、真逆の左下(数学的に素直な原点位置)にしてある。
数学的に素直な原点位置(左下)にした方が、FFT表示のバーのレベルと、ypos座標の大小の関係が
直感的になり解り易いので、以下の方法(後閑さん方式)により座標変換することにした。
dot描画関数の中で、page setと、bit(dot) setをしているところで以下のように座標変換することにした。
// unsigned char page = y0/8; // y座標を、セグメントのピクセル数=8で割った商が、ページNoになる。
unsigned char page = 7-(y0/8);
unsigned char b;
// b = 0x01 << (y0%8); // y座標を、セグメントのピクセル数=8で割った余りが、セグメント(バンク)内の、ドット位置になる。
b = 0x01 << 7-(y0%8);
・これで動きが一見まともになったが以下がNG
@ 音楽ソースのスピードに表示が十分追従していない。(サンプルFが高くなると顕著)→ 下の写真だと判りにくいかもしれないが・・
A 何故か、音楽ソースの動きが激しくなると、軸線+目盛+キャラクタ文字が浸食される。
・OLEDの制御がSPIだと、転送スピードを十分上げられない?
GLCDのように、8bitバス制御なら問題ないのかな?
今の転送クロックのスピードは、前に自作ロジアナで実測したPIC24Fでのデータによると、約33kHz(30uS周期)、単純に、8bitで
1データ転送すれば、これだけで240uS掛かってしまう。
単純に考えて、転送時間 <
サンプル周期の関係が成り立たなくなる。
そこで、SSD1306のSPIスペックを見てみたら、クロック周期は、100nSmin(10MHz)まではOKのようだ。(クロック幅=20nSmin)
現在は、クロック生成のソフト記述のところで、Delay1u(3);と、Delay1u(6);を入れているが、ここを
Nop();1個+Nop();2個にしてみた。(Nop();1個≒50nS(Fcy=40MHz時)なはずなので、周期≒150nSになってるはず。未確認だが・・)
これで追従性は良くなったが、相変わらず、音楽ソースの動きが激しくなると、軸線+目盛+キャラクタ文字が浸食される。
ただ単一波形を手で入力し、Fを可変する程度の動きであれば、軸線+目盛+キャラクタ文字が浸食されることは無い。
■ 2017.11.1
・たぶん下の目盛とキャラクタが、浸食されるのは、割り込み周期内に全てのFFT演算処理が終わってないからだと
思われる。
出来るだけ無駄な記述を省こうと、ソースを眺めていたら、以下のことに気付く。
GLCDでやっていた時と同じに、Line関数の中での、座標指定制限はやめ、
olcdData[i]から導いた、yposの後に、ypos座標のみの制限判断をし、Line関数を実行するようにしてみたら、
音楽ソースの動きが激しくなると、軸線+目盛+キャラクタ文字が浸食される現象は無くなった。
このように記述しただけです。
/// 最初のFFT描画抜粋(割込み関数側)
for(i=0;i<128;i++){ // 512ポイントFFTだが、液晶の表示分解能が、X方向128dotなので、ループ数=128
ypos= 10 + oledData[i]/3;
if(ypos >= 64) ypos= 63; // 171101
Draw_Line(i, 10, i, ypos, WHITE);
ypos_old[i]= ypos; // 今回のY座標データを、オールド配列に転送し次回の比較要素とする
}
/// Line描画関数側(冒頭部分抜粋)
void Draw_Line(int x0, int y0, int x1, int y1, char color){
/*
///// 171101 関数内での座標制限を削除
/// 座標制限
if(x0 > 127) x0 = 127;
if(x1 > 127) x1 = 127;
if(y0 > 63) y0 = 63;
if(y1 > 63) y1 = 63;
if(x0 == x1 && y0 == y1) return;
*/
・FFT表示処理は、Line関数を最大128回実行するので、関数内に座標制限があると、毎回その制限判断処理が
行われ処理時間が増える方向になる。
この処理(y座標についてのみ)を外で行った方が有利と思われる。
・これで真面にOLEDに、FFT表示させることが出来た。
表示例の写真については、このページトップの写真を参照してください。
尚、OLEDライブラリについては、dsPIC33F専用に書直しました。(といっても殆ど、PIC24Fの時と同じですが・・)
PIC24F_OLEDライブラリの時使っていた、水平線描画関数・垂直線描画関数・四角形描画関数は、
ドット描画関数とライン描画関数があれば全て描画可能なので削除しました。
---<ここから、追試:「小型OLED_オーディオ・FFTアナライザとして使える形にまとめる」の記事>-------------------------------------
■ 2017.11.3
・最初は、秋月の小サイズ・ユニバーサル基板:Cタイプ=72x47mmを、2枚使い、内1枚は、何時もの単3電池2本+DC/DC電源
にしようと考えました。
・水魚堂で回路図作成〜部品手配済ます。
■ 2017.11.7
・秋月よりパーツ到着。
簡単に部品配置を検討。
■ 2017.11.9
・部品実装が済んだ。
・いつもの電源ショート・チェックと無負荷でのVCC, AVCCを確認し、IC類を実装し、HEXを書込んだ。→ OK
・単3エネループx2本=公称1.2V*2=2.4V+昇圧式の秋月DC/DCモジュール:3.3V_STEPUP_DIP_VER2
構成の
出力3.3Vで直接駆動をしてみたが、OLEDをこの構成で駆動するのは厳しいようで、最初は起動したが、
直ぐに、DC/DC出力が、3V以下(2.8V位)に下がり駆動しなくなる。
このDC/DCは、VIN=2.45Vで、200mAほどしか電流を流せない。
VCCの負荷電流は、テスターの実測で、70mAmaxであったが、立ち上げ時のピーク電流は、たぶん100mA以上
流れていると思われる。
BAT入力では、DC/DCの効率が関係してくるので、出力の1.5倍(過去の実測より)位のIbatが流れていると思われる。
Ibat=150mAほどになるので駆動不足になっていると考える。
電池駆動は早々諦め、音源(WAVPlayer等)の、ICSPピンから、Vcc=3.3Vを供給して使う簡易的で一番確かな方法
に変更した。
ただ、電池が有ると、それが重石が代わりになって、座りが安定してよかったのだが、無くなったので
ベーク板の端切れで、足を2個作り、それを金属製のスタッドに取り付けて何とか座りを良くさせてみた。
<回路図>
・こちらから、どうぞ→ 「OLED_FFTアナライザ実験」
「小型OLED_FFTアナライザ」 ※ 171110: 使える形にまとめた版(ソース類は、下記テスト版のもので動きます。)
<最終ソース及びヘッダファイル>
・こちらから、どうぞ→ dsPIC33F_OLED_FftAnalyzer_Test.c
///
OLEDライブラリ
SSD1306_OLEDlib_dsPIC33F.c
SSD1306_OLEDlib_dsPIC33F.h
///
アスキーフォント
ASCII_font.h
※ プロジェクトを組む時に、DSPライブラリの登録が必要になります。
以下に、IDEのプロジェクト・ウインドウのキャプチャを示しましたので、参考にしてください。
尚、IDEは、MPLAB IDE v8.60を使っています。