Kode Dot FTP Explorer
A wireless FTP file server running on the Kode Dot (ESP32-S3). Serves the microSD card over Wi-Fi with a real-time AMOLED status display, battery monitoring, and persistent timekeeping.
Features
- FTP Server — Access the SD card from any FTP client (FileZilla, WinSCP, etc.)
- Wi-Fi from SD — Reads network credentials from
/Wi-Fi.jsonon the SD card - AMOLED UI — 410×502 LVGL 9.5 interface with live status, storage bar, clock
- Battery — Real-time charge percentage + charging indicator (BQ27220 + BQ25896)
- Persistent Clock — NTP sync → external RTC (MAX31329), survives power cycles
- Status LED — NeoPixel: green (idle), blue (connected), purple (transferring), red (error)
Hardware
| Component | Details |
|---|---|
| MCU | ESP32-S3, 240 MHz, 32 MB flash |
| Display | 410×502 AMOLED (QSPI, CO5300) |
| Storage | microSD via SD_MMC 1-bit |
| Battery | BQ27220 fuel gauge, BQ25896 PMIC |
| RTC | MAX31329 external clock |
| IO Expander | TCA9555 (buttons, SD detect) |
| LED | WS2812B NeoPixel on GPIO 4 |
Quick Start
1. Prepare the SD card
Create a Wi-Fi.json file in the root of your microSD card:
[
{ "ssid": "YourNetwork", "pass": "YourPassword" },
{ "ssid": "Fallback Network", "pass": "BackupPass" }
]
The device tries each network in order (20s timeout per attempt).
2. Build & Flash
# Build
pio run
# Flash (preserves KodeOS bootloader)
pio run -t upload
# Serial monitor
pio device monitor
3. Connect via FTP
| Setting | Value |
|---|---|
| Host | IP shown on display |
| Port | 21 |
| User | kode |
| Pass | kode |
FileZilla tip: Go to Site Manager → Transfer Settings → check "Limit number of simultaneous connections" and set to 1. SimpleFTPServer handles one client at a time.
UI Layout
┌─────────────────────────────────────┐
│ FTP Explorer 96% █ │ Header + battery
│─────────────────────────────────────│
│ 📶 Lago Sommer IoT │ Wi-Fi SSID
│ 192.168.178.102 │ IP address
│ │
│ ┌─────────────────────────────────┐ │
│ │ FTP Server │ │
│ │ ● Idle │ │ FTP panel
│ │ ftp://192.168.178.102 │ │
│ │ User: kode Pass: kode │ │
│ └─────────────────────────────────┘ │
│ │
│ Storage │
│ [██████░░░░] 61 MB / 7.3 GB 1% │ Storage bar
│ │
│ 14:32:45 │ Clock
│ Fri, 03 Apr 2026 │
└─────────────────────────────────────┘
LED Status
| Color | Meaning |
|---|---|
| 🟢 Green | Wi-Fi connected, FTP idle |
| 🔵 Blue | FTP client connected |
| 🟣 Purple | File transfer in progress |
| 🔴 Red | Error (no SD, no Wi-Fi) |
I2C Peripherals
| Device | Address | Function |
|---|---|---|
| TCA9555 | 0x20 | IO expander (buttons, SD detect) |
| BQ27220 | 0x55 | Battery fuel gauge |
| BQ25896 | 0x6B | PMIC / charger |
| MAX31329 | 0xD0 | External RTC |
Key Pin Assignments
| GPIO | Function |
|---|---|
| 4 | NeoPixel LED |
| 5, 6, 7 | SD_MMC (CMD, CLK, D0) |
| 47, 48 | I2C (SCL, SDA) |
| 8–10, 14–17 | QSPI display |
Dependencies
- LVGL 9 — UI framework
- SimpleFTPServer — FTP daemon
- ArduinoJson 7 — Wi-Fi.json parsing
- GFX Library for Arduino — Display driver
- Adafruit NeoPixel — Status LED
- TCA9555 — IO expander
- PMIC_BQ25896 — Charger
- kode_BQ27220 — Fuel gauge
- kode_MAX31329 — External RTC
Project Structure
├── platformio.ini Build config, libraries, upload command
├── partitions_app.csv Flash partition layout
├── Wi-Fi.json Example Wi-Fi credentials
├── boards/
│ └── kode_dot.json Custom board definition
├── src/
│ ├── main.cpp Firmware (Wi-Fi, FTP, NTP, battery, SD)
│ ├── ui.h / ui.cpp LVGL 9 display interface
│ └── lv_conf.h LVGL configuration
├── lib/kodedot_bsp/ Board support (display driver, pin config)
└── extra_scripts/ Build helpers (auto port, rename, framework libs)
License
MIT
Description
Languages
C
98.1%
C++
1.8%