Dynamic, widget and plugin blocks

Everything here is rendered by PHP rather than saved as HTML, which means the markup is whatever core or the plugin decides to emit and the theme has no say in its structure — only in how it looks. Blocks from plugins are on this page for the same reason as core blocks: they sit in the same registry and an author will reach for them just as readily.

Site identity

Build Mode

The tagline and the logo above render empty on this install: no site description is set and no custom logo has been uploaded. That is a content state, not a styling defect — setting either would change the header on every page of the site, which is outside this task.

Breadcrumbs

Home » QA · Dynamic, widgets and plugins

Search

Archives, categories, tags, calendar

September 2026
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
282930  

Arduino (2) ESP32 (2)

Arduino (2) ESP32 (2)

Post and comment listings

Page list and social links

Shortcode, raw HTML, widget group

A raw HTML block. Nothing about it goes through the block system, so it is the one escape hatch that can put anything at all on the page.

A widget group

A widget group

Navigation and language

Both WPML language-switcher blocks are deliberately absent from this page. Rendered without the inner template markup the block editor generates for them, they throw an uncaught Error and return HTTP 500 for the whole page. See the report.

Terms query

Query loop

Displaying 1 – 2 of 2
  • ESP32-S3-CAM N16R8: the Camera Board the ESP32-CAM Should Have Been

    ESP32-S3-CAM N16R8: the Camera Board the ESP32-CAM Should Have Been

    16–24 minutes
    0
    No comments on ESP32-S3-CAM N16R8: the Camera Board the ESP32-CAM Should Have Been
    q_admin Avatar

    An ESP32-S3 board with a 5 MP OV5640 camera, two USB-C ports, microSD, 16 MB of flash and 8 MB of PSRAM. What is wired to what, which of its 36 GPIOs are really free, how to set up Arduino…

    Keep reading: ESP32-S3-CAM N16R8: the Camera Board the ESP32-CAM Should Have Been

    ESP32-S3-CAM N16R8: the Camera Board the ESP32-CAM Should Have Been

    The AI-Thinker ESP32-CAM put a Wi-Fi camera within almost everyone’s reach, and taught a whole generation of makers patience along the way. It has no USB port, so every flash needs an external USB-to-UART adapter and a jumper on GPIO0. Of its 16 header pins only a handful are actually free, and the flash LED blinks every time the program writes to the memory card.

    The board in this article is the same idea, finished properly. It carries an ESP32-S3 with 16 MB of flash and 8 MB of PSRAM, a 5 MP OV5640 camera, a microSD slot, two USB-C ports and all 36 GPIOs of the module on its headers. There is one catch: once the camera and the memory card are running, only six of those pins are truly free. What follows is a detailed map of the board: what is wired to what, which port does which job, which pins you can take, and how to set up the Arduino IDE so the camera does not turn into a puzzle.

    Pinout diagram of the ESP32-S3 WROOM CAM. The left header runs, top to bottom, 3V3, EN, GPIO4, 5, 6, 7, 15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 5V. The right header runs GPIO43 (TX), 44 (RX), 1, 2, 42, 41, 40, 39, 38, 37, 36, 35, 0, 45, 48, 47, 21, 20, 19, GND. Coloured labels mark the camera, microSD, PSRAM, USB, UART, JTAG, ADC and touch functions.
    The ESP32-S3 WROOM CAM: both headers and what every pin does. Click for the full-size version.

    Which board this is about

    Shops sell this board under several names: ESP32-S3-CAM, ESP32-S3 WROOM CAM, ESP32-S3 CAM Development Board. The board itself modestly says ESP32-S3 WROOM, and the metal shield of the module reads ESP32-S3-N16R8. That marking is the key specification: N16 stands for 16 MB of flash, R8 for 8 MB of PSRAM. The module is an ESP32-S3-WROOM-1 with a PCB antenna.

    The layout copies the Freenove ESP32-S3-WROOM CAM: the same camera position, the same pins, two buttons and two USB-C ports. Freenove ships its board with a 2 MP OV2640 camera, while the one in this article carries a 5 MP OV5640, as the marking on its ribbon cable shows. Boards like this come from several factories, and the camera module and the USB-to-UART bridge can change from batch to batch. Before hunting for a driver or somebody else’s example, it is worth checking what your own board is marked with.

    Specifications

    PartSpecificationWhat it means in practice
    ModuleESP32-S3-WROOM-1-N16R8, PCB antennaA ready-made Espressif module measuring 18 × 25.5 × 3.1 mm; all 36 of its GPIOs are on the headers
    ProcessorTwo Xtensa LX7 cores, up to 240 MHz, FPUEnough for a JPEG stream, Wi-Fi and the application logic at once; it has instructions that accelerate neural networks and signal processing
    SoC memory512 KB of SRAM, 384 KB of ROMToo little internal memory for camera frames, which belong in PSRAM
    Flash16 MB, Quad SPIRoom for a large application, OTA and a file system
    PSRAM8 MB, Octal SPI (OPI)Holds the camera frame buffers; the Arduino IDE needs the OPI PSRAM setting
    Wi-Fi2.4 GHz, 802.11 b/g/n, up to 150 Mbit/sMJPEG streaming, photo uploads, over-the-air updates
    BluetoothBluetooth 5 (LE), mesh, up to 2 Mbit/s and Long RangeBLE only: the ESP32-S3 has no Classic Bluetooth, so no SPP or A2DP
    CameraOV5640, 5 MP (2592 × 1944), 8-bit DVP bus, configured over SCCBThe sensor compresses frames to JPEG itself; the bus takes 14 GPIOs
    Camera connector24-pin FPCThe camera module is replaceable with any module of the same standard
    Memory cardmicroSD, SDMMC in 1-bit modePhotos and time-lapses are written on the board itself; the slot takes GPIO38–40
    USBTwo USB-C ports: a USB-to-UART bridge on UART0 and the ESP32-S3’s own native USBFlashing and logs go through the right port, USB devices and debugging through the left
    GPIO36 pins on two 20-pin headersSix are free without conditions, a few more with them
    LEDs and buttonsON, TX, RX and IO2 (GPIO2) LEDs plus a WS2812 RGB LED (GPIO48); EN and BOOT (GPIO0) buttonsSomething to blink and something to press without any external parts
    Power5 V through USB-C or the 5V pin; the 3V3 pin carries 3.3 V from the board’s regulatorThe module needs a supply that can deliver at least 0.5 A
    Logic levels3.3 V; the GPIOs are not 5 V tolerantA 5 V signal needs level shifting
    Operating temperature−40 to +65 °C (modules with Octal PSRAM)Lower than the 85 °C of modules without PSRAM, which matters inside a closed case
    Development environmentsArduino IDE, PlatformIO, ESP-IDF; MicroPython with a build that includes a camera driverArduino is the easier quick start, ESP-IDF the better choice for a serious project

    A little arithmetic. A 5 MP frame in RGB565 takes 2592 × 1944 × 2 = 10,077,696 bytes, about 9.6 MiB. That is more than the whole 8 MB of PSRAM, which is why full resolution is only available as JPEG, compressed by the sensor itself. A UXGA frame of 1600 × 1200 in the same RGB565 takes about 3.7 MiB and does fit. In practice the camera almost always runs in JPEG: it needs less memory and is easier to send over Wi-Fi.

    Two USB-C ports, and which one does what

    The ports are not labelled on the front: the USB-UART and USB-OTG labels are printed on the back. That sets up a classic mirror trap, because once the board is turned face up, the label on the left sits under the right-hand port. Seen from the camera side, with the antenna at the top, the picture is this:

    PortWhat is behind itUse it for
    Left, USB-OTGThe ESP32-S3’s own native USB: GPIO19 is D−, GPIO20 is D+. The built-in USB Serial/JTAG or USB OTGDebugging without an external adapter, and your own USB devices: keyboard, mouse, MIDI, storage, webcam
    Right, USB-UARTA USB-to-UART bridge wired to UART0: GPIO43 is TX, GPIO44 is RXFlashing and the Serial Monitor, the most predictable route

    Which port gets the Serial output is decided by the USB CDC On Boot setting in the Arduino IDE. With Disabled, Serial is UART0 and the messages go to the right port. With Enabled, Serial moves to the native USB, which is the left port. If the Serial Monitor stays silent, this setting and the port the cable is plugged into are the first things to check. The ROM bootloader prints to both ports by default.

    The left port has a less obvious advantage too. The USB Serial/JTAG controller built into the ESP32-S3 lets you debug with breakpoints without an external adapter and without a single extra pin. That is particularly valuable here, because the default external JTAG pins (GPIO39–42) are partly taken by the memory card on this board.

    The headers, pin by pin

    The tables assume the board lies component side up, antenna at the top and USB ports at the bottom. The pin numbers on the silkscreen carry marks: underlined pins belong to the camera, a tilde marks the microSD pins and an asterisk the PSRAM ones. The legend is printed on the back.

    Left header, top to bottom

    PinOn this boardFree for your circuit?
    3V33.3 V from the board’s regulatorNot a GPIO
    ENReset, the EN button; active lowNo
    GPIO4Camera: SIOD, SCCB dataOnly without the camera
    GPIO5Camera: SIOC, SCCB clockOnly without the camera
    GPIO6Camera: VSYNCOnly without the camera
    GPIO7Camera: HREFOnly without the camera
    GPIO15Camera: XCLKOnly without the camera
    GPIO16Camera: D7 (Y9)Only without the camera
    GPIO17Camera: D6 (Y8)Only without the camera
    GPIO18Camera: D5 (Y7)Only without the camera
    GPIO8Camera: D2 (Y4)Only without the camera
    GPIO3Strapping pin; ADC1, Touch3With care
    GPIO46Boot-mode strapping pinWith care
    GPIO9Camera: D1 (Y3)Only without the camera
    GPIO10Camera: D3 (Y5)Only without the camera
    GPIO11Camera: D0 (Y2)Only without the camera
    GPIO12Camera: D4 (Y6)Only without the camera
    GPIO13Camera: PCLKOnly without the camera
    GPIO14Free; ADC2, Touch14Yes
    5V5 V railNot a GPIO

    Right header, top to bottom

    PinOn this boardFree for your circuit?
    TX (GPIO43)UART0 TX, to the USB-to-UART bridgeOnly without the right port
    RX (GPIO44)UART0 RX, from the USB-to-UART bridgeOnly without the right port
    GPIO1Free; ADC1, Touch1Yes, the best analogue input
    GPIO2IO2 LED; ADC1, Touch2Mind the LED
    GPIO42Free; MTMS of external JTAGYes
    GPIO41Free; MTDI of external JTAGYes
    GPIO40microSD: D0; MTDO of external JTAGOnly without the card
    GPIO39microSD: CLK; MTCK of external JTAGOnly without the card
    GPIO38microSD: CMDOnly without the card
    GPIO37Octal PSRAM inside the moduleNever
    GPIO36Octal PSRAM inside the moduleNever
    GPIO35Octal PSRAM inside the moduleNever
    GPIO0BOOT button, strapping pinWith care
    GPIO45Strapping pin: memory supply voltageBetter left alone
    GPIO48WS2812-compatible RGB LEDMind the LED
    GPIO47FreeYes
    GPIO21FreeYes
    GPIO20Native USB: D+ (left port)Only without native USB
    GPIO19Native USB: D− (left port)Only without native USB
    GNDGroundNot a GPIO

    Pins 35–37 do come out on the header, but they are off limits: in modules with Octal PSRAM they are wired to the memory inside, and any external signal on them interferes with it.

    36 GPIOs, and how many of them are yours

    Put everything together and the picture is sobering:

    Taken byGPIORule
    Camera4–13, 15–18Taken while the camera is on
    microSD38–40Taken while the card is mounted
    Octal PSRAM35–37Never use them
    Native USB19, 20Free only if you do not need the left port
    UART0 and the USB-to-UART bridge43, 44Free only if you do not need the right port
    On-board LEDs2, 48Usable if the LED does not get in the way
    Strapping pins0, 3, 45, 46Only once you know their levels at reset
    Nothing1, 14, 21, 41, 42, 47The first choice for your own circuit

    So with the camera and the memory card running, six pins are free without conditions: GPIO1, 14, 21, 41, 42 and 47. That is enough for an I²C sensor, a couple of buttons and a relay, but not for a sprawling set of peripherals. You can win back a couple more by giving up one of the USB routes: if the board only ever talks through the right port, GPIO19 and GPIO20 are released. If it only uses the left one, GPIO43 and GPIO44 are worth a try, bearing in mind that they are still wired to the USB-to-UART bridge.

    Analogue inputs are trickier. On the ESP32-S3, ADC1 is GPIO1–10 and ADC2 is GPIO11–20. The camera takes almost every ADC1 pin, so with the camera running the only clean analogue input is GPIO1. GPIO2 and GPIO3 belong to ADC1 too, but the first drives an LED and the second is a strapping pin. GPIO14 belongs to ADC2, and ADC2 shares resources with Wi-Fi: while the radio is busy, a reading may be delayed or fail. For sensors in a Wi-Fi project, choose ADC1. The touch inputs Touch1–Touch14 live on GPIO1–14, but of those only GPIO1 and GPIO14 are free without conditions.

    And four rules about the strapping pins that save an evening:

    1. GPIO0 is the BOOT button. If it is low at reset, the chip enters download mode instead of running the program. External circuitry must not pull GPIO0 to ground during start-up.
    2. GPIO46 is pulled down by default and selects the boot mode together with GPIO0. GPIO0 low with GPIO46 high at reset is an invalid combination.
    3. GPIO45 sets the memory supply voltage: low at reset means 3.3 V, high means 1.8 V. This module’s flash and PSRAM are 3.3 V parts, so GPIO45 must not be high during reset. It is pulled down by default, and that is how it should stay.
    4. GPIO3 selects the JTAG signal source, but only if the corresponding eFuse bit has been burned; on a module with factory settings its level is ignored. Espressif still lists it as a strapping pin, so it is better not to make it the first home for a button.

    The camera: an OV5640 on the right pin map

    The camera sits on a parallel DVP bus: eight data lines, three sync lines, the XCLK clock and a pair of SCCB lines to configure the sensor, 14 GPIOs in all. The PWDN and RESET pins are not connected on this board, so the configuration sets them to -1.

    The main trap is somebody else’s pin map. The most popular examples online are written for the AI-Thinker ESP32-CAM, and on an ESP32-S3 its GPIO numbers point, among other things, at pins 26–32, which the S3 gives to its internal memory, and at 22–25, which the S3 does not have at all. The good news is that this board’s wiring matches Espressif’s ESP32-S3-EYE exactly, and the Arduino core already describes that board.

    In the CameraWebServer example (File → Examples → ESP32 → Camera), the model is chosen in board_config.h. The default there is CAMERA_MODEL_ESP_EYE, which is a different board built on the original ESP32. Comment that line out and uncomment CAMERA_MODEL_ESP32S3_EYE. This is how that model’s pins look in camera_pins.h, exactly as on our board:

    #define PWDN_GPIO_NUM  -1
    #define RESET_GPIO_NUM -1
    #define XCLK_GPIO_NUM  15
    #define SIOD_GPIO_NUM  4
    #define SIOC_GPIO_NUM  5
    
    #define Y2_GPIO_NUM 11
    #define Y3_GPIO_NUM 9
    #define Y4_GPIO_NUM 8
    #define Y5_GPIO_NUM 10
    #define Y6_GPIO_NUM 12
    #define Y7_GPIO_NUM 18
    #define Y8_GPIO_NUM 17
    #define Y9_GPIO_NUM 16
    
    #define VSYNC_GPIO_NUM 6
    #define HREF_GPIO_NUM  7
    #define PCLK_GPIO_NUM  13

    For this model the example flips the picture vertically on its own with set_vflip. If the image comes out upside down, toggling V-Flip in the web interface is enough; the resolution is raised there too, since the stream starts in QVGA. A missing PSRAM, on the other hand, the example survives silently: if psramFound() returns false, the frame size is capped at SVGA and the buffer moves to internal memory. The camera still works, but far from at full strength.

    If the stream stays black

    The OV5640 has a known quirk on this board. Owners have reported that the example initialises the camera without errors, an OV2640 works on the same board, and the OV5640 delivers a black frame. According to their reports, changing the XCLK clock helps: 24 MHz or 12 MHz instead of the default 20 MHz. In setup() that is a single line, xclk_freq_hz; the other fields show what it is usually combined with:

    camera_config_t config;
    // ... pins as in camera_pins.h ...
    config.xclk_freq_hz = 24000000;   // 20 MHz gave black frames on some OV5640 boards; 12 MHz is the other reported fix
    config.pixel_format = PIXFORMAT_JPEG;
    config.frame_size   = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_location  = CAMERA_FB_IN_PSRAM;
    config.fb_count     = 2;
    config.grab_mode    = CAMERA_GRAB_LATEST;

    If that does not help, check that the ribbon cable is fully seated and its latch closed, and that the board is not overheating: the same discussions advise against keeping it in a closed case without ventilation while the camera runs. The sensor’s full resolution, FRAMESIZE_5MP at 2592 × 1944, is only available in JPEG.

    Arduino IDE settings

    The board needs no separate package: the standard ESP32S3 Dev Module profile from arduino-esp32 does the job. What matters most is describing the memory correctly, because that decides whether the program sees the PSRAM at all.

    SettingValueWhy
    BoardESP32S3 Dev ModuleThe generic ESP32-S3 profile
    Flash Size16MB (128Mb)The real flash size of the N16R8 module
    Flash ModeQIO 80MHzThe flash here is Quad SPI; OPI 80MHz is meant for modules with Octal flash
    PSRAMOPI PSRAMThe PSRAM is Octal SPI; with QSPI PSRAM or Disabled the program will not find it
    Partition Scheme16M Flash (3MB APP/9.9MB FATFS)CameraWebServer needs at least 3 MB for the application; the rest goes to files
    USB CDC On BootDisabled to work through the right port, Enabled through the leftDecides which port Serial uses
    USB ModeHardware CDC and JTAGThe built-in USB Serial/JTAG; USB-OTG (TinyUSB) is for your own USB devices
    Upload ModeUART0 / Hardware CDCFlashing through either port

    If flashing stops working, for example because the program reconfigured the native USB or fell into a reboot loop, put the board into the bootloader by hand: hold BOOT, briefly press EN, release BOOT and upload again. The right port may need a driver for the USB-to-UART bridge on your computer. The original Freenove board uses a CH343, clones sometimes carry other chips, so go by what the device manager actually reports. Current operating systems recognise the left port as a serial port without a separate driver.

    microSD, LEDs and buttons

    The microSD slot is wired for SDMMC in 1-bit mode: CMD on GPIO38, CLK on GPIO39, D0 on GPIO40. That is slower than 4-bit mode but saves three pins. Two of the three lines coincide with the default external JTAG pins (MTCK and MTDO), so the card and an external debugger get in each other’s way; with a card inserted, debugging through the left USB port is the easier route.

    There are five LEDs. ON shows power, TX and RX flicker with traffic through the USB-to-UART bridge, IO2 is a user LED on GPIO2, and 48 is a WS2812-compatible addressable RGB LED on GPIO48. In the ESP32S3 Dev Module profile, both LED_BUILTIN and RGB_BUILTIN point at that RGB LED, so the stock Blink sketch lights it white. Its colour is set with rgbLedWrite(); the older neopixelWrite() is deprecated.

    EN restarts the module, and BOOT is wired to GPIO0 for entering the bootloader by hand. Once the program is running, BOOT can be read like any other button. A quick self-test of the board mounts the card and reports the result in colour:

    #include "SD_MMC.h"
    
    void setup() {
      Serial.begin(115200);
    
      // One-bit SDMMC: CLK, CMD, D0
      SD_MMC.setPins(39, 38, 40);
    
      if (SD_MMC.begin("/sdcard", true)) {
        Serial.printf("microSD: %llu MB\n", SD_MMC.cardSize() / (1024 * 1024));
        rgbLedWrite(RGB_BUILTIN, 0, 32, 0);   // green: card mounted
      } else {
        Serial.println("microSD: mount failed");
        rgbLedWrite(RGB_BUILTIN, 32, 0, 0);   // red: no card
      }
    }
    
    void loop() {}

    Power and heat

    The board takes power through either USB-C port or the 5V pin. The 3V3 pin is the output of the board’s regulator and can feed low-power 3.3 V sensors. The GPIOs work at 3.3 V only: a 5 V signal on an input can damage the module, whose absolute maximum supply voltage is 3.6 V.

    The camera, Wi-Fi transmission and card writes all cause current peaks. The module datasheet asks for a supply that can deliver at least 0.5 A, and a weak USB port or a long, thin cable easily falls short. The symptoms are easy to recognise: the board resets the moment the stream starts, and the log shows a message from the brownout detector. The cure is a short, decent cable and a proper 5 V power supply.

    The second limit is less obvious: temperature. Modules with Octal PSRAM, the N16R8 included, are rated for an ambient temperature of up to 65 °C, whereas the variants without PSRAM go up to 85 °C. Espressif notes that enabling PSRAM error correction (ECC) raises the limit to 85 °C at the cost of 1/16 of the memory. The camera and the radio keep warming the board, so inside a closed case in the sun that margin disappears quickly; plan ventilation holes from the start.

    What to build on it: three telling cases

    1. A camera for the 3D printer

    Checking on a print from another room, and collecting a time-lapse along the way, is the most natural job for a board like this. Prusa-Firmware-ESP32-Cam, the firmware that connects a camera to the Prusa Connect service, has a dedicated page for the Freenove ESP32-S3-WROOM. The camera modules tested there are OV2640s, so OV5640 compatibility is something to find out for yourself, but the board layout is the same.

    2. A time-lapse recorder with its own card

    The microSD slot turns the board into a standalone recorder: wake on a timer, take a JPEG, write it to the card and go back to sleep. That is how people film plants growing, a building site across the street or a slow process in the workshop. The board is not optimised for battery power, though: the ON LED is always lit, and the camera’s PWDN pin is not connected, so the sensor cannot be powered down in hardware, only put into its software standby over SCCB. Sleep current will be noticeably higher than for a bare module; that does not matter for a mains-powered time-lapse, but it does on batteries.

    3. A USB webcam and vision on the device itself

    Native USB lets the ESP32-S3 present itself to a computer as a webcam. Espressif’s esp-iot-solution has a usb_webcam example: the board becomes a UVC device streaming MJPEG, and the example’s list of modes includes 1280 × 720 at 15 frames per second. By default it builds for the ESP32-S3-EYE, which means the same pin map as this board. The other direction is processing frames on the device itself: Espressif’s ESP-WHO framework targets the ESP32-S3 and can, for instance, detect faces with no cloud involved.

    Strengths and weaknesses

    StrengthsWeaknesses
    Two USB-C ports: flashing without an adapter, plus native USBThe ports are labelled only on the back and easy to mix up
    16 MB of flash and 8 MB of Octal PSRAMModules with Octal PSRAM are rated only up to 65 °C
    A replaceable 5 MP cameraThe OV5640 can give a black frame until the XCLK frequency is tuned
    A microSD slot right on the boardThe card takes three pins and clashes with external JTAG
    All 36 module GPIOs on the headers, with the taken ones marked on the silkscreenOnly six pins are free without conditions
    The pin map matches the ESP32-S3-EYE, so ready-made examples fit with a minimal changeNot optimised for battery devices: PWDN is not connected and the power LED is always on
    A user LED and an RGB LED on the boardBatches differ in the camera and the USB-to-UART bridge

    Bottom line

    The ESP32-S3-CAM N16R8 is an ESP32-CAM with nearly all of its teething troubles cured: proper USB, plenty of memory, a replaceable 5 MP camera and honest marking of the taken pins right on the board. For a workshop camera, a time-lapse, keeping an eye on a 3D printer or experimenting with machine vision, it is a very convenient base.

    The price of that convenience is a tight fit. The camera and the memory card eat almost every pin, the PSRAM has to be enabled correctly, and the OV5640 may need its clock tuned. Before the first flash it pays to run through a short list:

    1. ESP32S3 Dev Module profile: 16 MB flash, QIO 80MHz, PSRAM set to OPI PSRAM.
    2. Pin map: CAMERA_MODEL_ESP32S3_EYE, not AI-Thinker.
    3. Frame buffers in PSRAM, format JPEG.
    4. microSD as 1-bit SDMMC on GPIO38, 39 and 40.
    5. The cable in the port that matches the USB CDC On Boot setting.
    6. New connections on GPIO1, 14, 21, 41, 42 and 47 first.
    7. GPIO0, 3, 45 and 46 kept free of circuits that change their level at reset.

    Everything above in a single file: a reference to the board’s pins and hardware limits. Keep it next to your sketch, or hand it to a coding agent so it does not invent a pinout.

  • LILYGO TTGO T-Display: the ESP32 That Shows the Result Right Away

    LILYGO TTGO T-Display: the ESP32 That Shows the Result Right Away

    11–17 minutes
    0
    No comments on LILYGO TTGO T-Display: the ESP32 That Shows the Result Right Away
    q_admin Avatar

    An ESP32 board with a 1.14-inch colour screen already wired to it. What is connected where, which GPIOs are safe to use, how long it lasts on a battery — and where the classic T-Display ends and the S3 begins.

    Keep reading: LILYGO TTGO T-Display: the ESP32 That Shows the Result Right Away

    LILYGO TTGO T-Display: the ESP32 That Shows the Result Right Away

    An ordinary development board can do a great deal, but it talks to the developer mostly through lines in the Serial Monitor. The LILYGO TTGO T-Display has a more convincing way of doing it: a colour screen on the board itself. Wire up a sensor and you see the readings straight away. Pull data over Wi-Fi and you can draw a graph or a status line. Build a standalone instrument and there is no separate display to add, no power to route to it and no room to find for it inside the enclosure.

    That is why the T-Display is more interesting than just another ESP32 board. It is very nearly a finished front panel for a device: a microcontroller, a screen, two buttons, USB-C and single-cell Li-Po charging on one narrow circuit board.

    Pinout diagram of the classic LILYGO TTGO T-Display V1.1. The left header runs GND, GND, 21, 22, 17, 2, 15, 13, 12, GND, GND, 3V3 and the right header 3V3, 36, 37, 38, 39, 32, 33, 25, 26, 27, GND, 5V. The ST7789V display is on MOSI 19, SCLK 18, CS 5, DC 16, RST 23 and BL 4, and the two buttons are on GPIO0 and GPIO35.
    The classic T-Display, V1.1: both headers, the six display signals and the two buttons. Click for the full-size version.

    Which board this is about

    The name T-Display has grown into a whole family, so the first technical trap is to take the specifications of the wrong model. What follows is about the classic LILYGO/TTGO T-Display on the original ESP32, with a 1.14-inch screen and a resolution of 135 × 240 pixels. This is not the T-Display-S3: the S3 has a different processor, a 1.9-inch screen, a different display connection, different GPIOs and PSRAM.

    Current LILYGO documentation lists the SoC of the classic board as ESP32-D0WDQ6. Flash size and the USB-to-UART chip can differ between production batches, so a seller’s description or somebody else’s example code is no substitute for checking the board in your hand.

    Specifications

    PartSpecificationWhat it means in practice
    MicrocontrollerESP32-D0WDQ6The classic ESP32, not an S2, S3 or C3
    ProcessorTwo Xtensa LX6 cores, up to 240 MHzEnough for Wi-Fi, the interface, sensors and background logic at the same time
    Memory520 KB of on-chip SRAM, no PSRAMLarge images and double buffering call for careful memory budgeting
    FlashUsually 4 MB; a 16 MB variant existsThe size has to be checked before choosing a partition table
    Wireless2.4 GHz Wi-Fi 802.11 b/g/n; Bluetooth 4.2 BR/EDR and BLESuits MQTT, HTTP, ESP-NOW, BLE beacons and talking to a phone
    Display1.14-inch IPS TFT, ST7789V controllerA colour screen with good viewing angles
    Resolution135 × 240 in portrait; usually 240 × 135 in landscapeGood for one large figure, a few status lines or a small graph
    Display interface4-wire SPI; the stock TFT_eSPI profile runs it at 40 MHzThe screen is fast, but it occupies several GPIOs
    ControlsTwo buttons: GPIO0 and GPIO35Enough for a menu, page flipping, a confirmation or a wake-up
    PowerUSB-C or a single-cell Li-Po; charging on boardThe basis for a portable instrument with no separate charger module
    Battery monitoringADC on GPIO34, sense circuit enabled by GPIO14The charge level can be shown right in the interface
    USBUSB-C through a USB-to-UART bridgeThe original ESP32 has no native USB device; the port serves power, flashing and serial communication
    USB-to-UARTCH9102 on what is currently sold; older revisions used CP210xWhen a driver misbehaves, look at the actual VID/PID rather than guessing from the board name
    Logic levels3.3 V; the GPIOs are not 5 V tolerantA 5 V signal needs level shifting
    DimensionsAbout 51.5 × 25 mmNoticeably narrower than most “DevKit plus a separate TFT” builds
    Development environmentsArduino IDE, PlatformIO, ESP-IDF; MicroPython is possibleArduino is the easier quick start, ESP-IDF the stricter choice for a serious project

    A couple of numbers give a sense of the scale. A full frame in RGB565 takes 135 × 240 × 2 = 64,800 bytes, which is about 63.3 KiB. Two frame buffers are already around 126.6 KiB, before the Wi-Fi stack, the tasks and the application’s own data. That is why partial redraws, modestly sized sprites and updating only the regions that changed are especially useful on this board.

    Why the built-in display earns its place

    The screen here is useful as a development tool, not as decoration. It shortens the path from a prototype to something you can use without a computer.

    • Instant feedback. The device itself shows whether it joined Wi-Fi, what IP address it was given, what the sensor returned and why the actuator did not fire.
    • A local interface. Two buttons and a colour screen are enough for a menu, several pages, warnings and simple settings without a mobile app.
    • Diagnostics on the spot. If the sensor sits in a distribution board, a greenhouse or on a machine, the key readings are visible next to the equipment and not only in the cloud.
    • A compact, finished prototype. Add a battery and an enclosure and the T-Display already looks like a pocket instrument, a remote or a miniature monitoring panel.
    • A fast way to show the idea. A client or a colleague finds a live screen of statuses easier to judge than a stream of numbers in a terminal.

    The screen sets limits too. It is small and it is not a touchscreen, and six of the ESP32’s signals are already spoken for by the display. A backlight left on all the time makes a noticeable difference to battery life. Complex graphics run short of memory without PSRAM, so the T-Display is at its best not as a tiny smartphone but as a clear interface built from a few well-chosen readings.

    What is already wired to the ESP32

    Function on the boardGPIOWhat matters
    TFT MOSI19Data to the ST7789V
    TFT SCLK18The display clock line
    TFT CS5Display chip select, and an ESP32 boot-strapping pin at the same time
    TFT DC16Switches between command and data
    TFT RESET23Hardware reset for the display controller
    TFT backlight4Can be switched on, switched off and dimmed with PWM
    Button on GPIO00Also BOOT/strapping: holding it during a reset puts the ESP32 into the bootloader
    Second button35Input only; GPIO35 has no internal pull resistors
    Li-Po measurement34ADC1, input only
    Sense circuit enable14GPIO14 is usually driven high before the battery is read

    It is sensible to treat these pins as taken. SPI does in theory allow several devices to share the MOSI and SCLK lines, but for a first project it is safer to leave GPIO18 and GPIO19 to the screen and put an external SPI bus on free pins.

    The headers, pin by pin

    The tables below assume the display facing you and the USB-C connector at the bottom.

    Left header, top to bottom

    PinWhat it can doLimits and good uses
    GNDGroundTwo pins in a row
    GNDGround
    GPIO21Digital input/outputThe recommended SDA for I²C
    GPIO22Digital input/outputThe recommended SCL for I²C
    GPIO17Digital input/outputOne of the least troublesome free GPIOs; fine for UART TX or PWM
    GPIO2ADC2, Touch2, digital I/OA strapping pin: external circuitry must not force the wrong level at start-up
    GPIO15ADC2, Touch3, digital I/OStrapping and JTAG; use with care
    GPIO13ADC2, Touch4, digital I/OOverlaps JTAG, but is usually usable after boot
    GPIO12ADC2, Touch5, digital I/OStrapping and JTAG; an active external load during reset is especially unwelcome here
    GNDGroundTwo pins in a row
    GNDGround
    3V33.3 V powerNot a GPIO

    Right header, top to bottom

    PinWhat it can doLimits and good uses
    3V33.3 V powerNot a GPIO
    GPIO36 / SVPADC1_CH0, digital inputInput only, no internal pull resistor
    GPIO37ADC1_CH1, digital inputInput only, no internal pull resistor
    GPIO38ADC1_CH2, digital inputInput only, no internal pull resistor
    GPIO39 / SVNADC1_CH3, digital inputInput only, no internal pull resistor
    GPIO32ADC1_CH4, Touch9, digital I/OAn excellent general-purpose GPIO, and an analogue input that still works while Wi-Fi is running
    GPIO33ADC1_CH5, Touch8, digital I/OAn excellent general-purpose GPIO, and an analogue input that still works while Wi-Fi is running
    GPIO25ADC2_CH8, DAC1, digital I/OA true 8-bit DAC; handy as an output, as PWM, or as SCK for an external SPI bus
    GPIO26ADC2_CH9, DAC2, digital I/OThe second true 8-bit DAC; handy as MOSI for an external SPI bus
    GPIO27ADC2_CH7, Touch7, digital I/OA general-purpose GPIO; handy as MISO for an external SPI bus
    GNDGround
    5V5 V power railNot a GPIO, and not a sign of 5 V logic

    SVP and SVN are the historical names of the SENSOR_VP and SENSOR_VN analogue inputs, that is GPIO36 and GPIO39. They are not power pins.

    How to choose GPIOs without unpleasant surprises

    For ordinary digital inputs and outputs the first candidates are GPIO17, 21, 22, 25, 26, 27, 32 and 33. It makes sense to keep GPIO21 and GPIO22 for I²C.

    For a second SPI bus, the official LILYGO factory example uses a convenient group:

    External SPI signalGPIO
    SCK25
    MOSI26
    MISO27
    CS33

    For analogue sensors with Wi-Fi switched on, choose ADC1: GPIO32, 33, 36, 37, 38 or 39. On the classic ESP32, ADC2 shares a resource with Wi-Fi, so reading GPIO2, 12, 13, 15, 25, 26 or 27 as analogue inputs may simply not work while the radio is running. GPIO36–39, meanwhile, are input only and need an external pull resistor if the sensor or the button relies on one.

    There are three more rules that save a particularly large amount of time:

    1. GPIO0, 2, 5, 12 and 15 are read during reset as strapping pins. Connected peripherals must not force their start-up levels.
    2. GPIO34–39 are inputs only and have no software pull-up or pull-down. On the board itself, GPIO34 and GPIO35 are already taken by the battery and by a button.
    3. A load must not be powered straight from a GPIO. A relay, a motor, a solenoid or a high-power LED strip is switched through a transistor, a MOSFET or a driver with whatever protection it needs.

    Power and battery life

    The board takes power over USB-C and supports a single-cell Li-Po through a 1.25 mm two-pin connector. The cell can be charged on the board, and its voltage measured on GPIO34 once the sense circuit has been enabled with GPIO14. That is convenient for a charge indicator of your own, but a percentage cannot be obtained reliably from a simple linear formula: Li-Po voltage changes non-linearly, and the ADC of the original ESP32 needs calibration.

    The T-Display should not be mistaken for an ultra-frugal sensor node just because the ESP32 itself can deep-sleep. Hobbyist measurements of the classic board have produced rough figures of around 66 mA when active, 80–140 mA with Wi-Fi running and roughly 9 mA in light sleep. These are not datasheet guarantees: the result depends on brightness, firmware, supply quality and board revision. The main practical conclusion is to switch the backlight off or dim it, turn the radio off between sessions and wake the device with a button or a timer.

    What people build on a T-Display: three telling cases

    1. A local Home Assistant screen

    One of the most natural uses is to show a temperature, power consumption, the state of the heating or any other Home Assistant entity. In one published project the board displays the oven temperature through ESPHome, but the same template fits the time of the next train, the level in a tank or an internet speed. The value of this case is the minimal hardware: for a fixed panel, the T-Display and USB power are all it takes.

    2. A departure board by the door

    The open project ttgo-departure-board turns the board into a public transport display. The repository holds 33 firmware variants for networks in 17 countries: the ESP32 joins Wi-Fi, syncs the time over NTP, queries an API roughly every 30 seconds and updates the countdown every second. The two buttons switch stops and control the screen. It is a good example of an interface where 240 × 135 pixels is not too little: if you show only the direction, the line, the platform and the minutes, that is exactly as much information as you need before leaving the house.

    3. A tiny wireless monitor

    In 2025 a project drew attention by sending a shrunken image of the desktop over Wi-Fi to a compatible T-Display board. The computer compares frames and sends only the pixels that changed, applying batching and RLE. On an almost static picture its author reached up to 60 frames per second, and around 5 frames per second under heavy motion, with latency below 100 ms on a good network. It is not a practical replacement for a monitor, but it is a fine demonstration of how a traffic-saving algorithm can squeeze unexpectedly much out of an ESP32 and a small SPI display. One thing matters here: the project used a compatible TENSTAR board with 16 MB of flash, so that figure cannot be carried over to any LILYGO automatically.

    Another popular layer is mini-games. Two buttons, a colour screen and ready-made libraries have produced Space Shooter, Breakout and small handheld builds carrying several games at once. That is entertainment and, at the same time, a decent teaching bench for sprites, frame rate, button handling and memory management.

    The same T-Display shown three times: wired to a temperature sensor and displaying 22.6 °C, acting as a smart-home panel showing 428 W and 22.6 degrees, and running a game with a Li-Po cell plugged into its battery socket.
    One board, three roles: a portable meter, a desk panel and a pocket console.

    What people look for most often, and why

    Four themes repeat in the top results for queries about the classic T-Display: the first run, configuring TFT_eSPI, the pinout, and ready-made projects — clocks, weather, Home Assistant, MQTT panels and games. That is an accurate reflection of the board’s strengths and weaknesses.

    People are drawn in by how quickly they can get a good-looking result, and most often they stumble over the configuration of this particular display. TFT_eSPI needs the Setup25_TTGO_T_Display.h profile; it pins down the ST7789V, the 135 × 240 geometry and the correct GPIOs. On alternative stacks you have to account for the offset of the active area of the matrix, the BGR colour order and separate backlight control. A telling failure: the program and the LCD itself can both be working, yet the screen looks black simply because GPIO4 never switched the backlight on.

    The minimal Arduino test, once the TFT_eSPI profile has been selected, looks like this:

    #include <TFT_eSPI.h>
    
    TFT_eSPI tft;
    
    void setup() {
      pinMode(4, OUTPUT);
      digitalWrite(4, HIGH);
    
      tft.init();
      tft.setRotation(1);              // 240 × 135
      tft.fillScreen(TFT_BLACK);
      tft.setTextColor(TFT_CYAN, TFT_BLACK);
      tft.drawString("Wi-Fi: OK", 12, 12, 4);
    }
    
    void loop() {}

    In the Arduino IDE the manufacturer recommends the ESP32 Dev Module profile, a CPU frequency of 240 MHz, QIO, 4 MB of flash for the ordinary version, PSRAM disabled and an upload speed of 921600. If the firmware does not start or the bootloader does not answer, GPIO0 is used as BOOT: hold the button down, tap Reset, release BOOT and try the upload again.

    Strengths and weaknesses

    StrengthsWeaknesses
    A colour IPS panel is already fitted and proven by the design of the boardThe screen is small, with no touch layer
    Wi-Fi, Classic Bluetooth and BLEAn old ESP32 generation: no native USB and none of the newer ESP32-S3 capabilities
    Two buttons, USB-C, Li-Po charging, battery monitoringNo PSRAM; heavy graphics eat the SRAM quickly
    More compact than a DevKit plus a separate TFTThe display and the service circuits occupy a noticeable number of GPIOs
    Arduino, PlatformIO, ESP-IDF, TFT_eSPI and LVGL examples all existADC2 conflicts with Wi-Fi, and GPIO36–39 work as inputs only
    A good fit for standalone panels and metersThe backlight and Wi-Fi limit how long it runs on a battery
    Two true DACs on GPIO25/26 and plenty of ADC1 inputsRevisions differ in flash and USB-to-UART, so the specification of a particular unit has to be checked

    Bottom line

    The LILYGO TTGO T-Display is valuable not for record specifications but for a well-judged layout. It turns the invisible work of a microcontroller into an interface you can read: the device reports its state immediately, shows measurements, takes commands from two buttons and can run on a battery.

    For a desk clock, a Home Assistant indicator, a portable meter, an MQTT remote, a mini-game or a networked departure board, the classic T-Display remains a very sensible foundation. The main thing is to remember its age and its limits: do not confuse it with the T-Display-S3, do not count on PSRAM, protect the boot GPIOs, use ADC1 while Wi-Fi is active and check the flash size of the particular board. If 240 × 135 pixels and two buttons are enough for the project, the built-in screen saves not only components but the most expensive resource in prototyping — the time between an idea and the first result you can actually see.

    Everything above, condensed into a platform-independent hardware reference a coding agent can follow: pin allocation classes, electrical rules, the canonical GPIO matrix and a machine-readable board profile.

Author, navigation between posts

Comments

2 responses to “QA · Dynamic, widgets and plugins”

  1. Dana Avatar
    Dana

    Placed here so the comments block has something to render. A comment long enough to wrap is worth more than a one-word one, because the indentation of a reply only shows up against a real paragraph.

    1. Author Avatar
      Author

      And a threaded reply, so the nesting depth and the left margin that comes with it are on the page too.

Leave a Reply

2 responses to “QA · Dynamic, widgets and plugins”

  1. Placed here so the comments block has something to render. A comment long enough to wrap is worth more than a one-word one, because the indentation of a reply only shows up against a real paragraph.

Leave a Reply

Plugin blocks

    Does the board need an external programmer?

    No. The USB-to-serial bridge on the board handles it, provided the auto-reset capacitor is populated — without it you have to hold the boot button while the upload starts.

    Can I substitute a different regulator?

    Yes, as long as it is a low-quiescent part. The three measured in the parts table differ by three orders of magnitude in standby draw, which is the whole difference between a week and a year on the same cell.

    Why is the enclosure printed in PETG rather than PLA?

    Heat. A sealed box in direct sun goes past the glass transition of PLA, and the lid warps enough to break the gasket seal.

    Time needed: 1 hour and 30 minutes

    Assembling the bench supply from the parts listed above.

    1. Populate the through-hole parts

      Start with the shortest components so the board sits flat against the mat while you solder.

    2. Replace the stock output capacitor

      Desolder the electrolytic that shipped on the module and fit the polymer part in its place, watching the polarity mark.

    3. Set the current limit before anything is connected

      Short the output through the meter and turn the limit pot until the reading matches the figure you want.

    4. Close the enclosure

      Four screws into the printed bosses, finger tight. Overtightening splits the boss along the layer lines.