編集履歴一覧に戻る
chrmlinux03のアイコン画像

chrmlinux03 が 2024年01月26日09時44分27秒 に編集

初版

タイトルの変更

+

【SPRESENSE2023】LCD液晶基板ili9341でタッチパネルを使うよっ

タグの変更

+

タッチパネル

+

SPRESENSE

+

Module

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

Lチカの変更

Lチカが設定されました

本文の変更

+

# はじめに こんにちわっ リナちゃん X@chrmlinux03 です ``` このページは SPRESENSE2023コンテストで作った部品を紹介するものです 最初に 0.はじめに をお読みいただければ幸いです ``` インターネットを検索するとタッチパネルの記事は沢山あります だけど何故か SPRESENSE + タッチパネル ではヒットが出て来ません そこで今後の持ってるけど使えなくってうずうずしている方々への 感謝を込めて全部公開 目指せタッチパネルマスター ٩(ˊᗜˋ*)و # 用意するもの | 部品名 | 販売先 | 価格 | 御提供品 | |-|-|-|-| | インチタッチパネル付き液晶(ili9341) |どこでも|400~3,000円|〇| 赤い基板の液晶なんで "ili9341 + Arduino" とかで検索すると大体出てくる 2.4インチ 2.8インチ ... とか色々あるけど 液晶制御用のICが ili9341 だと今回の作業で使える 他のICでもちょこっと検索するとやり方が出てくる # 液晶基板とタッチパネル 赤い液晶基板には液晶とタッチパネル別のICが載っていて それらは SPI (Serial Peripheral Interface) と言う信号線で繋がっています ざっくり言うと CS 以外の それぞれの線を繋ぎたいデバイスの信号と 制御する側の信号に合わせて接続して もしも デバイスが2個以上あるのであれば CS 以外信号線は共通で CS だけ別なGPIOに繋がれば良いって感じですかね? ``` 画像 接続の概要 ``` 出典:http://www.lcdwiki.com/2.4inch_SPI_Module_ILI9341_SKU:MSP2402 出典:https://www.analog.com/jp/analog-dialogue/articles/introduction-to-spi-interface.html # 液晶の制御 色々制御方法はありますが 今回は ESP32シリーズでお世話になっています lovyanGFX で制御を行います ``` c++:spre.Graphics.hpp #ifndef __GRAPHIC_HPP__ #define __GRAPHIC_HPP__ #define SPI4_SCLK (13) #define SPI4_MISO (12) #define SPI4_MOSI (11) #define SPI4_CS (10) #define SPI4_DC ( 9) #define SPI4_RST ( 8) #define SPI4_CS2 ( 7) #define IO_SW4 ( 7) #define IO_SW3 ( 6) #define IO_SW2 ( 5) #define IO_SW1 ( 4) #define ROT0 (0) #define ROT90 (1) #define ROT180 (2) #define ROT270 (3) #define MEGA (1000 * 1000) #define LGFX_AUTODETECT #define LGFX_USE_V1 #include <LovyanGFX.hpp> class LGFX : public lgfx::LGFX_Device { lgfx::Panel_ILI9341 _panel_instance; lgfx::Bus_SPI _bus_instance; public: LGFX(void) { { auto cfg = _bus_instance.config(); cfg.spi_mode = 0; cfg.spi_port = 4; cfg.freq_write = (20 * MEGA); cfg.freq_read = (16 * MEGA); cfg.pin_dc = SPI4_DC; _bus_instance.config(cfg); _panel_instance.setBus(&_bus_instance); } { auto cfg = _panel_instance.config(); cfg.pin_cs = SPI4_CS; cfg.pin_rst = SPI4_RST; cfg.pin_busy = -1; cfg.panel_width = 240; cfg.panel_height = 320; cfg.bus_shared = true; _panel_instance.config(cfg); } setPanel(&_panel_instance); } }; static LGFX lcd; static LGFX_Sprite spr; static bool useGraphics = false; static uint16_t _w, _h; int16_t setupGraphics(int16_t rot) { lcd.init(); lcd.setRotation(rot); spr.setColorDepth(16); spr.createSprite(lcd.width(), lcd.height()); _w = spr.width(); _h = spr.height(); useGraphics = true; return 0; } #endif ``` ## ポイント ポイントは色々あるんですけど uint16_t setupGraphics(int16_t rot) という関数で lcd ... 画像描画用インスタンス spr ... スプライト用インスタンス _w ... スプライトの幅 _h ... スプライトの高さ を最初に確保するのが楽で良い♪ # タッチパネルの制御 lovyanGFX でも制御できるはずなんですが 何か SPI の所で嵌ってしまいそうなので 今回は 赤い基板に載ってる制御IC XPT2046 に特化した内容でご説明 他のICでもちょこっと検索するとやり方が出てくるから 次の次元へ行きたい方は是非チャレンジを ```c++:tinyTouch.hpp #ifndef __TOUCH_HPP__ #define __TOUCH_HPP__ #include <XPT2046_Touchscreen.h> XPT2046_Touchscreen tch(SPI4_CS2); static uint16_t _tx, _ty, _tz; static uint16_t _tw, _th, _tr; static uint16_t _thw, _thh; static bool _swap = 0; static bool useTouch = false; #define HARDWARETOUCH_W (390) #define HARDWARETOUCH_H (3900) //int16_t isTouch(void) { int16_t isTouch(int *tx, int *ty, int *tz) { if (!tch.touched()) { return 0; } TS_Point p = tch.getPoint(); _tz = p.z; int txmin = 0; int txmax = _tw; if (_swap) { txmin = _tw; txmax = 0; } switch (_tr) { case 0: _tx = map(p.y, _thh, _thw, txmin, txmax); _ty = map(p.x, _thw, _thh, 0, _th); break; case 1: _tx = map(p.x, _thw, _thh, txmin, txmax); _ty = map(p.y, _thw, _thh, 0, _th); break; case 2: _tx = map(p.y, _thw, _thh, txmin, txmax); _ty = map(p.x, _thh, _thw, 0, _th); break; case 3: _tx = map(p.x, _thh, _thw, txmin, txmax); _ty = map(p.y, _thh, _thw, 0, _th); break; } *tx = _tx; *ty = _ty; *tz = _tz; return 1; } void setupTouch(int16_t w, int16_t h, int16_t r, bool swap) { _tw = w; _th = h; _tr = r; _thw = HARDWARETOUCH_W; _thh = HARDWARETOUCH_H; _swap = swap; tch.begin(); } #endif ``` ## ポイント これも ポイントは沢山あるんですけど液晶の方向(角度?)が変化しても タッチパネルは絶対座標(左上原点)を返して来るから それは lovyanGFX を初期化するときに液晶の方向は ROT0..ROT270 で教えて置いた方が良い これも色々な方法があるけど 今のところはこれで💦 # ライブラリ等のダウンロード Arduio Ide で 上記 2本の ライブラリをカレントフォルダに入れたら 色々入れて下さい~とかエラーが出るので ``` XPT2046_Touchscreen LovyanGFX ``` この2本はダウンロードしてインストールすれば良いかも # なんとZ軸の筆圧が検知できる ``` 画像 Z軸の筆圧検知 ``` タッチパネルには色々種類があって 抵抗被膜式 静電容量式 : とかある ``` 画像 Z軸の筆圧検知 ``` 抵抗被膜式って言うのは薄い透明な被膜が接点の上に張ってあって そのどこかを押すと接点がONになる それをコントローラICが読み取って SPI で伝えるって感じですかね? # ライブラリ作成した ## もちろん後日ライブラリ登録します 上の2本が今回作ったやつです # 応用例 このモジュール群は以下の2点で使ってます是非ご参照くださいませ٩(ˊᗜˋ*)و ## SoundSerenity [[SoundSerenity]](https://elchika.com/) ## LoRaPager [[LoRaPager]](https://elchika.com/) # 残務と今後の考察 今回はたまたま ESP32 用に作ってあった基板を使ったので 工数がかなり短縮出来ましたけど まぁ最初はブレッドボードでも良いかも 最終的にはこれが完全に乗る基板を作りたいです ## ご参考 [[S2.BStemxxx]](https://elchika.com/) とかにも応用が出来ますよっ # さいごに なかなか厄介なタッチパネルですが 組込用のスイッチとしてはまだまだ健在です(安いから)💦 ご清聴ありがとうございました [[0.はじめに]](https://elchika.com/) に戻る