IPS(In-Plane-Switching)ディスプレイ ILI9342C について
TwitterのM5Stackユーザーの間で一時期話題?になった、IPS(In-Plane-Switching)ディスプレイについて見てみたいと思います。
最新バージョンのM5Stack BasicやM5Stack FIREはIPSディスプレイになっていて、現在流通しいるものはそろそろ全てIPSに入れ替わる頃ではないかなと思います。
初代M5StackのLCDのドライバーは ILI9341 でしたが、IPSディスプレイは ILI9342C になっています。
ただ、ILI9342C のデータシートを見ても、「IPS」という単語は見つからないんです。
なぜ?
IPSっていう用語は専門分野では一般的では無いんですかね?
これは謎ですが、視野角で実際に見てみると、確かにIPSディスプレイになっていました。
そもそも、IPS(In-Plane-Switching)ディスプレイとは、何ぞや? ということですが、私はド素人なのでよく分かりません。
仕組みは分子レベルの制御のお話らしく、長所短所があるようです。
長所: 中間輝度の視野角が広い。静止画が高画質。
欠点: 高価。動画再生等の高速応答に不向き。コントラスト比が悪い
これについては、以下のサイトにちゃんとした詳しい説明があります。
https://www.eizo.co.jp/eizolibrary/other/itmedia01_04/
中間輝度のピクセルに差が出るというところがミソです。
画素(ピクセル)中のRed, Green, Blueの値の何れかが最大輝度の場合、電圧が最大になるので、斜めから見ても視認できますが、中間輝度の場合は、視認性にハッキリ違いが現れるということです。確かに、初代M5Stack Basicでは、垂直方向の視野角があまりにも狭く、視認性が悪かったですね。
初代M5StackのLCDは、TN(Twisted Nematic)方式だそうです。
この用語もILI9341のデータシートには残念ながら見当たりませんでした。
因みに、ILI9342C データシートの概要を和訳してみたので、参考程度に・・・。
【ILI9342C データシート概要抜粋】
ILI9342Cは、960チャンネルのソースドライバー、240チャンネルのゲートドライバー、320RGBx240ドットのグラフィックディスプレイデータ用の172,800バイトのGRAMおよび電源回路で構成された、320RGBx240ドットの解像度を持つa-TFT液晶ディスプレイ用の262,144色のシングルチップSOCドライバーです。
ILI9342Cは、パラレル8-/9-/16-/18-bitデータバスMCUインターフェイス、6-/16-/18-bit データバスRGBインターフェイス、および3-/4-lineシリアルペリフェラルインターフェイス(SPI)をサポートしています。 動画像領域は、ウィンドウアドレス機能により内部GRAMで指定できます。 指定されたウィンドウ領域を選択的に更新できるため、静止画像領域に関係なく動画を同時に表示できます。
ILI9342Cはフルカラー、8色表示モード、およびスリープモードをサポートし、ソフトウェアによる正確な電力制御を可能にします。これらの機能により、ILI9342Cは、バッテリーの寿命は大きな懸念事項なデジタル携帯電話、スマートフォン、MP3、PMPなどの中規模または小型のポータブル製品に最適なLCDドライバーになります。
白黒反転、色反転してしまう問題
M5Stack公式ライブラリの最新版(0.2.9以降)を使用した時には、LCDパネルバージョンを自動認識するので、旧式でも新式でも問題無く動作します。
それ以外のライブラリを使用した場合、下図の様に色が反転してしまう場合があります。
ILI9341 と ILI9342C のデータシートを見てみると、色反転に関するレジスタコマンドは、
Display Inversion OFF ( 0x20 )
Display Inversion ON ( 0x21 )
です。
その他、白黒反転のレジスタコマンドは
Display Function Control ( 0xB6 )
RGBとBGRの切り替えは
Memory Access Control ( 0x36 )
です。
これは、ILI9341もILI9342Cでも、どちらも共通の値でした。
なのに、なぜかM5Stack FIREで色が反転してしまうんです。
M5Stack FIREを使う時だけ、スケッチを変更して、VSPI通信で、
Display Inversion ON ( 0x21 )
コマンドを送れば解決するのですが、不思議だったのが、M5Stack公式のライブラリではそんなことしなくてもどちらも色反転しておらず、正常に表示されていたことです。
私の自作ライブラリでは反転してしまったので、困る人がいそうです。
さて、どうしようか。。。
スケッチに新たに追加するように説明するのも面倒ですし、旧型と新型のM5Stackでプログラミングを変えてくださいとアナウンスするのも手間です。
その点では公式のM5Stackライブラリは優れているなぁと思いました。
そこで、何となくTwitterでつぶやいていたら、何と、M5Stackの神アプリ LovyanLauncherを開発された、らびやんさんから貴重な助言を頂戴しました。
何と、IPSパネルの変更時にリセットピンのプルアップ、プルダウンの設計変更も同時に行われていて、公式M5Stackライブラリでは、それをGPIOで読み取ることによってLCDパネルのバージョンを判断しているとのことです。
その関連ツイートは以下のリンクにあるので、参照してみてください。
https://twitter.com/mgo_tec/status/1213817202937171968
私は、SPI.transfer関数を使って、何とかしてLCDパネル情報を取得しようとしましたが、全然うまくいかなかったんです。
これは苦肉の策だったとはいえ、あまりにも予想外の対策で、逆に目から鱗ですね。
とっても勉強になりました。
これを参考に、私の自作ライブラリも変更して、M5StackのIPSパネルを自動判別するようにしました。
https://github.com/mgo-tec/ESP32_mgo_tec
ということで、らびやんさん、とっても助かりました。
ありがとうございました。
感謝感謝です。
m(_ _)m
IPSスクリーンとTNスクリーンの視野角比較
実際に点灯させてみるとこんな感じです。
初代M5Stack Basic
静止している文字や線は、RGBの何れかが最大輝度なので、素子がフルの電圧になります。
ですから、斜めの角度から見ても文字は問題無く見えますが、左上の画像領域のピクセルは中間輝度のピクセルだらけなので、真っ暗に見えてしまいます。
一方、M5Stack FIRE のIPSディスプレイの場合はこんな感じです。
この角度でも、中間輝度の画像領域がハッキリ映し出されていますね。
水平方向(横方向)は初代M5Stackでも視認性がありますが、やはりIPSディスプレイの方が断然高画質です。
医療分野で使われる理由が分かりますね。
ただ、動画の様な高速応答には向かないらしいです。
でも、M5Stackで動画を再生するにしてもそれほど高速応答は必要無いと思われるので、IPSで良いのではないかと思っています。
ということで、個人的にはIPSディスプレイのM5Stackは買いですね!
PSRAMを認識しない場合のトラブル対処
(※ここで紹介する対処方法は、M5Stack FIREのロットによっては不要かも知れませんので、注意してください。)
私が購入したM5Stack FIREの場合は、購入した直後、Arduino IDEでPSRAMを使ったプログラムをコンパイル書き込みすると、シリアルモニターに以下のメッセージ
[・・・・] spiram: SPI SRAM memory test fail
が出て、再起動を繰り返すことが頻繁にありました。
Arduino IDE のボード設定で、M5Stack-FIREのPSRAM Enable にしてもダメでした。
ただ、しばらく放置していると、正常に戻る時もあれば、延々とリセットを繰り返すこともありました。
いろいろ調べると、スイッチサイエンスさんの以下のページにいろいろと対処方法がありました。
https://www.switch-science.com/catalog/3953/?gclid=EAIaIQobChMIiby3hPHk5gIVmHZgCh2XOQ-uEAAYASAAEgKzhfD_BwE
でも、PSRAM不具合交換プログラムでは、2018年9月7日入荷分以降は正常な物を流通させているということでした。
私の手持ちの物は、明らかに2019年8月以降に生産されたものなので、おかしいなと思いました。
そこで、いろいろ試しているうちに、スイッチサイエンスさんのサイトで以下の消された文章を発見しました。
240Ωから1kΩの抵抗をUART通信ピンとGNDの間に追加することで、ピンのカットを行わず、PSRAMを有効にすることが可能
そういえば、先に述べたように、PSRAMはこのUART用のGPIO #16, #17に接続されていたので、これが原因かも知れないと思いました。
それで、思い切ってこれを試してみました。
M5Stack FIRE のBottomケースの基板に下図の様に手持ちのチップ抵抗1kΩをハンダ付けしました。
そうしたら、ビンゴ!
PSRAMが問題無く認識して、プログラムが動作するようになりました。
試しに、このBottomユニットを外して、本体をUSB電源供給して動作させようとしましたが、リセットを繰り返しました。
よって、私のロットではこの対策が有効でした。
ただ、バッテリーチャージベースユニットを着脱したあとは、たまになぜかリセットを繰り返すことがあり、バッテリーチャージベースユニットを外した状態でリセットすると正常に戻りました。
また、この方法では、Bottomユニットを外した状態で本体のみでUSB接続して使おうとすると、うまく動きませんので注意してください。
以上、この対策はロットによっては不要かも知れませんのでご注意ください。
では、次の節では、実際にArduinoプログラミングして、動作を確かめてみます。
コメント
はじめまして。サーボ と申します。
ついこの前に M5StackFire と M5Camera を購入し、いろいろ勉強しているところです。
mgo-tec さんの記事を見つけ、参考にさせていただいおり大変ありがたいです。
お忙しいところお疲れさまです。
「PSRAMを使った Arduino IDE スケッチ(プログラミング)例」で、
PSRAM data size が 220 となっている理由につきまして、ちょっと心当たりがあります。
c_buf1 には、ヌル文字を含む10文字の配列を5個分だけ格納する領域へのポインタを設定され、
c_buf2 には、上記領域を5分割してそれぞれの領域の先頭へのポインタを設定されているのかなと思います。
ps_malloc() で c_buf1 の領域を確保する処理につきまして、sizeof(char *) の代わりに
sizeof(char) で領域を確保してはいかがでしょうか。”char *” は M5StackFire では 4 バイトの変数なので、
確保したいメモリ量の 4 倍の量を確保してしまいます。
sizeof(char) に変更した場合の領域の量は、10 * 5 + 5 * 4 = 70 bytes かと思います。
修正して動作を確認すると、PSRAM data size は 72 となっておりました。
70 となっていないのは、mgo-tec さんのおっしゃる「4byte単位で」読み書きするため、4 バイト単位で
領域が確保されるのかなと思います。
少しでも参考になればと、コメントさせていただきました。
サーボさん
記事をご覧いただき、ありがとうございます。
おー!
そう言えば、sizeof(char *)はESP32では4byteでした。
すっかり忘れていました。
というか、2次元配列のps_malloc()確保は、ポインタ型でしか初期化できないと思い込んでいました。
今取組中の課題が終わったら試してみようと思います。
ありがとうございました。
m(_ _)m
mgo-tec さん
お役に立てて何よりです!
お体に気を付けながら、時間があるときにでも試してみてくださいませ (^^
はーい! ありがとうございまーす!!!