ESP32 OLEDディスプレイ(SPI接続)を使う

OLEDはどれを使う?

Amazon.co.jp: ACEIRMC 2.4インチ 128x64 OLED LCDディスプレイモジュール SSD1309 7ピン SPI/IIC I2C シリアルインターフェース Arduino UNO R3用(ブルー) : 産業・研究開発用品
Amazon.co.jp: ACEIRMC 2.4インチ 128x64 OLED LCDディスプレイモジュール SSD1309 7ピン SPI/IIC I2C シリアルインターフェース Arduino UNO R3用(ブルー) : 産業・研...

0.96インチって小さすぎないか!?
という疑問がモクモク湧くけれども、それでもOLEDタイプの液晶モニタは0.96インチが多い。

…けど、やはり小さい気がするので、2.4インチをテスト採用。

結構悩んだ結線、どうすればいい?

結線表
ESP32側OLED側
GPIO番号機能名称名称
GNDGNDGND
3.3VVCCVCC
18VSPI SCKSCK
23VSPI MOSISDA
0GPIORES
19VSPI MISODC
5VSPI SSCS
ESP32 ピンアサイン
OLED ピンアサイン

I2Cの方が結線数は少ない。けれど、SPIの方が動作が速い。
というわけでSPIで使用する。このOLEDも出荷時はSPIなので、その方が面倒臭くないし。

ただ、結線がちょっぴし悩んだ。

OLED側の SCK や SDA が、ESP32側の VSPI SCK や VSPI MOSI に繋がることはわかる。
けど、DCとCSはどっちがどっち!?RESは普通にGPIOでいいんだよな?
という感じで、この3本がポイントだった。

まぁ、

CSは「チップセレクト(Chip Select)」
SSは「スレーブセレクト(SlaveSelect)」
DCは「データ/コマンド(Data/Command)」

らしいので、結果、上の表のようにつなげばよいということが分かった。

ライブラリはどれを使えばいい?

速度的には直接制御したほうが入らしいが、そこまでは求めてないので、やっぱり便利さ優先でライブラリを使いたい。

大事なのはコントローラーに何が使われているのか。

購入先のwebサイトにある説明を参照するのもいいけど、Amazonなんかだと、時々違うものが届いたりすることもあるので、念のため、現物確認が一番間違いないでしょう。

てことで、今回のディスプレイは SSD1309 が使われている。
(実際には扱いやすいSSD1309が使われていて、0.96インチより大きいもの、という条件で探した)

では、ライブラリは…

U8g2を使おう

Arduino IDE のライブラリマネージャーで SSD1309 と検索すれば出てくる U8g2 をとりあえず使ってみた。

ライブラリのインストールが完了したら、

ファイル > スケッチ例 > U8g2 > u8x8 > GraphicsTest

辺りを使って、ちゃんと映るかどうか確認してみると良い。

スケッチが新規ウィンドウで開かれるので、その中の SSD1309 に該当する項目を編集する。
2024/08/03時点では101行目にそれがあった。

最初に確認した結線、どこに何が繋がってるのかは大事なので、やっぱりメモっとくのがいいね。
というわけで、該当項目の「//」を削除し、GPIOの番号を自分の機器と一致する番号に書き換える。
(上のスクリーンショットは変更後のもの)

ESP32側OLED側
GPIO番号機能名称名称
18VSPI SCKSCK
23VSPI MOSISDA
19VSPI MISODC
5VSPI SSCS

これで [CTRL] + [U] で書き込めば、グラフィックテストが実行される。はず。

GraphicsTestの実行

実際に使ってみる

PCやスマホとWiFi接続でソケット通信させて、それに応じてRS485からコマンドを出力する、という治具。

なんだけど、ESP32のIPアドレスは固定したくなくて、DHCPにしたい。
となると、WiFi接続後パッと見でそれがわかるようにしたい。
送受信したコマンドについても表示させたい。

そんな感じのものを作ったった。

実際に作ったものの実行状況

保護フィルムが張られたままなのはご愛敬…

雑記

配線について

ちょっとどうでもいいこと、間違っているかもしれないこと。

MOSIは Master Out Slave In
MISOは Master In Slave Out

つまり、「表示するだけ」ならMISOいらなくね?ということ。

SS(CS)は Slave Select(Chip Select)なので、一見、「SPIデバイスの選択に必要」となるけど、今回のように1台のディスプレイしか接続しないのであれば、ディスプレイ側のSS(CS)はGNDに落としちゃってもいいのではないか?
SS(CS)はLowにすることで通信デバイスを選択するので。
(基盤裏が格好悪くなるけど、ディスプレイ側のCS端子を適当な抵抗介してGNDにつなげちゃうとか)

もし、これでも問題ないようなら、デバイス間の配線は以下で事足りる。かもしれない。

MOSI ー SDA
SCK - SCK
MISO - DC
VCC - VCC
GND - GND

電圧について

ESP32系はGPIOの動作電圧が3.3Vなので、問題ない。
しかし、Arduino UNO のGPIOは5Vになる。

なので、Arduino UNO に3.3Vのみに対応したディスプレイをそのまま繋げると壊れる。たぶん。

じゃぁ、今回使用したディスプレイは?

駆動電圧3.3~5V

と書いてあるから、Arduinoのような5VのI/Oを繋げても大丈夫?

これちょっとわからん。

通常、チップ単位でみれば電源電圧=最大信号電圧みたいになるけれど、この製品が電源電圧が5Vまで対応してるから、信号も5Vまで大丈夫とは言い切れない。
電源電圧だけを5Vから3.3Vに落としてるかもなので…

時間あるときに確認してみようかな。
なんとなく、今回使用したディスプレイ、電源だけは5VでもOKな仕様な気がする…
信号は3.3Vじゃないとダメだろうな。

https://www.hpinfotech.ro/SSD1309.pdf

2024/08/11 追記

やっぱりダメっぽい。
いや、ギリギリ動いちゃうみたいだから、まぁ、いいっちゃぁいいのか?

今回使ったOLEDディスプレイは4.7kΩで3.3Vにプルアップされてる。
レベル変換なるような仕組みは入ってない。

なので…

Arduino UNO R3 の場合はNG。
マイコンがATMega328なのでGPIOがオープンドレインではない。(CMOS?)
なので、5Vがそのままかかる。
要は、ATMega328だとダメってことだね。

Arduino UNO R4 の場合はOK。
R4になってからは、マイコンがRENESASのRA4M1になり、これだとGPIOがオープンドレインなので、問題なさそう。
ただし、ディスプレイ側で3.3Vにプルアップされているならば、だけど。
(R4側で5Vにプルアップしちゃってたら微妙…)

https://www.renesas.com/jp/ja/document/dst/ra4m1-group-datasheet

この記事にコメントしてみる