TinyC — Custom Build Guide¶
Pre-built firmware is provided for ESP32 (4MB), ESP32-S3 (16MB), ESP32-C3 (4MB), and ESP8266 (4MB). For other ESP32 variants, build your own firmware using the configurations below.
Prerequisites¶
- PlatformIO installed (CLI or VS Code extension)
- Tasmota source tree cloned:
git clone https://github.com/gemu2015/Sonoff-Tasmota - No other
#define device_*active inuser_config_override.h
Required Defines¶
The TINYC_TESTING build flag (set via -DTINYC_TESTING in platformio) activates all
necessary defines in user_config_override.h. This includes:
// Core TinyC
#define USE_TINYC // TinyC VM (XDRV_124)
#define USE_TINYC_IDE // Browser IDE endpoint
// Hardware buses
#define USE_I2C // I2C bus
#define USE_SPI // SPI bus
#define USE_UFILESYS // Filesystem (required for IDE)
// Display (ESP32 only)
#define USE_DISPLAY // Display driver
#define USE_UNIVERSAL_DISPLAY // Universal display
#define USE_UNIVERSAL_TOUCH // Touch input
// Networking
#define USE_WEBCLIENT_HTTPS // HTTPS client (required for repo loading)
#define USE_WEBSEND_RESPONSE // Web response forwarding
#define USE_SENDMAIL // Email support
// Optional features
#define USE_SML_M // Smart meter interface
#define USE_DEEPSLEEP // Deep sleep support
#define USE_COUNTER // Pulse counter
#define USE_SUNRISE // Sunrise/sunset calculation
Note: TinyC has its own I2C, SPI, and serial implementations and does not require the
Tasmota Scripter engine. The -DTINYC_NO_SCRIPTER flag (included by default in all recommended
configurations below) excludes Scripter entirely, saving ~120 KB of flash.
Build Flags¶
| Flag | Effect | Default |
|---|---|---|
-DTINYC_TESTING |
Enable TinyC with all standard features | Required |
-DTINYC_NO_SCRIPTER |
Exclude Tasmota Scripter engine (~120 KB flash saved) | Recommended |
-DTINYC_HOMEKIT |
Enable Apple HomeKit support (≈+152 KB flash) | S3/16 MB only by policy — links on 4 MB but leaves too little headroom (see Flash Budget) |
-DTINYC_MATTER |
Enable Matter (USE_MATTER_C, pure-C engine). Mutually exclusive with -DTINYC_HOMEKIT — same build slot; the gate enables one or the other. Crypto rides on the resident BearSSL, so the incremental flash is modest. |
Opt-in (e.g. the tinyc32c6-matter env) |
-DTINYC_CAMERA |
Enable integrated camera driver (ESP32/S3 only, not RISC-V) — ≈+42 KB flash | ESP32/S3 builds |
-DUSE_TINYC_BLE |
Enable BLE scripting (scan + GATT client). Pulls in USE_BLE_ESP32 (the common-BLE driver) — ≈+292 KB flash / +9 KB RAM. Requires NimBLE-capable framework (BT enabled in sdkconfig) and -DCONFIG_NIMBLE_CPP_IDF globally. ESP32 family only. Off → BLE builtins are runtime no-ops |
Opt-in (e.g. the tinyc32s3-ble env) |
-DTINYC_NO_DISPLAY |
Exclude display support (~80 KB flash saved) | Optional |
Flash Budget (measured, tinyc32-4M — classic ESP32 4 MB, the tightest target)¶
The 4 MB ESP32 app partition (app1856k) is a hard wall at 1,900,544 B (1856 KB).
Numbers below are measured firmware deltas on this env (commit-era 1.6.8):
| Component | Flash | Notes |
|---|---|---|
| App partition ceiling | 1,900,544 B | over → build fails |
| Baseline shipped (TinyC ✓, camera ✓, HomeKit ✗) | 1,634,895 B | ≈259 KB free |
| TinyC subsystem itself | ≈196 KB | hand-measured; full driver — VM + ~70 syscalls + web widgets + IDE serving + bridges (not the bare interpreter, which is tiny) |
HomeKit (-DTINYC_HOMEKIT) |
+152 KB | technically fits 4 MB (→ ≈108 KB free) but leaves too little headroom — see rule of thumb |
Camera (-DTINYC_CAMERA) |
+42 KB | cheap; keep it |
BLE (-DUSE_TINYC_BLE → USE_BLE_ESP32) |
+292 KB (+≈9 KB RAM) | the heaviest optional subsystem — pulls in NimBLE. Too big for the 4 MB ESP32 alongside the full TinyC stack; use S3/16 MB (env tinyc32s3-ble drops Matter/camera for headroom). Off by default |
TinyC IDE blob (tinyc_ide.html.gz) |
~165 KB | lives on the filesystem partition, not app0 — does not count against the 1856 KB ceiling |
Rule of thumb: on 4 MB ESP32 (Tensilica), TinyC (~196 KB) is the single
largest optional subsystem — bigger than HomeKit. Enabling HomeKit would
still link (≈108 KB free), but that margin is too thin given TinyC's growth
rate plus per-build extras (extra sensors, display variants, etc.). So as a
policy HomeKit ships only in the ESP32-S3 / 16 MB builds, which have a far
larger app partition and ample headroom; the 4 MB env force-drops it
(build_unflags = -DTINYC_HOMEKIT in [env:tinyc32-4M]). RISC-V (C3) is
tighter still and also omits camera.
What's Included in Pre-Built Firmware¶
All pre-built firmware includes: - Display — Universal display + touch support - SML — Smart meter interface - Email — SMTP with file/picture attachments - I2C / SPI / Serial — Hardware bus access (native TinyC, no Scripter dependency)
- HomeKit — Apple Home integration via
-DTINYC_HOMEKIT. Only in the ESP32-S3 / 16 MB builds by policy — it adds ≈152 KB; on 4 MB that would link but leaves too little headroom (see Flash Budget above), so the 4 MB / C3 builds force-drop it.
ESP32 and ESP32-S3 builds additionally include:
- Camera — Integrated camera driver via -DTINYC_CAMERA (≈+42 KB, measured). Supports OV2640, OV3660, OV5640 with MJPEG streaming, PSRAM slot management, and motion detection
Build-flag-gated TinyC commands¶
The camera and HomeKit syscalls are conditionally compiled — they exist in the firmware only if the matching build flag was set. A script using them on firmware built without the flag will fail to compile in the IDE (unknown builtin) or be a no-op:
| Build flag | Gated TinyC builtins |
|---|---|
-DTINYC_CAMERA (USE_TINYC_CAMERA) |
cameraInit, camControl, dspLoadImageFromCam, dspImageToCam |
-DTINYC_HOMEKIT (USE_HOMEKIT) |
hkInit, hkAdd, hkStart, hkStop, hkReset, hkReady, hkVar, hkSetCode, HomeKitWrite callback |
-DTINYC_MATTER (USE_MATTER_C) |
matterReset, matterAdd, matterCluster, matterAttr, matterSet, matterGet, matterStart, MatterInvoke callback (replaces HomeKit — same slot) |
-DUSE_TINYC_BLE (USE_BLE_ESP32) |
scan + GATT client: bleScan, bleScanStop, bleNext, bleMac, bleAddrType, bleRssi, bleName, bleMfg, bleTarget, bleReadStart, bleWriteStart, bleDone, bleResult. GATT server (peripheral): bleServer, bleService, bleChar, bleServerStart, bleConnected, bleCharWritten, bleCharRead, bleCharSet, bleNotify, bleServerStop (+ consts BLE_READ/BLE_WRITE/BLE_NOTIFY). Unlike the camera/HomeKit builtins these are always present in the IDE compiler (scripts compile anywhere) and simply no-op at runtime on a non-BLE build |
Since the 4 MB / C3 pre-built firmware ships without HomeKit, the hk*
builtins are unavailable there — use an S3/16 MB build for HomeKit scripts.
ESP32-C3 (RISC-V) does not include camera support — the esp32-camera library requires Xtensa.
platformio_override.ini Sections¶
Add these sections to your platformio_override.ini. Each extends the TinyC base
configuration. Build with: pio run -e <environment-name>
Common Base (required)¶
[env:tinyc_base]
; Common TinyC build settings — inherits from tasmota32_base
; All builds get HomeKit + display, no Scripter
build_flags = ${env:tasmota32_base.build_flags}
-DTINYC_TESTING
-DTINYC_NO_SCRIPTER
-DTINYC_HOMEKIT
ESP32 (4MB) — with Camera¶
Classic ESP32 WROOM module. The standard build for most ESP32 devices.
[env:tinyc32-4M]
extends = env:tasmota32_base
board = esp32
board_build.f_cpu = 240000000L
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32-S3 (16MB) — with Camera¶
Dual-core Xtensa S3 with 16MB flash. Default for S3 devkits.
[env:tinyc32s3]
extends = env:tasmota32_base
board = esp32s3_16M
board_build.f_cpu = 240000000L
board_build.mcu = esp32s3
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32-S3 Mini (4MB flash, 2MB quad PSRAM) — Matter host¶
The small dual-core S3 module (e.g. Lolin/Wemos S3 Mini, chip ESP32-S3FH4R2:
4 MB flash + 2 MB quad/QSPI PSRAM). A compact Matter host — dual-core + PSRAM
(so matter_ctx offloads to PSRAM, freeing internal DRAM) in the footprint of a
classic ESP32. Native USB-CDC console (single USB-C port).
Key differences from the 16 MB S3 build: the qio_qspi board selects quad
PSRAM — not the qio_opi (octal) used by larger S3s; octal mode would fail
PSRAM init and boot-loop. The partition is overridden to the 4 MB app1856k
layout (Matter fits at ~81 %) so the 1.3 MB filesystem holds the IDE + scripts +
Matter fabric store. No camera, no BLE — 4 MB can't fit Matter + either.
[env:tinyc32s3-mini]
extends = env:tasmota32_base
board = esp32s3-qio_qspi ; quad PSRAM (NOT qio_opi/octal)
board_build.f_cpu = 240000000L
board_build.mcu = esp32s3
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_MATTER -DMTRC_ATTEST_TEST_CREDS
build_unflags = -DTINYC_HOMEKIT
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
esp32-camera
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
First flash over the single USB-C port (native USB): esptool ... write_flash
0x0 .pio/build/tinyc32s3-mini/firmware.factory.bin. Updates: OTA via the
safeboot flow (GET /u4?u4=fct&api=1 → poll true → POST firmware.bin to /u2).
ESP32-C3 (4MB) — no Camera¶
RISC-V single-core. Camera library not available (requires Xtensa).
[env:tinyc32c3]
extends = env:tasmota32_base
board = esp32c3
board_build.f_cpu = 160000000L
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib/libesp32/CORE2_Library
libesp32_lvgl
esp32-camera
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
Additional Variants¶
ESP32-S3 with USB CDC (DFRobot, native USB)¶
For boards with native USB (no UART chip), like DFRobot Firebeetle 2 ESP32-S3:
[env:tinyc32s3-usb]
extends = env:tinyc32s3
build_unflags = -DARDUINO_USB_MODE=0
-DARDUINO_USB_CDC_ON_BOOT=0
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
-DARDUINO_USB_MODE=1
-DARDUINO_USB_CDC_ON_BOOT=1
-DUSE_USB_CDC_CONSOLE
ESP32-S3 Sunton (QIO/OPI, RGB Display)¶
For Sunton boards with PSRAM in OPI mode and RGB displays:
[env:tinyc32s3-sunton]
extends = env:tasmota32_base
board = esp32s3ser-qio_opi_120
board_build.f_cpu = 240000000L
board_build.mcu = esp32s3
build_flags = ${env:tinyc_base.build_flags}
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32-S2 (4MB)¶
Single-core Xtensa, 4MB flash. Good for simple USB-connected devices.
[env:tinyc32s2]
extends = env:tasmota32_base
board = esp32s2
board_build.f_cpu = 240000000L
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib/libesp32/CORE2_Library
libesp32_lvgl
esp32-camera
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32-C6 (4MB)¶
RISC-V single-core with WiFi 6 and Zigbee/Thread. Same architecture as C3.
[env:tinyc32c6]
extends = env:tasmota32_base
board = esp32c6
board_build.f_cpu = 160000000L
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib/libesp32/CORE2_Library
libesp32_lvgl
esp32-camera
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32 Solo1 (4MB)¶
Single-core ESP32 (some Sonoff devices, ESP32-SOLO1 module).
[env:tinyc32solo1]
extends = env:tasmota32_base
board = esp32_solo1_4M
board_build.f_cpu = 160000000L
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32-S3 (8MB)¶
Dual-core Xtensa with 8MB flash. Many devkits and modules use 8MB.
[env:tinyc32s3-8M]
extends = env:tasmota32_base
board = esp32s3_8M
board_build.f_cpu = 240000000L
board_build.mcu = esp32s3
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32-S3 (4MB)¶
Dual-core Xtensa S3 with only 4MB flash. Use optimized partition.
[env:tinyc32s3-4M]
extends = env:tasmota32_base
board = esp32s3_4M
board_build.f_cpu = 240000000L
board_build.mcu = esp32s3
board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
ESP32 (16MB)¶
Classic ESP32 with 16MB flash (e.g., ESP32-WROVER-E 16MB).
[env:tinyc32-16M]
extends = env:tasmota32_base
board = esp32_16M
board_build.f_cpu = 240000000L
build_flags = ${env:tinyc_base.build_flags}
-DTINYC_CAMERA
lib_ignore = ${env:tasmota32_base.lib_ignore}
TTGO TWatch Library
Micro-RTSP
epdiy
lib_extra_dirs = ${common.lib_extra_dirs}
lib/libesp32
lib/libesp32_div
E-Paper Variants (Legacy UDisplay)¶
For e-paper displays that require the legacy UDisplay library instead of UDisplay_legacy:
[env:tinyc32c3-epd]
extends = env:tinyc32c3
lib_ignore = Servo(esp8266)
ESP8266AVRISP
ESP8266LLMNR
ESP8266NetBIOS
ESP8266SSDP
SP8266WiFiMesh
Ethernet(esp8266)
GDBStub
TFT_Touch_Shield_V2
ESP8266HTTPUpdateServer
ESP8266WiFiMesh
EspSoftwareSerial
SPISlave
universal display Library
ArduinoOTA
TTGO TWatch Library
Micro-RTSP
epdiy
lib/libesp32/CORE2_Library
libesp32_lvgl
esp32-camera
[env:tinyc32s3-epd]
extends = env:tinyc32s3
lib_ignore = Servo(esp8266)
ESP8266AVRISP
ESP8266LLMNR
ESP8266NetBIOS
ESP8266SSDP
SP8266WiFiMesh
Ethernet(esp8266)
GDBStub
TFT_Touch_Shield_V2
ESP8266HTTPUpdateServer
ESP8266WiFiMesh
EspSoftwareSerial
SPISlave
universal display Library
ArduinoOTA
TTGO TWatch Library
Micro-RTSP
epdiy
Camera Support Notes¶
The -DTINYC_CAMERA flag enables the integrated TinyC camera driver, which provides:
- Board-specific pin configuration via cameraInit(pins[], ...)
- MJPEG stream server on port 81
- PSRAM slot management (up to 4 concurrent captures)
- Motion detection
- Direct sensor register access
Supported targets: ESP32 and ESP32-S3 (Xtensa). The esp32-camera library does not compile on RISC-V targets (C3, C6) — add esp32-camera to lib_ignore for those.
Size impact: Adding camera support adds ~34 KB to firmware size.
Camera boards tested: - AI-Thinker ESP32-CAM (OV2640) - Goouuu ESP32-S3-CAM (OV2640) - DFRobot Firebeetle 2 ESP32-S3 AI CAM DFR1154 (OV3660)
Camera pin definitions are in the TinyC source file (camera.tc, webcam_tinyc.tc), not in the firmware — any camera board can be used by defining the correct pin array.
Partition Tables¶
| Flash Size | Partition File | App Size | Filesystem | Notes |
|---|---|---|---|---|
| 4MB | esp32_partition_app1856k_fs1344k.csv |
1,856 KB | 1,344 KB | Recommended for 4MB with safeboot |
| 8MB | esp32_partition_app3904k_fs3392k.csv |
3,904 KB | 3,392 KB | 8MB with safeboot |
| 16MB | esp32_partition_app3904k_fs11584k.csv |
3,904 KB | 11,584 KB | 16MB with safeboot (default for S3-16M) |
For 4MB boards: the TinyC firmware is ~1,650 KB, leaving ~200 KB headroom in the 1,856 KB app partition. Without Scripter (-DTINYC_NO_SCRIPTER), firmware is ~120 KB smaller, giving more headroom.
Build Command¶
# Build a specific environment
pio run -e tinyc32-4M
# Build and upload via serial
pio run -e tinyc32-4M --target upload
# Build and upload via OTA
pio run -e tinyc32-4M --target upload --upload-port <device-ip>
OTA Partition Management¶
Devices in sealed housings without serial access can resize their partition layout
at runtime using the chkpt console command. This is useful when switching between
firmware versions of different sizes.
Commands¶
| Command | Effect |
|---|---|
chkpt |
List current partition table |
chkpt p |
Auto-pack: shrink app0 to firmware size + ~200 KB overhead, expand filesystem. Warning: all files on the filesystem are lost! |
chkpt p <KB> |
Set app0 to a specific size in KB (1024–3904), adjust filesystem accordingly. Warning: all files on the filesystem are lost! |
chkpt a1 |
Add 64 KB custom partition (for plugin drivers), taken from filesystem |
chkpt a2..a4 |
Add 128/192/256 KB custom partition |
chkpt r |
Remove custom partition, return space to filesystem |
chkpt n <name> <kb> |
Add a named DATA partition of <kb> KB (64 KB-aligned), carved from the filesystem tail — for large read-only blobs you want to memory-map. Any partition already after the filesystem (e.g. custom) keeps its flash offset. |
chkpt d <name> |
Delete a named partition (must be the one directly after the filesystem); space returns to the filesystem |
Examples¶
# Device has app0=2880 KB, spiffs=256 KB — shrink app to gain filesystem:
chkpt p
→ app0=1856 KB, spiffs=1280 KB (firmware 1603 KB + 252 KB overhead)
# Need to flash a larger firmware later — expand app first:
chkpt p 2880
→ app0=2880 KB, spiffs=256 KB
# With custom plugin partition present — custom is always preserved:
chkpt p
→ app0=1856 KB, spiffs=1280 KB, custom=64 KB (unchanged at end of flash)
Notes¶
- The device reboots automatically after any partition change
- Filesystem (LittleFS) is formatted during resize — back up files first
- The custom partition (plugin drivers) is never moved or removed by
chkpt p - The
chkptinfrastructure is always compiled into TinyC firmware, no extra build flags needed - App size is aligned to 64 KB boundaries
chkpt prequires a safeboot partition — devices without safeboot are refused (no recovery if partition table gets corrupted)
Named Data Partitions (for memory-mapped blobs)¶
chkpt n / chkpt d + the /partu upload let you carve a named, memory-mappable
DATA partition at runtime and fill it over the network — for large read-only
blobs that you want to access directly from flash (esp_partition_mmap) instead of
copying into RAM: TTS voices, fonts, ML models, lookup tables, images.
Why a partition and not a file: a LittleFS file isn't contiguous, so to get a single addressable pointer you'd have to read it into RAM. A raw partition is contiguous and mmap-able — the CPU cache fetches bytes on demand, costing 0 RAM. On a RAM-tight board that's the difference between fitting and not.
Workflow (all OTA, no serial, no custom partition table baked into the build):
# 1. Carve the partition(s) — each carves from the filesystem tail and reboots.
# Carve the LATER one first so offsets line up (it lands further from the FS).
chkpt n picotts_sg 640 # 640 KB DATA partition named "picotts_sg"
chkpt n picotts_ta 448 # 448 KB DATA partition named "picotts_ta"
# 2. Upload a blob straight into each partition (the multipart FILENAME picks the
# target partition). Streams to flash with per-sector erase+write — bypasses
# the (now possibly tiny) filesystem entirely.
curl -F "f=@de-DE_sg.bin;filename=picotts_sg" http://<device-ip>/partu
curl -F "f=@de-DE_ta.bin;filename=picotts_ta" http://<device-ip>/partu
A consumer then mmaps it by name, e.g. esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_ANY, "picotts_ta") + esp_partition_mmap(...).
Notes¶
- Created partitions are type DATA, subtype 0x40 (user-data, not auto-mounted).
- Ordering is LIFO. Each
chkpt ncarves from the filesystem tail, so the newest partition sits directly after the filesystem and older carves stack outward (towardcustom).chkpt dcan therefore only remove the partition directly after the filesystem — the most-recently-carved one; to drop an older partition, delete the newer ones first. This is deliberate: it keeps the layout gap-free (freed space always merges straight back into the filesystem) and lets every partition past the carve zone — e.g.custom— keep its flash offset. There is no way to leave a hole between the filesystem and a named partition. /partuonly writes DATA/0x40 partitions — it cannot clobberapp0,nvs,safeboot, or the filesystem.- Resizing the filesystem reformats it — back up files first (same as
chkpt p). - Safeboot-gated and self-logged (the new table is printed before it's written); a bad table is recoverable via safeboot.
Example: German TTS on a 4 MB / 2 MB-PSRAM ESP32-S3¶
picotts (SVOX) needs a ~1.1 MB engine arena plus the ~1.05 MB de-DE voice. Both in PSRAM = ~2.15 MB, which won't fit a 2 MB part. Putting the voice in mmap'd flash partitions (0 PSRAM) leaves the whole arena for PSRAM, so it fits:
- Build with
USE_PICOTTS(the I2SAUDIO BinPlugin carries the codec +I2Sttscommand; the engine is in the firmware). chkpt n picotts_sg 640thenchkpt n picotts_ta 448(reboots between)./partuthe twode-DE_{sg,ta}.binvoice files into them.- Leave the FS voice files absent →
PicoLazyInitskipspicotts_set_resources()and the engine memory-maps the partitions directly. I2Stts "Hallo"→ German speech, voice at 0 PSRAM.
See examples/esf37_scale.tc (a BLE body-composition scale that announces your
weight in German via this path) and examples/esf37_speak.tc (the minimal version).
After Flashing¶
- Upload
tinyc_ide.html.gzto the device filesystem via Consoles > Manage File System - Open
http://<device-ip>/tinyc_ide.htmlin a browser - Write code, press Ctrl+Enter to compile, Ctrl+Shift+Enter to run on device