I2Cデバイスの情報表示に最適MiniOLEDの使い方

MiniOLEDの使い方

超小型0.42インチ(72×40)OLED有機ELディスプレイ「MiniOLED(M5Stack社製)」の使い方について、I2Cセンサと併用した使用例も含めてサンプルプログラムで詳しく紹介します。

小さいですが、それなりの情報(10文字3行程度)が表示できるので、液晶表示の無いデバイスでI2Cセンサの測定値やIPアドレスの表示等、便利に使えるOLED(有機ELディスプレイ)です。

今回は「ATOMS3 LITE」を使用して「I2C通信」の温湿度気圧センサ「ENV.IV」の測定値を表示する方法を例に紹介していきます。

「ATOMS3 LITE」と「ENV.IV」の使い方は以下のリンクで詳しく紹介しています。

AtomS3 Liteの使い方、端子配列、初期設定をサンプルプログラムで詳しく紹介
Atom Liteの高機能版AtomS3 Liteの使い方を,端子配列,開発環境別の初期設定,Atom Liteとの違い等をサンプルプログラムで詳しく紹介します。
M5StickC Plus2 I2C通信で温度、湿度測定ENV IVセンサの使い方
M5StickC Plus2でI2C通信の温湿度気圧センサENV IVをライブラリ使用とライブラリを使用せずI2C通信で直接データ受信する方法で詳しく紹介します。

「MiniOLED」は「スイッチサイエンス」や、以下の製造元「M5Stack」のサイトで約650円で購入できます。

M5Stack - Modular Rapid ESP32 IoT Development Board - ESP32 dev kits
Open-source modular toolkits for IoT devices based on ESP32-updated version of ESP8266. With stackable modules, user-friendly IDE, enabling rapid and high-quali...
スポンサーリンク

1.MiniOLEDについて

「MiniOLED」の外観は以下になります。
液晶のサイズは「0.42インチ」でドット数は「72×40」です。

MiniOLEDの外観
MiniOLEDの外観
MiniOLEDの外観
MiniOLEDの外観
両サイドに「Groveコネクタ」がついているため、制御デバイスのI2C通信端子と片側を接続して、もう一方を別のI2Cデバイスと接続することで、OLEDと同時に別のI2Cデバイスも制御することができます。
スポンサーリンク

2.ATOMS3 LITEについて

今回は「MiniOLED」の制御デバイスとして「M5Stack社製」の「ATOMS3 LITE」を使用しました。

小型で安価ですが、入出力端子と本体ボタン、I2CやUART通信、Wi-FiやBluetooth通信も搭載しています。機能は豊富ですが、液晶表示は無いため、ちょっとした情報(内部状態や測定データ、IPアドレス等)の確認をしたい時に「MiniOLED」があると「Groveコネクタ」で接続するだけなので便利に使えます。

「ATOMS3 LITE」の端子配列は以下になります。

AtomS3-Liteの使い方、端子配列

今回使用するのは「PORT.A」の「Groveコネクタ」で、「MiniOLED」に付属の配線を接続するだけです。


「ATOMS3 LITE」の初期設定や使い方は以下のリンクで詳しく紹介しています。

AtomS3 Liteの使い方、端子配列、初期設定をサンプルプログラムで詳しく紹介
Atom Liteの高機能版AtomS3 Liteの使い方を,端子配列,開発環境別の初期設定,Atom Liteとの違い等をサンプルプログラムで詳しく紹介します。
スポンサーリンク

3.基本の文字表示

「MiniOLED」に文字表示を行う方法を紹介します。
配線は以下のように「MiniOLED」に付属の「Groveコネクタ配線」で接続するだけです。

MiniOLEDの使い方

・ライブラリ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つのフォントを文字サイズで使い分けるのが、見やすくて良いのではと思います。

3行表示の場合は文字高さ「8」、2行表示なら文字高さ「14」が丁度いいです。

u8g2_font_ncenB08_tr

MiniOLEDの使い方

u8g2_font_ncenB14_tr

MiniOLEDの使い方

u8g2_font_helvR08_tr

MiniOLEDの使い方

u8g2_font_helvR14_tr

MiniOLEDの使い方

フォントは「U8g2.h」ファイルの中を覗くと確認できますが、非常にたくさんあります。
多いですが実用的にはASCII文字が一通り使えるものを選ぶと良いと思います。

ASCIIコードの「32 ~ 127」がよく使う文字になりますが、これはフォント名の末尾が「_tr」のものになります。

「U8g2」のフォント名は以下のような構成で名付けられています。

「U8g2」のフォント名構成
 <接頭辞> ‘‘ <名前> ‘‘ <目的> <文字セット>

末尾の<目的>と<文字セット>は以下のような意味を表します。

<目的> 説明
 t:透明フォント、背景色は使用しないでください。
 h:すべてのグリフは共通の高さを持ちます。
 m:すべてのグリフは共通の高さと幅 (等幅) を持ちます。
 8:すべてのグリフは 8×8 ピクセル ボックスに収まります。

<文字セット> 説明
 f:フォントには最大 256 個のグリフが含まれます。
 r:ASCII コード 32 ~ 127 の範囲のグリフのみがフォントに含まれます。
 u:ASCII コード 32 ~ 95 の範囲のグリフ (大文字) のみがフォントに含まれます。
 n:フォントには、日付と時刻の文字列を書き込むための数字と追加のグリフのみが含まれます。
 …:その他の外字リスト。

英文を直訳したのでわかりにく表現もあるかと思いますが、雰囲気で確認してください^^;
用途にもよりますが末尾「_tr」のフォントを目安に表示させて確認していくと、目的にあったフォントが見つけやすいのではと思います。

・サンプルプログラム

「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」の外観は以下のようになります。
温度と湿度と気圧の測定ができますが、今回は温度と湿度の測定用として使用します。

温湿度気圧センサENV IV外観
温湿度気圧センサENV IV外観

I2C温湿度気圧センサ「ENV.IV」の使い方は以下のリンクで詳しく紹介しています。

M5StickC Plus2 I2C通信で温度、湿度測定ENV IVセンサの使い方
M5StickC Plus2でI2C通信の温湿度気圧センサENV IVをライブラリ使用とライブラリを使用せずI2C通信で直接データ受信する方法で詳しく紹介します。

配線は下画像のように「MiniOLED」のGroveコネクタに接続するだけです。

MiniOLEDの使い方
「MiniOLED」と「ENV.IV」は「ATOMS3 LITE」と同じI2C通信端子のライン上に接続されていますが、デバイスアドレスが異なるものであれば同時に制御することができます。

・サンプルプログラム

「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アドレスの表示用として最適と思います。

AtomS3 Liteの使い方、端子配列、初期設定をサンプルプログラムで詳しく紹介
Atom Liteの高機能版AtomS3 Liteの使い方を,端子配列,開発環境別の初期設定,Atom Liteとの違い等をサンプルプログラムで詳しく紹介します。

コメント

タイトルとURLをコピーしました