縦(横?)に長いカラーLCDを探していたところ AliExpress で入手できるのがわかったのだが,どれも例外なくドライバーが NV3007 だった.これは使ったことがなくいつも使っているライブラリ(Lovyan GFX)も現状では NV3007 をサポートしていない.
とはいえ,とりあえずこれ(TFT LCDシリアルスクリーンディスプレイ、カラーnv3007ドライブ、2.79インチ、142×428)を購入.

NV3007 について調べたところ,描画コマンドはST7789などと同じで何とかなりそうな気がしたので,Lovyan GFX 用にヘッダファイルを作成することにした.ちょっと気楽に構えていたがそんな甘いものではなく初期化はかなり苦労してしまった.
最終的には下記のヘッダでうまく動作した.
/*-----------------------------------------
Panel_NV3007.hpp
------------------------------------------*/
#pragma once
#include "Panel_LCD.hpp"
namespace lgfx
{
inline namespace v1
{
//-----------------------------------------
struct Panel_NV3007 : public Panel_LCD
{
Panel_NV3007(void)
{
_cfg.panel_width = 142;
_cfg.panel_height = 428;
_cfg.memory_width = 168;
_cfg.memory_height = 428;
_cfg.offset_x = 12;
_cfg.offset_y = 0;
_cfg.dummy_read_pixel = 8;
_cfg.dummy_read_bits = 1;
}
const uint8_t* getInitCommands(uint8_t listno) const override {
static constexpr uint8_t list0[] = {
0xFF, 1, 0xA5,
0x9A, 1, 0x08,
0x9B, 1, 0x08,
0x9C, 1, 0xB0,
0x9D, 1, 0x16,
0x9E, 1, 0xC4,
0x8F, 2, 0x55, 0x04,
0x84, 1, 0x90,
0x83, 1, 0x7B,
0x85, 1, 0x33,
// ===== Gamma =====
0x60, 1, 0x00, 0x70, 1, 0x00,
0x61, 1, 0x02, 0x71, 1, 0x02,
0x62, 1, 0x04, 0x72, 1, 0x04,
0x6C, 1, 0x29, 0x7C, 1, 0x29,
0x6D, 1, 0x31, 0x7D, 1, 0x31,
0x6E, 1, 0x0F, 0x7E, 1, 0x0F,
0x66, 1, 0x21, 0x76, 1, 0x21,
0x68, 1, 0x3A, 0x78, 1, 0x3A,
0x63, 1, 0x07, 0x73, 1, 0x07,
0x64, 1, 0x05, 0x74, 1, 0x05,
0x65, 1, 0x02, 0x75, 1, 0x02,
0x67, 1, 0x23, 0x77, 1, 0x23,
0x69, 1, 0x08, 0x79, 1, 0x08,
0x6A, 1, 0x13, 0x7A, 1, 0x13,
0x6B, 1, 0x13, 0x7B, 1, 0x13,
0x6F, 1, 0x00, 0x7F, 1, 0x00,
// ===== Power =====
0x50, 1, 0x00,
0x52, 1, 0xD6,
0x53, 1, 0x08,
0x54, 1, 0x08,
0x55, 1, 0x1E,
0x56, 1, 0x1C,
// ===== GOA / Scan =====
0xA0, 3, 0x2B, 0x24, 0x00,
0xA1, 1, 0x87,
0xA2, 1, 0x86,
0xA5, 1, 0x00,
0xA6, 1, 0x00,
0xA7, 1, 0x00,
0xA8, 1, 0x36,
0xA9, 1, 0x7E,
0xAA, 1, 0x7E,
// ===== Timing =====
0xB9, 1, 0x85,
0xBA, 1, 0x84,
0xBB, 1, 0x83,
0xBC, 1, 0x82,
0xBD, 1, 0x81,
0xBE, 1, 0x80,
0xBF, 1, 0x01,
0xC0, 1, 0x02,
0xC1, 1, 0x00,
0xC2, 1, 0x00,
0xC3, 1, 0x00,
0xC4, 1, 0x33,
0xC5, 1, 0x7E,
0xC6, 1, 0x7E,
0xC8, 2, 0x33, 0x33,
0xC9, 1, 0x68,
0xCA, 1, 0x69,
0xCB, 1, 0x6A,
0xCC, 1, 0x6B,
0xCD, 2, 0x33, 0x33,
0xCE, 1, 0x6C,
0xCF, 1, 0x6D,
0xD0, 1, 0x6E,
0xD1, 1, 0x6F,
0xAB, 2, 0x03, 0x67,
0xAC, 2, 0x03, 0x6B,
0xAD, 2, 0x03, 0x68,
0xAE, 2, 0x03, 0x6C,
0xB3, 1, 0x00,
0xB4, 1, 0x00,
0xB5, 1, 0x00,
0xB6, 1, 0x32,
0xB7, 1, 0x7E,
0xB8, 1, 0x7E,
// ===== Panel =====
0xE0, 1, 0x00,
0xE1, 2, 0x03, 0x0F,
0xE2, 1, 0x04,
0xE3, 1, 0x01,
0xE4, 1, 0x0E,
0xE5, 1, 0x01,
0xE6, 1, 0x19,
0xE7, 1, 0x10,
0xE8, 1, 0x10,
0xEA, 1, 0x12,
0xEB, 1, 0xD0,
0xEC, 1, 0x04,
0xED, 1, 0x07,
0xEE, 1, 0x07,
0xEF, 1, 0x09,
0xF0, 1, 0xD0,
0xF1, 1, 0x0E,
0xF9, 1, 0x17,
0xF2, 4, 0x2C, 0x1B, 0x0B, 0x20,
0xE9, 1, 0x29,
0xEC, 1, 0x04,
0x35, 1, 0x00,
0x44, 2, 0x00, 0x10,
0x46, 1, 0x10,
// exit vendor
0xFF, 1, 0x00,
0x3A, 1, 0x05, //RGB565
CMD_SLPOUT, 0+CMD_INIT_DELAY, 200,
0x29, 0+CMD_INIT_DELAY, 150,
0xFF,0xFF, // end
};
switch (listno) {
case 0: return list0;
default: return nullptr;
}
}
};
//--------------------------------------------
}
}
これは,今回購入した N279-1428KIWIG01-C1 という型式のものでしか動作確認できていない.
NV3007 はLCDごとに初期化が異なるらしく,他のLCDで動作するかどうかは不明.
Panel_NV3007.hpp を Lovyan GFX の “panel” フォルダ内に置いて,下記のコードで動作確認できる.
/*
NV3007_test.ino
for ESP32
*/
#include <LovyanGFX.hpp>
// 自前で追加した Panel_xxx.hpp は 絶対パスでinclude.
#include "\0_work\Arduino\libraries\LovyanGFX\src\lgfx\v1\panel\Panel_NV3007.hpp"
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_NV3007 _panel_instance;
lgfx::Bus_SPI _bus_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
cfg.spi_host = VSPI_HOST; // or SPI2_HOST , SPI3_HOST
cfg.spi_mode = 0;
cfg.freq_write = 20000000;
cfg.freq_read = 16000000;
cfg.spi_3wire = false;
cfg.use_lock = true;
cfg.dma_channel = SPI_DMA_CH_AUTO;
cfg.pin_sclk = 18; // SCLK
cfg.pin_mosi = 23; // MOSI
cfg.pin_miso = -1; // MISO(-1 = disable)
cfg.pin_dc = 2; // D/C
_bus_instance.config(cfg);
_panel_instance.setBus(&_bus_instance);
}
{
auto cfg = _panel_instance.config();
cfg.pin_cs = 5; // CS
cfg.pin_rst = 15; // RST
cfg.pin_busy = -1; // BUSY
cfg.offset_rotation = 3; // 1 or 3, 1はなぜかNG
cfg.readable = false;
cfg.invert = false;
cfg.rgb_order = true;
cfg.dlen_16bit = false;
cfg.bus_shared = false;
_panel_instance.config(cfg);
}
setPanel(&_panel_instance);
}
};
LGFX lcd;
void setup() {
lcd.init();
lcd.setColorDepth(16);
}
void loop() {
lcd.fillScreen(TFT_BLACK);
lcd.setTextColor(TFT_CYAN);
lcd.setFont(&fonts::Font4);
lcd.setCursor( 0, 0 );
lcd.printf( "NV3007 Test" );
delay(400);
lcd.fillScreen(TFT_WHITE);
delay(400);
}
自前で追加した Panel_NV3007.hpp はとりあえずこのファイル内で絶対パス指定で include する必要があるみたい.なにかいい方法があるかもしれないけどとりあえずこれで.
cfg.offset_rotation は 3 限定.上下左右を逆にしようとして 1 に設定すると表示がおかしくなる.今のところLCDの表示方向を配慮して取り付けるようにしないといけない.
