Wi-Fi thermal receipt printer: a full build guide
An ESP8266 that hosts a little web page on your network. Open it on your phone, type a message, hit send — and it prints on a thermal receipt printer, timestamped and correctly oriented as the paper feeds out. It's a genuinely fun first "it does a physical thing over Wi-Fi" project, and it teaches web serving, serial, and ESC/POS printer control in one go.
Inspired by the thermal-printer message-board concept popularized by Peter / Urban Circles. This is my own firmware build of the idea, written up so you can make your own.
How it works, end to end
Parts you need
Some links in this parts list are Amazon affiliate links. I may earn a commission from qualifying purchases at no extra cost to you.
- A WeMos D1 Mini (ESP8266) for the microcontroller.
- A 58mm embedded thermal receipt printer with TTL serial input. Check for TTL/UART input before buying; a USB-only desktop printer will not work with this wiring.
- An external 5V or 9V power supply rated for at least 2A. Match the voltage and connector polarity printed on your specific printer.
- A roll of 58mm thermal paper.
- A Dupont jumper-wire kit and breadboard kit for prototyping.
Wiring
The one thing beginners get wrong: do not power the printer from the D1 Mini. The print head can draw an amp or more in bursts — that will brown out the ESP and cause resets or garbage prints. Give the printer its own supply and just share a common ground.
The exact connections:
| From (D1 Mini) | To (thermal printer) | Why |
|---|---|---|
| D8 (TX) | RX / DIN | Serial data at 9600 baud |
| GND | GND | Signals need a shared reference — required |
| — | VIN | Printer power, from the external PSU (not the D1 Mini) |
| 5V / USB | — | Powers the D1 Mini itself |
| GND | PSU (−) | Tie the PSU ground to the common ground too |
Most 58mm TTL printers accept 3.3V logic on RX, so the D1 Mini's TX drives them directly. If yours is finicky, add a logic level converter between D8 and RX.
The firmware, in the parts that matter
Connect to Wi-Fi from a git-ignored secrets file (never hardcode credentials — see the security note below):
#include "secrets.h" // WIFI_SSID / WIFI_PASSWORD live here, git-ignored
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASSWORD;
Talk to the printer over SoftwareSerial on D8, TX-only, at 9600 baud, and send the ESC/POS init + heat settings. Print quality is almost entirely in the heat values — too low is faint, too high ghosts and scorches:
SoftwareSerial printer(D8, -1); // D8 = TX, no RX pin
printer.begin(9600);
printer.write(0x1B); printer.write('@'); // ESC @ — reset
printer.write(0x1B); printer.write('7'); // ESC 7 — heating config
printer.write(15); // heating dots (max 15)
printer.write(150); // heating time
printer.write(250); // heating interval
The fun bug-that's-a-feature — printing upside down. Thermal printers feed paper out the top, so a normally-printed receipt reads bottom-to-top in your hand. The fix is two wrongs making a right: enable the printer's 180° rotation and print the wrapped lines in reverse order, so the finished slip reads top-to-bottom:
printer.write(0x1B); printer.write('{'); printer.write(0x01); // ESC { 1 — rotate 180°
// ...then emit the word-wrapped lines last-to-first:
for (int i = lineCount - 1; i >= 0; i--) printLine(lines[i]);
The ESP also runs a tiny web server that serves the "Leave a Message" form and, on submit, hands the text to the printer with an NTP timestamp.
Troubleshooting
- Garbage characters / resets: power problem. Give the printer its own 2A+ supply and check the common ground.
- Faint or scorched print: tune the three heat values above.
- Nothing prints: wrong baud (try 19200) or TX/RX swapped.
- Text reads bottom-to-top: you have the rotation but not the reversed line order (or vice-versa) — you need both.
What I'd add next
- A small I2C OLED display for status and the current IP.
- A Home Assistant hook so automations can print (e.g. the day's calendar at 7am).
⚠️ Security note
The sketch reads Wi-Fi credentials from a git-ignored secrets.h — never commit them:
// secrets.h (add to .gitignore)
#define WIFI_SSID "your-ssid"
#define WIFI_PASSWORD "your-password"
Gear used
- WeMos D1 Mini (ESP8266)
- 58mm TTL thermal receipt printer
- Compatible 5V or 9V, 2A+ power supply
- 58mm thermal paper
- Jumper wires, breadboard, and soldering mat
Get the free Starter Kit →