ESP32でssd1306を使って複数のページを表示してみる

ESP32でssd1306を使って複数のページを表示してみる

動いている様子

参考にしたサイト

SSD1306を使うためのライブラリのページ。下の方にページ分けするためのAPIが書かれています。

前提となる記事

ソフトウェア関連

  • windows10 home
  • Arduino 1.8.5
  • ESP32 core for arduino 1.0.0

使用部品

ESP32のピン配置

回路


ソースコード(コピペで動く)

#include "SSD1306Wire.h"
#include "OLEDDisplayUi.h"

SSD1306Wire  display(0x3c, 21, 22);
OLEDDisplayUi ui( &display );

void msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->setFont(ArialMT_Plain_10);
  display->drawString(30, 0, "Brightness: " + String(analogRead(A7)));
}

void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->setFont(ArialMT_Plain_16);
  display->drawString(10 + x,20 + y,"Wak-tech.com");
}

void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->setFont(ArialMT_Plain_24);
  display->drawString(0+x,30+y,"Page 2");
}

FrameCallback frames[] = { drawFrame1, drawFrame2};

int frameCount = 2;

OverlayCallback overlays[] = { msOverlay };
int overlaysCount = 1;

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  pinMode(A7,INPUT);
  
  ui.setTargetFPS(30);

  // You can change this to
  // TOP, LEFT, BOTTOM, RIGHT
  ui.setIndicatorPosition(BOTTOM);

  // Defines where the first frame is located in the bar.
  ui.setIndicatorDirection(LEFT_RIGHT);

  // You can change the transition that is used
  // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN
  ui.setFrameAnimation(SLIDE_LEFT);

  // Add frames
  ui.setFrames(frames, frameCount);

  // Add overlays
  ui.setOverlays(overlays, overlaysCount);

  // Initialising the UI will init the display too.
  ui.init();

}


void loop() {
  int remainingTimeBudget = ui.update();

  if (remainingTimeBudget > 0) {
    delay(remainingTimeBudget);
  }
}

解説

このプログラムはスケッチ例をベースに作りました。スケッチ例は以下のように開けます。

uiのライブラリが提供されていて、それを使うようです。簡単な流れを説明すると、

  1. ui制御をするuiオブジェクトを作る
  2. 描画したいページをフレームの関数として用意
  3. フレームの関数をuiオブジェクトに入れる

となります。

コードで説明すると、

SSD1306Wire  display(0x3c, 21, 22);
OLEDDisplayUi ui( &display );

void Frame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->setFont(ArialMT_Plain_16);
  display->drawString(10 + x,20 + y,"Wak-tech.com");
}

void Frame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->setFont(ArialMT_Plain_24);
  display->drawString(0+x,30+y,"Page 2");
}

//関数の名前の入ったリストを作る
FrameCallback frames[] = {Frame1,Frame2}

//フレームの数の指定
frameCount = 2
//framesに入ったページをセット
ui.setFrames(frames, frameCount);

が全体の流れです。Frame1の中身は普通に描画するのと書き方は変わりませんね。ただ一つ変化しているのは、座標にx,yが入っているという点です。このようにしないと画面が移り変わってくれません。

常に画面に固定される「Overlay」を設定する

Overlayも同様にまず関数を作ります。

void msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
  display->setTextAlignment(TEXT_ALIGN_LEFT);
  display->setFont(ArialMT_Plain_10);
  display->drawString(30, 0, "Brightness: " + String(analogRead(A7)));
}

Frameと違う点は、x,yを入れなくていいということです。画面に固定されるからですね。ここではA7に繋がったフォトトランジスタの値を出力するようにしています。

その後、

OverlayCallback overlays[] = { msOverlay };
int overlaysCount = 1;
ui.setOverlays(overlays,overlaysCount);

でオーバーレイを登録します。もちろん、overlays[]は複数含めますので、上下に固定表示をさせるのも容易です。

インジケーターを表示する

インジケーターとは、ここでは画面下に表示されるページ数を表すもののことを言います。場所がTOP,LEFT,BOTTOM,RIGHTが選べるようです。私はBOTTOMを選びました。

ui.setIndicatorPosition(BOTTOM);

さらに、どの位置に最初のフレームが来るかを設定できます。

ui.setIndicatorDirection(LEFT_RIGHT);

フレームの移動方向を設定する

  // You can change the transition that is used
  // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN
  ui.setFrameAnimation(SLIDE_LEFT);

で左へと画面が流れていくような設定になります。

画面を更新する

ただこれだけでは画面が更新されません。更新するには、

ui.update()

をする必要があります。ですので、これをloop文に入れます。
さらにこの関数は処理の合間時間を返してくれるので、

int remainingTimeBudget = ui.update();

  if (remainingTimeBudget > 0) {
  //ここに好きな処理を入れる
    delay(remainingTimeBudget);
  }

その合間時間に他の処理をさせることができます。

そのほかの設定方法

そのほかのuiの設定はライブラリのgithubページに詳しく書かれています。

まとめ

これで、いろいろな情報を複数に分けて表示できるようになりました。
いよいよこれと天気APIおよびNTPの正確な時間を使って便利なお天気ステーションを作っていきます!

twitterアカウントの方で最新記事のお知らせや記事にならないような小さな情報を小出ししています。もしよろしければフォローお願いいたしますm(__)m

ご覧いただきありがとうございました!

>>ESP32チュートリアル一覧に戻る

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です