esp32.diy

MicroPython ESP32 psRAM LoBo: Build Firmware with 4MB RAM

Oct 13, 2026 · 5 min read

Advanced 873 stars 347 forks C NOASSERTION Updated 2023-10-19

ESP-WROVER-KIT v3, the primary reference board used to test and develop this MicroPython psRAM firmware.

TL;DR The LoBo MicroPython port unlocks the full 4MB psRAM on compatible ESP32 modules, jumping from under 100KB of free memory to over 3MB available to your Python scripts. It bundles a BUILD.sh script and esp-idf menuconfig system so you can compile a custom firmware image packed with TFT display, MQTT, FTP, SSH, GSM, OTA and dozens of other modules — all configured without touching a single header file.
What you need
  • M5Stack Development Kit (psRAM version)
  • TTGO T8 V1.1
  • ESP-WROVER-KIT
  • WiPy 3.0
  • TTGO TAudio
  • Lolin32 Pro
  • ESP-WROVER module
  • ALB32-WROVER module
  • Pycom S01 / L01 / G01 OEM modules
BoardESP32 with psRAM (ESP-WROVER-KIT, M5Stack, TTGO T8, WiPy 3.0 and others)
Frameworkesp-idf (menuconfig-based)
LanguageC (firmware) / MicroPython (user scripts)
LicenseSee repository
Default Heap2MB MicroPython heap in SPIRAM (up to 4MB)
DifficultyAdvanced

What You Will Build — and Why It Matters

Standard MicroPython on an ESP32 gives you fewer than 100KB of free memory. That limit forces you to keep scripts tiny, avoid large data structures and skip memory-hungry libraries. The LoBo port removes that ceiling.

By building firmware that maps the module's external SPIRAM (psRAM) into the MicroPython heap, you get 2MB of heap by default — and you can push that to 4MB or beyond with a config change. The boot log from a running board says it all:

uPY heap: 3073664/5664/3068000 bytes (in SPIRAM using malloc)

Beyond raw memory, the LoBo port compiles in a full set of extras that the standard port omits: SPI TFT display driver, MQTT client, FTP server, telnet REPL, SSH with sftp/scp, libcurl for HTTP/FTP/email, GSM/PPPoS for cellular internet, Neopixel via the RMT peripheral, BTree database, improved threading with inter-thread messaging, NTP-synced RTC with deep-sleep wakeup, ymodem file transfer and more. Everything is selected or deselected at build time through menuconfig — no manual header editing required.

What You Need

Hardware

You need an ESP32 module or development board that carries external SPIRAM. The README lists these confirmed options:

The firmware can also be built for plain ESP32 boards without psRAM; you simply configure a smaller heap.

Software and build host

A USB-to-serial adapter or a board with an onboard USB bridge (such as the ESP-WROVER-KIT) is needed for flashing.

Typical use cases

Memory-Hungry MicroPython Scripts

Run data-processing scripts, large JSON payloads or image buffers that would crash a standard ESP32 MicroPython build due to heap exhaustion.

SPI TFT Display Projects

Drive color TFT displays from MicroPython using the built-in C display driver — no slow pure-Python framebuffer needed.

IoT Gateway with GSM Fallback

Use WiFi as the primary uplink and fall back to a GSM module over PPPoS when the local network is unavailable — all configured in firmware.

Wireless Development and Deployment

Develop over a telnet REPL, manage files via FTP, and push firmware updates over OTA — no USB cable required after initial flash.

How It Works Under the Hood

The firmware is compiled as an esp-idf component. That means the entire Espressif SDK configuration system — menuconfig — is available to tune both the ESP32 itself and the MicroPython layer. You can switch between unicore and dualcore FreeRTOS, choose Flash speed and mode (QIO/QOUT/DIO/DOUT), set heap sizes, enable or disable individual modules, and configure the default time zone — all from the same curses-style menu used for normal esp-idf projects.

At runtime, the SPIRAM is registered with the esp-idf heap allocator immediately after boot. MicroPython's gc allocator then uses that pool as its main heap while a separate 32KB block of internal DRAM is reserved for DMA and C-level allocations. The terminal session in the README shows both heaps live side by side:

Heap outside of MicroPython heap:
  Free: 239920   Allocated: 52328

SPIRAM info:
  Free: 1048532  Allocated: 3145728

Peripheral modules (MQTT, FTP, mDNS) each run as independent FreeRTOS tasks, so they stay active while your Python script does other work. The internal Flash filesystem uses the esp-idf wear-leveling driver to extend Flash lifespan; SPIFFS can replace FatFS if preferred.

Building the Firmware

The repository ships a BUILD.sh script that automates the entire toolchain and build sequence. Detailed step-by-step instructions — including how to set up the host environment on Linux, macOS and Windows — are documented on the project Wiki.

The high-level flow is:

  1. Clone the repository to your build machine.
  2. Run BUILD.sh from the MicroPython_BUILD directory. The script accepts arguments to invoke menuconfig, build or flash. Consult the Wiki for the exact flags.
  3. Run menuconfig (via BUILD.sh) to tailor the firmware: choose unicore vs. dualcore, set heap size, enable/disable modules such as TFT, MQTT, SSH, GSM, BTree and SPIFFS, set your time zone.
  4. Build — BUILD.sh compiles MicroPython and all selected esp-idf components into a flashable binary.
  5. Flash — BUILD.sh can also invoke esptool to write the firmware over the serial port.

For Eclipse users, the repo includes project files. Import MicroPython_BUILD as an existing project and rebuild the index to get IDE integration.

Once the board is running, verify the psRAM heap at the REPL:

import micropython, machine
micropython.mem_info()
machine.heap_info()

Working with the Built-In Modules

Once the firmware is running, a wide set of modules is available at the REPL. A few highlights:

SD card

import uos
uos.mountsd()
uos.listdir('/sd')

The sdmmc driver supports 1-bit SD, 4-bit SD and SPI modes; the SD card can be connected to any pins.

RTC and NTP sync

rtc = machine.RTC()
rtc.init((2017, 6, 12, 14, 35, 20))
rtc.ntp_sync(server="<ntp_server>" )
rtc.synced()
rtc.now()

Deep sleep with external wakeup

rtc.wake_on_ext0(Pin, level)
rtc.wake_on_ext1(Pin, level)
machine.deepsleep(10000)

After wakeup, machine.wake_reason() and machine.wake_description() report exactly what woke the board.

Telnet REPL — enable the telnet module and you get a wireless Python prompt over WiFi without a USB cable.

FTP server — runs as a background task; connect any FTP client to browse and edit files on the board's internal or SD filesystem.

GSM/PPPoS — connect a GSM module to an ESP32 UART and the board gains cellular internet without WiFi.

Extending the Build and Limitations to Know

Ideas to take it further

Limitations to keep in mind

Verdict

The LoBo MicroPython port is the most feature-complete ESP32 MicroPython build available for psRAM-equipped modules, turning a memory-constrained microcontroller into a capable embedded Linux-like platform with 3MB+ of Python heap. The BUILD.sh and menuconfig workflow keeps custom builds manageable, though it does demand a proper build environment and comfort with toolchain setup. If you have an ESP-WROVER-KIT or M5Stack with psRAM and want MicroPython with display, networking and filesystem features that the standard port cannot offer, this firmware is worth the build effort.

Sources

github.comloboris/MicroPython_ESP32_psRAM_LoBo — repository & README

Facts in this article come from the project's public README and GitHub metadata at the time of writing. Images belong to their respective owners and link back to the original source.