JLX12864G 液晶を SPI コマンドで動かしてみる

![IMG_20240108_151114.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f79ab613-c6e7-dd3b-7f01-80ef83880a1d.jpeg)

「JLX12864G 液晶を ESP32で動かしてみる」
https://qiita.com/nanbuwks/items/0f75341fb7a503fbd79c

では、同じ ST7567 コントローラを持つ 秋月電子「超小型グラフィックＬＣＤ　	ＡＱＭ１２４８Ａ」用に先人が作成したスケッチを元に動かしてみました。

今回は、先人のスケッチを更に改良し、また JLC12864G 液晶に最適化してみます。


# 環境

- Arduino IDE 1.8.19
- esp32 by Espressif Systems Version 2.0.14
- ESP32 オジリナルボード
![IMG_20240108_151101.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ac958add-6cfc-8d33-f8c6-e31a0e7c09da.jpeg)

https://github.com/nanbuwks/ozone12864

# 配線

以下のように割り当てています。

|LCD PCB上表記|信号の意味|ESP32信号|
|:---:|:---:|:---:|
|VSS |GND|GND|
|VDD |3V3|3V3|
|RS |Data/Command|17|
|CS |CableSelect|5|
|07(SDA) |MOSI|-|
|06(SCK) |CLOCK|18|
|RST |LCD RESET|16|
|LEDA |LCD BACKLIGHT|15|

# スケッチの内容

以下の3つの操作を行うようにしています。

- LCDの初期化
- LCD全体のクリア
- LCD1ピクセルの操作

文字列描画については、文字列を1キャラクタごとに分解し、1キャラクタのピクセルごとにLCDピクセルに書き込むようにしています。

しかしながら JLX12864G 液晶に SPI でデータを送る時は縦8ドットごとに1バイトのデータ形式となっています。SPI はバイトごとに書込むことになり、そしてデータをリードする機能はありません。ということは すでに書き込まれている内容をクリアせずに1ドットだけ操作するということができないということになります。

それを解決するためにフレームバッファをESP32上に用意します。フレームバッファにピクセルごとに操作したあと、該当のデータバイトを JLX12864G 液晶に送るようになっています。

# スケッチ
 

```

#include <SPI.h>

#define LCD_CS           5
#define LCD_RS          17
#define LCD_RSET        16
#define SPI_CLK         18
#define TFT_BACKLIGHT_PIN 15


//    Font Data
const char Font[192][5] =
{
    { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " " 0x20
    { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // !   0x21
    { 0x00, 0x07, 0x00, 0x07, 0x00 }, // "   0x22
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #   0x23
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $   0x24
    { 0x23, 0x13, 0x08, 0x64, 0x62 }, // %   0x25
    { 0x36, 0x49, 0x55, 0x22, 0x50 }, // &   0x26
    { 0x00, 0x05, 0x03, 0x00, 0x00 }, // '   0x27
    { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (   0x28
    { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )   0x29
    { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // *   0x2A
    { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // +   0x2B
    { 0x00, 0x50, 0x30, 0x00, 0x00 }, // ,   0x2C
    { 0x08, 0x08, 0x08, 0x08, 0x08 }, // -   0x2D
    { 0x00, 0x60, 0x60, 0x00, 0x00 }, // .   0x2E
    { 0x20, 0x10, 0x08, 0x04, 0x02 }, // /   0x2F
    { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0   0x30
    { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1   0x31
    { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2   0x32
    { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3   0x33
    { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4   0x34
    { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5   0x35
    { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6   0x36
    { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7   0x37
    { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8   0x38
    { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9   0x39
    { 0x00, 0x36, 0x36, 0x00, 0x00 }, // :   0x3A
    { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;   0x3B
    { 0x08, 0x14, 0x22, 0x41, 0x00 }, // <   0x3C
    { 0x14, 0x14, 0x14, 0x14, 0x14 }, // =   0x3D
    { 0x00, 0x41, 0x22, 0x14, 0x08 }, // >   0x3E
    { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?   0x3F
    { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @   0x40
    { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A   0x41
    { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B   0x42
    { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C   0x43
    { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D   0x44
    { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E   0x45
    { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F   0x46
    { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G   0x47
    { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H   0x48
    { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I   0x49
    { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J   0x4A
    { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K   0x4B
    { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L   0x4C
    { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M   0x4D
    { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N   0x4E
    { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O   0x4F
    { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P   0X50
    { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q   0X51
    { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R   0X52
    { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S   0X53
    { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T   0X54
    { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U   0X55
    { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V   0X56
    { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W   0X57
    { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X   0X58
    { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y   0X59
    { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z   0X5A
    { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [   0X5B
    { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\" 0X5C
    { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ]   0X5D
    { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^   0X5E
    { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _   0X5F
    { 0x00, 0x01, 0x02, 0x04, 0x00 }, // `   0X60
    { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a   0X61
    { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b   0X62
    { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c   0X63
    { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d   0X64
    { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e   0X65
    { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f   0X66
    { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g   0X67
    { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h   0X68
    { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i   0X69
    { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j   0X6A
    { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k   0X6B
    { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l   0X6C
    { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m   0X6D
    { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n   0X6E
    { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o   0X6F
    { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p   0X70
    { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q   0X71
    { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r   0X72
    { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s   0X73
    { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t   0X74
    { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u   0X75
    { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v   0X76
    { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w   0X77
    { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x   0X78
    { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y   0X79
    { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z   0X7A
    { 0x00, 0x08, 0x36, 0x41, 0x00 }, // {   0X7B
    { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // |   0X7C
    { 0x00, 0x41, 0x36, 0x08, 0x00 }, // }   0X7D
    { 0x08, 0x08, 0x2a, 0x1c, 0x08 }, // ->  0X7E
    { 0x08, 0x1c, 0x2a, 0x08, 0x08 }, // <-  0X7F
    { 0x08, 0x46, 0x4a, 0x32, 0x1e }, // ta  0x80
    { 0x0a, 0x4a, 0x3e, 0x09, 0x08 }, // ti  0x81
    { 0x0e, 0x00, 0x4e, 0x20, 0x1e }, // tu  0x82
    { 0x04, 0x45, 0x3d, 0x05, 0x04 }, // te  0x83
    { 0x00, 0x7f, 0x08, 0x10, 0x00 }, // to  0x84
    { 0x44, 0x24, 0x1f, 0x04, 0x04 }, // na  0x85
    { 0x40, 0x42, 0x42, 0x42, 0x40 }, // ni  0x86
    { 0x42, 0x2a, 0x12, 0x2a, 0x06 }, // nu  0x87
    { 0x22, 0x12, 0x7b, 0x16, 0x22 }, // ne  0x88
    { 0x00, 0x40, 0x20, 0x1f, 0x00 }, // no  0x89
    { 0x78, 0x00, 0x02, 0x04, 0x78 }, // ha  0x8A
    { 0x3f, 0x44, 0x44, 0x44, 0x44 }, // hi  0x8B
    { 0x02, 0x42, 0x42, 0x22, 0x1e }, // hu  0x8C
    { 0x04, 0x02, 0x04, 0x08, 0x30 }, // he  0x8D#include <SPI.h>

#define LCD_CS           5
#define LCD_RS          17
#define LCD_RSET        16
#define SPI_CLK         18
#define TFT_BACKLIGHT_PIN 15


//    Font Data
const char Font[192][5] =
{
    { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " " 0x20
    { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // !   0x21
    { 0x00, 0x07, 0x00, 0x07, 0x00 }, // "   0x22
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #   0x23
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $   0x24
    { 0x23, 0x13, 0x08, 0x64, 0x62 }, // %   0x25
    { 0x36, 0x49, 0x55, 0x22, 0x50 }, // &   0x26
    { 0x00, 0x05, 0x03, 0x00, 0x00 }, // '   0x27
    { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (   0x28
    { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )   0x29
    { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // *   0x2A
    { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // +   0x2B
    { 0x00, 0x50, 0x30, 0x00, 0x00 }, // ,   0x2C
    { 0x08, 0x08, 0x08, 0x08, 0x08 }, // -   0x2D
    { 0x00, 0x60, 0x60, 0x00, 0x00 }, // .   0x2E
    { 0x20, 0x10, 0x08, 0x04, 0x02 }, // /   0x2F
    { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0   0x30
    { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1   0x31
    { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2   0x32
    { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3   0x33
    { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4   0x34
    { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5   0x35
    { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6   0x36
    { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7   0x37
    { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8   0x38
    { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9   0x39
    { 0x00, 0x36, 0x36, 0x00, 0x00 }, // :   0x3A
    { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;   0x3B
    { 0x08, 0x14, 0x22, 0x41, 0x00 }, // <   0x3C
    { 0x14, 0x14, 0x14, 0x14, 0x14 }, // =   0x3D
    { 0x00, 0x41, 0x22, 0x14, 0x08 }, // >   0x3E
    { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?   0x3F
    { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @   0x40
    { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A   0x41
    { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B   0x42
    { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C   0x43
    { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D   0x44
    { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E   0x45
    { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F   0x46
    { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G   0x47
    { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H   0x48
    { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I   0x49
    { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J   0x4A
    { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K   0x4B
    { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L   0x4C
    { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M   0x4D
    { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N   0x4E
    { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O   0x4F
    { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P   0X50
    { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q   0X51
    { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R   0X52
    { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S   0X53
    { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T   0X54
    { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U   0X55
    { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V   0X56
    { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W   0X57
    { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X   0X58
    { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y   0X59
    { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z   0X5A
    { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [   0X5B
    { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\" 0X5C
    { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ]   0X5D
    { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^   0X5E
    { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _   0X5F
    { 0x00, 0x01, 0x02, 0x04, 0x00 }, // `   0X60
    { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a   0X61
    { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b   0X62
    { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c   0X63
    { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d   0X64
    { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e   0X65
    { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f   0X66
    { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g   0X67
    { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h   0X68
    { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i   0X69
    { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j   0X6A
    { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k   0X6B
    { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l   0X6C
    { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m   0X6D
    { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n   0X6E
    { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o   0X6F
    { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p   0X70
    { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q   0X71
    { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r   0X72
    { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s   0X73
    { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t   0X74
    { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u   0X75
    { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v   0X76
    { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w   0X77
    { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x   0X78
    { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y   0X79
    { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z   0X7A
    { 0x00, 0x08, 0x36, 0x41, 0x00 }, // {   0X7B
    { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // |   0X7C
    { 0x00, 0x41, 0x36, 0x08, 0x00 }, // }   0X7D
    { 0x08, 0x08, 0x2a, 0x1c, 0x08 }, // ->  0X7E
    { 0x08, 0x1c, 0x2a, 0x08, 0x08 }, // <-  0X7F
    { 0x08, 0x46, 0x4a, 0x32, 0x1e }, // ta  0x80
    { 0x0a, 0x4a, 0x3e, 0x09, 0x08 }, // ti  0x81
    { 0x0e, 0x00, 0x4e, 0x20, 0x1e }, // tu  0x82
    { 0x04, 0x45, 0x3d, 0x05, 0x04 }, // te  0x83
    { 0x00, 0x7f, 0x08, 0x10, 0x00 }, // to  0x84
    { 0x44, 0x24, 0x1f, 0x04, 0x04 }, // na  0x85
    { 0x40, 0x42, 0x42, 0x42, 0x40 }, // ni  0x86
    { 0x42, 0x2a, 0x12, 0x2a, 0x06 }, // nu  0x87
    { 0x22, 0x12, 0x7b, 0x16, 0x22 }, // ne  0x88
    { 0x00, 0x40, 0x20, 0x1f, 0x00 }, // no  0x89
    { 0x78, 0x00, 0x02, 0x04, 0x78 }, // ha  0x8A
    { 0x3f, 0x44, 0x44, 0x44, 0x44 }, // hi  0x8B
    { 0x02, 0x42, 0x42, 0x22, 0x1e }, // hu  0x8C
    { 0x04, 0x02, 0x04, 0x08, 0x30 }, // he  0x8D
    { 0x32, 0x02, 0x7f, 0x02, 0x32 }, // ho  0x8E
    { 0x02, 0x12, 0x22, 0x52, 0x0e }, // ma  0x8F
    { 0x00, 0x2a, 0x2a, 0x2a, 0x40 }, // mi  0x90
    { 0x38, 0x24, 0x22, 0x20, 0x70 }, // mu  0x91
    { 0x40, 0x28, 0x10, 0x28, 0x06 }, // me  0x92
    { 0x0a, 0x3e, 0x4a, 0x4a, 0x4a }, // mo  0x93
    { 0x04, 0x7f, 0x04, 0x14, 0x0c }, // ya  0x94
    { 0x40, 0x42, 0x42, 0x7e, 0x40 }, // yu  0x95
    { 0x4a, 0x4a, 0x4a, 0x4a, 0x7e }, // yo  0x96
    { 0x04, 0x05, 0x45, 0x25, 0x1c }, // ra  0x97
    { 0x0f, 0x40, 0x20, 0x1f, 0x00 }, // ri  0x98
    { 0x7c, 0x00, 0x7e, 0x80, 0x30 }, // ru  0x99
    { 0x7e, 0x40, 0x20, 0x10, 0x08 }, // re  0x9A
    { 0x7e, 0x42, 0x42, 0x42, 0x7e }, // ro  0x9B
    { 0x0e, 0x02, 0x42, 0x22, 0x1e }, // wa  0x9C
    { 0x42, 0x42, 0x40, 0x20, 0x18 }, // n   0x9D
    { 0x02, 0x04, 0x01, 0x02, 0x00 }, // "   0x9E
    { 0x07, 0x05, 0x07, 0x00, 0x00 }, // .   0x9F
  { 0x00, 0x00, 0x00, 0x00, 0x00 }, //     0xA0
  { 0x70, 0x50, 0x70, 0x00, 0x00 }, //  .  0xA1
  { 0x00, 0x00, 0x0f, 0x01, 0x01 }, //  [  0xA2
  { 0x40#include <SPI.h>

#define LCD_CS           5
#define LCD_RS          17
#define LCD_RSET        16
#define SPI_CLK         18
#define TFT_BACKLIGHT_PIN 15


//    Font Data
const char Font[192][5] =
{
    { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " " 0x20
    { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // !   0x21
    { 0x00, 0x07, 0x00, 0x07, 0x00 }, // "   0x22
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #   0x23
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $   0x24
    { 0x23, 0x13, 0x08, 0x64, 0x62 }, // %   0x25
    { 0x36, 0x49, 0x55, 0x22, 0x50 }, // &   0x26
    { 0x00, 0x05, 0x03, 0x00, 0x00 }, // '   0x27
    { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (   0x28
    { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )   0x29
    { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // *   0x2A
    { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // +   0x2B
    { 0x00, 0x50, 0x30, 0x00, 0x00 }, // ,   0x2C
    { 0x08, 0x08, 0x08, 0x08, 0x08 }, // -   0x2D
    { 0x00, 0x60, 0x60, 0x00, 0x00 }, // .   0x2E
    { 0x20, 0x10, 0x08, 0x04, 0x02 }, // /   0x2F
    { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0   0x30
    { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1   0x31
    { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2   0x32
    { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3   0x33
    { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4   0x34
    { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5   0x35
    { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6   0x36
    { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7   0x37
    { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8   0x38
    { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9   0x39
    { 0x00, 0x36, 0x36, 0x00, 0x00 }, // :   0x3A
    { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;   0x3B
    { 0x08, 0x14, 0x22, 0x41, 0x00 }, // <   0x3C
    { 0x14, 0x14, 0x14, 0x14, 0x14 }, // =   0x3D
    { 0x00, 0x41, 0x22, 0x14, 0x08 }, // >   0x3E
    { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?   0x3F
    { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @   0x40
    { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A   0x41
    { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B   0x42
    { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C   0x43
    { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D   0x44
    { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E   0x45
    { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F   0x46
    { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G   0x47
    { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H   0x48
    { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I   0x49
    { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J   0x4A
    { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K   0x4B
    { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L   0x4C
    { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M   0x4D
    { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N   0x4E
    { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O   0x4F
    { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P   0X50
    { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q   0X51
    { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R   0X52
    { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S   0X53
    { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T   0X54
    { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U   0X55
    { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V   0X56
    { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W   0X57
    { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X   0X58
    { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y   0X59
    { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z   0X5A
    { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [   0X5B
    { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\" 0X5C
    { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ]   0X5D
    { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^   0X5E
    { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _   0X5F
    { 0x00, 0x01, 0x02, 0x04, 0x00 }, // `   0X60
    { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a   0X61
    { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b   0X62
    { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c   0X63
    { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d   0X64
    { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e   0X65
    { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f   0X66
    { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g   0X67
    { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h   0X68
    { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i   0X69
    { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j   0X6A
    { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k   0X6B
    { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l   0X6C
    { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m   0X6D
    { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n   0X6E
    { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o   0X6F
    { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p   0X70
    { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q   0X71
    { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r   0X72
    { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s   0X73
    { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t   0X74
    { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u   0X75
    { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v   0X76
    { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w   0X77
    { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x   0X78
    { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y   0X79
    { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z   0X7A
    { 0x00, 0x08, 0x36, 0x41, 0x00 }, // {   0X7B
    { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // |   0X7C
    { 0x00, 0x41, 0x36, 0x08, 0x00 }, // }   0X7D
    { 0x08, 0x08, 0x2a, 0x1c, 0x08 }, // ->  0X7E
    { 0x08, 0x1c, 0x2a, 0x08, 0x08 }, // <-  0X7F
    { 0x08, 0x46, 0x4a, 0x32, 0x1e }, // ta  0x80
    { 0x0a, 0x4a, 0x3e, 0x09, 0x08 }, // ti  0x81
    { 0x0e, 0x00, 0x4e, 0x20, 0x1e }, // tu  0x82
    { 0x04, 0x45, 0x3d, 0x05, 0x04 }, // te  0x83
    { 0x00, 0x7f, 0x08, 0x10, 0x00 }, // to  0x84
    { 0x44, 0x24, 0x1f, 0x04, 0x04 }, // na  0x85
    { 0x40, 0x42, 0x42, 0x42, 0x40 }, // ni  0x86
    { 0x42, 0x2a, 0x12, 0x2a, 0x06 }, // nu  0x87
    { 0x22, 0x12, 0x7b, 0x16, 0x22 }, // ne  0x88
    { 0x00, 0x40, 0x20, 0x1f, 0x00 }, // no  0x89
    { 0x78, 0x00, 0x02, 0x04, 0x78 }, // ha  0x8A
    { 0x3f, 0x44, 0x44, 0x44, 0x44 }, // hi  0x8B
    { 0x02, 0x42, 0x42, 0x22, 0x1e }, // hu  0x8C
    { 0x04, 0x02, 0x04, 0x08, 0x30 }, // he  0x8D
    { 0x32, 0x02, 0x7f, 0x02, 0x32 }, // ho  0x8E
    { 0x02, 0x12, 0x22, 0x52, 0x0e }, // ma  0x8F
    { 0x00, 0x2a, 0x2a, 0x2a, 0x40 }, // mi  0x90
    { 0x38, 0x24, 0x22, 0x20, 0x70 }, // mu  0x91
    { 0x40, 0x28, 0x10, 0x28, 0x06 }, // me  0x92
    { 0x0a, 0x3e, 0x4a, 0x4a, 0x4a }, // mo  0x93
    { 0x04, 0x7f, 0x04, 0x14, 0x0c }, // ya  0x94
    { 0x40, 0x42, 0x42, 0x7e, 0x40 }, // yu  0x95
    { 0x4a, 0x4a, 0x4a, 0x4a, 0x7e }, // yo  0x96
    { 0x04, 0x05, 0x45, 0x25, 0x1c }, // ra  0x97
    { 0x0f, 0x40, 0x20, 0x1f, 0x00 }, // ri  0x98
    { 0x7c, 0x00, 0x7e, 0x80, 0x30 }, // ru  0x99
    { 0x7e, 0x40, 0x20, 0x10, 0x08 }, // re  0x9A
    { 0x7e, 0x42, 0x42, 0x42, 0x7e }, // ro  0x9B
    { 0x0e, 0x02, 0x42, 0x22, 0x1e }, // wa  0x9C
    { 0x42, 0x42, 0x40, 0x20, 0x18 }, // n   0x9D
    { 0x02, 0x04, 0x01, 0x02, 0x00 }, // "   0x9E
    { 0x07, 0x05, 0x07, 0x00, 0x00 }, // .   0x9F
  { 0x00, 0x00, 0x00, 0x00, 0x00 }, //     0xA0
  { 0x70, 0x50, 0x70, 0x00, 0x00 }, //  .  0xA1
  { 0x00, 0x00, 0x0f, 0x01, 0x01 }, //  [  0xA2
  { 0x40, 0x40, 0x78, 0x00, 0x00 }, //  ]  0xA3
  { 0x10, 0x20, 0x40, 0x00, 0x00 }, //  ,  0xA4
  { 0x00, 0x18, 0x18, 0x00, 0x00 }, //  .  0xA5
  { 0x0a, 0x0a, 0x4a, 0x2a, 0x1e }, // wo  0xA6
  { 0x04, 0x24, 0x34, 0x14, 0x0c }, // a   0xA7
  { 0x20, 0x10, 0x78, 0x04, 0x00 }, // i   0xA8
  { 0x18, 0x08, 0x4c, 0x48, 0x38 }, // u   0xA9
  { 0x48, 0x48, 0x78, 0x48, 0x48 }, // e   0xAA
  { 0x48, 0x28, 0x18, 0x7c, 0x08 }, // o   0xAB
  { 0x08, 0x7c, 0x08, 0x28, 0x18 }, // ya  0xAC
  { 0x40, 0x48, 0x48, 0x78, 0x40 }, // yu  0xAD
  { 0x54, 0x54, 0x54, 0x7c, 0x00 }, // yo  0xAE
  { 0x18, 0x00, 0x58, 0x40, 0x38 }, // tu  0xAF
  { 0x08, 0x08, 0x08, 0x08, 0x08 }, //  -  0xB0
  { 0x01, 0x41, 0x3d, 0x09, 0x07 }, //  a  0xB1
  { 0x20, 0x10, 0x7c, 0x02, 0x01 }, //  i  0xB2
  { 0x0e, 0x02, 0x43, 0x22, 0x1e }, //  u  0xB3
  { 0x42, 0x42, 0x7e, 0x42, 0x42 }, //  e  0xB4
  { 0x22, 0x12, 0x0a, 0x7f, 0x02 }, //  o  0xB5
  { 0x42, 0x3f, 0x02, 0x42, 0x3e }, // ka  0xB6
  { 0x0a, 0x0a, 0x7f, 0x0a, 0x0a }, // ki  0xB7
  { 0x08, 0x46, 0x42, 0x22, 0x1e }, // ku  0xB8
  { 0x04, 0x03, 0x42, 0x3e, 0x04 }, // ke  0xB9
  { 0x42, 0x42, 0x42, 0x42, 0x7e }, // ko  0xBA
  { 0x02, 0x4f, 0x22, 0x1f, 0x02 }, // sa  0xBB
  { 0x4a, 0x4a, 0x40, 0x20, 0x1c }, // si  0xBC
  { 0x42, 0x22, 0x12, 0x2a, 0x46 }, // su  0xBD
  { 0x02, 0x3f, 0x42, 0x4a, 0x46 }, // se  0xBE
  { 0x06, 0x48, 0x40, 0x20, 0x1e } // so  0xBF

  
};


char v_buf[128][8];


SPISettings spiSettings = SPISettings(SPI_CLK, SPI_MSBFIRST, SPI_MODE1);


void Init_LCD()
{
    pinMode(LCD_CS, OUTPUT);
    digitalWrite(LCD_CS,HIGH);

    pinMode(LCD_RS, OUTPUT);
    digitalWrite(LCD_RS,HIGH);

    pinMode(LCD_RSET, OUTPUT);
    digitalWrite(LCD_RSET,LOW);
    delay(500);
    digitalWrite(LCD_RSET,HIGH);

    digitalWrite(LCD_CS,LOW);
    digitalWrite(LCD_RS,LOW);

    SPI.transfer(0xAE);  // display off
    SPI.transfer(0xA0);  // ADC normal ( Column address is left to right )
    SPI.transfer(0xC8);  // line scan is reverce ( bottom to top ) 
    SPI.transfer(0xA3);  // LCD bias = 1/7

    SPI.transfer(0x2C);  // Voltage supply up converter on 
    delay(50);
    SPI.transfer(0x2E);  // Voltage supply voltage regurator on
    delay(50);
    SPI.transfer(0x2F);  // foltage supply voltage follower on

    SPI.transfer(0x23);  // contrast rough (0x20-0x27)
    SPI.transfer(0x81);  // contrast trim command
    SPI.transfer(0x08);  // contrast trim data (0x00-0x3F) 

    SPI.transfer(0xA4);  // all dot displays: normal
    SPI.transfer(0x40);  // display start line set 0 (0x40-0x7F)
    SPI.transfer(0xA6);  // display normal/reverse: normal
    SPI.transfer(0xAF);  // display on

    digitalWrite(LCD_CS,HIGH);
}

void LCD_CLS(char data)
{
    int a,b;

    digitalWrite(LCD_CS,LOW);
    for(b=0; b<8; b ++) 
    {
        digitalWrite(LCD_RS,LOW);
        SPI.transfer(0xB0+b);  // page address 0xB0-0Xb8
        SPI.transfer(0x10);    // data0x10:0x00 means column address 0x00  
        SPI.transfer(0x00);

        digitalWrite(LCD_RS,HIGH);
        for(a=0; a<128; a++)
        {
            SPI.transfer(data);
            v_buf[a][b]=data;
        }
    }
    digitalWrite(LCD_CS,HIGH);
}


void LCD_PSET(int x_data, int y_data, int cl)
{

    int a,b;
    char c;

//  y_data
    a=y_data >> 3; b= y_data & 0x07;
    c=0x1;
    while(b)
    {
        c <<= 1; b --;
    }

    if(cl) v_buf[x_data][a] |= c;
    else
    {
        c = ~c; v_buf[x_data][a] &= c;
    }

    digitalWrite(LCD_CS,LOW);
    digitalWrite(LCD_RS,LOW);
    SPI.transfer(0xB0+a);
    c=x_data >> 4; c |= 0x10;
    SPI.transfer(c);
    c=x_data & 0xf;
    SPI.transfer(c);
    digitalWrite(LCD_RS,HIGH);
    SPI.transfer(v_buf[x_data][a]);
    digitalWrite(LCD_CS,HIGH);
}

void LCD_Print_Char(int x, int y, char mozi, int bw,int scale)
{
    int fontno,fontx,fonty,dot;
    char bitmask;

    fontno = mozi - 0x20;
    for(fontx=0; fontx<5; fontx ++)
    {
        bitmask=0x1;
        for(fonty=0; fonty<8; fonty ++)
        {
            if(Font[fontno][fontx] & bitmask){
              dot=1;
            } else {
              dot=0;
            }
            if(bw == 0)
            {
                if( 1 == dot){
                  dot=0;
                } else {
                  dot=1;
                }
            }
            for ( int dx=0; dx<scale;dx++) {
              for ( int dy=0; dy<scale;dy++) {
                LCD_PSET(x+fontx*scale+dx,  y + fonty*scale+dy  ,dot);
              }
            }
            bitmask <<= 1;
        }
    }
    
    for(fontx=0; fontx<1*scale; fontx ++)
    { 
      for(fonty=0; fonty<8*scale; fonty ++)
      {
        if(bw == 0) {
          dot=1;
        } else {
          dot=0;
        }
        LCD_PSET(x+7*scale+fontx,y + fonty,dot);
      }
    }
}

void LCD_Print(int x, int y, char *str, int bw,int scale)
{
    int len,i;
    len = strlen(str);
    for ( i=0; i<len;i++)
    {
        if(*str == 0xef) // for kana
        {
            str += 2;
            i += 2;
        }
        LCD_Print_Char(x,y,*str,bw,scale);
        x += 6*scale; str ++;
    }
}

void setup(void){


    pinMode(TFT_BACKLIGHT_PIN, OUTPUT);
    digitalWrite(TFT_BACKLIGHT_PIN,HIGH);
    
    SPI.begin();
    Init_LCD();
    LCD_CLS(0);  // zero clear
    LCD_Print(10,27,"JLX12864G Hello!",1,1);
    


}
void loop(void){

}

```

# 改善点

「aqm1248a esp8266 esp32」
https://hatakekara.com/aqm1248a/

のスケッチから、以下を改善しています。


- フォント描画のスケール指定ができるようになった
- コントラスト値の改善