How to Use a Thermal Printer With ESP32 (PNP-500 Tutorial for DIY Projects)

by ElectroScope Archive in Circuits > Microcontrollers

5921 Views, 73 Favorites, 0 Comments

How to Use a Thermal Printer With ESP32 (PNP-500 Tutorial for DIY Projects)

InvoicePrintedReducedSize.gif

If you’ve ever bought a coffee and gotten one of those skinny little receipts, you’ve already met a thermal printer. They’re everywhere: stores, hospitals, kiosks, even those shady “print your own movie ticket” machines. The magic? No ink, no toner, no messy cartridges. Just heat, special paper, and a whirring little mechanism that spits out text faster than you can say “transaction approved.”

And yes, you can hook one up to your ESP32. That’s what I did with the PNP-500 thermal printer, and in this post I’ll show you how it works, why it’s fun, and how to make it churn out text, barcodes, or even tiny QR codes. Honestly, it's among the most satisfying ESP32 projects I’ve built so far.

Supplies

  1. ESP32 Dev Board (any common devkit works)
  2. Thermal Printer (plus a compatible thermal paper roll)
  3. Power Supply for the Printer (5V and at least 2A, very important)
  4. Jumper Wires (male to female)
  5. Breadboard (optional but useful for prototyping)
  6. USB Cable (to power and program the ESP32)

Wiring the ESP32 to the Thermal Printer

ESP32-Thermal-Printer-Circuit-Diagram.png

Most thermal printers use simple serial communication and need just four wires:

  1. Printer VCC (5V) → 5V on your power supply
  2. Printer GND → GND on your ESP32 AND GND on your power supply
  3. Printer RX → ESP32 GPIO 17 (TX2)
  4. Printer TX → ESP32 GPIO 16 (RX2)

Important: do not power the printer from the ESP32 5V pin.

Do make use of a dedicated 5V / 2A supply and make sure both devices share a common ground.

Flash the Code

Plug the ESP32 into your computer and open the Arduino IDE.

Make sure you have the “ESP32 by Espressif Systems” board package installed.

Paste and upload the following code:

#include "Arduino.h"
#include "HardwareSerial.h"

HardwareSerial mySerial(2); // use UART2 (GPIO17 TX, GPIO16 RX)

void setup() {
Serial.begin(115200);
mySerial.begin(19200, SERIAL_8N1, 16, 17); // RX, TX

delay(2000);
// Print a test message
mySerial.println("=== Thermal Printer Test ===");
mySerial.println("Hello from the ESP32!");
mySerial.println("This is a thermal printer demo.");
}

void loop() {
// nothing here
}

Time to Power It Up

  1. We can now power the ESP32 over USB
  2. Power the thermal printer with the separate 5V 2A supply
  3. Check the paper roll to see if it's installed the right way (thermal side up)
  4. Open the Serial Monitor
  5. Reset the ESP32

If everything is wired correctly, the printer should immediately print:

=== Thermal Printer Test ===
Hello from the ESP32!
This is a thermal printer demo.

Print Custom Messages

You can customize the output by editing the strings in mySerial.println(...).

Example:

mySerial.println("WiFi password:\n12345678");
mySerial.println("--------");
mySerial.println("Have a nice day :)");

Plain ASCII characters are your safest bet, since many cheap printers do not support UTF-8.

Printing Images

Bitmap-To-Byte-Array-Conversion.png

If you want to get fancy and print actual images instead of just plain text, you totally can.

The easiest way is to convert a JPG/PNG into a byte array using the free online tool image2cpp (javi.github.io/image2cpp).

Here’s how:

  1. Go to the website and upload your image (keep it small, around 128×64 or 200×200 pixels)
  2. Choose “Transparent” for background and use Binary dithering
  3. Adjust the brightness/alpha threshold until the preview looks clean in black and white
  4. In Code output format, pick “Arduino code, single bitmap”
  5. Click Generate code - you’ll get a long byte array like
  6. const unsigned char imageData[] PROGMEM = { … };

Paste that array into your sketch and then send it to the printer like this:


for (int i = 0; i < sizeof(imageData); i++) {
mySerial.write(imageData[i]);
}

That’s literally it. The printer will draw the bitmap line-by-line.

Note: You might want to up your power supply to 6-9V to avoid faint images.

Helpful Formatting Tips

  1. mySerial.println() → prints text and adds a new line
  2. mySerial.print() → prints text without adding a line break
  3. mySerial.write(0x0A) → manually adds a line feed
  4. delay(ms) → pauses the code before sending the next thing

Want a bit of extra space after the last line?

for(int i = 0; i < 10; i++){
mySerial.write(0x0A);
}

Final Thoughts

TonyStarkPrinted.gif

That’s really all there is.

Wire up TX and RX, give the printer a solid 5V supply, and use Serial.println() as if you’re printing to a console. The only difference is that paper comes out of the other end.

Use this to print sensor data, fortunes, to-do lists, weird memes, or whatever randomly pops into your head.

If nothing prints at all → check power

If the output looks like random symbols → check the baud rate (19200 works for most)


If you're interested in a version that goes way deeper than this: ESP32 Thermal Printer