
Arduino UNO R4でJPEGDecoderとSdFatを動かす:期待したほど速くはなかった
Arduino UNO R4でディスプレイ表示ができるようになったので、次の段階として画像を表示したいと思います。BMPの表示はTFTのサンプルであるので、圧縮画像としてJPEG画像を表示させたいと思います。
といっても、すでにJPEGDecoderというライブラリがあるので、SDカードに保存されたJPEG画像を表示するのは、SDライブラリとJPEGDecoderライブラリをライブラリマネージャでインストールすれば、SDカードに保存したJPEGファイルをデコードできます。
Arduino UNO R4用にコンパイルする場合は、コンパイルオプションに-fpermissiveを付ける必要があるかと思います。その方法(platform.txtを修正する方法)はOLEDディスプレイのときの説明を参考にしてください。


ただ、SDライブラリは、残念ながら8文字+拡張し子3文字のファイル名にしか対応していません。ロングファイル名に対応しているものとしてSdFatライブラリというのがあります。ネットを見るとアクセス速度的にもSDライブラリより速いらしいです。
JPEGDecoderはSdFatライブラリにも対応しているようなのですが、Arduino UNO R4の環境で試してみたところ、SdFatライブラリではコンパイルがうまく通りませんでした。
なので、UNO R4のコンパイラでもコンパイルできるように改修してみました。
Arduino IDEのメニュー「スケッチ」ー「ライブラリをインクルード」ー「.ZIP形式のライブラリをインストール」を選び、ダウンロードしたzipファイルを選べばインストールできます。インストール場所は、
$HOME/Arduino/libraries/JPEGDecoder_v2.0kです。
ライブラリマネージャを使ったオリジナルのJPEGDecoderライブラリのインストールは必要ありません。すでにオリジナルのJPEGDecoderをインストールしてある場合は、$HOME/Arduino/libraries/JPEGDecoderディレクトリを削除してください。
SDカードのアクセスにSdFatライブラリを使う場合には、ライブラリマネージャの画面でSdFatライブラリをインストールします。

ライブラリをインストールしたら、試しにメニューの「ファイル」ー「スケッチ例」ー「JPEGDecoder v2.0k」の中のTFT_Jpeg_UNO_R4を開いて、コンパイル、書き込みをしてみてください。

SDライブラリを使うかSdFatライブラリを使うかは、$HOME/Arduino/libraries/JPEGDecoder_v2.0/src/User_Config.hの中で指定します。
SDライブラリを使う場合には、LOAD_SD_LIBRARYを有効にして、LOAD_SDFAT_LIBRARYとSDFAT_FILE_TYPEをコメントアウトします。SdFatライブラリを使う場合はその逆です。下記は、SdFatライブラリを使う場合の例です。
// #define LOAD_SD_LIBRARY // Default SD Card library
#define LOAD_SDFAT_LIBRARY // Use SdFat library instead, so SD Card SPI can be bit bashed
#define SDFAT_FILE_TYPE 1 // 1:SdFat32, 2:SdExFat, 3:SdFs
サンプルのTFT_Jpeg_UNO_R4.inoは、ディスプレイにSeeed studioのTFT Touchシールドを使っていますが、ディスプレイを使わずにデコードだけを試す場合には、#define ENABLE_TFTをコメントアウトすれば、ディスプレイがなくても動作します。但し、SDカードのインタフェースを別途用意する必要があります。
また、デコード対象として、$HOME/Arduino/libraries/JPEGDecoder_v2.0k/extras内のJPEGファイル(arduino.jpgなど)を、パソコンなどでSDカードに書き込んでおいてください。
SDライブラリを使った場合とSdFatライブラリを使った場合の速度を比較してみました。画像はarduino.jpgとtiger.jpgです。デコード画像のディスプレイへの描画は何の工夫もしていなく、1画素ごとに書き込んでいます。




SdFatの方が速度は速くなりますが、ディスプレイの描画をしない場合を見ると、若干速いという程度です。ディスプレイに描画した場合は、差はやや広がりますがそれでも少し速くなるという程度でした。
ディスプレイに描画したときの方が速度差が大きくなる原因は定かではありませんが、ディスプレイとSDカードとを共通のSPIでアクセスしているためかなと思います。
iPhoneで撮影した大きなJPEG画像のデコードも試してみました。描画はディスプレイの大きさ(240x320画素)の範囲だけなので、描画なしとの差は少ないです。どちらも2分弱と、とても時間がかかります。

結果として、SdFatライブラリは期待したほど速くありませんでした。小さなディスプレイに表示する程度の小さなJPEG画像であるなら無理して使わなくても、標準的なSDライブラリでも良いのかなと思いました。SdFatを使うメリットは、ロングファイル名が使えるということの方が大きいように思います。
修正したJPEGDecoderライブラリでは、UNO R4環境でコンパイルする場合には、SDライブラリのグローバルオブジェクト(SD)を使っているdecodeSdFile()メソッドのほとんどと、decodeFile()メソッドを使えなくしています。UNO R4以外のコンパイル環境ではオリジナルと同じとなるように修正したつもりですが、試してないのでわかりません。
インストールした修正版JPEGDecoderライブラリを削除したい場合は、$HOME/Arduino/libraries/JPEGDecoder_v2.0kディレクトリをまるごと削除してください。