Archive for 2月 2019
Use ILI9488 with M5Stack
3.5″ 480×320 TFT ILI9488 Display を M5Stackで使用しました。 2019.02.05
費用は 2100円。
M5Stack との接続は Expansion Module で接続します。
3.5インチ 480×320 は 大きな画面で見やすいです。
タッチパネルで 多様な入力が可能になります。
以下は キーボード入力の例で 画面は「SHIF」で切り替えます。
![]() |
![]() |
![]() |
![]() |
タッチ操作のスケッチを応用すると 多彩な機能が実現します。
3.5″ 480×320 TFT SPI ILI9488 Touch Panel Display の 仕様:
Drive IC:ILI9488
規格:LITEK社:320(RGB) x 480 Resolution, 16.7M-color With Internal GRAM
サイズ:3.5 inch
解像度:480 x 320 Pixel
機能1:Touch Sensor
機能2:SD SLOT
Data Interface:4-wire SPI interface
SPI FREQUENCY:40MHz
SPI TOUCH FREQUENCY:25MHz
部品表:
No | Nomen | Purchase | Price |
1 | 3.5″ 480×320 ILI9488 display | Hong Kong feng tai co., LTD | 1332円 |
2 | 2.54mm L型ピンヘッダー(オス型) | 秋月電子通商: 2×40 | 50円 |
3 | 2.54mm ピンヘッダー(オス型) | 秋月電子通商:2×40 | 25円 |
4 | ロープロファイルピンソケット低メス | 秋月電子通商:2×15 5.7mm | 40円 |
5 | 基板:十字配線ユニバーサル | 秋月電子通商:Dタイプ 60円 | 20円 |
6 | 基板:230×320 厚さ0.4mm | 千石電商:0.4mm曲がる基板 | 234円 |
6 | (基板:180×300 厚さ0.4mm) | (aitendo:ハサミで切れる基板) | (224円) |
7 | M2 5mm ナベ Tapping Screw(4ea) | 西川電子部品株式会社 | 6円 |
8 | M3 16mm Hex Bolt | ebay:regan0331 store | 9円 |
9 | ケース | 自作:Top, body, Down | 394円 |
10 | Library: | Bodmer:TFT-eSPI | – |
====================== | =================== | ====== | |
費用総計 | 2110円 |
_ Price:一部を使用する部品は 使用した分のみの費用です。
ILI9488:
_ 販売:ebay:Hong Kong feng tai co., LTD Store
_ 価格:1332円。(1 JPY = 0.00848724 USD)。輸送期間=15日。
_ 販売価格状況:2019.02.03現在
Price | Shop | MEMO |
$11.21 | Surenoo Store | 100pcs=$1,121.06 |
$12.29 | Surenoo Store | 10pcs=$123.29 |
$13.10 | Hong Kong feng tai co., LTD | 輸送期間=15日 |
$14.85 | Shenzhen High-quality new products | |
$15.80 | JR E-Shop | |
$17.54 | Surenoo Store | |
$18.14 | Shenzhen More-Suns Electronics Co.,Ltd | |
EUR 14.99 | surenoo |
国内での販売は まだ 見かけていませんが 販売されると高値になると思われます。
_ 理由は ILI9486 420×320 TFT (Raspberry pi 用)は aitendo(3500円税別) とアマゾン、
_ スイッチサイエンス(4834円)、千石電商(5980円) で高価の為です。
配線:12本配線します。
TFT MISO:
_ M-BUS と TFT MISO(青)を接続すると TFT-eSPI で TFT の内部を
_ 読む事ができます。ただし TouchとSDは使用出来なくなります。
_ よって使用時は TFT MISO へは接続しません。
ILI9488 VCC:3.3V もしくは 5Vdc 接続です。
ILI9488 LED:3.3V のみです。注意:5V を加えると LED が破損します。
ILI9488 TFT | VCC | GND | CS | RESET | DC | MOSI | SCK | LED | MISO |
M-BUS | 3V3 | GND | 15 | EN | 2 | 23 | 18 | 3V3 | unused |
. | |||||||||
ILI9488 TOUCH | T_CLK | T_CS | _ | T_DIN | T_DO | T_IRQ | _ | _ | _ |
M-BUS | 18 | 19 | _ | 23 | 16 | unused | _ | _ | _ |
基板のサイズは 100x55mmです。
右端のメスピンソケットは ILI9488 のピンを接続するコネクターです。
右の基板は「十字配線ユニバーサル」を使用し 横の配線にカットします。
十字基板の下は ピンヘッダーとピンソケットを接続します。
端子配列とスケッチの記述は以下です。
#define TFT_MISO 16 // (leave TFT SDO disconnected if other SPI devices share MISO) #define TFT_MOSI 23 // #define TFT_SCLK 18 // #define TFT_CS 15 // Chip select control pin #define TFT_DC 2 // Data Command control pin #define TFT_RST -1 // Reset pin (could connect to RST pin) #define TOUCH_CS 19
ケース:
_ Expansion Adapter のケースは プリンターの精度にあった
_ 自由な設計が可能です。基板を固定する 2mmネジ穴の位置は
_ 基板のスルーホールの位置に合わせています。
スケッチ:「キーボード入力」
Bodmer:TFT-eSPI のサンプルに Keypad_480x320.ino があります。
_ このサンプルは char keyLabel の配列 に値を記載する事により
_ 自由にキーボードを製作する事が可能な 汎用性のあるスケッチです。
_ このサンプルを キーボード入力 に移植致しました。
_ 「キーボード入力」のリストは このページの最後に記載しました。
キャリブレーション:
_ 初回起動では Touch Sens のキャリブレーションが行われます。
_ 起動後に画面が黒くなっています。しばらくしてから画面に
_ 表示されますので 矢印の支持に従い画面を操作します。
Bodmer:TFT-eSPI の examples:
1. Keypad_480x320:キーボード入力。
_ TFT_eSPI / examples / 480 x 320 / Keypad_480x320
2. Touch_Controller_Demo:キャリブレーションと x,y 表示。
_ TFT_eSPI / examples / Test and diagnostics / Touch_Controller_Demo
_ 最初にキャリブレーションを実施し、次に TFTの画面に x と y の値(数値)
_ と 点を 抽画します。
3. Touch_calibrate:キャリブレーションとキャリブレーションデーター作成。
_ TFT_eSPI / examples / Generic / Touch_calibrate
_ 指示に従い画面操作すると キャリブレーションデーターを得られます。
_ 値は シリアルモニターに表示されます。この値を スケッチの中に記載します。
// Use this calibration code in setup(): uint16_t calData[5] = { 301, 3495, 393, 3211, 7 }; tft.setTouch(calData);
4. Read_User_Setup:User_Setup が シリアルモニターに表示されます。
_ TFT_eSPI / examples / Test and diagnostics / Read_User_Setup
Processor = ESP32 Frequency = 240 MHz Transactions = Yes Interface = SPI Display driver = 9488 Display width = 320 Display height = 480 MOSI = D23 (GPIO 23) MISO = D16 (GPIO 16) SCK = D18 (GPIO 18) TFT_CS = D15 (GPIO 15) TFT_DC = D2 (GPIO 2) TOUCH_CS = D19 (GPIO 19) Font GLCD loaded Font 2 loaded Font 4 loaded Font 6 loaded Font 7 loaded Font 8 loaded Smooth font enabled Display SPI frequency = 40.0 MHz Touch SPI frequency = 2.5 MHz
5. Read_ID_bitbash_ESP32:ILI9488 のレジスター値を読む方法。
_ M-BUS 16 と TFT_MISO を接続すると 0x00 から 0xFF までの値が
_ シリアルモニターに表示されます。以下に スケッチがあります。
_ Bodmer/TFT_eSPI:Is it support ILI9488 480×320 in 18bit mode #187
TFT driver register values: =========================== Register 0x01: 0x00 Register 0x04: 0x548066 Register 0x09: 0x610000 Register 0x0A: 0x08 . . Register 0xFF: 0x06 Register 0xFF: 0xC0000 Register 0xFF: 0xC000000
ILI9486 と ILI9488 の速度比較:ILI9488 は ILI9486 より 1.4倍 高速です。
_ ILI9486 480×320 TFT Touch Display。(20MHz 動作):赤色
_ ILI9488 480×320 TFT Touch Display。(40MHz 動作):青色
参考:
ILI9488 規格:LITEK社:320(RGB) x 480 Resolution, 16.7M-color With Internal GRAM
Bodmer:TFT-eSPI :ライブラリー
Bodmer/TFT_eSPI:Is it support ILI9488 480×320 in 18bit mode #187 :動作に対する質問と回答。
macsbug:2016.04.16:Using the TFT LCD display in the ESP8266:2.4inch 240×320 SPI ILI9341
macsbug:2016.10.07:1.44″ 128×128 Color TFT in ESP8266:1.44″ 128×128 SPI Color TFT ST7735
macsbug:2016.12.17:2.4 Inch TFT Display For ESP32:2.4 inch 240×320 SPI TFT LCD ILI9341
macsbug:2017.02.11:ESP32 Adapter Board and TFT Display:1.44″ SPI TFT 128 x 128 Display
macsbug:2017.08.12:TFT display for Raspberry pi with ESP32:3.5 ” 480×320 SPI TFT RPi touch Display
macsbug:2018.04.17:TFT_eSPI Library supports M5STACK:M5Stack_TFT_ILI9341 ( Custom ILI9341)
macsbug:2018.12.30:M5Stack Extension Module:M-BUSを拡張するモジュール製作。
macsbug:2018.12.31:Production of PROTO MODULE of M5Stack:幾つかの PROTO Moduleの製作。
macsbug:2019.01.01:Connect 3.5″ 480 x 320 Display to M5Stack:3.5″ 480×320 TFT SPI ILI9486 Display
感想:
ディスプレー:
_ TFT Dsiplay は ある製品の一部の部品と思われます。
_ 例として車の CDやDVDのDisplayに使用され大量生産で低価格になった部品。
_ 特に 320×240 ILI9341 は ebayで700円程度の低価格です。
ILI9488と販売:
_ ILI9488 の存在は espressifでの話が May 2017 にありましたが販売情報は無しでした。
_ 初めての販売は Aliexpress JR E-Shop は OCT 2018, Shenzhen High-quality new products
_ Store と Hong Kong feng tai co., LTD Storeは Nov 2018 に販売され比較的に最近です。
ケースの高さ:ILI9488は ILI9486より高さを低く出来ます。
_ ILI9486 の高さは 25mm:RPI 接続用のコネクターがあり高くなります。
_ ILI9488 の高さは 21mm:
今後:ILI9488 の価格は ILI9486 より少し高いですが 高速、高さが低い、
_ SD SLOT があり、今後 ILI9488 を使用する事にしました。
配線:今回の配線は ILI9488 のコネクタ位置は M-BUS から遠くなっています。
_ 長い基板を使用し費用がかかっています。専用基板を安く作ると 今回の費用より
_ 低費用にする事ができると思います。配線が長く信号的には良く無いですが
_ ケースの長さを短くする為のレイアウトとなりました。
_ SPI_FREQUENCY は 40MHz ですが 65MHz でも動作します。
Expansion Module:専用基板は tomorrow56氏により 設計製作済みです。
_ Expansion Module と Expansion Adapter は 配布予定になっています。
_ 汎用性の高い設計で多様にアレンジできる構造になっています。
告知:2019.02.10 の Yahoo LODGE にて 開催される 「同人ハードウェアフェス」
_ に Expansion Module 、Expansion Adapter、他の作品や部品を展示する予定です。
USER_Setup リスト:
// See SetupX_Template.h for all options available #define ILI9488_DRIVER #define TFT_MISO 16 // (leave TFT SDO disconnected if other SPI devices share MISO) #define TFT_MOSI 23 // #define TFT_SCLK 18 // #define TFT_CS 15 // Chip select control pin #define TFT_DC 2 // Data Command control pin #define TFT_RST -1 // Reset pin (could connect to RST pin) #define TOUCH_CS 19 #define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH #define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters #define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters #define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm #define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:. #define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-. #define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts #define SMOOTH_FONT #define SPI_FREQUENCY 40000000 #define SPI_TOUCH_FREQUENCY 2500000
スケッチ リスト:
/* The TFT_eSPI library incorporates an Adafruit_GFX compatible button handling class, this sketch is based on the Arduin-o-phone example. This example diplays a keypad where numbers can be entered and send to the Serial Monitor window. The sketch has been tested on the ESP8266 (which supports SPIFFS) The minimum screen size is 320 x 240 as that is the keypad size. TOUCH_CS and SPI_TOUCH_FREQUENCY must be defined in the User_Setup.h file for the touch functions to do anything. */ // modify keybordpad : 2019.01.23 rev.1 macsbug // The SPIFFS (FLASH filing system) is used to hold touch screen // calibration data #include "FS.h" #include <SPI.h> #include <TFT_eSPI.h> // Hardware-specific library TFT_eSPI tft = TFT_eSPI(); // Invoke custom library // This is the file name used to store the calibration data // You can change this to create new calibration files. // The SPIFFS file name must start with "/". #define CALIBRATION_FILE "/TouchCalData2" // Set REPEAT_CAL to true instead of false to run calibration // again, otherwise it will only be done once. // Repeat calibration if you change the screen rotation. #define REPEAT_CAL false // Keypad start position, key sizes and spacing #define KEY_X 20 //40 // Centre of key #define KEY_Y 96 #define KEY_W 62 // Width and height #define KEY_H 30 #define KEY_SPACING_X 18 // X and Y gap #define KEY_SPACING_Y 20 #define KEY_TEXTSIZE 1 // Font size multiplier // Using two fonts since numbers are nice when bold #define LABEL1_FONT &FreeSansOblique12pt7b // Key label font 1 #define LABEL2_FONT &FreeSansBold12pt7b // Key label font 2 // Numeric display box size and location #define DISP_X 1 #define DISP_Y 10 #define DISP_W 478 // 238 #define DISP_H 50 #define DISP_TSIZE 3 #define DISP_TCOLOR TFT_CYAN // Number length, buffer for storing it and character index #define NUM_LEN 24 // 12 char numberBuffer[NUM_LEN + 1] = ""; uint8_t numberIndex = 0; // We have a status line for messages #define STATUS_X 240 // 120 // Centred on this #define STATUS_Y 65 // Create 15 keys for the keypad int shift = 0; char keyLabel[60][5] = { // 00 01 02 03 04 05 06 07 08 09 10 11 "!", "?", "#", "$", "%", "&", "(", ")", "<", ">", "+", "NEW", // 11 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "DEL", // 23 "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "*", "SHIF", // 35 "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "/", "Send", // 47 "Z", "X", "C", "V", "B", "N", "M", "_", ",", ".", "=", " " // 59 }; char keyLabel_0[60][5] = { // 00 01 02 03 04 05 06 07 08 09 10 11 "!", "?", "#", "$", "%", "&", "(", ")", "<", ">", "+", "NEW", // 11 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "DEL", // 23 "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "*", "SHIF", // 35 "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "/", "Send", // 47 "Z", "X", "C", "V", "B", "N", "M", "_", ",", ".", "=", " " // 59 }; char keyLabel_1[60][5] = { // 00 01 02 03 04 05 06 07 08 09 10 11 "!", "?", "#", "$", "%", "&", "(", ")", "<", ">", "+", "New", // 11 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "Del", // 23 "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "*", "Shif", // 35 "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "/", "Send", // 47 "z", "x", "c", "v", "b", "n", "m", ":", ",", ".", "=", " " // 59 }; char keyLabel_2[60][5] = { // 00 01 02 03 04 05 06 07 08 09 10 11 " ", " ", " ", " ", "A", "B", "C", "D", "E", "F", " ", "New", // 11 " ", " ", " ", " ", "9", "8", "7", "+", " ", " ", " ", "Del", // 23 " ", " ", " ", " ", "6", "5", "4", "-", " ", " ", " ", "Shif", // 35 " ", " ", " ", " ", "3", "2", "1", "*", " ", " ", " ", "Send", // 47 " ", " ", " ", " ", "0", ".", "=", "/", " ", " ", " ", " " // 59 }; uint16_t keyColor[60] = { TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_RED, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_DARKGREY, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_DARKGREEN, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE, TFT_BLUE }; TFT_eSPI_Button key[60]; // Invoke the TFT_eSPI button class and create all the button objects //------------------------------------------------------------------------------------------ void setup() { Serial.begin(115200); // Use serial port tft.init(); // Initialise the TFT screen tft.setRotation(1); // Set the rotation before we calibrate touch_calibrate(); // Calibrate the touch screen and retrieve the scaling factors tft.fillScreen(TFT_BLACK);// Clear the screen tft.fillRect(0, 0, 480, 320, TFT_DARKGREY);//240, 320// Draw keypad background tft.fillRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_BLACK);// Draw number display area and frame tft.drawRect(DISP_X, DISP_Y, DISP_W, DISP_H, TFT_WHITE); drawKeypad(); // Draw keypad } //------------------------------------------------------------------------------------------ void loop(void) { uint16_t t_x = 0, t_y = 0; // To store the touch coordinates boolean pressed = tft.getTouch(&t_x, &t_y);// Pressed will be set true is there is a valid touch on the screen for (uint8_t b = 0; b < 60; b++) { // Check if any key coordinate boxes contain the touch coordinates if (pressed && key[b].contains(t_x, t_y)) { key[b].press(true); // tell the button it is pressed } else { key[b].press(false); // tell the button it is NOT pressed } } for (uint8_t b = 0; b < 60; b++) { // 15 // Check if any key has changed state //if (b < 3) tft.setFreeFont(LABEL1_FONT); if ( b == 11 || b == 23 || b == 35 || b == 47 ) tft.setFreeFont(LABEL1_FONT); else tft.setFreeFont(LABEL2_FONT); if (key[b].justReleased()) key[b].drawButton(); // draw normal if (key[b].justPressed()) { key[b].drawButton(true); // draw invert //if (b >= 3) { // if a numberpad button, append the relevant # to the numberBuffer uint8_t bx = 0; if ( b == 11 || b == 23 || b == 35 || b == 47){ bx = 1 ;} if ( bx == 0) { // if a numberpad button, append the relevant # to the numberBuffer if (numberIndex < NUM_LEN) { numberBuffer[numberIndex] = keyLabel[b][0]; numberIndex++; numberBuffer[numberIndex] = 0; // zero terminate } status(""); // Clear the old status } if (b == 23) { // Del button, so delete last char numberBuffer[numberIndex] = 0; if (numberIndex > 0) { numberIndex--; numberBuffer[numberIndex] = 0;//' '; } status(""); // Clear the old status } if (b == 47) { status("Sent value to serial port"); Serial.println(numberBuffer); } if (b == 11) { // new status("Value cleared"); numberIndex = 0; // Reset index to 0 numberBuffer[numberIndex] = 0; // Place null in buffer } if (b == 35) { // shift status("Value shift"); for ( int i=-1; i<60; i++){ if ( shift == 0 ) ( keyLabel[i][5] = keyLabel_1[i][5]); if ( shift == 1 ) ( keyLabel[i][5] = keyLabel_2[i][5]); if ( shift == 2 ) ( keyLabel[i][5] = keyLabel_0[i][5]); } drawKeypad(); // Draw keypad if ( shift == 0 ){ shift = 1; return;} if ( shift == 1 ){ shift = 2; return;} if ( shift == 2 ){ shift = 0; return;} } // Update the number display field tft.setTextDatum(TL_DATUM); // Use top left corner as text coord datum tft.setFreeFont(&FreeSans18pt7b); // Choose a nicefont that fits box tft.setTextColor(DISP_TCOLOR); // Set the font colour // Draw the string, the value returned is the width in pixels int xwidth = tft.drawString(numberBuffer, DISP_X + 4, DISP_Y + 12); // Now cover up the rest of the line up by drawing a black rectangle. No flicker this way // but it will not work with italic or oblique fonts due to character overlap. tft.fillRect(DISP_X + 4 + xwidth, DISP_Y + 1,DISP_W - xwidth - 5,DISP_H - 2,TFT_BLACK); delay(10); // UI debouncing } } } //------------------------------------------------------------------------------------------ void drawKeypad(){ // Draw the keys for (uint8_t row = 0; row < 5; row++) { for (uint8_t col = 0; col < 12; col++) { // 3 uint8_t b = col + row * 12; // 3 if (b == 11 || b == 23 || b == 35 || b == 47) tft.setFreeFont(LABEL1_FONT); // ❤ else tft.setFreeFont(LABEL2_FONT); int xw1 = 43; int xw2 = 27; if (b == 11 || b == 23 || b == 35 || b == 47 ){ xw1 = 41; xw2 = 0;} key[b].initButton(&tft, KEY_X + col * (KEY_W + KEY_SPACING_X - xw1), KEY_Y + row * (KEY_H + KEY_SPACING_Y), // x, y, w, h, outline, fill, text KEY_W - xw2, KEY_H, TFT_WHITE, keyColor[b], TFT_WHITE, keyLabel[b], KEY_TEXTSIZE); key[b].drawButton(); } } } //------------------------------------------------------------------------------------------ void touch_calibrate(){ uint16_t calData[5]; uint8_t calDataOK = 0; if (!SPIFFS.begin()) { // check file system exists Serial.println("Formating file system"); SPIFFS.format(); SPIFFS.begin(); } // check if calibration file exists and size is correct if (SPIFFS.exists(CALIBRATION_FILE)) { if (REPEAT_CAL){ // Delete if we want to re-calibrate SPIFFS.remove(CALIBRATION_FILE); }else{ File f = SPIFFS.open(CALIBRATION_FILE, "r"); if (f) { if (f.readBytes((char *)calData, 14) == 14) calDataOK = 1; f.close(); } } } if (calDataOK && !REPEAT_CAL) { // calibration data valid tft.setTouch(calData); } else { // data not valid so recalibrate tft.fillScreen(TFT_BLACK); tft.setCursor(20, 0); tft.setTextFont(2); tft.setTextSize(1); tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.println("Touch corners as indicated"); tft.setTextFont(1); tft.println(); if (REPEAT_CAL) { tft.setTextColor(TFT_RED, TFT_BLACK); tft.println("Set REPEAT_CAL to false to stop this running again!"); } tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.println("Calibration complete!"); // store data File f = SPIFFS.open(CALIBRATION_FILE, "w"); if (f) { f.write((const unsigned char *)calData, 14); f.close(); } } } //------------------------------------------------------------------------------------------ void status(const char *msg){ // Print something in the mini status bar tft.setTextPadding(240); //tft.setCursor(STATUS_X, STATUS_Y); tft.setTextColor(TFT_WHITE, TFT_DARKGREY); tft.setTextFont(0); tft.setTextDatum(TC_DATUM); tft.setTextSize(1); tft.drawString(msg, STATUS_X, STATUS_Y); } //------------------------------------------------------------------------------------------