MakePython ESP32 Color LCD で LovyanGFXを堪能
Makerfabs 様よりいただいたMakePython ESP32 Color LCDの
ディスプレイにLovyanGFXライブラリをもちいてアニメーションを表示してみました。
目次
MakePython ESP32 Color LCD
240×240サイズのカラーLCD (ST7789)が搭載されたESP32マイコンです。
はじめからマイコン向けのPython環境であるMicroPythonでコーディングできるようになっています。
しかし、私はPythonよりArduino IDEのほうが親しみが深いので
ここではArduinoでコーディングいたします。
一度Arduinoで書き込むとMicroPythonで書き込みできなくなってしまいます。
再度 MicroPythonを使用する場合には、以下の手法でMicro Pythonのファームを
MakePython ESP32 Color LCDにアップロードしてください。
FlashUpload MicroPython Firmware to ESP32
Party Parrot
MakePython ESP32 Color LCDに表示する画像はParty Parrotにいたしました。
参考:Party Parrot とは 〜イカれたオウムの歴史を紐解く〜
以下の動画にインスパイアされましたw カワイイ♪
— ゆー@なんか作っている (@YoutechA320U) May 18, 2020
Party ParrotのGIFは10枚の絵で構成されており、
MakePython ESP32 Color LCDに表示するために240×240の10枚のjpegにして
バイナリの配列にして書き込みました。
バイナリエディタには FavBinEdit というソフトを使用しました。
LovyanGFX
LovyanGFX は、@lovyan03さんによって開発された高機能・高速動作グラフィックライブラリです。
Wio Terminal にひきつづきまして、今回もありがたく使用させていただきました!
Arduino IDEのライブラリマネージャより簡単に導入できます。
LovyanGFX SPI設定
LovyanGFXのSPI LCD向けサンプルコードを MakePython ESP32 Color LCD の構成、ピン接続に従って修正します。
LCD ST7789周りの構成
Arduino コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
// LovyanGFX SPIバスおよび使用パネルの設定を伴う使い方 // ヘッダをincludeします。 #include <LovyanGFX.hpp> #include "pic.h" unsigned long startTime; // SPI設定用の構造体を用意します。 // 構造体の名称に決まりはありませんが、 // 構造体の各メンバ変数の名前と型は例の通りにしてください。 struct LGFX_Config { // 使用するSPIを VSPI_HOST または HSPI_HOST で設定します。 static constexpr spi_host_device_t spi_host = VSPI_HOST; // 使用するDMAチャンネルを 1か2で設定します。 // 使用しない場合は省略するか0を設定します。 static constexpr int dma_channel = 1; // SPIのSCLKのピン番号を設定します。 static constexpr int spi_sclk = 14; // SPIのMOSIのピン番号を設定します。 static constexpr int spi_mosi = 13; // SPIのMISOのピン番号を設定します。 // SDカード等と共通のSPIバスを使う場合はMISOも必ず設定してください。 // 使わない場合は省略するか-1を設定します。 static constexpr int spi_miso = 12; // SPI通信のデータ長を指定します。 // RaspberryPi用のLCD等を使用する場合に16を指定します。 // 省略時は 8 です。大抵のパネルは8ですので、基本的には省略してください。 //static constexpr int spi_dlen = 16; }; // 用意した設定用の構造体を、LGFX_SPIクラスにテンプレート引数として設定し、インスタンスを作成します。 static lgfx::LGFX_SPI<LGFX_Config> lcd; static LGFX_Sprite sprite(&lcd); // Panelクラスのインスタンスを作成します。使用するパネルにあったクラスを選択してください。 static lgfx::Panel_ST7789 panel; void setup(void){ Serial.begin(115200); // パネルクラスに各種設定値を代入していきます。 // (LCD一体型製品のパネルクラスを選択した場合は、 // 製品に合った初期値が設定されているので設定は不要です) // 通常動作時のSPIクロックを設定します。 // ESP32のSPIは80MHzを整数で割った値のみ使用可能です。 // 設定した値に一番近い設定可能な値が使用されます。 panel.freq_write = 80000000; //panel.freq_write = 20000000; // 単色の塗り潰し処理時のSPIクロックを設定します。 // 基本的にはfreq_writeと同じ値を設定しますが、 // より高い値を設定しても動作する場合があります。 panel.freq_fill = 80000000; //panel.freq_fill = 27000000; // LCDから画素データを読取る際のSPIクロックを設定します。 panel.freq_read = 16000000; // SPI通信モードを0~3から設定します。 panel.spi_mode = 0; // データ読み取り時のSPI通信モードを0~3から設定します。 panel.spi_mode_read = 0; // 画素読出し時のダミービット数を設定します。 // 画素読出しでビットずれが起きる場合に調整してください。 panel.len_dummy_read_pixel = 8; // データの読取りが可能なパネルの場合はtrueを、不可の場合はfalseを設定します。 // 省略時はtrueになります。 panel.spi_read = true; // データの読取りMOSIピンで行うパネルの場合はtrueを設定します。 // 省略時はfalseになります。 panel.spi_3wire = false; // LCDのCSを接続したピン番号を設定します。 // 使わない場合は省略するか-1を設定します。 panel.spi_cs = 15; // LCDのDCを接続したピン番号を設定します。 panel.spi_dc = 22; // LCDのRSTを接続したピン番号を設定します。 // 使わない場合は省略するか-1を設定します。 panel.gpio_rst = 21; // LCDのバックライトを接続したピン番号を設定します。 // 使わない場合は省略するか-1を設定します。 panel.gpio_bl = 5; // バックライト使用時、輝度制御に使用するPWMチャンネル番号を設定します。 // PWM輝度制御を使わない場合は省略するか-1を設定します。 panel.pwm_ch_bl = -1; // バックライト点灯時の出力レベルがローかハイかを設定します。 // 省略時は true。true=HIGHで点灯 / false=LOWで点灯になります。 panel.backlight_level = true; // invertDisplayの初期値を設定します。trueを設定すると反転します。 // 省略時は false。画面の色が反転している場合は設定を変更してください。 panel.invert = true; // パネルの色順がを設定します。 RGB=true / BGR=false // 省略時はfalse。赤と青が入れ替わっている場合は設定を変更してください。 panel.rgb_order = false; // パネルのメモリが持っているピクセル数(幅と高さ)を設定します。 // 設定が合っていない場合、setRotationを使用した際の座標がずれます。 // (例:ST7735は 132x162 / 128x160 / 132x132 の3通りが存在します) panel.memory_width = 240; panel.memory_height = 240; // パネルの実際のピクセル数(幅と高さ)を設定します。 // 省略時はパネルクラスのデフォルト値が使用されます。 panel.panel_width = 240; panel.panel_height = 240; // パネルのオフセット量を設定します。 // 省略時はパネルクラスのデフォルト値が使用されます。 panel.offset_x = 0; panel.offset_y = 0; // setRotationの初期化直後の値を設定します。 panel.rotation = 0; // setRotationを使用した時の向きを変更したい場合、offset_rotationを設定します。 // setRotation(0)での向きを 1の時の向きにしたい場合、 1を設定します。 panel.offset_rotation = 0; // 設定を終えたら、LGFXのsetPanel関数でパネルのポインタを渡します。 lcd.setPanel(&panel); // SPIバスの初期化とパネルの初期化を実行すると使用可能になります。 lcd.init(); lcd.startWrite(); lcd.setColorDepth(24); } void loop(void){ startTime = millis(); lcd.drawJpg(pic0, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic1, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic2, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic3, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic4, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic5, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic6, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic7, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic8, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); lcd.drawJpg(pic9, sizeof(pic0) / sizeof(byte), 0, 0, 240, 240 ,0, 0, JPEG_DIV_NONE); Serial.println(millis() - startTime); } |
pic.hは10枚の画像の配列です。
1 2 3 4 5 6 7 8 9 10 |
byte pic0[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic1[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic2[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic3[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic4[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic5[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic6[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic7[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic8[] = {0xFF,0xD8,‥,0xFF,0xD9}; byte pic9[] = {0xFF,0xD8,‥,0xFF,0xD9}; |
動作
なかなか激しく動いておりますww
実はここまでのスピードで表示させるまでに色々ございましたので以下に記します。
表示高速化への道
当初は動きがカクカクでしたが、LovyanGFXライブラリの開発者の @lovyan03さんに手取り足取り教えていただき
かなりのスピードアップが実現できました!
初期状態
MakePython ESP32 Color LCD
https://t.co/lkEjFKQV7l #Makerfabs#LovyanGFXJPEGパラパラ表示
調整で改善しますでしょうか? pic.twitter.com/XXfKfj4aU7— HomeMadeGarbage (@H0meMadeGarbage) May 19, 2020
setColorDepth(24) 追加
ありがとうございます!!
setColorDepth(24)追加だけで早くなりました!#Makerfabs#LovyanGFX pic.twitter.com/twXlMPlmv9— HomeMadeGarbage (@H0meMadeGarbage) May 19, 2020
SPIクロックを80MHZへ
panel.freq_write = 20000000 → 80000000
panel.freq_fill = 27000000 → 80000000
に変更
ありがとうございます!
早くなりましたー#Makerfabs#LovyanGFX pic.twitter.com/DeJ4iFXZ4D— HomeMadeGarbage (@H0meMadeGarbage) May 20, 2020
どんどん早くなります!
画像圧縮
jpeg画像を更に圧縮してファイルサイズを1/3ほどにしてみました。
以下のサイトで画像の画質を落としてサイズダウンしました。
https://resizer.myct.jp/index.php
絵は汚くなってしまいますが、高速動作は実現できました。
表示速度
10枚の画像を表示するまでの時間をまとめました。
表示速度 [msec / 10フレーム] | |
初期状態 | 930 |
setColorDepth(24) 追加 | 676 |
SPIクロックを80MHZへ | 492 |
画像圧縮 | 443 |
最終的には倍以上のスピードになったことになります。
奥深すぎる。。。助けがなければ絶対実現できなかったです。
lovyanさん本当にありがとうございます!!
おわりに
さて これで MakePython ESP32 Color LCD に所望の画像を表示できるようになりました。
せっかくESP32が載っているのですから、次回は無線で画像を送って表示させてみたいです。
です…jpegデコーダかなり魔改造しました。
これも同じ仕組みでWiFiで受信しながらデコードして、最大32fps出ます。https://t.co/TK7FxWBn8w https://t.co/RAe56xXZwq— らびやん (@lovyan03) May 20, 2020
もしご興味がございましたら…ScreenShotReceiverはコチラになります。送信側がWindows用のみですが…。https://t.co/kB7rSm5LlE
これも今のところTFT_eSPIが必要になっているのですが、SPI設定のみに利用してる感じなので…いずれLovyanGFX仕様に変更しようと思います。— らびやん (@lovyan03) May 20, 2020
果たしてできるのであろうか。。。
次回を待て!
追記
LovyanGFX v0.1.9 更新 (20/5/22)
LovyanGFXライブラリがアップデートされ、examplesにPartyParrotが追加もされました。
#LovyanGFX v0.1.9更新
・drawBmpとdrawPngがメモリ上の配列から描画できなくなっていたバグを修正
・examplesにPartyParrotを追加 https://t.co/m7qzjPLYU6— らびやん (@lovyan03) May 21, 2020
PartyParrotサンプルをMakePython ESP32 Color LCDにも導入してみました。
爆速ですね! pic.twitter.com/CLCBxINbqE
— HomeMadeGarbage (@H0meMadeGarbage) May 22, 2020
信じられないくらい早くなりましたwww
8bit 128×96のビットマップをsprite描画なるものを施して
拡大表示しているとのことです。
Jpegデコード表示にくらべてこんなに差があるんですね。
笑えるレベルで早い!!!
これはぶっ飛べますね pic.twitter.com/sF8PCV8D7e
— HomeMadeGarbage (@H0meMadeGarbage) May 22, 2020
「MakePython ESP32 Color LCD で LovyanGFXを堪能」への1件のフィードバック