はじめに
丸型液晶モジュールを手に入れたので、ディスプレイのないM5atomLITEに繋いでみました。
lovyanGFXで外付け液晶に表示させるための設定方法もメモしておきたいと思います。
コード中のピン22,23の設定が間違っていたので訂正しました。(2022 8.14)
誤 SCLK 22 -> 正 SCLK 23
誤 RST 23 -> 正 RST 22
M5atomLITEにLCDを接続する
今回手に入れたLCDモジュールはこれ。
ドライバはGC9A01。LovyanGFXでサポートされているドライバです。(GitHubで確認しました)
LCDモジュールは色々種類があって、買ってみたはいいけど動かないとかなったら悲しいので、対応したライブラリがあるか確認は大事です。まあAruduino対応とか書いてあれば大抵大丈夫みたいですが。
実は「lovyanGFX GC9A01」で検索すると、今回手に入れたのと似た別のLCDモジュールの例がいくつも出てきます。これ写真を見るとわかるんですが、液晶は同じでもピンの配置も名前も今回手に入れたものとは違うんです。
ピンの名前くらい全部共通にしておいてくれればいいのに!どうせなら配列も同じにしておいてほしい!そうすればサンプルコピペで使えるのに!
ぷりぷり腹を立てながら調べてみたところ、どうやらここのユーザー設定例を参考に、自分でピンの番号などを指定する必要があるという事が分かりました。
lovyanGFX 2_user_setting.ino GitHub
lovyan03さんがサポートしているならいけるに違いない。うん。
データはメーカーのサポートwikiに詳細に書かれていて助かる。
接続はSPI接続…… 聞いたことはあります 。
(この記事はこういうレベルの人が書いています)
SPIのピンの接続
LCDモジュール側
PIN | Description |
---|---|
VCC | 3.3V/5V |
GND | Ground |
DIN | SPI data input |
CLK | SPI clock input |
CS | Chip selection |
DC | Data/Command control |
RST | Reset |
BL | Backlight |
DIN,CLK,CS……。要するにあれでしょ、同じ名前のピンをマイコンと繋いでいけばいいんだよね?( 初心者的理解 )
M5atom側のピン配置を見てみると、
M5ATOM側
SPI | PIN |
---|---|
MOSI | G19 |
CLK | G23 |
MISO | G33 |
……あ、あれ?ピン3つしかない。DINとかDCとかRSTとか、無いよ?
CLKはあるけど、MISOとかMOSIとか知らない名前が増えてるし。
LCDにはそんな名前なかったよね…?
わかりません!教えて偉い人!
おお…疑問の答えがすべて書いてある。ありがたし。
それじゃとりあえず繋いで、試行錯誤してみましょうか。一回で上手くいくわけないし。
……と、その前に、lovyanGFXの設定が何やら必要だったはず。
lovyanGFXへの対応
ということで、改めてこちらを見てみます。
lovyanGFX 2_user_setting.ino GitHub
設定できる項目がたくさんありますし、「独自の設定をするならヘッダファイルにして保存推奨」とかあるのですが まずはとにかく表示をさせてみたいよね?
ということで編集したものがこちらになります。
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_GC9A01 _panel_instance;
lgfx::Bus_SPI _bus_instance; // SPIバスのインスタンス
public:
LGFX(void)
{
{ // バス制御の設定
auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。
// SPIバスの設定
cfg.spi_host = VSPI_HOST; // 使用するSPIを選択 ESP32-S2,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
cfg.spi_mode = 0; // SPI通信モードを設定 (0 ~ 3)
cfg.freq_write = 40000000; // 送信時のSPIクロック (最大80MHz, 80MHzを整数で割った値に丸められます)
cfg.freq_read = 16000000; // 受信時のSPIクロック
cfg.spi_3wire = true; // 受信をMOSIピンで行う場合はtrueを設定
cfg.use_lock = true; // トランザクションロックを使用する場合はtrueを設定
cfg.dma_channel = SPI_DMA_CH_AUTO; // 使用するDMAチャンネルを設定 (0=DMA不使用 / 1=1ch / 2=ch / SPI_DMA_CH_AUTO=自動設定)
cfg.pin_sclk = 23; // SPIのSCLKピン番号を設定
cfg.pin_mosi = 19; // SPIのMOSIピン番号を設定
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
cfg.pin_dc = 33; // SPIのD/Cピン番号を設定 (-1 = disable)
_bus_instance.config(cfg); // 設定値をバスに反映します。
_panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
}
{ // 表示パネル制御の設定
auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。
cfg.pin_cs = 21; // CSが接続されているピン番号 (-1 = disable)
cfg.pin_rst = 22; // RSTが接続されているピン番号 (-1 = disable)
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
cfg.panel_width = 240; // 実際に表示可能な幅
cfg.panel_height = 240; // 実際に表示可能な高さ
cfg.offset_x = 0; // パネルのX方向オフセット量
cfg.offset_y = 0; // パネルのY方向オフセット量
cfg.offset_rotation = 0; // 回転方向の値のオフセット 0~7 (4~7は上下反転)
cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
cfg.dummy_read_bits = 1; // ピクセル以外のデータ読出し前のダミーリードのビット数
cfg.readable = true; // データ読出しが可能な場合 trueに設定
cfg.invert = false; // パネルの明暗が反転してしまう場合 trueに設定
cfg.rgb_order = false; // パネルの赤と青が入れ替わってしまう場合 trueに設定
cfg.dlen_16bit = false; // 16bitパラレルやSPIでデータ長を16bit単位で送信するパネルの場合 trueに設定
cfg.bus_shared = false; // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)
_panel_instance.config(cfg);
}
setPanel(&_panel_instance); // 使用するパネルをセットします。
}
};
内容を説明しまう。
サンプルから変更する必要のあった箇所のみ解説します。
まずはパネルの型にあったインスタンスの選択から。
今回ドライバがGC9A01なので、それにあったものにします。
//lgfx::Panel_GC9A01 _panel_instance;
...
lgfx::Panel_ILI9341 _panel_instance;
GC9A01を選択するためにコメント解除。
ILI9341を選択していた行はコメントにするか消去します。
lgfx::Panel_GC9A01 _panel_instance;
...
//lgfx::Panel_ILI9341 _panel_instance;
バックライト制御、タッチスクリーンの制御に関する部分は今回使わないので全部消去。
(必要なければ削除)と書いてあるので安心。
つぎ、大事なSPI関係です。
cfg.pin_sclk = 18; // SPIのSCLKピン番号を設定
cfg.pin_mosi = 23; // SPIのMOSIピン番号を設定
cfg.pin_miso = 19; // SPIのMISOピン番号を設定 (-1 = disable)
cfg.pin_dc = 27; // SPIのD/Cピン番号を設定 (-1 = disable)
上の記述ををM5atomのピン配置に書き換えるのですが、 ここのポイントはpin G33をD/Cに設定することです。MISOではありません。 MISOは-1にします。
モジュール側の要求にあうようにマイコン側を合わせるとかそういう感じなんだろうか。
cfg.pin_sclk = 23; // SPIのSCLKピン番号を設定
cfg.pin_mosi = 19; // SPIのMOSIピン番号を設定
cfg.pin_miso = -1; // SPIのMISOピン番号を設定 (-1 = disable)
cfg.pin_dc = 33; // SPIのD/Cピン番号を設定 (-1 = disable)
そしてもう一か所、pin関係の設定項目があります。
cfg.pin_cs = 14; // CSが接続されているピン番号 (-1 = disable)
cfg.pin_rst = 33; // RSTが接続されているピン番号 (-1 = disable)
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
これは次のように決めました。
cfg.pin_cs = 21; // CSが接続されているピン番号 (-1 = disable)
cfg.pin_rst = 22; // RSTが接続されているピン番号 (-1 = disable)
cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)
このCSとRSTは別にこのピンでなければならないわけではなく、空いている他のピンでも設定さえちゃんとすれば動くみたいです。
余談ですが、
CS(チップセレクト)というのは複数SPI接続しているときに必要になってくるもので、LCDしかSPI接続していない今回は関係ありません……だからといって 「それなら繋がずにほっといても同じことだよね」とか思ってどこにもつながずにいるとLCDに何も表示されないぞ!気をつけろ!
CSを0vにしないとモジュールが信号を受け取ってくれないので、CS用のピンに接続するかもしくはGNDに接続しとかなければならないみたいです。
余談ですが、
このLCDモジュールにはバックライト制御のためのBLというピンも出ています。
が、今回使わないので繋いでいません。(こっちは接続しなくてもOK)
最後にパネルの解像度を設定します。
このパネルは縦横240×240ドットという事なのでそのように。
(実際の表示範囲は240×240の正方形の内接円の範囲になります)
あと、パネルの明暗が反転してたのでコメントの指示通りcfg.invertをtrueに。
cfg.panel_width = 240; // 実際に表示可能な幅
cfg.panel_height = 240; // 実際に表示可能な高さ
...
cfg.invert = true; // パネルの明暗が反転してしまう場合 trueに設定
これで最低限LCDに表示ができるようになりました。
スケッチへの追加
準備ができたので、ようやくスケッチに組み込んで使ってみたいと思います。
lovyanGFXには丸形液晶用のサンプルがあります。さすが手厚い。
ClockSample GitHub
このサンプルの次の部分に、先程書いた設定をコピペします。
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
//ここにコピペ
これで完成!
実行結果
設定を色々試して、とりあえず反転表示のほうが見た目が好みだったので反転表示にしました。
液晶が丸形というだけでなんかいい雰囲気ですね。
どのように使うか、使い方を考えるのが楽しみです。