概要
少し前にネットで見かけた、電子ペーパーを額装して飾るとやたらカッコいいを試してみたいと思い、Spresenseで試してみました。Spresenseカメラボードで撮影したJPEG画像を、電子ペーパーに表示する実験です。電子ペーパーは、電子ペーパーの実験で試した、Waveshare社の400ドットx300ドット、3色(白、黒、黄)の電子ペーパーモジュールを利用しました。
以下のことを行いました。
このページでは、主にJPEGをビットマップに変換する部分を記載しています。
以下は、黄色の判断を強めに設定して、撮影したサンプルです。白と黒、黄色の3色しか表示できないので、色判断の閾値の設定が難しいです。この状態で他のものをとっても黄色が多くなりすぎます。
実験
写真を撮る
Spresense公式ページのCamera チュートリアルやCamera ライブラリを参考に以下のAPIを呼び出しました。theCamera
は、事前に定義されているオブジェクト名です(Serial
とかと同じです)。
API名 | 説明 |
---|---|
theCamera.begin() | カメラモジュールを初期化する。 |
theCamera.setAutoWhiteBalanceMode() | 自動ホワイトバランス調整モードを設定する。 |
theCamera.setAutoISOSensitive() | 自動ISO感度調整をする。 |
theCamera.setStillPictureImageFormat() | 静止画写真の画像フォーマットを設定する。 |
theCamera.takePicture() | 写真を撮影する。 |
JPEGをビットマップに変換する
JPEGデータからビットマップデータに変換するために、TJpgDec - Tiny JPEG Decompressorを利用しました。このライブラリは、小規模の組込みシステム向けに作成されていて、少メモリで動作するそうです。TJpgDec Module Application Noteに使い方が説明されています。
以下のAPIが提供されています。
API名 | 説明 |
---|---|
jd_prepare() | JPEGデータを解析して変換プロセスの準備を行う。 |
jd_decomp() | JPEGイメージをRGBデータに変換する。 |
上記のAPIを利用するために、目的やJPEGデータの保存形態に沿った、以下の構造体と関数を作成する必要があります。
作成するもの | 説明 |
---|---|
IODEV構造体 | 以下のコールバック関数内で参照可能な構造体。 |
入力関数 | JPEGデータを読みこむ。jd_prepare()から呼び出されるコールバック関数。 |
出力関数 | ビットマップデータを取得する。jd_decomp()から呼び出されるコールバック関数。 |
IODEV構造体
入力関数と出力関数から参照可能な構造体です。この構造体は、TJpgDec自身が利用するわけではなく、以下の入力関数と出力関数で自分が利用するためのものです。
グローバル変数を利用するなどのときは、特になくても問題はありません。TJpgDec内では、void*型なので、IODEVという型名である必要もないようです。
今回は、入力関数で利用するために、以下の構造体を定義しました。
|
|
入力関数
JPEGデータを読みこみ、TJpgDecライブラリに渡すための関数です。jd_prepare()から複数回呼び出されます。以下の形で定義します。
|
|
JDECは、ライブラリが利用するデータを格納するための構造体です。jdec->device
が、先ほど定義した、IODEV構造体へのポインタを保持しています。
この関数で必要な操作は以下の通りです。
- buffがNULLでない場合は、JPEGデータの現在位置からndataバイト分のデータを、buffにコピーする。
- buffがNULLの場合は、ndataバイト分のJPEGデータを読み飛ばす。
- コピーしたデータもしくは読み飛ばしたデータのサイズ(基本的にはndata)を返却する。
出力関数
デコードされたビットマップデータを、取得するための関数です。jd_decomp()から複数回呼び出されます。以下の形で定義します。
|
|
TJpgDecライブラリは、JPEGデータを一気にデコードするわけではなく、小さい矩形領域のデータを何回も返却するようです。矩形領域の情報は上記のrectに格納されています。JRECTは、以下のように定義されています。
|
|
この矩形領域のビットマップデータが、左上から右下に向かって、bitmapに格納されています。ビットマップデータは、RGB888もしくはRGB565で、1ピクセル分のデータが、RGB888の場合は3バイト、RGB565の場合は1バイト単位で格納されています。
RGB888を利用するのかRGB565を利用するのかは、ヘッダファイル(tjpgd.h)内のJD_FORMATというマクロで制御します。0の場合RGB888、1の場合RGB565です。
出力関数では、このデータを自分の用途に合わせて加工していきます。
ビットマップを電子ペーパーに表示する
こちらは、電子ペーパーの実験の通りに行いました。Spresenseでも問題なく動作しました(ピン番号もデフォルトのままで動作しました)。
プログラム
接続
Spresenseと電子ペーパーモジュールは以下のように接続しました。
Spresenseのピン | 意味 | 電子ペーパーモジュールのピン | 備考 |
---|---|---|---|
3.3V | 電源 | 3.3V | |
GND | GND | GND | |
11 | MOSI | DIN | SPI |
13 | SCK | CLK | SPI |
10 | CS | CS | |
9 | DC | DC | |
8 | RST | RST | |
7 | BUSY | BUSY |
プログラム
プログラムを以下に示します。利用していない関数も含まれています。
|
|
バージョン
Hardware: | Spresense |
Software: | Arduino IDE 1.8.13/Spresense Arduino Library 2.0.2 |
最終更新日
July 14, 2024