SSD1306 OLEDディスプレイを使ってみる
2023.09.16


ESP32を使うようになって、SSD1306のOLEDモジュールを使う機会がありました。
ピン数が多いと扱いにくいのでI2Cモデルを買ってみたのですが、
意外と躓くところがあったので、備忘録的に残しておきます。

まずSSD1306はこれは0.96インチのモノクロモジュールです。
買うとケースに入って送られてきた・・
送料込み270円程度なのになかなかやるじゃん(;´Д`)
カラーモジュールはSSD1331らしく型番が違う。
カラーの影響なのか4本I2Cでの接続はできないらしい。
あと1.3インチのモノクロモジュールはSSH1106となっていて全部型番がちがう。
これに気が付かないで買ってしまうといろいろと後悔するかもしれない。
今回は白文字で表示できればよかったので、0.96インチのSSD1306で
この事実に気が付かずもトラブル回避できていた。
今回勝ったSSD1306は4pinのI2C接続なので、

VCC(5V or 3.3V)
GND
SCL
SDA

の4か所を接続するだけでOK! とても簡単。
ただし、ESP32側のプログラムではちょっとてこずった。
ネットで検索するとAdafruit社のライブラリを使ったソースコードが多々見つかる。
ChatGPTに聞いてもAdafruitを使ったコードを出してくる。
きっと書籍とかでもよく紹介している方法なんだと思うが、
私の環境ではライブラリの導入でトラブルが続出した。
Arduino IDEのライブラリマネージャーから
Adafruit SSD1306というライブラリをインストールするだけのはずが、
どうもコンパイルするとエラーが出る。何かが足りないといったメッセージだ。
結局ネットで検索し、Adafruitのサイトからダウンロードして組み込んだら動くようになった。
今この問題を解決できたとしても、ソースファイルをほかのPCに移したりPCを買い替えたりしたとき
また同じ問題に直面するとすれば時間的ロスが半端ないので、
今回はSSD1306.hを利用する方式を採用した。
このssd1306.hもArduino IDEのライブラリマネージャーから「ESP32 SSD1306」で検索し、
「ESP8266 and ESP32 OLED driver for SSD1306 displays」
をインストールするだけ。バージョンはとりあえず最新を選んだ。

ESP32のSDAは21ピン、SCLは22ピンと決まっているので

#define OLED_SDA 21 //I2C接続のSDAを21番に接続
#define OLED_SCL 22 //I2C接続のSCLを22番に接続
SSD1306 display(0x3c, OLED_SDA, OLED_SCL); //SSD1306インスタンスの作成(I2Cアドレス,SDA,SCL)

と定義してあげれば管理しやすい。
0x3cはI2Cのポートを意味する。売られている物のほとんどは0x3cになっているようだ。
実際私が購入したのは0x3Cで動いた。
ところがモジュールの背面を見ればわかるのだが、
ポートは背面をみて判断するのがお決まりらしい。



稀に0x78や0x7Aと書かれているものは抵抗がどちらに張り付いているかでわかる。
私のOLEDも裏には0x78と示している。(8がBのようにもみえるがおそらくはプリントミスだと思われる)
これはどういうことなのだろうか?
調べたところによると、I2Cのアドレスは7ビットで使われており、
8ビット目は使用されない。つまり0x78と指定しても0x3Cとして使われ、
0x7Aと指定しても0x3Dとして使われるという話。
だから最初から0x3Cと指定しているということらしい。
ここら辺も知っておかないとハマる原因になりかねない。



ちなみに1.3インチの裏面も同じようになっています。

さて上の3行が定義できれば後はもう自由に表示させることが可能。
命令の種類はネットで調べたところ

display.setPixel(x,y)で点を打つ
display.drawRect(x1,y1,x2,y2)で四角形を描く
display.fillRect(x1,y1,x2,y2)で四角形を描き中を塗る
display.drawHorizontalLine(x,y,ドット幅)でラインを引く
display.drawCircle(x,y,半径)で四角形を描く
display.fillCircle(x,y,半径)で四角形を描き中を塗る
display.setTextAlignment(TEXT_ALIGN_LEFT) 文字表示座標の起点を指示。他にTEXT_ALIGN_CENTER、TEXT_ALIGN_RIGHTがある
display.drawString(x,y,"半角文字") //文字の表示
display.setFont //フォントと文字サイズを指定
display.drawVerticalLine
display.drawProgressBar(X, Y, 幅, 高さ, 少数第2位の実数);
display.setColor(WHITE) //色を指定WHITE or BLACK
display.clear() 画面の初期化
display.display() //指定された描画命令を反映

これらが見つかった。もしかしたらもっとあるかもしれない。
これだけあれば特に困ることはないが、
Adafruitのライブラリのように改行があれば便利だったかなと思う。
フォントのサイズは3種類。実行すればそれ以降のdisplay.drawStringが対象となる。

display.setFont(ArialMT_Plain_10); //約17文字×6行 Yに対して10の倍数
display.setFont(ArialMT_Plain_16); //約10.5文字×3行 Yに対して16の倍数
display.setFont(ArialMT_Plain_24); //約7文字×2.5行 Yに対して24の倍数

フォントの種類は1種類しか見つけ出せてない。
このフォントはプロポーショナルフォントで、横幅が狭いアルファベットは詰められるので
表示できる文字数は書く文字によって変化することに注意。Iなんて文字は横幅が無いので一気に詰められる。
漢字を試しに打ち込んでみたら何も表示されず暗黒のままだった(;'∀')
display.setColorカラー指定ができるが、1306のモジュールは白と黒だけ選択できる。
他のモジュールなら細かく設定できるのかもしれない。
どの描画命令もdisplay.display()を実行しないと反映されない。
LOOP内で頻繁にdisplay.display() を繰り返すとOLEDがチカチカするので
LOOP内の最後らへんに1つだけ置いておくといいかもしれない。

画像を黒に消し去りたいときはdisplay.clear()を使う。

以下は使ってみた感想。
0.96インチは思っていた以上に小さい。
フォントサイズ10で文字を表示したら老眼の人にはかなり厳しいだろうと思う。
1.3インチを使ったほうが段違いに見やすい。コストダウンを考えて選択したのが裏目に出た(;'∀')
余分な部分が少ないので取り回しは楽。
LCDモジュールをよく使っていたけど、OLEDは画像が鮮明で見やすい。
LCDのように角度によっては見えにくいなんてことはないと思う。
基板に固定穴がついているのがいい。液晶は基板ではなくフタにつけることが多いので非常に助かる。
今のところはっきりわかるほどの熱はでてない。
これが1か月も1年もロングランさせるのであればどうなのかは今後の検証次第というとこ。
トラックバックURL
トラックバック一覧

- CafeNote -