液晶表示器OLED(SH1107)の使い方。M5GFXライブラリ使用。

Arduinoコマンド:液晶表示器SH1107の使い方Arduinoコマンド
スポンサーリンク

液晶表示器(OLED:有機EL液晶)の使い方について紹介します。
今回使う液晶は1.3インチのモノクロ液晶「M5Stack用1.3インチ 128 x 64 OLEDディスプレイユニット SH1107」です。

I2C通信に対応しており、液晶表示の無い「ATOM LITE」や「ESP32」等に接続して「M5GFX」ライブラリを使うことで簡単に表示を行うことができます。

ATOM LITEで液晶表示(SH1107)
「ATOM LITE」って何?って方は → こちら
「開発環境の準備」がまだの方は → こちら

1.サンプル画面の紹介

基本的な表示内容として下画像のようなサンプル画面を準備しました。

ATOM LITEで液晶表示(SH1107)

①日本語表示
②ボタンの動作で内容が変化
③ボタンを押した回数を表示
④指定した座標から平行線
⑤始点終点を座標で指定した線
⑥指定した座標から垂線
⑦円と塗り潰し円
⑧三角と塗り潰し三角
⑨四角と塗り潰し四角


2.サンプルプログラムの紹介

この液晶を「ATOM LITE」に接続してサンプル画面を表示するプログラムは以下のようになります。

※下コード(黒枠)内の右上角にある小さなアイコンのクリックでコピーできます。

#include <M5Atom.h>
#include <M5UnitOLED.h> //M5GFXライブラリ使用

//OLED設定
M5UnitOLED display(26, 32, 400000); //任意の端子でI2Cを使用する場合(SDA, SCL, FREQ)
M5Canvas canvas(&display);          //表示する内容を保持する仮想画面をcanvasとして準備

//変数設定
int cnt = 0;                        //カウント数格納用
//FastLED(CRGB構造体)設定
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
  return (CRGB)((r << 8) | (g << 16) | b);
}
//-------------------------------------------------
// 初期設定
//-------------------------------------------------
void setup() {
  M5.begin(false, false, true);  //Serial,POWER,LED
  // OLED(M5GFX)初期設定
  display.init();             //液晶表示器初期化
  display.setRotation(1);     //表示方向(コネクタ位置基準):0下,1右,2上,3左
  canvas.setColorDepth(1);    //モノクロ(1ビット、白黒2色)カラーの場合は対応するビット数
  canvas.setTextWrap(false);  //改行をしない(画面をはみ出す時自動改行する場合はtrue)
  canvas.setTextSize(1);      //文字サイズ(倍率)
  canvas.createSprite(display.width(), display.height()); //canvasサイズ

  M5.dis.drawpix(0, dispColor(20, 20, 20)); //LED全消灯
}
//-------------------------------------------------
// メイン
//-------------------------------------------------
void loop() {
  M5.update(); //ボタン状態更新

  // 日本語表示
  canvas.setCursor(10, 0);                      //座標を指定
  canvas.setFont(&fonts::lgfxJapanGothicP_16);  //ゴシック体
  canvas.print("液晶表示テスト");     //表示内容をcanvasに準備

  // 本体ボタンON/OFF状態表示
  canvas.setCursor(5, 23);        //座標を指定(2行目、左側)
  canvas.setFont(&fonts::Font2);  //フォント設定
  canvas.print("         ");      //表示内容消去

  canvas.setCursor(5, 23);        //座標を指定(2行目、左側)
  if (M5.Btn.isPressed()) {       //ボタンを押していれば
    M5.dis.drawpix(0, dispColor(0, 0, 100));  //本体LED青
    canvas.print("BTN=ON");       //ボタンオン状態表示
  } else {                        //ボタンを押してなければ
    M5.dis.drawpix(0, dispColor(20, 20, 20)); //本体LED白
    canvas.print("BTN=OFF");      //ボタンオフ状態表示
  }
  // 本体ボタンON回数カウント表示
  if (M5.Btn.wasPressed()) {      //ボタンが押されていたら
    cnt++;                        //カウント+1
  }
  canvas.setCursor(68, 23);       //座標を指定(2行目右側)
  canvas.setFont(&fonts::Font2);  //フォント設定 0,2,4,6,7,8
  canvas.print("CNT=");           //カウント数
  canvas.setCursor(100, 24);      //座標を指定(2行目右側)
  canvas.setTextSize(0.3);        //文字サイズ変更
  canvas.setFont(&fonts::Font7);  //7セグ
  canvas.printf("%03d", cnt);     //カウント数(3桁指定)
  canvas.setTextSize(1);          //文字サイズ1へ戻す

  canvas.drawLine(0, 20, 128, 20, TFT_WHITE);   //線(始点終点指定)
  canvas.drawFastVLine(64, 22, 17, TFT_WHITE);  //線(指定座標から垂線)
  canvas.drawFastHLine(0, 40, 128, TFT_WHITE);  //線(指定座標から平行線)

  canvas.drawCircle(10, 55, 8, TFT_WHITE);      //円
  canvas.fillCircle(30, 55, 8, TFT_WHITE);      //円(塗り潰し)

  canvas.drawTriangle(46, 62, 54, 48, 62, 62, TFT_WHITE); //三角
  canvas.fillTriangle(66, 62, 74, 48, 82, 62, TFT_WHITE); //三角(塗り潰し)

  canvas.drawRect(90, 47, 16, 16, TFT_WHITE);   //四角
  canvas.fillRect(110, 47, 16, 16, TFT_WHITE);  //四角(塗り潰し)

  canvas.pushSprite(0, 0);    //準備したcanvasを座標を指定して表示する
  delay(100);                 //遅延時間
}

3.「M5GFX」ライブラリのインストールと初期設定

液晶表示器に表示を行うためには、まず表示するために必要なライブラリの追加を行います。
今回は「M5GFX」ライブラリを使用しますのでヘッダー部の2行目に以下のように記入します。

#include <M5UnitOLED.h> //M5GFXライブラリ使用

「PlatformIO」の「ホーム」画面の「Libraries」から「M5GFX」で検索して追加を行ってください

※ライブラリの追加方法は以下のリンクで「FastLED」ライブラリの追加で紹介しています。

PlatformIOでのライブラリの追加方法は → こちら

次に4行目~6行目のように液晶表示器との通信(I2C)設定と仮想描画領域(canvas)の準備を行います。

//OLED設定
M5UnitOLED display(26, 32, 400000); //任意の端子でI2Cを使用する場合(SDA, SCL, FREQ)
M5Canvas canvas(&display);          //表示する内容を保持する仮想画面をcanvasとして準備
M5UnitOLED display( SDA端子SCL端子周波数(400000)) ;
M5Canvas canvas( &display) ; 

M5UnitOLED display:表示器と通信する端子と通信周波数を指定するコマンド。
SDA端子:入出力可能な端子で任意に指定できます。(付属のGroveコネクタ配線黄色)
SCL端子:入出力可能な端子で任意に指定できます。(付属のGroveコネクタ配線白色)
周波数:周波数は400000で指定してください。

M5Canvas canvas(&display):表示する内容を保持する仮想画面を「canvas」として準備します。

画面への表示は一旦「canvas」として準備した仮想画面上に描画されます。
全ての描画が完了したら一括で表示させます。
これにより画面の「チラツキ」を抑えることができます。(後述

次に19行目~25行目のように液晶表示器の初期設定を行います。

void setup() {
  // OLED(M5GFX)初期設定
  display.init();             //液晶表示器初期化
  display.setRotation(1);     //表示方向(コネクタ位置基準):0下,1右,2上,3左
  canvas.setColorDepth(1);    //モノクロ(1ビット、白黒2色)カラーの場合は対応するビット数
  canvas.setTextWrap(false);  //改行をしない(画面をはみ出す時自動改行する場合はtrue)
  canvas.setTextSize(1);      //文字サイズ(倍率)
  canvas.createSprite(display.width(), display.height()); //canvasサイズ
}

基本的な初期設定は上コードのようになります。
表示方向を変えたい場合はコネクタの位置を基準にして0~3で指定してください。


4.表示用コマンドの紹介

次にサンプル画面の各表示のコマンド(35行目~77行目)について紹介します。


・①日本語の表示

日本語表示部を抜粋したものが以下になります。

  // 日本語表示
  canvas.setCursor(10, 0);                        //座標を指定
  canvas.setFont(&fonts::lgfxJapanGothicP_16);    //ゴシック体
  canvas.print("液晶表示テスト");       //表示内容をcanvasに準備
canvas.setCursor ( xy ) ;                //座標を指定
canvas.setFont ( &fonts::フォント ) ;  //フォントを指定
canvas.print ( 表示内容 ) ;                //表示内容を指定

canvas.setCursor:表示させたい位置を ( xy ) の座標で指定するコマンドです。
 座標の位置は文字の左上角になります。

canvas.setFont:フォントを指定するコマンドです。
 &fonts::に続けてフォント を指定します。
 使用できる日本語フォントは以下4種類になります。
 ・&fonts::lgfxJapanMincho_16):明朝体(固定長)
 ・&fonts::lgfxJapanMinchoP_16):明朝体(可変長)
 ・&fonts::lgfxJapanGothic_16):ゴシック体(固定長)
 ・&fonts::lgfxJapanGothicP_16):ゴシック体(可変長)
 _16のように数値で文字サイズを指定します。
 サイズは8,12,16,20,24,28,32,36,40です。

canvas.print:表示内容を指定します「   」で挟まれた内容が表示されます。


・②ボタンの動作で内容が変化

ボタンの動作で表示内容が変化する部分を抜粋したものが以下になります。
「if文」で本体ボタンの状態に応じて表示内容を切り替えます。
本体ボタンを押すと「BTN=ON」と表示されます。
本体ボタンを離すと「BTN=OFF」と表示されます。

// 本体ボタンON/OFF状態表示
canvas.setCursor(5, 23);        //座標を指定(2行目、左側)
canvas.setFont(&fonts::Font2);  //フォント設定
canvas.print("         ");      //表示内容消去

canvas.setCursor(5, 23);        //座標を指定(2行目、左側)
if (M5.Btn.isPressed()) {       //ボタンを押していれば
  M5.dis.drawpix(0, dispColor(0, 0, 100));  //本体LED青
  canvas.print("BTN=ON");       //ボタンオン状態表示
} else {                        //ボタンを押してなければ
  M5.dis.drawpix(0, dispColor(20, 20, 20)); //本体LED白
  canvas.print("BTN=OFF");      //ボタンオフ状態表示
}

表示位置、フォント、表示内容の指定方法は「①日本語の表示」と同じです。
フォントについて、ここでは「英数字」のみのフォント「Font2」を指定しています。
「英数字」のフォントは以下のようになります。
・英数字:Font0, 2, 4
・数字のみ:Font6, 7, 8で 7は「7セグ」風です。


・③ボタンを押した回数を表示

ボタンを押した回数を表示する部分を抜粋したものが以下になります。
ボタンが押されるごとに変数「cnt」のカウント数を+1して表示しています。

// 本体ボタンON回数カウント表示
if (M5.Btn.wasPressed()) {      //ボタンが押されていたら
  cnt++;                        //カウント+1
}
canvas.setCursor(68, 23);       //座標を指定(2行目右側)
canvas.setFont(&fonts::Font2);  //フォント設定 0,2,4,6,7,8
canvas.print("CNT=");           //カウント数
canvas.setCursor(100, 24);      //座標を指定(2行目右側)
canvas.setTextSize(0.3);        //文字サイズ変更
canvas.setFont(&fonts::Font7);  //7セグ
canvas.printf("%03d", cnt);     //カウント数(3桁指定)
canvas.setTextSize(1);          //文字サイズ1へ戻す

表示位置、フォント、表示内容の指定方法は「①日本語の表示」と同じです。
フォントについて、ここでは「英数字」のみのフォント「Font2」を指定しており、カウント数は「7セグ」風の「Font7」を指定しています。

「Font7」の文字サイズは大きいため「0.3」倍に小さくして、表示が終わったら今後の表示のために「1」倍に戻しています。


・④指定した座標から平行線

指定した座標から平行線を描く場合は以下のように指定します。

canvas.drawFastHLine(0, 40, 128, TFT_WHITE);  //線(指定座標から平行線)
canvas.drawFastHLine(x, y, 長さ, TFT_); 

x, yで座標を指定して、その座標からの長さを指定します。
はこの液晶はモノクロなのでTFT_WHITEとなります。


・⑤始点終点を座標で指定した線

始点終点を座標で指定した線を描く場合は以下のように指定します

canvas.drawLine(0, 20, 128, 20, TFT_WHITE);   //線(始点終点指定)
canvas.drawLine(x1, y1, x2, y2, TFT_);

始点をx1, y1、終点をx2, y2で指定してそれぞれを結ぶ線を描きます。
はこの液晶はモノクロなのでTFT_WHITEとなります。

・⑥指定した座標から垂線

指定した座標から垂線を描く場合は以下のように指定します。

canvas.drawFastVLine(64, 22, 17, TFT_WHITE);  //線(指定座標から垂線)
canvas.drawFastVLine(x, y, 長さ, TFT_); 

x, yで座標を指定して、その座標からの長さを指定します。
※長さは指定した座標から下へ向けて指定します。
はこの液晶はモノクロなのでTFT_WHITEとなります。

・⑦円と塗り潰し円

円と塗り潰し円は以下のように指定します。

canvas.drawCircle(10, 55, 8, TFT_WHITE);    //円
canvas.fillCircle(30, 55, 8, TFT_WHITE);    //円(塗り潰し)
canvas.drawCircle(x, y, 半径, TFT_);
※塗り潰しはcanvas.fillCircleで指定

円の中心をx, yで指定して、半径を指定することで円を描きます。
はこの液晶はモノクロなのでTFT_WHITEとなります。

・⑧三角と塗り潰し三角

三角と塗り潰し三角は以下のように指定します。

canvas.drawTriangle(46, 62, 54, 48, 62, 62, TFT_WHITE); //三角
canvas.fillTriangle(66, 62, 74, 48, 82, 62, TFT_WHITE); //三角(塗り潰し)
canvas.drawTriangle(x1, y1, x2, y2, x3, y3, TFT_);
※塗り潰しはcanvas.fillTriangleで指定

座標 x1, y1x2, y2x3, y3 を結ぶ三角を描きます。
はこの液晶はモノクロなのでTFT_WHITEとなります。

・⑨四角と塗り潰し四角

四角と塗り潰し四角は以下のように指定します。

canvas.drawRect(90, 47, 16, 16, TFT_WHITE);   //四角
canvas.fillRect(110, 47, 16, 16, TFT_WHITE);  //四角(塗り潰し)
canvas.drawRect(x, y, , 高さ, TFT_);
※塗り潰しはcanvas.fillRectで指定

四角の左上座標を x, y で指定して幅と高さを指定して四角を描きます。
※高さは指定した座標から下へ向けて指定します。
はこの液晶はモノクロなのでTFT_WHITEとなります。


5.仮想描画領域「canvas」について

表示する文字や図形の座標、寸法の指定が終わったら、サンプルプログラムの79行目のように以下を実行して画面への表示を行います。

canvas.pushSprite(0, 0);    //準備したcanvasを座標を指定して表示する

サンプルプログラムの6行目で以下のように指定して、表示する内容を保持する仮想画面をcanvasとして準備しています。

M5Canvas canvas(&display);  //表示する内容を保持する仮想画面をcanvasとして準備

表示する画面はまず、この仮想画面上に描画され「canvas.pushSprite」を実行する事で画面に一括で出力されます。

仮想画面に描画せず、直接液晶画面に表示させることもできます。
この場合は「canvas」の部分を「display」で指定します。


試しに40行目~52行目の「②ボタンの動作で表示内容が変化」するプログラムを「display」で指定して表示してみましょう。

下コードをコピーして40行目~52行目を置き換えてください。

// 本体ボタンON/OFF状態表示
display.setCursor(5, 23);        //座標を指定(2行目、左側)
display.setFont(&fonts::Font2);  //フォント設定
display.print("         ");      //表示内容消去

display.setCursor(5, 23);        //座標を指定(2行目、左側)
if (M5.Btn.isPressed()) {        //ボタンを押していれば
  M5.dis.drawpix(0, dispColor(0, 0, 100));  //本体LED青
  display.print("BTN=ON");       //ボタンオン状態表示
} else {                         //ボタンを押してなければ
  M5.dis.drawpix(0, dispColor(20, 20, 20)); //本体LED白
  display.print("BTN=OFF");      //ボタンオフ状態表示
}

書き込んで実行すると「②ボタンの動作で表示内容が変化」の部分の表示だけが点滅していると思います。

この表示部は「ON」と「OFF」の表示文字数が違うため「OFF」のあとに「ON」を指定すると「OFF」の上に「ON」が表示されるため重なって「ONF」となってしまいます。

こうならないように事前に「”         “」スペースで全文消去を行っているので、消去して表示を繰り返しているためです。

canvas」で指定すると、「全文消去して表示した結果」が出力されますが
display」で指定すると、「全文消去して表示する過程」も表示されるため点滅するように表示されてしまいます。

このように「canvas」で指定した仮想画面を使用することで画面の「チラツキ」を抑えることができます。

処理速度の長いプログラムで高速で表示させたい時は「display」で指定した方が良い場合もあるので用途に応じて使い分けましょう
今回の場合は「”         “」のようにスペースで全文消去せずに「ON」の後にスペースを入れて「ON 」とすることで「OFF」と文字数を合わせれば問題なく表示できます。
書き方によっては少ないコードで同じ動作をさせることができるので、いろいろ工夫してみましょう。

以前紹介したストップウオッチを作るプログラムでは0.01秒の表示を高速で行いたいため「display」を採用しています。

ストップウオッチを作ろう(タイマー割込み使用)の記事は → こちら

コメント

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