This project demonstrates how to interface a Thermal Printer with Raspberry Pi using hardware serial communication (UART) to print receipts containing logos, QR codes, barcodes, text, and graphical characters. The project uses the python-escpos library to control the thermal printer and send ESC/POS commands for various printing operations.
Project Tutorial: Circuit Digest - Thermal Printer Interfacing with Raspberry Pi
- Features
- Components Required
- About Thermal Printers
- Technical Specifications
- Circuit Diagram
- Prerequisites
- Installation
- Usage
- Code Examples
- Sample Receipt Output
- Troubleshooting
- Future Enhancements
- References
- Print formatted text with customizable fonts and sizes
- Generate and print QR codes
- Generate and print barcodes (CODE39, CODE128, UPC, etc.)
- Print images and logos
- Create professional receipts with alignment and styling
- Hardware serial communication via GPIO pins
- Support for ESC/POS commands
- Low power consumption and eco-friendly operation
| Component Name | Quantity | Description |
|---|---|---|
| Thermal Printer (MAXIM PNP-500) | 1 | ESC/POS compatible thermal printer |
| Raspberry Pi 3 or Raspberry Pi Zero | 1 | Main controller board |
| Jumper Wires (Male to Female) | As required | For connections |
| 9V 1A Power Adapter | 1 | Power supply for thermal printer |
| Thermal Paper Roll (57mm) | As required | Printing paper |
Note: The printer requires at least 6V to operate. Always check your printer's user manual for specific power requirements.
A thermal printer uses a heating head on thermal paper to produce images without requiring ink cartridges or ribbons. This makes them:
- Cost-effective: No consumables like ink or toner
- Eco-friendly: Minimal waste generation
- Quiet operation: Noise-free printing
- Fast: Quick monochromatic printing
- Durable: Print head life up to 50 km
- Compact: Small form factor ideal for embedded applications
Thermal printers are widely used in:
- Point of Sale (POS) systems
- Ticket counters
- Grocery stores
- Healthcare facilities
- Entertainment venues
- Corporate industries
| Specification | Details |
|---|---|
| Print Method | Thermal Direct Line Printing |
| Paper Width | 57 mm |
| Print Width | 48 mm |
| Resolution | 8 dots/mm (384 dots/line) |
| Print Speed | 50 mm/sec (Max: 80 mm/sec) |
| Character Size | 9Ă—17 dots, 12Ă—24 dots |
| Chinese Character Size | 12Ă—24 dots, 24Ă—24 dots |
| Interface | Serial (RS232C, TTL) / USB |
| Input Power | DC 5-9V / 12V |
| Operating Temperature | 0°C ~ 55°C |
| Operating Humidity | 10% ~ 80% |
| Dimensions | 76.8 Ă— 77.4 Ă— 47.6 mm (WĂ—DĂ—H) |
| Paper Roll Specification | Width: 58mm, Max diameter: 40mm |
| Thermal Printer | Raspberry Pi GPIO |
|---|---|
| RXD | GPIO 14 (TXD) |
| TXD | GPIO 15 (RXD) |
| GND | GND |
| VCC | 9V Power Supply |
| TDR | GND |
Important Notes:
- Cross-connect RX and TX pins (Printer RX → Pi TX, Printer TX → Pi RX)
- Connect TDR pin to GND if printer doesn't print
- Use dedicated 9V power supply for the printer
- Serial port:
/dev/serial0(ttyAMA0) - Default baud rate: 9600
- Raspberry Pi 3 or Raspberry Pi Zero
- Raspberry Pi OS (Raspbian) installed
- Internet connection for package installation
- SSH or direct terminal access
- Python 3.x
- pip package manager
- python-escpos library
Open the Raspberry Pi configuration tool:
sudo raspi-configNavigate to: Interfacing Options → Serial Port
- Serial Login Shell: No (Disable)
- Hardware Serial Port: Yes (Enable)
Reboot your Raspberry Pi:
sudo rebootCheck if serial port is enabled:
ls -l /devYou should see /dev/serial0 linked to ttyAMA0.
Install the library using pip:
sudo pip install python-escposOr for Python 3:
sudo pip3 install python-escpos- Connect the thermal printer to Raspberry Pi GPIO pins as per the circuit diagram
- Connect the 9V power adapter to the thermal printer
- Load thermal paper into the printer
from escpos.printer import Serial
# Initialize serial connection
p = Serial(
devfile='/dev/serial0',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.00,
dsrdtr=True
)p.text("Hello World\n")p.set(
underline=1,
align="left",
font="a",
width=2,
height=2,
density=3,
invert=0,
smooth=False,
flip=False,
)
p.textln("Hello World")# CODE39 barcode
p.barcode('123456', 'CODE39')
# CODE128 barcode
p.barcode('CIRCUITDIGEST', 'CODE128')p.qr("Circuit Digest", native=True, size=12)# Image width should not exceed 360 pixels
p.image("/home/pi/logo.png", impl="bitImageColumn")# Left align
p.set(align="left")
p.text("Left Aligned Text\n")
# Center align
p.set(align="center")
p.text("Center Aligned Text\n")
# Right align
p.set(align="right")
p.text("Right Aligned Text\n")from escpos.printer import Serial
from datetime import datetime
# Get current date and time
now = datetime.now()
dt_string = now.strftime("%b/%d/%Y %H:%M:%S")
# Initialize printer
p = Serial(
devfile='/dev/serial0',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.00,
dsrdtr=True
)
# Print logo
p.set(align="center", width=2, height=2)
p.image("/home/pi/logo.png", impl="bitImageColumn")
# Print header
p.set(align="left")
p.textln("CIRCUIT DIGEST\n")
p.text("AIRPORT ROAD\n")
p.text("LOCATION : JAIPUR\n")
p.text("TEL : 0141222585\n")
p.text("GSTIN : \n")
p.text("Bill No. : \n\n")
# Print date and time
p.set(width=2, height=2)
p.text("DATE : ")
p.text(dt_string)
p.textln("\n")
p.textln("CASHIER : ")
p.textln(" ===========================")
p.textln(" ITEM QTY PRICE GB")
p.textln(" --------------------------")
p.textln("IR SENSOR 2 30 60")
p.textln("ULTRASONIC 2 80 160")
p.textln("RASPBERRY 1 3300 3300")
p.textln("ADOPTOR 2 120 240")
p.textln(" --------------------------")
p.textln(" SUBTOTAL: 3760")
p.textln(" DISCOUNT: 0.8")
p.textln(" VAT @ 18%: 676.8")
p.textln(" ===========================")
p.textln(" BILL TOTAL: 4436.8")
p.textln(" TENDERD: 0.8")
p.textln(" BALANCE: 676.8")
p.textln(" --------------------------")
p.textln(" THANK YOU")
p.textln(" ===========================")
# Print QR code
p.set(align="center")
p.qr("Circuit Digest", native=True, size=12)
# Print barcode
p.textln("")
p.barcode('123456', 'CODE39')
# Cut paper (if supported)
p.cut()
print("Receipt printed successfully!")Problem: Printer doesn't print anything
Solutions:
- Check if hardware serial is enabled in raspi-config
- Verify power supply is properly connected (9V, 1A minimum)
- Connect TDR pin to GND
- Check RX/TX connections (should be crossed)
- Verify
/dev/serial0exists usingls -l /dev
Problem: Printed text is unreadable or contains strange characters
Solutions:
- Check baud rate matches (default: 9600)
- Verify parity, stop bits, and data bits settings
- Ensure proper encoding in Python code
Problem: Images don't appear on printed output
Solutions:
- Ensure image width doesn't exceed 360 pixels
- Use PNG or BMP format
- Try different implementation:
impl="bitImageColumn"orimpl="bitImageRaster" - Check image file path is correct
Problem: ModuleNotFoundError: No module named 'escpos'
Solutions:
sudo pip install python-escpos
# or
sudo pip3 install python-escposProblem: PermissionError: [Errno 13] Permission denied: '/dev/serial0'
Solutions:
sudo usermod -a -G dialout $USER
sudo reboot- Create dynamic receipt generation system
- Integrate with database for inventory management
- Add web interface for remote printing
- Implement network printing capabilities
- Create mobile app integration
- Add support for multiple font styles
- Implement automatic paper detection
- Create receipt templates library
The thermal printer uses ESC/POS (Epson Standard Code for Point of Sale) commands. The python-escpos library abstracts these commands for easier implementation.
| Function | Description |
|---|---|
text() |
Print text |
textln() |
Print text with newline |
set() |
Set text properties |
image() |
Print image |
qr() |
Print QR code |
barcode() |
Print barcode |
cut() |
Cut paper |
ln() |
Line feed |
Documentation: python-escpos Documentation
- Python-escpos GitHub Repository
- MAXIM PNP-500 User Manual
- ESC/POS Command Reference
- Raspberry Pi GPIO Documentation
- Raspberry Pi Projects
- Cost-effective: No ink or toner required
- Portable: Compact design suitable for mobile applications
- Easy integration: Simple serial communication
- Versatile: Supports text, images, barcodes, and QR codes
- Long-lasting: Print head life up to 50 km
- Low maintenance: Minimal upkeep required
- Retail: Point of sale receipts
- Healthcare: Patient reports and labels
- Transportation: Ticket printing
- Hospitality: Order receipts
- Logistics: Shipping labels
- Events: Entry tickets
- Banking: Transaction receipts
Feel free to contribute to this project by:
- Reporting bugs
- Suggesting new features
- Submitting pull requests
- Improving documentation
This project is open-source and available for educational and commercial purposes.
- Circuit Digest for the comprehensive tutorial
- python-escpos library developers
- Raspberry Pi Foundation
- MAXIM for thermal printer hardware
For questions, issues, or suggestions:
- Visit: Circuit Digest
- Tutorial: Thermal Printer Interfacing with Raspberry Pi
