超小型0.42インチ(72×40)OLED有機ELディスプレイ「MiniOLED(M5Stack社製)」の使い方について、I2Cセンサと併用した使用例も含めてサンプルプログラムで詳しく紹介します。
小さいですが、それなりの情報(10文字3行程度)が表示できるので、液晶表示の無いデバイスでI2Cセンサの測定値やIPアドレスの表示等、便利に使えるOLED(有機ELディスプレイ)です。
「ATOMS3 LITE」と「ENV.IV」の使い方は以下のリンクで詳しく紹介しています。
「MiniOLED」は「スイッチサイエンス」や、以下の製造元「M5Stack」のサイトで約650円で購入できます。
1.MiniOLEDについて
2.ATOMS3 LITEについて
3.基本の文字表示
・ライブラリU8g2について
・フォントについて
・サンプルプログラム
4.I2Cデバイスの情報表示
・I2C温湿度気圧センサーENV.IVについて
・サンプルプログラム
5.まとめ
1.MiniOLEDについて
「MiniOLED」の外観は以下になります。
液晶のサイズは「0.42インチ」でドット数は「72×40」です。
2.ATOMS3 LITEについて
今回は「MiniOLED」の制御デバイスとして「M5Stack社製」の「ATOMS3 LITE」を使用しました。
小型で安価ですが、入出力端子と本体ボタン、I2CやUART通信、Wi-FiやBluetooth通信も搭載しています。機能は豊富ですが、液晶表示は無いため、ちょっとした情報(内部状態や測定データ、IPアドレス等)の確認をしたい時に「MiniOLED」があると「Groveコネクタ」で接続するだけなので便利に使えます。
「ATOMS3 LITE」の端子配列は以下になります。
今回使用するのは「PORT.A」の「Groveコネクタ」で、「MiniOLED」に付属の配線を接続するだけです。
「ATOMS3 LITE」の初期設定や使い方は以下のリンクで詳しく紹介しています。
3.基本の文字表示
「MiniOLED」に文字表示を行う方法を紹介します。
配線は以下のように「MiniOLED」に付属の「Groveコネクタ配線」で接続するだけです。
・ライブラリU8g2について
文字表示を行うためにはライブラリ「U8g2」を使用します。(使い方の詳細はサンプルプログラム参照)
「U8g2」は多くのOLED表示器に対応しており、たくさんのフォントが準備されています。
「MiniOLED」を使用するには、「U8g2」ライブラリを開発環境(ArduinoIDE、PlatformIO等)にインストールして、以下のようにSSD1306の設定を使用します。
#include <U8g2lib.h> // U8g2ライブラリをインクルード
// OLED表示用のインスタンスを作成
U8G2_SSD1306_72X40_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // MiniOLED 0.42" 72x40
初期設定(setup)の中で以下のように「I2C通信」に使用する端子番号を設定し「OLED」の初期化を行います。
Wire.begin(2, 1); // I2C通信初期化(SDA, SCL)、グローブコネクタの端子番号を指定
u8g2.begin(); // OLED初期化
メインプログラムの中で以下のように文字表示を行います。
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_ncenB08_tr); // フォント設定
u8g2.drawStr(5, 10, "Hello World!"); // 座標を指定して文字列表示 (x, y, 文字列)
u8g2.sendBuffer(); // OLED表示実行
注意が必要なのは、表示できるのは文字列だけというところです。便利な「printf」は使えません。
このため、変数の値を表示するには以下のように「sprintf」を使用して、変数の値を文字列に変換して、他の文字列と結合して準備しておく必要があります。
float data = 1.23; // 表示するデータ
char data_str[20]; // 表示文字列格納用
// データをOLEDに表示するために文字列として結合
sprintf(data_str, "DATA:%f", data); // データ表示用文字列結合
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_ncenB08_tr); // フォント設定
u8g2.drawStr(5, 10, data_str); // 座標を指定して文字列表示 (x, y, 文字列)
u8g2.sendBuffer(); // OLED表示実行
// 表示結果:DATA:1.23
・フォントについて
「U8g2」ライブラリには非常にたくさんのフォントが準備されています。
たくさんありますが今回使用するのは「0.42インチ」の小さなOLEDのため、実用的なフォントは限られます。
好みもあるとは思いますが、いろんなフォントを試してみたところ、個人的には以下の2つのフォントを文字サイズで使い分けるのが、見やすくて良いのではと思います。
u8g2_font_ncenB08_tr
u8g2_font_ncenB14_tr
u8g2_font_helvR08_tr
u8g2_font_helvR14_tr
フォントは「U8g2.h」ファイルの中を覗くと確認できますが、非常にたくさんあります。
多いですが実用的にはASCII文字が一通り使えるものを選ぶと良いと思います。
「U8g2」のフォント名は以下のような構成で名付けられています。
<接頭辞> ‘‘ <名前> ‘‘ <目的> <文字セット>
末尾の<目的>と<文字セット>は以下のような意味を表します。
<目的> 説明
t:透明フォント、背景色は使用しないでください。
h:すべてのグリフは共通の高さを持ちます。
m:すべてのグリフは共通の高さと幅 (等幅) を持ちます。
8:すべてのグリフは 8×8 ピクセル ボックスに収まります。
<文字セット> 説明
f:フォントには最大 256 個のグリフが含まれます。
r:ASCII コード 32 ~ 127 の範囲のグリフのみがフォントに含まれます。
u:ASCII コード 32 ~ 95 の範囲のグリフ (大文字) のみがフォントに含まれます。
n:フォントには、日付と時刻の文字列を書き込むための数字と追加のグリフのみが含まれます。
…:その他の外字リスト。
・サンプルプログラム
「MiniOLED」に文字を表示するサンプルプログラムは以下になります。
実行すると、上で紹介した2つのフォントで文字サイズ違いが順番に表示されます。
サンプルプログラムは以下になります。「コピペ」して書き込んでください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。
#include <M5AtomS3.h> // ヘッダーファイル準備(別途FastLEDライブラリもインストール)
#include <U8g2lib.h>
// FastLEDライブラリでフルカラーLEDを使用する設定
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
return (CRGB)((r << 8) | (g << 16) | b);
}
// OLED表示用のインスタンスを作成
U8G2_SSD1306_72X40_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // MiniOLED 0.42" 72x40
// 初期設定 -------------------------------------------------
void setup(void) {
M5.begin(false, true, false, true); // 初期化(液晶, USBシリアル, I2C[38,39]を使うならtrue, LED)
USBSerial.begin(9600); // USBシリアル通信初期化
Wire.begin(2, 1); // I2C通信初期化(SDA, SCL)、グローブコネクタの端子番号を指定
u8g2.begin(); // OLED初期化
USBSerial.println("MiniOLED 0.42 test"); // シリアル出力
M5.dis.drawpix(dispColor(50, 50, 50)); // 本体LED色指定
M5.dis.show(); // 本体フルカラーLED出力
}
// メイン ---------------------------------------------------
void loop(void) {
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_ncenB08_tr); // フォント設定
u8g2.drawStr(2, 12, "1234567890"); // 文字列表示
u8g2.drawStr(2, 25, "ABCDEFGHIJK");
u8g2.drawStr(2, 37, "!#$%&()=~@+*");
u8g2.drawHLine(0, 0, 72); // 指定座標から横線(x, y, width)
u8g2.drawHLine(0, 39, 72);
u8g2.drawVLine(0, 0, 40); // 指定座標から縦線(x, y, length)
u8g2.drawVLine(71, 0, 40);
u8g2.sendBuffer(); // OLED表示実行
delay(2000);
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_ncenB14_tr); // フォント設定
u8g2.drawStr(2, 17, "1234567890"); // 文字列表示
u8g2.drawStr(2, 37, "ABCDEFGHIJK");
u8g2.drawHLine(0, 0, 72); // 指定座標から横線(x, y, width)
u8g2.drawHLine(0, 39, 72);
u8g2.drawVLine(0, 0, 40); // 指定座標から縦線(x, y, length)
u8g2.drawVLine(71, 0, 40);
u8g2.sendBuffer(); // OLED表示実行
delay(2000);
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_helvR08_tr); // フォント設定
u8g2.drawStr(2, 12, "1234567890"); // 文字列表示
u8g2.drawStr(2, 25, "ABCDEFGHIJK");
u8g2.drawStr(2, 37, "!#$%&()=~@+*");
u8g2.drawHLine(0, 0, 72); // 指定座標から横線(x, y, width)
u8g2.drawHLine(0, 39, 72);
u8g2.drawVLine(0, 0, 40); // 指定座標から縦線(x, y, length)
u8g2.drawVLine(71, 0, 40);
u8g2.sendBuffer(); // OLED表示実行
delay(2000);
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_helvR14_tr); // フォント設定
u8g2.drawStr(2, 17, "1234567890"); // 文字列表示
u8g2.drawStr(2, 37, "ABCDEFGHIJK");
u8g2.drawHLine(0, 0, 72); // 指定座標から横線(x, y, width)
u8g2.drawHLine(0, 39, 72);
u8g2.drawVLine(0, 0, 40); // 指定座標から縦線(x, y, length)
u8g2.drawVLine(71, 0, 40);
u8g2.sendBuffer(); // OLED表示実行
delay(2000);
}
4.I2Cデバイスの情報表示
「MiniOLED」の両サイドには「Groveコネクタ」が接続できるため、「MiniOLED」経由で他のI2C通信デバイスを接続することができます。
今回は温度と湿度が測定できるセンサー「ENV.IV」を接続して、測定したデータを「MiniOLED」に表示してみます。
・I2C温湿度気圧センサーENV.IVについて
「ENV.IV」の外観は以下のようになります。
温度と湿度と気圧の測定ができますが、今回は温度と湿度の測定用として使用します。
I2C温湿度気圧センサ「ENV.IV」の使い方は以下のリンクで詳しく紹介しています。
配線は下画像のように「MiniOLED」のGroveコネクタに接続するだけです。
・サンプルプログラム
「ENV.IV」で測定した温度と湿度を「MiniOLED」に表示させるサンプルプログラムは以下になります。
サンプルプログラムは以下になります。「コピペ」して書き込んでください。
※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。
#include <M5AtomS3.h> // ヘッダーファイル準備(別途FastLEDライブラリもインストール)
#include <U8g2lib.h>
#define SHT3X_ADDR 0x44 // SHT3X(温度、湿度センサ)I2C通信アドレス
// OLED表示用のインスタンスを作成
U8G2_SSD1306_72X40_ER_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // MiniOLED 0.42" 72x40
// 変数宣言
unsigned int data[6]; // 温度、湿度受信データ格納用
float t_degC = 0.0; // 温度換算データ格納用
float rh_pRH = 0.0; // 湿度換算データ格納用
char t_str[20]; // 温度表示文字列格納用
char rh_str[20]; // 湿度表示文字列格納用
// 初期設定 -------------------------------------------------
void setup(void) {
M5.begin(false, true, false, true); // 初期化(液晶, USBシリアル, I2C[38,39]を使うならtrue, LED)
USBSerial.begin(9600); // USBシリアル通信初期化
Wire.begin(2, 1); // I2C通信初期化(SDA, SCL)、グローブコネクタの端子番号を指定
u8g2.begin(); // OLED初期化
}
// メイン ---------------------------------------------------
void loop(void) {
// I2Cデータ送信
Wire.beginTransmission(SHT3X_ADDR); // デバイスアドレスを指定して I2C通信開始
Wire.write(0xFD); // 要求コマンド送信(高精度測定を指定)
Wire.endTransmission(true); // 書き込み完了
delay(10); // データ受信待ち(時間はデータシートによる:0.01s)
// I2Cデータ受信(温度、湿度それぞれ 測定データ:8bit ×2 + CRC:8bit で合計6byte)
Wire.requestFrom(SHT3X_ADDR, 6); // 受信データリクエスト(6byte)
for (int i = 0; i < 6; i++) { // 6byte分繰り返し
data[i] = Wire.read(); // 受信データ格納
}
// I2C受信データを温度、湿度に換算(計算方法はデータシート確認)
t_degC = -45 + 175 * (data[0] * 256 + data[1])/65535; // 温度データ換算
rh_pRH = -6 + 125 * (data[3] * 256 + data[4])/65535; // 湿度データ換算
// 測定データシリアル出力
USBSerial.printf("%.1f, %.1f\n", t_degC, rh_pRH);
// データをOLEDに表示するために文字列として結合
sprintf(t_str, "T:%.1f'c", t_degC); // 温度データ表示用文字列結合
sprintf(rh_str, "H:%.1f%%", rh_pRH); // 湿度データ表示用文字列結合
// OLED表示
u8g2.clearBuffer(); // OLED表示初期化
u8g2.setFont(u8g2_font_helvR14_tr); // フォント設定
u8g2.drawStr(2, 18, t_str); // 温度文字列表示
u8g2.drawStr(2, 38, rh_str); // 湿度文字列表示
u8g2.sendBuffer(); // OLED表示出力
delay(1000); // 遅延時間
}
5.まとめ
超小型の0.42インチ(72×40)OLED有機ELディスプレイ「MiniOLED」の使い方について詳しく紹介しました。
あまりにも小さすぎて、何が表示できるんだろう?・・・と興味本位で買いましたが、使ってみるとそこそこの情報量(10文字3行程度)が表示できたので、色々便利に使えると思います。
「MiniOLED」の両サイドには「Groveコネクタ」がついているため、制御デバイスのI2C通信端子と片側を接続して、もう一方を別のI2Cデバイスと接続することで、デバイスアドレスの異なる別のI2CデバイスもOLEDと同時に、制御することができます。
表示サイズは小さいですが、10文字程度で3行の表示も可能で、液晶表示の無いデバイスの内部状態やセンサの測定値、IPアドレスの表示用として最適と思います。
コメント