実現したいこと
ESP32モジュール基板にili9488というTFTモジュールを接続して、lvglライブラリを使用してタッチパネル用の画面プロジェクトを作成したいと思っています。
既に、hello worldのような簡単なプロジェクトが動作していることを確認済みで、ESP32とili9488間の配線は正常であることを確認しました。
次に、画面中央に大きめのボタンを1個配置して、正常にタッチ動作できるかをやっています。
発生している問題・分からないこと
画面中央に大きめのボタンを1個配置して、正常にタッチ動作できるかを、chat GPTに簡単なプログラムを作ってもらって、ボタンは表示できたのですが、タッチ動作の反応が全くない状態になります。
ボタンをタッチするとモニター出力されるはずの文字列
cpp
1// シンプルなボタンイベントハンドラ 2static void simple_button_event_handler(lv_event_t *e) { 3 lv_event_code_t code = lv_event_get_code(e); 4 if(code == LV_EVENT_CLICKED) { 5 Serial.println("Simple Button Pressed!"); 6 } 7}
この文字列がボタンを押しても全く出力されません。
そうなると、simple_button_event_handlerという割り込み関数が全く動いていないような状態だと思いますし、なぜ動いていないのかが全然わかりません。
改善方法などありましたらご教示の程よろしくお願い致します。
該当のソースコード
main.cファイルの内容はこちらです。
cpp
1//main.cファイル内容 2 3#include <Arduino.h> 4#include <lvgl.h> 5#include <TFT_eSPI.h> // ILI9488ドライバを含むライブラリ 6 7void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p); // ILI9488用のflush関数 8 9TFT_eSPI tft = TFT_eSPI(); // TFTインスタンスを作成 10 11static lv_style_t style_pressed; 12 13// ボタンイベントハンドラ 14static void button_event_handler(lv_event_t *e) { 15 lv_event_code_t code = lv_event_get_code(e); 16 lv_obj_t *button = lv_event_get_target(e); 17 if(code == LV_EVENT_CLICKED) { 18 Serial.println("Button Pressed!"); // デバッグメッセージを追加 19 20 // ボタンの背景色を変更するスタイルを作成 21 22 lv_style_init(&style_pressed); 23 lv_style_set_bg_color(&style_pressed, lv_color_make(0xFF, 0xA5, 0x00)); // オレンジ色に設定 24 25 // スタイルをボタンに適用 26 lv_obj_add_style(button, &style_pressed, 0); 27 28 const char *btn_text = lv_label_get_text(lv_obj_get_child(button, 0)); 29 lv_obj_t *label = (lv_obj_t *)lv_event_get_user_data(e); // 修正:ユーザーデータを正しく取得 30 lv_label_set_text(label, btn_text); 31 } 32} 33 34// シンプルなボタンイベントハンドラ 35static void simple_button_event_handler(lv_event_t *e) { 36 lv_event_code_t code = lv_event_get_code(e); 37 if(code == LV_EVENT_CLICKED) { 38 Serial.println("Simple Button Pressed!"); 39 } 40} 41 42 43static lv_disp_draw_buf_t draw_buf; 44static lv_color_t buf[320 * 10]; // 描画バッファを定義 45 46 47static lv_disp_drv_t disp_drv; 48 49void setup() { 50 Serial.begin(115200); // シリアル通信を開始 51 lv_init(); // LVGLを初期化 52 tft.begin(); // TFTを初期化 53 tft.setRotation(1); // 必要に応じて画面の向きを設定 54 55 //uint16_t calData[5] = { 275, 3620, 264, 3532, 1 }; 56 //tft.setTouch(calData); 57 58 59 lv_disp_draw_buf_init(&draw_buf, buf, NULL, 320 * 10); 60 61 // ディスプレイドライバを設定 62 63 lv_disp_drv_init(&disp_drv); 64 disp_drv.hor_res = 480; 65 disp_drv.ver_res = 320; 66 disp_drv.flush_cb = my_disp_flush; // ここでILI9488用のflush関数を設定 67 disp_drv.draw_buf = &draw_buf; 68 lv_disp_drv_register(&disp_drv); 69 70 // シンプルなボタンを作成 71 lv_obj_t *btn = lv_btn_create(lv_scr_act()); 72 lv_obj_set_size(btn, 200, 100); 73 lv_obj_align(btn, LV_ALIGN_CENTER, 0, 0); 74 lv_obj_add_event_cb(btn, simple_button_event_handler, LV_EVENT_ALL, NULL); 75} 76 77void loop() { 78 lv_timer_handler(); // LVGLタイマーを処理 79 delay(5); 80} 81 82// ILI9488用のflush関数(ディスプレイドライバの設定に必要) 83void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { 84 uint32_t w = (area->x2 - area->x1 + 1); 85 uint32_t h = (area->y2 - area->y1 + 1); 86 tft.startWrite(); 87 tft.setAddrWindow(area->x1, area->y1, w, h); 88 tft.pushColors((uint16_t *)&color_p->full, w * h, true); 89 tft.endWrite(); 90 lv_disp_flush_ready(disp); 91}
また、TFT_eSPIライブラリのUser_Setup.hファイルの編集内容はこちらです。
cpp
1----(中略)---- 2 3//#define ILI9481_DRIVER 4//#define ILI9486_DRIVER 5#define ILI9488_DRIVER // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high) 6//#define ST7789_DRIVER // Full configuration option, define additional parameters below for this display 7//#define ST7789_2_DRIVER // Minima 8 9----(中略)---- 10 11// The hardware SPI can be mapped to any pins 12 13#define TFT_MISO 19 14#define TFT_MOSI 23 15#define TFT_SCLK 18 16#define TFT_CS 4 // Chip select control pin 17#define TFT_DC 2 // Data Command control pin 18//#define TFT_RST 3 // Reset pin (could connect to RST pin) 19//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST 20 21// For ESP32 Dev board (only tested with GC9A01 display) 22// The hardware SPI can be mapped to any pins 23 24//#define TFT_MOSI 15 // In some display driver board, it might be written as "SDA" and so on. 25//#define TFT_SCLK 14 26//#define TFT_CS 5 // Chip select control pin 27//#define TFT_DC 27 // Data Command control pin 28//#define TFT_RST 33 // Reset pin (could connect to Arduino RESET pin) 29//#define TFT_BL 22 // LED back-light 30 31#define TOUCH_CS 27 // Chip select pin (T_CS) of touch screen 32 33//#define TFT_WR 22 // Write strobe for modified Raspberry Pi TFT only 34 35----(中略)---- 36 37//#define SPI_FREQUENCY 1000000 38// #define SPI_FREQUENCY 5000000 39// #define SPI_FREQUENCY 10000000 40//#define SPI_FREQUENCY 20000000 41#define SPI_FREQUENCY 27000000 42// #define SPI_FREQUENCY 40000000 43// #define SPI_FREQUENCY 55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz) 44// #define SPI_FREQUENCY 80000000 45 46// Optional reduced SPI frequency for reading TFT 47#define SPI_READ_FREQUENCY 20000000 48 49// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here: 50#define SPI_TOUCH_FREQUENCY 2500000 51 52// The ESP32 has 2 free SPI ports i.e. VSPI and HSPI, the VSPI is the default. 53
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
念のため、main.cファイル内の
static void button_event_handler(lv_event_t *e)
static void simple_button_event_handler(lv_event_t *e)
2つのハンドラーがあるので、使っていないbutton_event_handlerは削除してみましたが、不具合は解消しません。
タッチ操作によるハンドラー呼び出しでは何か特別な設定などありますでしょうか?
補足
なお、TFT_eSPIライブラリのみで作成した下記の画面プログラムは、タッチ操作も正常にできていることを確認しています。
なので、ESP32基板とili9488との物理的な配線やTFT_eSPIライブラリの各種設定は問題ないのでは?と思うのですが・・・
他に確認すべきことなどありますでしょうか?
cpp
1#include <Arduino.h> 2#include <WiFi.h> 3#include <NTPClient.h> 4#include <WiFiUdp.h> 5#include <TFT_eSPI.h> 6 7// Wi-Fiの設定 8const char *ssid = "my_SSID"; // ここにSSIDを入力 9const char *password = "my_password"; // ここにWi-Fiパスワードを入力 10 11// NTPサーバの設定 12WiFiUDP ntpUDP; 13NTPClient timeClient(ntpUDP); 14 15void drawButtons(); 16void drawButton(int buttonIndex, uint32_t color); 17 18// TFTディスプレイの設定 19TFT_eSPI tft = TFT_eSPI(); // TFT_eSPIオブジェクトの作成 20 21void setup() { 22 Serial.begin(115200); 23 24 // Wi-Fi接続 25 WiFi.begin(ssid, password); 26 while (WiFi.status() != WL_CONNECTED) { 27 delay(500); 28 Serial.print("."); 29 } 30 Serial.println("WiFi Connected"); 31 32 // TFTディスプレイの初期化 33 tft.init(); 34 tft.setRotation(1); // 画面の向きを調整 35 36 uint16_t calData[5] = { 231, 3567, 344, 3355, 7 }; 37 tft.setTouch(calData); 38 39 // NTPサーバに接続 40 timeClient.begin(); 41 timeClient.setTimeOffset(3600 * 9); // 日本時間の場合、UTC+9時間 42 43 // ボタンの表示(一度だけ実行) 44 drawButtons(); 45 46} 47 48void drawButtons() { 49 for (int i = 0; i < 10; i++) { 50 drawButton(i, TFT_BLACK); // デフォルトの色でボタンを描画 51 } 52} 53 54 55void drawButton(int buttonIndex, uint32_t color) { 56 int x = (buttonIndex % 5) * 80; // ボタンのX座標を更新 57 int y = (buttonIndex / 5) * 60 + 100; // ボタンのY座標を更新 58 tft.fillRect(x, y, 80, 60, color); // 新しいサイズでボタンの背景を描画 59 tft.drawRect(x, y, 80, 60, TFT_WHITE); // 新しいサイズでボタンの枠を描画 60 tft.setCursor(x + 30, y + 25); // テキストの位置を調整 61 tft.print(buttonIndex + 1); // ボタンの番号を描画 62} 63 64 65// タッチされたボタンのインデックスと時間を記録する変数 66int lastButtonIndex = -1; 67unsigned long lastButtonTime = 0; 68 69// グローバル変数として前回の時刻を記録するための変数を追加 70String lastTime = ""; 71 72void loop() { 73 timeClient.update(); 74 75 String currentTime = timeClient.getFormattedTime(); 76 if (currentTime != lastTime) { 77 // 時計表示エリアのみを更新 78 tft.fillRect(0, 0, 240, 80, TFT_BLACK); // 時計表示エリアをクリア 79 tft.setTextColor(TFT_WHITE); 80 tft.setTextSize(2); 81 tft.setCursor(10, 10); 82 tft.print("Time: "); 83 tft.setTextSize(3); 84 tft.setCursor(10, 40); 85 tft.print(currentTime); 86 87 lastTime = currentTime; // 現在の時刻を記録 88 // シリアルモニターに時刻を出力 89 Serial.println(timeClient.getFormattedTime()); 90 } 91 92 // タッチ座標の変数を宣言 93 uint16_t t_x, t_y; 94 95 // タッチ入力の検出 96 if (tft.getTouch(&t_x, &t_y)) { 97 int buttonIndex = (t_x / 80) + (t_y - 100) / 60 * 5; // 幅80ピクセル、高さ60ピクセルに基づく計算 98 if (buttonIndex >= 0 && buttonIndex < 10) { 99 drawButton(buttonIndex, TFT_RED); 100 lastButtonIndex = buttonIndex; 101 } 102 } else { 103 // タッチが終了した場合、ボタンの色を戻す 104 if (lastButtonIndex != -1) { 105 drawButton(lastButtonIndex, TFT_BLACK); 106 lastButtonIndex = -1; 107 } 108 } 109 110 delay(10); 111 112} 113

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。