fc2ブログ
2021-03-11 17:00 | カテゴリ:Arduino関連

前回は、初の試みとして、6jiroさんとブログのシンクロ作戦を行いましたが、初の試みながら、楽しんでいただけたのではと思います。

今回は、前回の続きとして、「SDカードに記録したBMPファイルをOLEDに表示する」を検討していきます。

(ES0200)

ES0200.jpg



実は、このプログラムを相当苦労して製作していたのですが、6jiroさんが、あっという間に、しかも

実質数行のプログラムで、実現してしまうという、超快挙! 奇跡を起こしてしまうとは、この時は

知る由もありませんでした。

種明かしは、この記事の最後に。

続きは、、、、




そこで、私の方は、SDにはBMPデータを入れて、それをESP32の大きなメモリー上にすべて記憶し

それをOLEDに転送する仕様で検討
しています。

というのも、オリジナルでは、シリアルでPCのテキスト通信で送り込む仕様なので、データは

0Xff の形式で作成しなければならず、とても手作業では無理です。

なので、PCでBMPファイルを編集し、それをSDに書き込んで表示できるように検討を進めたいと

思います。


BMPファイルの形式はこのようになっています。


(ES0105)


BMPファイル構造
ES0105.jpg



ここから、BMPデータの先頭アドレスを見つけて、そこからデータを連続的に読みだします。



(ES0106)


BMP_Dump_Header_OK
ES0106.jpg



今回の使用するデータのBMPファイルのファイルダンプはこんな感じです。

ファイルヘッダはBMで、データの開始アドレスは、0x36で、ちゃんとそこから0xffの

データが始まっています。


(ES0107)


DataRead8192_begin
ES0107.jpg



(ES0108)

DataRead8192
ES0108.jpg





BMPデータがちゃんと読み出せているか確認する為に、読み出しソフトにデータを表示確認

する命令を入れて、読み出すアドレスとデータをSerialに表示させる様にしてみました。

これらを確認するとちゃんとデータが読み出せているようです。


そこで全体を組みなおして、実際のテストです。

セットしたbmpデータはこれです。


(ES0109)



Boy
ES0109.jpg



そして、実際に初めて表示されたデータがこれ。


(ES0110)

ES0110.jpg



表示はされていますが、色合いが変です

BMPファイルの3バイトのRGBのデータを2バイトのRGBに組みなおす際の順番が

違っているようです。

いろいろ触って、


(ES0111)

ES0111.jpg



(ES0112)

ES0112.jpg



そして、最終的には、元の画像がうまく再生、表示できました。

(ES0113)

ES0113.jpg



3バイトを2バイトに圧縮していますので、色の再現性は、気持ち低下しています

他の画像を再生しても上手くいきました。

と、ここまで書いていて気づきました。

画像が左右反転しています。

うむ~ これはOLEDのドライバを解析して、ディスプレイの表示そのものを変更しなければならず、ちょっとお預けにします。

(ES0114)

ES0114.jpg


(ES0115)

ES0115.jpg




また、BMP形式のデータをSDに書き込んで、それを一旦内部メモリに読み込んで表示させることに成功。

もう、目にも止まらぬ速さで、動画のごとく表示されています。

(ES0116)

メモリ再生動画



delay()を入れなければ何が何だか分からないので、Delayを入れて表示させています。

(筆者注)
内部メモリに保存しているデータを繰り返し表示させると問題が生じます。
この記事の文末を参照下さい。



delay()を入れないと

(ES0116A)






しかし問題が。

流石のESP32もメモリーが無限に使えるわけでもなく、64x64ドットの画像は、せいぜい10ー15枚

位しかメモリに記憶できません。

これでは6jiroさんの要求仕様に合わないようです。

そこで、1枚の画像毎にSDから読み出し、OLEDへ転送表示という仕様に変更。

これだとSDカードの容量分の画像を記録できます。

しかし、実際に表示させてみると、フレームレート的には2-3FPSくらいです。



(ES0117)

SD-Memory順次表示動画




プログラム中に遅延は入れていません。

遅延を入れた前の動画と変わらないくらいです。

やはり、SDとのSPI接続、OLEDとのSEP接続のダブル転送で、時間を要しているようです。

これを解決するには、SPIでSDとOLEDを個別に通信するのではなく、ESP32に備わっている

DMA(ダイレクト・メモリ・アクセス)機能を使用して、CPUを介さずに周辺機器のデータを

メモリ上に読み書きする様にすれば高速化ができる
と思いますが、

ここまでが、素人ソフトエンジニアの限界です~! (ちょっと勉強しますが)

この後はきっと6jiroさんが何とかしていただけるのでは?


「6jiroさんのブログ記事はこちらです」


ESP32用のプログラムです
(参考程度に)

Exam7_Blog.txt
Exam7_Blog.txt


========================================================================

以下はArduinoもしくはESP32の問題と思われるトラブルで、結構てこずったので
記録しておきます。

(問題1)

ESP32のHSPIにSDカードモジュールを接続し、VSPIにはOLEDを接続し、その状態で
プログラムをESP32に書き込むとERRとなって、書き込みができません。
色々調べて、回避策としてPIN12を外すか、SDカードの電源をOFFにして
書き込みを実行したらOKでした。

(ES0118)




(問題2)

これ、解決まで結構手間取りました。
OLED表示関数に、表示したいドットデータを格納した

 uint8_t Image_Buff[5][64 * 64 * 2]

の配列を

myOLED.write_bytes(Image_Buff[i], true, I_size);

として渡して表示させるのですが、実際にデータを表示した後は、このImage_Buff[i]の
中身は保存されません。
つまり、表示させたデータは「破壊されます」。
従って、同じデータを繰り返し表示させる場合には、このデータをあらかじめ他の配列に
記憶させて、表示の都度、データをコピーして渡さねばなりません。
これ、結構はまりました。

一つのデータをSDから読み込んで、それを表示し、また読み込んで表示する様な場合は
問題になりませんが、注意が必要です。

なお、データをコピーするには

//-------------------------------------
// OLEDへ配列のデータを転送
// これをしないと、OLED表示関数に引き渡した
// 配列データの中身は破壊されるので注意
//-------------------------------------

memcpy(IC_Buff, Image_Buff, sizeof(Image_Buff));// 画像データの配列をコピーしてそれをOLED関数へ渡す

の関数が便利でした。

二つの動画をメモリに取り込んで繰り返し送信するプログラムでは
この問題を解決する為に、配列コピーを使用しています。

Exam7Buff07.txt



=======================================================================

関連記事

管理者のみに表示する