MFT2014に出展したmbedを使ったニコニコ新着動画表示器

この記事はmbed Advent Calendar 2014 - Adventarの18日目の記事です。

以前、作ったニコニコ新着動画表示器にサムネイル表示機能をつけて、MFT2014で展示してきました。

1. 全体の構成

大きな構成は変更しておらず、mbedからHerokuを経由してニコニコ新検索βAPIニコニコ大百科に書いてあった動画情報を取得するAPIへアクセスして、データを返しています。

2. Heroku上で動いているプログラム

mia-0032/nico-category-recent-videos-for-mbed · GitHub

で公開しています。

以下の2つのAPIを作りました。

  1. カテゴリを指定すると新着動画を取得し、mbedで表示するために整形して、JSON形式で返すAPI
  2. 動画IDを指定するとその動画のサムネイルをbmp3に変換して返すAPI

mbedでjpegのデコードライブラリをいくつか試したのですが、画像によってはうまくいかないことがあったので、サーバー側ですべてbmp3に変換しています。

ビットマップ形式はデコードが必要なく、1バイトずつ読みこめば画像を表示することができるので、扱いが楽で良いです。

ついでにサーバー側でサムネイルサイズの違いを吸収して、すべて128*128で返すようにしており、mbed側で画像のサイズに合わせてオフセットをつけるといった処理を省きました。

3. mbed側の処理

サムネイル表示にはMARY-OB OLED基板を使いました。

mbedとの接続は以下のようにしています。

p5 <-> OLED_SDIN
p7 <-> OLED_SCK
p8 <-> OLED_CNS
p12 <-> OLED_RESN
p11 <-> OLED_VCC_ON

書いたプログラムは以下に公開しています。

mbed_recent_nicovideo_display_pub - a mercurial repository | mbed

Herokuのホスト名部分(SERVER_HOST)だけ変えれば動くと思います。

MARY-OB OLED基板用のライブラリとして MARMEX_OB基板OLEDライブラリ (MARMEX_OB_oled) | mbed を使っています。

mbedのバージョンアップで、そのままだと動かないので、SPI_FREQUENCY = 16000000に変更して動かしています。

mbed側では以下のように処理を行っています。

  1. カテゴリ名を指定してHerokuにアクセスし新着動画の取得。
  2. JSONをパースし、動画ID、カテゴリ、タイトルを取得。
  3. 動画IDを指定してHerokuにアクセスして動画サムネイル画像を取得。
  4. 一度、mbedのストレージに画像を書き出す。
  5. 画像を読み出し、OLEDへ表示。
  6. タイトルなどをOLEDへ表示。

3と4についてはaccess_thumb_apiの関数で行っています。

bmpファイルは424Dから始まるので、ネットワークから取得したデータのその部分からローカルファイルに書き出しています。

5の部分についてはdisplay_bmpの関数で行っています。

bmp3は最初の54バイトはヘッダ情報になっているのでスキップして、それ以降のデータを表示しています(注:今回はあらかじめサーバー側でサイズなどを全部固定しているのでスキップして問題ないです)。

bmpファイルは画像の左下から右上の順にデータが並んでおり、それをそのままOLEDのドットに反映しているので、下から更新されていく感じになっています。

4. 現状の問題

  • 有機ELモジュール SEL10016B (文字を表示している方)の初期化がうまくいかない問題があります。
    • 電源投入直後は初期化処理がうまくいかないようで、一度、有機ELモジュールを抜いて、その後mbedをリセットをすると表示されるようになります。
      • 初期化処理のタイミングの問題かなとは思っています。
  • 長時間動作させるとフリーズします。
    • まだ原因不明です。
  • サムネイル表示処理(ダウンロードと表示)に数十秒かかっています。
    • ダウンロードしたファイルをストレージに書き込む部分で時間がかかっているようです。
    • できればもう少し高速化したいところです。

5. まとめ

  • サーバー側でだいぶ処理を挟んで楽をしました。
  • 使いたい部品についてmbed.orgで探すとたいてい誰かが作ったライブラリがあるのがいいです。

明日は@ssci_officialさんです。よろしくお願いします。