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ラボデジタルサイネージ(短期ワークショップ用テキスト)

Last updated at Posted at 2021-11-29

本記事は、株式会社 函館ラボラトリが運営する「Bラボ」における、大人向け「看板アプリ(デジタルサイネージ)を作るコース」用テキストです。
一からコードを書くわけではなく、あらかじめ用意したコードの一部を改変しながら、デジタルサイネージを作っていきましょう。

テンプレートプログラムは、下記GitHubリポジトリのShortTermディレクトリに入っています。

(11/29時点、本テキストは執筆中です)

デジタルサイネージとは何か?

下記記事の「概要」をご参照ください。

必要なもの

下記記事の「必要なもの」をご参照ください。

実装

あらかじめ途中まで実装した状態のプログラムを用意します(ShortTermディレクトリの中にあります)。
1つの機能をもつパーツ(モジュール)がすでに実装されていますが、現時点で実行しても各モジュールは表示されません。

モジュールについての説明は、下記記事の「機能実現の方針」をご参照ください。

ひとつひとつのモジュールが表示されるよう、プログラムを書いていきましょう。

電子部品の配置

モジュールのうち、下記のモジュールの機能を実現するために、ブレッドボード上に電子部品を配置します。

  • 開店/閉店表示機能(OpenCloseRModule)用のスライドスイッチ
  • 温度表示機能(TemperatureRModule)用の温度センサ
  • 明るさ表示機能(BrightnessRModule)用の明るさセンサ

スライドスイッチの配置

下記記事の「電子部品の配置」に従い、ブレッドボードに部品を配置してください。

温度センサの配置

下記記事の「電子部品の配置」に従い、ブレッドボードに部品を配置してください。

明るさセンサの配置

下記記事の「電子部品の配置」に従い、ブレッドボードに部品を配置してください。

モジュール表示、ページ切り替えの実装

1つの機能を持つ塊である「モジュール」の分類については、下記記事の「機能実現の方針」をご覧ください。

これらのモジュールたちを画面に配置し、情報が表示されるようにします。

モジュールの表示(1ページ目)

各モジュールを表示する関数は、drawBusRModule()のように、頭に「draw」とつく関数として用意されています。
モジュール表示用の関数は、いまは何も描画していない関数drawModules()内で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }
}

まずは1ページ目を作ってみましょう。
下図のような画面を作ります。

0041.png

「GridModule」でモジュール配置場所の基準線を表示

0003.png

「GridModule」の描画用関数は、M_Grid.pde内のdrawGridModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawGridModule(); /* 追加 */
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }
}

「PlaceholderModule」でモジュール配置場所に枠を表示

0008.png

「PlaceholderModule」の描画用関数は、M_Placeholder.pde内のdrawPlaceholderModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawGridModule();
    drawPlaceholderModule(); /* 追加 */
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }
}

「FullImageModule」で画面全体に画像を表示

0006.png

「FullImageModule」の描画用関数は、M_FullImage.pde内のdrawFullImageModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。
かっこの中には、すでに読み込んである画像backgroundを入れます。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background); /* 追加 */
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }
}

「LocationModule」でデジタルサイネージ設置場所を表示

0054.png

定数LOCATIONに入っている文字列を表示します。

DigitalSignage.pde
// デジタルサイネージが設置されている場所や店舗などを書く。
final String LOCATION = "北海道函館市美原2丁目 / MIRAI BASE";

「LocationModule」の描画用関数は、M_Location.pde内のdrawLocationModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule(); /* 追加 */
}

「DateModule」で現在時刻を表示

0036.png

「DateModule」の描画用関数は、M_Date.pde内のdrawDateModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule(); /* 追加 */
}

「ProgressBarModule」で次のページに切り替わるまでの時間を視覚化

0038.png

「ProgressBarModule」の描画用関数は、M_ProgressBar.pde内のdrawProgressBarModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule(); /* 追加 */
}

「PageControlModule」で現在表示中のページを視覚化

0020.png

「PageControlModule」の描画用関数は、M_PageControl.pde内のdrawPageControlModule()として実装されています。
この関数を、drawModules()nowPageID=0の部分で呼び出します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule(); /* 追加 */
}

「WeatherRModule」で現在の天気を表示

0015.png

OpenWeatherのアカウントを取得していることが前提です。
下記記事の「必要な変数の定義」に従って、API Keyを取得します。

API Keyは、定数WEATHER_API_KEYへ代入してください。

DigitalSignage.pde
final String WEATHER_API_KEY = "取得したAPI Key";

WeatherRModuleを描画します。
描画時の基準となるエリアはArea.area1とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1); /* 追加 */
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

「BusRModule」でバス停の直近2件の時刻表を表示

0023.png

下記記事の「時刻表スプレッドシートの作成」の手順で得たURLを使い、バスの時刻表を取得します。
作成したAPIのURLを定数BUS_API_URLに代入します。

DigitalSignage.pde
final String BUS_API_URL = "取得したURL";

BusRModuleを描画します。
描画時の基準となるエリアはArea.area3とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3); /* 追加 */
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

「GomiRModule」で直近1週間のごみカレンダーを表示

0004.png

下記記事の「ごみカレンダースプレッドシートの作成」以降に従い、APIを作ってください。

得られたAPIのURLを、定数GOMI_API_URLに代入します。

DigitalSignage.pde
final String GOMI_API_URL = "取得したURL";

GomiRModuleを描画します。
描画時の基準となるエリアはArea.area5とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3);
    drawGomiRModule(Area.area5); /* 追加 */
  } else if (nowPageID == 1) {
    // ModuleやRModuleの描画用関数を呼び出す
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

ページ切り替えの実装

デジタルサイネージの画面を、10秒ごとに自動で切り替わるようにします。
下記記事の「ページ更新用の関数」に従い、関数updatePageID()を完成させてください。

モジュールの表示(2ページ目)

0145.png

「TwitterRModule」で画像付きツイートを表示

0013.png

Twitterアカウントを持っており、Developer Accountとしての申請がTwitter社に受理された状態が前提です。
下記記事の「ライブラリ導入」に従い、ライブラリ「Twitter4J」を導入してください。
Twitter APIで取得できる4つのキーを、下記記事「キーの取得」に従い取得してください。

各キーは定数に代入します。

DigitalSignage.pde
final String CONSUMER_KEY = "取得したAPI Key";
final String CONSUMER_KEY_SECRET = "取得したAPI Key Secret";
final String ACCESS_TOKEN = "取得したAccess Token";
final String ACCESS_TOKEN_SECRET = "取得したAccess Token Secret";

TwitterRModuleを描画します。
描画時の基準となるエリアはArea.area3とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3);
    drawGomiRModule(Area.area5);
  } else if (nowPageID == 1) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawTwitterRModule(Area.area3); /* 追加 */
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

「OpenCloseRModule」で開店/閉店を表示

0189.png

0010.png

OpenCloseRModuleを描画します。
描画時の基準となるエリアはArea.area5とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3);
    drawGomiRModule(Area.area5);
  } else if (nowPageID == 1) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawTwitterRModule(Area.area3);
    drawOpenCloseRModule(Area.area5); /* 追加 */
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

「TemperatureRModule」で温度を表示

0011.png

TemperatureRModuleを描画します。
描画時の基準となるエリアはArea.area1とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3);
    drawGomiRModule(Area.area5);
  } else if (nowPageID == 1) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawTemperatureRModule(Area.area1); /* 追加 */
    drawTwitterRModule(Area.area3);
    drawOpenCloseRModule(Area.area5);
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

「BrightnessRModule」で明るさを表示

0037.png

BrightnessRModuleを描画します。
描画時の基準となるエリアはArea.area2とします。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3);
    drawGomiRModule(Area.area5);
  } else if (nowPageID == 1) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawTemperatureRModule(Area.area1);
    drawBrightnessRModule(Area.area2); /* 追加 */
    drawTwitterRModule(Area.area3);
    drawOpenCloseRModule(Area.area5);
  } else if (nowPageID == 2) {
    // ModuleやRModuleの描画用関数を呼び出す
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

広告画像の表示

配列adImageに入っている画像を、drawFullImageModule()で描画します。

DigitalSignage.pde
void drawModules() {
  if (nowPageID == 0) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawWeatherRModule(Area.area1);
    drawBusRModule(Area.area3);
    drawGomiRModule(Area.area5);
  } else if (nowPageID == 1) {
    drawFullImageModule(background);
    drawGridModule();
    drawPlaceholderModule();
    drawTemperatureRModule(Area.area1);
    drawBrightnessRModule(Area.area2);
    drawTwitterRModule(Area.area3);
    drawOpenCloseRModule(Area.area5);
  } else if (nowPageID == 2) {
    drawFullImageModule(adImage[0]); /* 追加 */
  }

  drawLocationModule();
  drawDateModule();
  drawProgressBarModule();
  drawPageControlModule();
}

これでデジタルサイネージの実装は完了です。
もし余力があれば、各モジュールをカスタマイズしてみてください。

デジタルサイネージを1から作ってみたい方へ

プログラムを段階的に書いていく形式の記事を用意しています(20本のシリーズです)。
下記の記事から読み始めてください。

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?