0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Bラボデジタルサイネージ19】起動画面を表示する「LaunchingScreenModule」

Last updated at Posted at 2021-11-12

本記事は、株式会社 函館ラボラトリが運営する「Bラボ」における、大人向け「看板アプリ(デジタルサイネージ)を作るコース」用教材テキストです。

  1. 【Bラボデジタルサイネージ1】Processing+ラズパイでデジタルサイネージを作る!
  2. 【Bラボデジタルサイネージ2】ラズパイ初期設定
  3. 【Bラボデジタルサイネージ3】準備プログラム作成&機能実現の方針決定
  4. 【Bラボデジタルサイネージ4】レイアウトの基準になるグリッドを表示する「GridModule」
  5. 【Bラボデジタルサイネージ5】レイアウトの基準になる枠を表示する「PlaceholderModule」
  6. 【Bラボデジタルサイネージ6】画像を全画面表示する「FullImageModule」
  7. 【Bラボデジタルサイネージ7】ページの自動切り替え
  8. 【Bラボデジタルサイネージ8】設置されている場所の名前を表示する「LocationModule」
  9. 【Bラボデジタルサイネージ9】現在の時間を表示する「DateModule」
  10. 【Bラボデジタルサイネージ10】ページ切り替えの時間が分かる「ProgressBarModule」
  11. 【Bラボデジタルサイネージ11】現在の表示中のページが分かる「PageControlModule」
  12. 【Bラボデジタルサイネージ12】現在の天気を表示する「WeatherRModule」
  13. 【Bラボデジタルサイネージ13】直近2件のバス時刻表を表示する「BusRModule」
  14. 【Bラボデジタルサイネージ14】ごみ出しカレンダーを表示する「GomiRModule」
  15. 【Bラボデジタルサイネージ15】(発展編)ツイートを表示する「TwitterRModule」
  16. 【Bラボデジタルサイネージ16】開店/閉店を表示する「OpenCloseRModule」
  17. 【Bラボデジタルサイネージ17】部屋の温度を表示する「TemperatureRModule」
  18. 【Bラボデジタルサイネージ18】部屋の明るさを表示する「BrightnessRModule」
  19. 【Bラボデジタルサイネージ19】起動画面を表示する「LaunchingScreenModule」(本記事)
  20. 【Bラボデジタルサイネージ20】RModuleの影を実装

作るもの

現状は起動時に何も表示されない状態のため、データの読み込みが完了するまでの間、起動画面を表示できるようにします。

0007.png

現状の初期化処理

これまでの記事を通して実装した各機能の実現のため、多くの画像をデジタルサイネージに使用しました。
しかし画像の読み込みやWeb APIの利用といった処理は、完了するまでに時間がかかります。

現状の関数setup()内での初期化は、関数initialize()を呼ぶことで実現しています。

DigitalSignage.pde
void setup() {
  frameRate(1);
  noCursor();
  colorMode(HSB, 360, 100, 100, 100);
  WHITE_COLOR = color(0, 0, 100);
  NEARLY_WHITE_COLOR = color(100, 2, 98);
  NEARLY_GREEN_COLOR = color(100, 5, 98);
  BLACK_COLOR = color(0, 0, 0);
  LIGHT_COLOR = color(0, 0, 80);
  GRAY_COLOR = color(0, 0, 50);
  GREEN_COLOR = color(150, 100, 60);
  
  textFont(createFont("NotoSansCJKjp-Bold", 32));
  
  background = pImageCut(loadImage("background.jpg"), CENTER, CENTER, width, height);
  
  GPIO.pinMode(SWITCH_PIN, GPIO.INPUT);
  i2c = new I2C(I2C.list()[0]);
  spi = new SPI(SPI.list()[0]);
  spi.settings(500000, SPI.MSBFIRST, SPI.MODE0);
  
  initialize();
}

関数initialize()では、すべてのモジュールで使うデータを用意するため、実行完了まで多くの時間を要します。
これは、initialize()を実行完了するまで、関数draw()が実行されない(なにも画面に描画されない)ということを意味します。

起動画面を実現するには、画面の描画のためにdraw()を実行しつつ、initialize()でのデータ初期化を並行して実行する必要があります。
そこで、データ初期化を描画と並行して実行するために、「非同期処理」を実装してみます。

非同期処理を用いた初期化

Processingでは、関数thread()を使うことで、非同期処理が実現できます。
たとえば、関数initialize()が定義されている状態で、以下のように書くとします。

thread("initialize");

上の例だと、関数initialize()の処理を、描画処理と並行して実行することになります。
これを踏まえて関数setup()を書き換えます。

DigitalSignage.pde
void setup() {
  frameRate(1);
  noCursor();
  colorMode(HSB, 360, 100, 100, 100);
  WHITE_COLOR = color(0, 0, 100);
  NEARLY_WHITE_COLOR = color(100, 2, 98);
  NEARLY_GREEN_COLOR = color(100, 5, 98);
  BLACK_COLOR = color(0, 0, 0);
  LIGHT_COLOR = color(0, 0, 80);
  GRAY_COLOR = color(0, 0, 50);
  GREEN_COLOR = color(150, 100, 60);
  
  textFont(createFont("NotoSansCJKjp-Bold", 32));
  
  background = pImageCut(loadImage("background.jpg"), CENTER, CENTER, width, height);
  
  GPIO.pinMode(SWITCH_PIN, GPIO.INPUT);
  i2c = new I2C(I2C.list()[0]);
  spi = new SPI(SPI.list()[0]);
  spi.settings(500000, SPI.MSBFIRST, SPI.MODE0);
  
  thread("initialize"); /* 変更 */
}

これで、関数initialize()setup()内で実行されますが、関数setup()initialize()の終了を待たずに終了するようになりました。
initialize()が実行中でも、並行して関数draw()の描画が実行されることになります。

(この時点で実行しても、まだエラーになります。)

どこまで初期化されたかを管理

0007.png

起動画面の「カレンダー取得」「画像取得」など、どこまで読み込みが済んだか(初期化されたか)を示すために、状態管理用の変数を宣言します。

DigitalSignage.pde
/* 略 */

int nowPageID = 0;

/* ここから追加 */
// 起動画面用の初期化済フラグ
boolean isInitializedImages = false;
boolean isInitializedDates = false;
boolean isInitializedWeather = false;
boolean isInitializedBus = false;
boolean isInitializedGomi = false;
boolean isInitializedTwitter = false;
/* ここまで追加 */

final String AD_PATH = "ad/";

/* 略 */

読み込みが完了した項目の値をtrueに変えるよう、関数initialize()に追記します。

Initialize.pde
void initialize() {
  initializeDate();
  isInitializedDates = true; /* 追加 */
  
  initializeImage();
  initializeGrid();
  initializePlaceholder();
  initializeRModuleBackground();
  isInitializedImages = true; /* 追加 */
  
  isUpdatedWeather = updateWeather();
  isInitializedWeather = true; /* 追加 */
  
  isUpdatedBus = updateBus();
  isInitializedBus = true; /* 追加 */
  
  isUpdatedGomi = updateGomi();
  isInitializedGomi = true; /* 追加 */
  
  isUpdatedTwitter = updateTwitter();
  isInitializedTwitter = true; /* 追加 */
  
  isUpdatedOpenClose = updateOpenClose();
  isUpdatedTemperature = updateTemperature();
  isUpdatedBrightness = updateBrightness();
}

LaunchingScreenModuleの描画

新しくM_LaunchingScreen.pdeを作り、関数drawLaunchingScreenModule()を定義します。

M_LaunchingScreen.pde
void drawLaunchingScreenModule() {

}

背景画像と「DIGITAL SIGNAGE」の文字、設置場所を表示します。

M_LaunchingScreen.pde
void drawLaunchingScreenModule() {
  /* ここから追加 */
  drawFullImageModule(background);
  
  drawText(CENTER, BASELINE, GREEN_COLOR, 148, "DIGITAL SIGNAGE", width/2, height/2-380);
  drawText(CENTER, BASELINE, BLACK_COLOR, 48, LOCATION, width/2, height/2-180);
  stroke(BLACK_COLOR);
  strokeWeight(5);
  noFill();
  line(300, height/2-200, width-300, height/2-200);
  /* ここまで追加 */
}

「カレンダー取得」「画像取得」など、どこまで読み込みが済んだかを表示する部分を作ります。
読み込みが済んだ項目は緑色、そうでない項目は黒色の文字で表示します。

M_LaunchingScreen.pde
void drawLaunchingScreenModule() {
  drawFullImageModule(background);
  
  drawText(CENTER, BASELINE, GREEN_COLOR, 148, "DIGITAL SIGNAGE", width/2, height/2-380);
  drawText(CENTER, BASELINE, BLACK_COLOR, 48, LOCATION, width/2, height/2-180);
  stroke(BLACK_COLOR);
  strokeWeight(5);
  noFill();
  line(300, height/2-200, width-300, height/2-200);

  /* ここから追加 */
  if (isInitializedDates) {
    drawText(CENTER, BASELINE, GREEN_COLOR, 36, "カレンダー取得", width/2, height/2+40);
  } else {
    drawText(CENTER, BASELINE, BLACK_COLOR, 36, "カレンダー取得", width/2, height/2+40);
  }
  
  if (isInitializedImages) {
    drawText(CENTER, BASELINE, GREEN_COLOR, 36, "画像取得", width/2, height/2+100);
  } else {
    drawText(CENTER, BASELINE, BLACK_COLOR, 36, "画像取得", width/2, height/2+100);
  }
  
  if (isInitializedWeather) {
    drawText(CENTER, BASELINE, GREEN_COLOR, 36, "天気情報取得", width/2, height/2+160);
  } else {
    drawText(CENTER, BASELINE, BLACK_COLOR, 36, "天気情報取得", width/2, height/2+160);
  }
  
  if (isInitializedBus) {
    drawText(CENTER, BASELINE, GREEN_COLOR, 36, "バス情報取得", width/2, height/2+220);
  } else {
    drawText(CENTER, BASELINE, BLACK_COLOR, 36, "バス情報取得", width/2, height/2+220);
  }
  
  if (isInitializedGomi) {
    drawText(CENTER, BASELINE, GREEN_COLOR, 36, "ごみカレンダー取得", width/2, height/2+280);
  } else {
    drawText(CENTER, BASELINE, BLACK_COLOR, 36, "ごみカレンダー取得", width/2, height/2+280);
  }
  
  if (isInitializedTwitter) {
    drawText(CENTER, BASELINE, GREEN_COLOR, 36, "ツイート取得", width/2, height/2+340);
  } else {
    drawText(CENTER, BASELINE, BLACK_COLOR, 36, "ツイート取得", width/2, height/2+340);
  }
  /* ここまで追加 */
}

起動画面を示すページ番号は-1として扱います。
ページ番号の初期値を変更します。

DigitalSignage.pde
int nowPageID = -1; /* 変更 */

データの初期化が終わった後に、ページ番号が-1から0になるようにします。

Initialize.pde
void initialize() {
  initializeDate();
  isInitializedDates = true;
  
  initializeImage();
  initializeGrid();
  initializePlaceholder();
  initializeRModuleBackground();
  isInitializedImages = true;
  
  isUpdatedWeather = updateWeather();
  isInitializedWeather = true;
  
  isUpdatedBus = updateBus();
  isInitializedBus = true;
  
  isUpdatedGomi = updateGomi();
  isInitializedGomi = true;
  
  isUpdatedTwitter = updateTwitter();
  isInitializedTwitter = true;
  
  isUpdatedOpenClose = updateOpenClose();
  isUpdatedTemperature = updateTemperature();
  isUpdatedBrightness = updateBrightness();

  updateNowPageID(true); /* 追加 */
}

関数draw()内で、ページ番号が-1の場合に対応できるよう条件分岐を書きます。

DigitalSignage.pde
void draw() {
  /* ここから変更 */
  if (nowPageID == -1) {
    drawLaunchingScreenModule();
  } else {
    updateDatas();
    drawModules();
  }
  /* ここまで変更 */
}

ここまで記述して実行してみると、読み込みが終わるまで起動画面が表示され、読み込みが終われば画面が切り替わるようになります。

0007.png

最後に

これで、起動画面を表示する「LaunchingScreenModule」が実装できました。
このシリーズは、次の記事で最後になります。
最後に**RModuleに影を実装**してみましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?