HomeForge

HomeForge / Builds

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

Your phone (web form) D1 Mini web server Thermal printer Printed slip Wi-Fi TX D8 paper
Phone → the ESP's web form → serial (TX pin D8) → the printer → a slip you can hold.

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.

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.

Wemos D1 Mini (ESP8266) Thermal printer (TTL serial) External 5–9V PSU (2A or more) D8 (TX) → RX · 9600 baud power → VIN common ground — tie every GND together
Data on one wire, power on another, and a shared ground. That's the whole circuit.

The exact connections:

From (D1 Mini)To (thermal printer)Why
D8 (TX)RX / DINSerial data at 9600 baud
GNDGNDSignals need a shared reference — required
VINPrinter power, from the external PSU (not the D1 Mini)
5V / USBPowers the D1 Mini itself
GNDPSU (−)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

What I'd add next

⚠️ 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


Get the free Starter Kit →