Most budget 3D printers have a UART port on the mainboard and run Marlin. That's all you need. An ESP32 sitting between your router and that UART port turns any of them into a WiFi-connected printer with a local web interface and touch display — no OctoPrint, no Raspberry Pi, no cloud account, no subscription. One module. Three wires. Done.
MalyanLink Bridge v3 introduces a full printer profile system. Each supported printer has a verified entry in profiles.h — baud rate, UART header label, voltage level, capabilities, and material presets pulled directly from official Marlin configs and hardware testing. Set ACTIVE_PROFILE to your printer, flash, done.
MalyanLink Bridge started as a reverse engineering project to rescue Malyan M300 printers whose original WiFi firmware depended on a dead CDN. The hardware was perfectly fine — only the ESP8266 needed replacing. The full Malyan UART protocol was reconstructed from a 2019 M300 firmware binary. The M300 is a delta printer — the malyan profile is verified at ~80% functionality against that specific hardware/firmware combination. Other Malyan models (M200, M320) and the Monoprice Select Mini share compatible hardware but have not yet been tested on real hardware. From there the project grew into something more general: the same bridge works with any Marlin printer over standard G-Code UART.
| OctoPrint | Klipper | MalyanLink Bridge | |
|---|---|---|---|
| Hardware needed | Raspberry Pi + SD + PSU | Raspberry Pi + reflash | One ESP32 module |
| Setup time | Hours | Hours / days | Minutes |
| Invasive? | Takes over USB port | Replaces printer firmware | Non-invasive, parallel |
| Cloud / Subscription | No | No | Never |
| Touch UI on printer | No | Optional, complex | Built in |
| Price | ~80–120€ DIY | ~80–120€ DIY | ~20€ module |
Started as a hardware proof of concept: repurposing the Malyan M300 UI board (ESP8266EX + ILI9488 display) as a real-time PC system monitor. Proved out the custom 9-bit SPI bit-banging driver for the ILI9488, which lacks a D/C pin and requires a 9th bit per byte to distinguish commands from data.
After reverse engineering the original Malyan firmware binary, the full UART protocol was recovered. This grew into a universal bridge firmware — Malyan is just the first supported profile.
Browser → HTTP → ESP32 → UART → Marlin → Printer Touch UI ↗ ← ← ←
The ESP32 hosts a local web server on port 80 and drives a touch display simultaneously. Commands from the web UI or touch screen get translated into the appropriate UART protocol for your printer profile and sent to Marlin. With AUTOREPORT_TEMP enabled (verified on Geeetech A10), the printer pushes temperature data automatically every 3 seconds via M155 S3 — no polling needed. No internet required after initial WiFi setup. If WiFi isn't available, the module opens a local access point automatically.
HW-458 (ESP32-2432S028) ├── ILI9341 Touch Display → 5-screen touch UI (Status / Temp / Move / Fan / Info) ├── WiFi → Web dashboard, OTA updates ├── Serial1 (IO27/IO22) → UART to printer mainboard └── Web API /cmd /status → JSON endpoint for integrations GT2560 V4.0 (Geeetech A10) └── MC-TX / MC-RX / PGND1 → dedicated WiFi header, 3.3V TTL, 250000 baud
| Printer | Board | Baud | UART Header | Status |
|---|---|---|---|---|
| Geeetech A10 | GT2560 V4.0 | 250000 | MC-TX / MC-RX / PGND1 | ✅ Hardware verified |
| Malyan M300 (Delta) | ESP8266EX UI Board | 115200 | UART header | ✅ ~80% verified (2019 binary) · 🧪 other revisions untested |
| Malyan M200 | — | 115200 | — | 🧪 Needs testing |
| Malyan M320 | — | 115200 | — | 🧪 Needs testing |
| Monoprice Select Mini v1/v2 | — | 115200 | — | 🧪 Needs testing |
| Creality Ender 3 / CR-10 | 4.2.2 / RAMPS | 115200 | AUX-1 / WiFi header | 🧪 Community testing |
| BTT SKR boards | SKR Mini / v1.3+ | 115200 | TFT / WiFi header | 🧪 Community testing |
| Any Marlin printer with UART | — | varies | check board silkscreen | 🧪 Community testing |
Most Marlin boards since 2015 have a dedicated WiFi/BT header with TX/RX/GND at 3.3V TTL. Check your board's silkscreen for labels like MC-TX, MT-TX, WIFI, or AUX-1.
Standard Marlin G-Code over UART. Baud rate varies by board — Geeetech uses 250000, Creality 115200. Check your board or run M115 via Arduino IDE Serial Monitor to identify firmware and capabilities.
M104 S200 → extruder to 200°C M140 S60 → bed to 60°C M155 S3 → auto-report temps every 3s (AUTOREPORT_TEMP:1) M114 → get current position G28 → home all axes M112 → emergency stop ok T:185.0 /200.0 B:55.0 /60.0 ← auto-report response X:10.00 Y:20.00 Z:5.00 E:0.00 ← M114 response
Verified capabilities on Geeetech A10 (Marlin 1.1.8):
AUTOREPORT_TEMP: 1 → M155 S3 aktivieren, kein M105 Polling nötig EEPROM: 1 → M500 / M501 / M503 PRINT_JOB: 1 → M73 progress tracking PROGRESS: 0 → kein nativer SD-Progress Steps/mm: X:80.30 Y:80.30 Z:400.00 E:93.00 PLA preset: E:215°C B:55°C (aus M145 S0) ABS preset: E:240°C B:90°C (aus M145 S1)
Recovered from the original Malyan firmware binary. Custom JSON-like command wrapper over UART at 115200 baud.
{C:T0190} → extruder to 190°C
{C:P050} → bed to 50°C
{C:T0000} → extruder off
{J:A+5} → jog +5mm
{P:X} → cancel print
{P:H} → pause print
{P:P} → resume print
{RC:C} → connect handshake
T185/190P50/50I ← idle
T185/190P50/50/75P ← printing at 75%
TFT_eSPI (Bodmer), XPT2046_Touchscreen (Paul Stoffregen)The GT2560 V4.0 has a dedicated WiFi header on the back of the board, right of the display connector, labeled MC-TX / MC-RX / PGND1.
HW-458 Serial Header GT2560 V4.0 TX (IO27) → MC-RX RX (IO22) → MC-TX GND → PGND1 VIN → NOT connected
✅ GT2560 V4.0 confirmed 3.3V TTL on MC-TX/MC-RX — no level shifter needed.
⚠️ Baud rate for Geeetech A10 is 250000, not 115200. Set PRINTER_BAUD 250000 in the firmware config before flashing.
Look for a 3–4 pin header labeled WIFI, MT-TX/RX, MC-TX/RX, BT, or AUX-1. Cross TX→RX, RX→TX, connect GND. Check your board's schematic for voltage level before connecting.
User_Setup.h into your TFT_eSPI library folder (overwrites existing)User_Setup_Select.h ensure only #include <User_Setup.h> is activeMalyanLink_Bridge_A10.ino, set WIFI_SSID / WIFI_PASSWORDPRINTER_BAUD to match your printer (250000 for Geeetech, 115200 for most others)ESP32 Dev Module, Partition: Default 4MB with spiffs, CPU: 240MHzhttp://malyanlink.local or http://<ip>💡 If WiFi credentials are wrong or unavailable, the module automatically opens a hotspot: SSID: MalyanLink / PW: malyanlink
After first flash, go to the INFO tab on the touch display. The raw touch coordinates are shown live. If touch targets feel offset, adjust TOUCH_X_MIN / TOUCH_X_MAX / TOUCH_Y_MIN / TOUCH_Y_MAX to match your panel's actual range.
CH341 TX → Board RX CH341 RX → Board TX CH341 GND → Board GND CH341 5V → Board VCC (display board runs on 5V)
The middle button of the three display buttons is the boot/flash button.
Board: Generic ESP8266 Module Flash Mode: DIO Flash Size: 4M (1M SPIFFS) Upload Speed: 115200 Reset Method: nodemcu
⚠️ The display board takes 5V on VCC. CH341 UART signals must be 3.3V logic — check your adapter has a voltage jumper.
⚠️ The ESP8266EX has 4MB flash at 80MHz. Do not replace with an 8MB chip — only the first 4MB are addressable.
💾 Backup your original firmware before flashing:esptool.py --port COMX read_flash 0x000000 0x400000 backup.bin
TFT_MISO removed from User_Setup.h (IO12 LOW at boot prevented ESP32 from starting)M155 S3 Auto-Report replaces M105 polling — verified AUTOREPORT_TEMP:1 on A10MalyanLink hotspot if WiFi unavailable, no silent fail/status JSON endpoint for future integrations{F:start}/{F:end} framing reconstructed from dump, not yet hardware verified on MalyanMalyanLink Bridge is a one-person project built in spare time. Expanding hardware support to more printers requires firmware dumps and real-world testing — things that only the community can provide.
esptool.py read_flash 0x000000 0x400000 dump.bin) lets me reverse the protocol and add official support. Send it to nira.wav@gmail.com.MIT — do whatever you want with it, just don't blame me if your printer catches fire.