【Raspberry Pi Pico入門 – 応用編】有機ELディスプレイ
概要
有機ELディスプレイとは別名OLEDディスプレイとも呼ばれる表示器の1種です。仕組みについては割愛しますが、液晶ディスプレイ(LCD)に比べて視認性が良くてコントラストがハッキリ表示できるが、高価で長期的に見ると劣化しやすいという特徴があります。(劣化が早いとはいえ、数年レベルではほとんど差はありません)
今回はI2C通信で使用するタイプの有機ELディスプレイを使ってみます。I2C通信タイプは配線の数が少なくて組み立てやすいが、通信スピードが遅いという特徴があります。遅いと言っても1秒間に数回更新するくらいは出来るので十分実用的かと思います。
実行環境
IDE:Arduino IDE 2.3.2
MCU:Raspberry Pi Pico
フォトカプラ:OLEDディスプレイ(0.91インチ、128×64ピクセル、SSD1306私用)
今回は以下のディスプレイを使います。「SSD1306」というのがディスプレイを制御しているICで、他のサイズの有機ELディスプレイにもよく使われています。SSD1306と書かれていたら今回の解説と全く同じ方法で動作するので、興味があれば使ってみてください。
回路
以下のように配線します。I2C通信はデフォルトのGPIO4とGPIO5を使用します。
回路図は以下のようになっています。
ライブラリのインストール
ライブラリマネージャーで「u8g2」と検索し、以下のライブラリをインストールしてください。
これは汎用のディスプレイ制御用ライブラリで、画像や文字をいい感じに表示してくれるので便利です。
コーディング
新しくスケッチを作成し、以下の内容をコピペしてください。ディスプレイに「Hello World!」と表示するコードです。
#include <U8g2lib.h> // デバイスに合わせてインスタンスの生成 // デバイスのIC:SSD1306、解像度:128x64、ブランド:ノーブランド、通信タイプ:ハードウェアI2C(4ピンタイプ) U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); void setup() { u8g2.begin(); } void loop() { u8g2.clearBuffer(); // 描画データをクリア u8g2.setFont(u8g2_font_ncenB08_tr); // 文字列のフォントを設定 u8g2.drawStr(0, 10, "Hello World!"); // 描画データの左から0ピクセル・上から10ピクセルの位置に文字列を追加 u8g2.sendBuffer(); // 描画データをOLEDディスプレイに送信(画面の更新) delay(1000); }
動作確認
書き込み完了と同時にディスプレイに「Hello World!」と表示されれば成功です。
解説
I2C通信
詳細についてはかなり長くなるので割愛します。シリアル通信の1種で、SCL(クロック)・SDA(データ)・GNDの3本で通信する通信規格の名前、ということだけ憶えてもらえれば使う分には十分です。
Arduino IDEでI2C通信を使うには<wire.h>というライブラリのインクルードが必要なのですが、今回は<U8g2lib.h>の中でインクルードされているので書く必要はありません。
U8g2ライブラリ
本来、有機ELディスプレイは128×64ピクセルの全ての画素について点灯/消灯を支持することで表示を更新する必要があります。ただ、これを毎回手打ちで制御するのはめちゃくちゃ大変なので、Arduinoではライブラリを使用して表示するのが一般的です。
その中でもU8g2ライブラリは制御がシンプルで、文字列のフォントが豊富なことが特徴のライブラリになります。
マイコン開発でのフォントは文字サイズが固定なため、サイズを変えるにはフォントを変えるしかないのですが、U8g2ライブラリは小さいものは3ピクセル・大きいものは92ピクセルまでフォントが用意されています。その分データ量が大きいのがネックなのですが、Raspberry Pi PicoならROMの数%しか使わないので問題ないだろうと判断して採用しました。
インスタンス生成
このライブラリで1番のハマリどころです。使用したいデバイスに合わせて変数型を選ぶのですが、選択肢が約300種類あるのでどれを選べばいいか迷うかと思います。。。
[スケッチ例]-[full_buffer]-[HelloWorld]を開くと以下のように選択肢が全て書かれているサンプルスケッチが見れます。
私がこれまでに使用した実績のあるデバイスについて、以下に随時更新していきます。
- 128×64 0.96インチ SSD1306 I2C接続
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
文字のフォント設定
以下のU8g2公式Wikiから使用したいフォントを選びます。サイズ別に整理されているので、表示したいサイズをおおまかに決めてからの方が探しやすいです。
デザインから決めたい場合はグループ一覧からフォントの辺りを付けます。所望のサイズがあるとは限らないので注意してください。
末尾のアルファベットはフォントタイプとフォントに含まれる文字を表しています。サンプルコードで使用している「u8g2_font_ncenB08_tr」は「透明フォント、大文字の英数字・記号」となります。詳しくは参考リンク先に英語で解説されています。
t | 透明フォント |
h | 高さが全て一定のフォント |
m | 等幅フォント(高さと幅が全て一定) |
8 | すべてが8×8ピクセルのフォント |
f | 半角カナを含むASCIIコード | 記号・数字・大文字の英字・小文字の英字・半角カナ |
r | 基本的な英数字・記号 | 記号・数字・大文字の英字・小文字の英字 |
u | 大文字の英数字・記号 | 記号・数字・大文字の英字 |
n | 数字と一部の記号のみ | 日付・時刻を表示するのに必要な文字のみ |
その他 | 特殊記号 |
フォントを決めたら、以下の関数でフォントを設定します。サンプルコードでは「u8g2_font_ncenB08_tr」に設定しています。
u8g2.setFont(u8g2_font_ncenB08_tr);
文字の配置
文字の配置は以下の関数で設定します。左上から何ピクセルの位置に表示するか、で指定します。
1つめが左から何ピクセルか、2つめが上から何ピクセルか、になります。指定した位置に文字列の左下が来るように配置されます。
u8g2.drawStr(0, 10, "Hello World!");
例えば、もう少し右に配置したかったら以下のように変更します。
u8g2.drawStr(5, 10, "Hello World!");
以下、公式Wikiのイメージ図です。
日本語の表示
U8g2ライブラリには数は少ないですが日本語フォントが入っており、日本語出力に対応しています。
日本語の文字列データを扱うにはUTF-8エンコードを有効にする必要があるため、少しコードが変わります。
日本語フォントはデータサイズが大きく、以下のコードだけでRaspberry Pi Picoのフラッシュの21%を使います。
ただ、画像を表示したりするのでなければ容量を圧迫するほどではないので、↓このコードをデフォルトで使うのもありかもです。
#include <U8g2lib.h> // デバイスに合わせてインスタンスの生成 // デバイスのIC:SSD1306、解像度:128x64、ブランド:ノーブランド、通信タイプ:ハードウェアI2C(4ピンタイプ) U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); void setup() { u8g2.begin(); //初期化 u8g2.enableUTF8Print(); //UTF-8エンコードされた文字列の使用を有効化 } void loop() { u8g2.clearBuffer(); // 描画データをクリア u8g2.setFont(u8g2_font_b12_t_japanese3); // 文字列のフォントを設定 u8g2.setCursor(0, 20); //描画データの左から0ピクセル・上から10ピクセルの位置にカーソルを設定 u8g2.print("日本語テスト"); // カーソルの位置に文字列を追加 u8g2.sendBuffer(); // 描画データをOLEDディスプレイに送信(画面の更新) delay(1000); }
日本語のフォントは以下です。
フォントの定義名 | サイズ(px) | 太字フォント | 使える漢字の種類 |
---|---|---|---|
u8g2_font_b10_t_japanese1 | 10 | – | 少ない |
u8g2_font_b10_t_japanese2 | 10 | – | 普通 |
u8g2_font_b10_b_t_japanese1 | 10 | ◯ | 少ない |
u8g2_font_b10_b_t_japanese2 | 10 | ◯ | 普通 |
u8g2_font_b12_t_japanese1 | 12 | – | 少ない |
u8g2_font_b12_t_japanese2 | 12 | – | 普通 |
u8g2_font_b12_t_japanese3 | 12 | – | 多い |
u8g2_font_b12_b_t_japanese1 | 12 | ◯ | 少ない |
u8g2_font_b12_b_t_japanese2 | 12 | ◯ | 普通 |
u8g2_font_b12_b_t_japanese3 | 12 | ◯ | 多い |
u8g2_font_unifont_t_japanese1 | 16 | – | 少ない |
u8g2_font_unifont_t_japanese2 | 16 | – | 普通 |
u8g2_font_unifont_t_japanese3 | 16 | – | 多い |
u8g2_font_b16_t_japanese1 | 16 | – | 少ない |
u8g2_font_b16_t_japanese2 | 16 | – | 普通 |
u8g2_font_b16_t_japanese3 | 16 | – | 多い |
u8g2_font_b16_b_t_japanese1 | 16 | ◯ | 少ない |
u8g2_font_b16_b_t_japanese2 | 16 | ◯ | 普通 |
u8g2_font_b16_b_t_japanese3 | 16 | ◯ | 多い |
他の機能
U8g2ライブラリには他にもたくさんの機能があります。ここで解説しているもの以外の機能については公式Wikiのリファレンスマニュアル(英語)を確認してみてください。図形描画も出来るので、頑張れば簡単なゲームも作れそうです。
ディスカッション
コメント一覧
まだ、コメントがありません