VFO(4)

LCDへの表示がうまくいったので,次はOLED(NHD-1.69-160128UGC3) に表示させてみる.
これのコントローラチップは,SEPS525
16bitごとにCSの区切りが必要なのかどうか読み切れなったが,なんとなく「当然必要でしょ」という雰囲気が感じられたので,LCDのときのようにはいかないかも… と思いながら,とりあえず同じ転送プログラムを試してみた.
やはりNG…
spi.write16() を使って1ピクセルずつ送るとOKだったので,16bitごとにCSの区切りが必要のようだ.
そこで転送プログラム以下のようにしてみた.

s2.png

ブロックサイズを16にしてやることで,16bitごとにCSがネゲートされうまくいった.

20190212_234133.jpg
しかし,CSが頻繁にネゲートされるのでその時間(1回あたり600ns程度)が加わり,転送時間が25ms程度になってしまった.
これにダイアルイメージ描画時間35msとあわせて,更新レートはおよそ60msとなった.
これくらいになると動きのスムーズさがいま一つと感じるのは否めない.
RX621のシステムでは8bitパラレル転送+描画時間20msで更新レートが約30ms程度だったので,それに比べるとかなり動きが悪く見える.

何とかしたいところだが,これ以上プログラムの最適化で何とかできるようにも思えないので,デュアルコアを活用し描画処理と転送を別のコアで行うことで速度UPを試みる.

こちらのサイトを参考にさせていただき,メインのLOOPとは別のコアで動作するもう一つのタスクを作った.

setup()内で,

xTaskCreatePinnedToCore(task0, “Task0”, 4096, NULL, 1, NULL, 0);

として,次の関数を用意すればいいようだ.

void task0(void* arg)
{
while (1)
{
//SPI転送処理
delay(1);
}
}

delay(1) がないとシステムリセットが繰り返し発生した.
よくわかっていないが,おそらくOSに処理を返す必要があるからだろうと推測.
また,同じディレイ時間にも関わらず delayMicroseconds(1000) ではNGだった.

とにかく,これでloop() とtask0() が別コアに割り当てられ同時に動く(と思う).
あとは,この2つの処理間でのデータの同期に気を付ければいい.

というわけで,
一時はあきらめて,IOピンがまだ余っているのでOLEDはパラレルでいこうか…,などと考えたが,OLEDでもSPIで更新レートを50ms以下になんとかすることができた.

もっと簡単にRX621からESP32に移行できると思っていたが,思いの外苦労してしまった.
とは言え,初めてESP32を使ったのにもかかわらず,短時間でそれなりのものが組めたのは,いろんな方がネットにUPしてくれている情報のおかげなのは間違いない.

感謝の意味を込めて今回作成したソース(VFOsys)をこちらに公開しておく(無保証,サポートなしで).
エンコーダを回せば,ダイアルが動き(動画)その周波数が出力されるだけのものなので,そこからはこのソースをベースに各々機能を追加していただければと思う.

とにかく,ようやくシステムがうまく動き出したので,次はLCDとOLEDの比較をしてみよう.