T4-S3 Quick Start
This guide covers Arduino, PlatformIO, LVGL, and peripheral usage for the T4-S3. For hardware specs and pin mapping, see the T4-S3 product page.
Pin Definitions
The T4-S3 uses the LilyGo_AMOLED library which abstracts all hardware access. The pin constants below are for reference; you generally do not need to define them manually.
// Display (RM690B0 — QSPI)
#define BOARD_DISP_DATA0 14
#define BOARD_DISP_DATA1 10
#define BOARD_DISP_DATA2 16
#define BOARD_DISP_DATA3 12
#define BOARD_DISP_SCK 15
#define BOARD_DISP_CS 11
#define BOARD_DISP_RESET 13
#define BOARD_DISP_TE 18 // Tearing Effect — do NOT use for other purposes
// Touch (CS226SE — I2C)
#define BOARD_TOUCH_SDA 6
#define BOARD_TOUCH_SCL 7
#define BOARD_TOUCH_IRQ 8
#define BOARD_TOUCH_RST 17
// PMU (SY6970 — I2C, shares I2C bus with touch)
#define BOARD_PMU_SDA 6
#define BOARD_PMU_SCL 7
#define BOARD_PMU_IRQ 5
#define BOARD_PMU_EN 9 // PMIC power enable
// SD card (SPI)
#define BOARD_SD_MISO 4
#define BOARD_SD_MOSI 2
#define BOARD_SD_SCK 3
#define BOARD_SD_CS 1
// Button
#define BOARD_BOOT_PIN 0GPIO18 / TE pin: GPIO18 is internally connected to the AMOLED display TE (tearing effect) signal. Do not use it for any other purpose.
Arduino
Arduino IDE
Install Board Support
- Open Arduino IDE → File → Preferences
- Add to "Additional boards manager URLs":
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - Open Tools → Board → Boards Manager, search esp32, install esp32 by Espressif Systems
Version note: The
LilyGo-AMOLED-Serieslibrary requires arduino-esp32 ≥ 2.0.5 and < 3.0.0. Versions ≥ 3.0.0 are not supported.
Install Libraries
Copy all folders from the project libdeps/ directory to your Arduino Sketchbook libraries/ folder, or install via Library Manager:
| Library | Version | Purpose |
|---|---|---|
| LilyGo-AMOLED-Series | latest | Board HAL, display, touch, PMU |
| lvgl | 8.4.0 | GUI framework (v8) |
| XPowersLib | 0.2.7 | PMU (SY6970 / AXP2101) |
| SensorLib | 0.2.4 | Touch (CS226SE) |
| TFT_eSPI | 2.5.31 | Low-level SPI display driver |
| TinyGPSPlus | 1.0.3 | GNSS NMEA parsing (Qwiic shield) |
| Adafruit NeoPixel | 1.11.0 | NeoPixel LED (1.47-inch model only) |
Board Settings
| Arduino IDE Setting | Value |
|---|---|
| Board | ESP32S3 Dev Module |
| Upload Speed | 921600 |
| USB Mode | Hardware CDC and JTAG |
| USB CDC On Boot | Enabled |
| CPU Frequency | 240 MHz (WiFi) |
| Flash Mode | QIO 80 MHz |
| Flash Size | 16MB (128Mb) |
| Partition Scheme | 16M Flash (3MB APP/9.9MB FATFS) |
| PSRAM | OPI PSRAM |
Upload
Select the correct COM port and click Upload.
If upload fails: hold BOOT (GPIO0), press and release RST, then click Upload.
PlatformIO
platformio.ini
[platformio]
default_envs = T-Display-AMOLED
src_dir = examples/Factory
; src_dir = examples/Touchpad
; src_dir = examples/lvgl/widgets/btn
; src_dir = examples/PPM_Example_for_T4S3
; src_dir = examples/SPI_SDCard
boards_dir = boards
[env:T-Display-AMOLED]
platform = espressif32@6.12.0
board = T-Display-AMOLED
framework = arduino
upload_speed = 921600
monitor_speed = 115200
lib_extra_dirs = ${PROJECT_DIR}
build_flags =
-DBOARD_HAS_PSRAM
-DLV_CONF_INCLUDE_SIMPLE
-DDISABLE_ALL_LIBRARY_WARNINGS
-DARDUINO_USB_CDC_ON_BOOT=1
-DCORE_DEBUG_LEVEL=1
lib_deps =
lvgl/lvgl@8.4.0
lewisxhe/XPowersLib@0.2.7
lewisxhe/SensorLib@0.2.4
bodmer/TFT_eSPI@2.5.31
mikalhart/TinyGPSPlus@1.0.3
adafruit/Adafruit NeoPixel@1.11.0Steps
- Install Visual Studio Code and Python
- Install the PlatformIO IDE extension in VS Code
- Clone the
LilyGo-AMOLED-Seriesrepository and open it in VS Code - PlatformIO will download dependencies automatically on first build
- Uncomment the
src_dirfor the example you want to run - Click ✓ to compile, → to upload
LVGL
The T4-S3 uses LVGL v8.4.0 via the LilyGo_AMOLED library. The display driver, touch input, and flush callbacks are handled by beginLvglHelper() — you do not need to configure them manually.
lv_conf.h
Place lv_conf.h next to the lvgl/ folder in your Arduino libraries directory. Key settings used by this board:
#define LV_COLOR_DEPTH 16
#define LV_COLOR_16_SWAP 1 // required for QSPI AMOLED
#define LV_MEM_CUSTOM 1
#define LV_MEM_CUSTOM_INCLUDE <esp32-hal-psram.h>
#define LV_MEM_CUSTOM_ALLOC ps_malloc
#define LV_MEM_CUSTOM_FREE free
#define LV_MEM_CUSTOM_REALLOC ps_realloc
#define LV_TICK_CUSTOM 1
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h"
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())Hello World (LVGL v8)
#include <LilyGo_AMOLED.h>
#include <LV_Helper.h>
LilyGo_AMOLED amoled;
void setup()
{
Serial.begin(115200);
// beginAMOLED_241() initialises the 2.41-inch AMOLED (RM690B0) on T4-S3
if (!amoled.beginAMOLED_241()) {
Serial.println("Display init failed");
while (true) delay(1000);
}
// Set up LVGL with display + touch in one call
beginLvglHelper(amoled);
// Create a label
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello T4-S3!");
lv_obj_set_style_text_font(label, &lv_font_montserrat_24, 0);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
void loop()
{
lv_task_handler();
delay(2);
}Peripheral Examples
Examples
| Example | Description |
|---|---|
| display_touch | LVGL UI showing live touch coordinates, a 5-entry touch log, and a dot that follows the finger |
Display (RM690B0 — QSPI AMOLED)
The display is a 2.41-inch 600 × 450 AMOLED driven over QSPI. Use pushColors() or the LVGL/TFT_eSPI wrappers — direct pixel access via pushColors() is available if needed.
#include <LilyGo_AMOLED.h>
LilyGo_AMOLED amoled;
void setup()
{
amoled.beginAMOLED_241();
amoled.setBrightness(200); // 0–255
// Fill with red (RGB565)
uint16_t w = amoled.width();
uint16_t h = amoled.height();
uint16_t *buf = (uint16_t *)ps_malloc(w * h * 2);
if (buf) {
for (int i = 0; i < w * h; i++) buf[i] = 0xF800; // red
amoled.pushColors(0, 0, w, h, buf);
free(buf);
}
}
void loop() {}Touch (CS226SE)
Touch is handled automatically by beginAMOLED_241(). Use getPoint() to poll coordinates.
#include <LilyGo_AMOLED.h>
LilyGo_AMOLED amoled;
void setup()
{
Serial.begin(115200);
amoled.beginAMOLED_241();
}
void loop()
{
int16_t x, y;
if (amoled.getPoint(&x, &y, 1)) {
Serial.printf("Touch X=%d Y=%d\n", x, y);
}
delay(10);
}SD Card (SPI)
The T4-S3 has an onboard MicroSD slot. Call amoled.installSD() to mount it with the default pins (MISO=4, MOSI=2, SCK=3, CS=1).
#include <LilyGo_AMOLED.h>
#include <SD.h>
LilyGo_AMOLED amoled;
void setup()
{
Serial.begin(115200);
amoled.beginAMOLED_241();
if (!amoled.installSD()) {
Serial.println("SD card mount failed");
return;
}
Serial.printf("SD card size: %llu MB\n", SD.cardSize() / (1024 * 1024));
// List root
File root = SD.open("/");
File f = root.openNextFile();
while (f) {
Serial.println(f.name());
f = root.openNextFile();
}
}
void loop() {}PMU (SY6970)
The SY6970 power management IC is accessed via the amoled.BQ object (PowersBQ25896-compatible API via SY6970).
#include <LilyGo_AMOLED.h>
LilyGo_AMOLED amoled;
void setup()
{
Serial.begin(115200);
amoled.beginAMOLED_241();
Serial.printf("Battery voltage : %u mV\n", amoled.getBattVoltage());
Serial.printf("VBUS voltage : %u mV\n", amoled.getVbusVoltage());
Serial.printf("Charging : %s\n", amoled.isCharging() ? "Yes" : "No");
Serial.printf("Battery present : %s\n", amoled.isBatteryConnect() ? "Yes" : "No");
}
void loop() {}Brightness Control
amoled.setBrightness(128); // 0 (off) – 255 (full)
uint8_t level = amoled.getBrightness();Sleep / Wake
// Enter display sleep (keeps MCU running)
amoled.disp_sleep();
// Wake display
amoled.disp_wakeup();
// Deep sleep (touch pad can wake the device)
amoled.sleep(true); // true = enable touchpad wakeupQwiic / I2C Expansion
The two Qwiic (JST-SH 1.0 mm) ports expose the I2C bus (SDA=6, SCL=7). Use standard Wire calls:
#include <Wire.h>
void setup()
{
Wire.begin(6, 7); // SDA=6, SCL=7
// Scan for I2C devices
for (uint8_t addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.printf("Found I2C device at 0x%02X\n", addr);
}
}
}ESP-IDF
No official ESP-IDF project template exists for the T4-S3. For IDF development:
- Create a new project:
idf.py create-project t4-s3 - Set target:
idf.py set-target esp32s3 - Enable PSRAM in
menuconfig: Component config → ESP PSRAM → Enable, type = Octal PSRAM - Set Flash to 16 MB: Serial flasher config → Flash size → 16 MB
- Refer to ESP-IDF Programming Guide
FAQ
Q. The screen shows nothing after upload. A. Make sure PSRAM is set to OPI PSRAM in Arduino IDE. The library checks
BOARD_HAS_PSRAMat compile time and will abort if PSRAM is not enabled.Q. Upload fails. A. Hold BOOT (GPIO0), press and release RST, then click Upload. Release BOOT after the upload starts.
Q.
beginAMOLED_241()returns false. A. Ensure the arduino-esp32 core is ≥ 2.0.5 and < 3.0.0. Version 3.x is not currently supported by the library.Q. Which
begin()function should I use? A. Useamoled.beginAMOLED_241()for T4-S3 (2.41-inch). Alternatively,amoled.begin()auto-detects the board butbeginAMOLED_241()is more reliable.
