CircuitPython

It's easy to use the thermal printer with CircuitPython (or Python) and the Adafruit CircuitPython Thermal Printer module.  This module allows you to easily write Python code that controls the printer, like printing text and barcodes (note right now bitmap printing is not supported by CircuitPython code).

CircuitPython Microcontroller Wiring

First wire up a thermal printer to your board with a serial connection exactly as shown on the previous pages for Arduino.  Be sure to supply a power supply to the printer which can provide 5-9V at about 1.5 to 2 amps of current. 

Remember too there are two ways to wire the printer, the simplest is just to connect the TX of your board to the RX of the printer--this allows you to print anything but not check the paper status:

  • Printer power positive (red wire) to 5-9V power supply positive.
  • Printer power ground (black wire next to red) to power supply negative / ground.
  • Printer RX (yellow) to board serial TX.
  • Printer ground (black wire next to yellow) to board ground / GND.

A more advanced option is to connect the printer's TX pin to your board's serial RX pin.  However be very careful to ensure your board supports a 5 volt serial input!  Many boards, like the Feather M0, do not support a 5V serial input and will be damaged!  You can however create a simple voltage divider with a resistor divider circuit to knock the printer's 5V output down to a safer 3.3V level:

  • Printer power positive (red wire) to 5-9V DC power supply positive.
  • Printer power ground (black wire next to red) to power supply negative / ground.
  • Printer RX (yellow) to board serial TX.
  • Printer ground (black wire next to yellow) to board ground / GND.
  • Printer TX to one side of a 2.2KΩ resistor.
  • One side of a 3.3KΩ resistor to the opposite side of the 2.2KΩ resistor. Other side of the 3.3KΩ resistor to board ground / GND.
  • Board RX to the junction of the 3.3KΩ and 2.2KΩ resistor (i.e. output of the voltage divider).
Again be very careful connecting the printer TX (green wire) to your board! As mentioned above you can damage your board if it does not support 5 volt inputs. When in doubt, leave the green wire disconnected! You can still print without the green wire, you only lose the ability to read if paper is present.

 Python Computer Wiring

Since there's dozens of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported.

Here you have two options: An external USB-to-serial converter, or the built-in UART on the Pi's TX/RX pins. Here's an example of wiring up the USB-to-serial converter:

  • USB TX to printer RX
  • USB Ground to printer Ground

Here's an example using the Pi's built-in UART:

  • Pi GND to printer Ground (black wire)
  • Pi TXD to printer RX (yellow wire)

If you want to use the built-in UART, you'll need to disable the serial console and enable the serial port hardware in raspi-config. See the UART/Serial section of the CircuitPython on Raspberry Pi guide for detailed instructions on how to do this.

If you want to be able to check the printer paper status, you can create a simple voltage divider with a 2.2KΩ and 3.3KΩ resistor circuit to knock the printer's 5V output down to a safer 3.3V level:

  • Printer RX (yellow) to Pi serial TXD.
  • Printer ground (black wire next to yellow) to Pi GND.
  • Printer TX to one side of a 2.2KΩ resistor.
  • One side of a 3.3 KΩ resistor to the opposite side of the 2.2KΩ resistor. Other side of the 3.3KΩ resistor to Pi GND.
  • Pi RXD to the junction of the 3.3KΩ and 2.2KΩ resistor (i.e. output of the voltage divider).

You can use the same technique with the USB-to-serial cable:

  • USB ground to breadboard ground rail.
  • Printer RX (yellow) to USB TX (green).
  • Printer ground (black wire next to yellow) to ground rail.
  • Printer TX to one side of a 2.2KΩ resistor.
  • One side of a 3.3 KΩ resistor to the opposite side of the 2.2KΩ resistor. Other side of the 3.3KΩ resistor to ground rail.
  • USB RX to the junction of the 3.3KΩ and 2.2KΩ resistor (i.e. output of the voltage divider).

CircuitPython Installation of Thermal Printer Library

If you're using a CircuitPython microcontroller, you'll need to install the Adafruit CircuitPython Thermal Printer library on your CircuitPython board.

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  Our introduction guide has a great page on how to install the library bundle for both express and non-express boards.

Remember for non-express boards like the Trinket M0, Gemma M0, and Feather/Metro M0 basic, you'll need to manually install the necessary libraries from the bundle:

  • adafruit_thermal_printer

You can also download the adafruit_thermal_printer folder from its releases page on Github.

Before continuing make sure your board's lib folder or root filesystem has the adafruit_thermal_printer folder copied over.

Python Installation of GPS Library

If you're using a Raspberry Pi or other computer with Python, you'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python. This may require verifying you are running Python 3. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!

Once that's done, from your command line run the following command:

Download: file
sudo pip3 install adafruit-circuitpython-thermal-printer

Firmware Version and Baud Rate

Before you can use the printer module you must determine the firmware version and baud rate of the printer.  This is easy to find out by printing a test page from the printer as described on the first test page, hold the printer button as power is applied.  Print out the test page and take note of these values printed at the bottom:

  • Baudrate - Remember this value, typically 19200 or 9600.
  • Version - Take note of this value too, it's a value like 2.2, 2.64, 2.68, etc.  You will use the version to pick the appropriate module for interacting with the printer.

Usage

If you're using a CircuitPython microcontroller, connect to the board's serial REPL so you are at the CircuitPython >>> prompt.  If you're using a computer like the Raspberry Pi, bring up a REPL at the command prompt by typing python3.  (On some systems, python may run Python 3 - just make sure you're not using Python 2, as it isn't supported.)

To demonstrate the usage of the sensor we'll initialize it and print some text from the REPL.

First you must import the necessary modules to initialize the hardware serial connection to the printer.  These commands will vary depending on your hardware - choose the appropriate set:

Download: file
# On a CircuitPython microcontroller:
import board
import busio
uart = busio.UART(board.TX, board.RX, baudrate=19200)
Download: file
# On the Raspberry Pi with the USB-to-serial converter:
import serial
uart = serial.Serial("/dev/ttyUSB0", baudrate=19200, timeout=3000)
Download: file
# On the Raspberry Pi with built-in UART:
import serial
uart = serial.Serial("/dev/serial0", baudrate=19200, timeout=3000)

Notice the baud rate of the serial connection is specified with the baudrate keyword.  For most printers they'll use a rate of 19200 baud, however other printers might be configured to use a different rate like 9600 baud.  Use the baud rate you saw printed on the test page of your printer!

Also be aware CircuitPython currently requires bi-direction UART connections so even if you don't have the board RX pin hooked up (as recommended) you must keep the RX pin disconnected and ignore using it in your project.

Create ThermalPrinter Class

Next you'll need to import the thermal printer module and call a function to get the right class depending on the version of your printer firmware.  Be sure you've found the exact version number for your printer by following the steps mentioned above and on the previous test page!

Download: file
import adafruit_thermal_printer
ThermalPrinter = adafruit_thermal_printer.get_printer_class(2.69)

Notice you call the get_printer_class function from within the adafruit_thermal_printer module.  You must pass this function the version of the thermal printer that you're using and it will internally find the right class to import and use in your code.  In this example we're specifying a printer with version 2.69 firmware, but be sure to specify your printer's version!

The result is a class which you can immediately initialize:

Initialize ThermalPrinter

Now construct an instance of the ThermalPrinter class:

Download: file
printer = ThermalPrinter(uart)

Notice you must pass in the serial UART connection that was previously constructed.

Be aware it will take from a half to even 5 seconds for the printer to be created and initialize itself and warm up.  You can optionally specify auto_warm_up=False as a keyword and manually call the warm_up function to control when this warm-up time occurs if needed in your application (or you are confused why your code takes so long to start up).

Test Page Print

Now you're ready to print!

Try printing a full test page with the test_page function:

Download: file
printer.test_page()

You should see the printer test page print out.

You can advance the paper forward a number of lines with the feed function, try feeding 2 lines to make some space:

Download: file
printer.feed(2)

Now print a small line of text with the print function and feed a few lines to move it out of the printer to read:

Download: file
printer.print('Hello from CircuitPython!')
printer.feed(2)

Printer Fonts

There are a few properties you can use to adjust how text is printed.  Each of these can be set to a True value to enable, or a False value to disable:

  • bold - Print bold text.
  • inverse - Print inverted (white on black) text.
  • upside_down - Print upside down text (might not work on all versions of printers).
  • double_height - Double height size text.
  • double_width - Double width size text.
  • strike - Strike-through text (again might not work on all versions of printers).

Try turning on bold text and printing a line:

Download: file
printer.bold = True   # Turn on bold
printer.print('This is bold text!')
printer.bold = False  # Turn off bold
# Feed lines to make visible:
printer.feed(2)

There are a few properties you can set to special values to further control text printing:

  • underline - This controls underline printing and can be None (off), adafruit_thermal_printer.UNDERLINE_THIN, or adafruit_thermal_printer.UNDERLINE_THICK.
  • size - This controls the size of text and can be adafruit_thermal_printer.SIZE_SMALL, adafruit_thermal_printer.SIZE_MEDIUM, or adafruit_thermal_printer.SIZE_LARGE.  The default is small.
  • justify - This controls the justification or location of printed text and can be adafruit_thermal_printer.JUSTIFY_LEFT, adafruit_thermal_printer.JUSTIFY_CENTER, or adafruit_thermal_printer.JUSTIFY_RIGHT.  The default is justify left.

For example to print thick underlined, medium text, with center justification:

Download: file
printer.underline = adafruit_thermal_printer.UNDERLINE_THICK
printer.size = adafruit_thermal_printer.SIZE_MEDIUM
printer.justify = adafruit_thermal_printer.JUSTIFY_CENTER
printer.print('Medium center!')
# Reset back to normal printing:
printer.underline = None
printer.size = adafruit_thermal_printer.SIZE_SMALL
printer.justify = adafruit_thermal_printer.JUSTIFY_LEFT
# Feed lines to make visible:
printer.feed(2)

Print Barcodes

Finally you can print a barcode with the print_barcode function.  Each printer supports a different type and format of barcode so consult the product sheet in the downloads section for each type.  However here's an example of printing a UPC A barcode with value '123456789012':

Download: file
printer.print_barcode('123456789012', printer.UPC_A)
printer.feed(2)

The first parameter to print_barcode is a string that defines the barcode value (this varies depending on the type of barcode, a UPC A code is 13 digits).  The second parameter is the type of the barcode, which again is dependent on the printer firmware.  Typical values you might use include:

  • printer.UPC_A
  • printer.UPC_E
  • printer.EAN13
  • printer.EAN8
  • printer.CODE39
  • printer.ITF
  • printer.CODABAR
  • printer.CODE93
  • printer.CODE128

Check Paper

If you've connected the RX pin of your board to the printer TX (again be very careful to make sure your board supports a 5V serial RX--many don't!) you can query paper status with the has_paper function that returns True or False if there is paper present:

Download: file
printer.has_paper()

That's all there is to using the thermal printer with CircuitPython!

A complete demo of the usage is in the thermal_printer_simpletest.py demo in the library.

If you're running thermal_printer_simpletest.py on the Raspberry Pi (or any computer), you'll have to make some changes.

On the Raspberry Pi, comment out the uart = busio(...) line, and uncomment the import serial and uart = serial.Serial(...) lines, changing /dev/ttyUSB0 to the appropriate serial port.

Unless you used a voltage divider to hook up the printer TX line, make sure you comment out the paper check code:

Download: file
# Check if the printer has paper.  This only works if the RX line is connected
# on your board (but BE CAREFUL as mentioned above this RX line is 5V!)
#if printer.has_paper():
#    print('Printer has paper!')
#else:
#    print('Printer might be out of paper, or RX is disconnected!')

  Now you can run the program with the following command:

Download: file
python3 thermal_printer_simpletest.py
# Simple demo of printer functionality.
# Author: Tony DiCola
import board
import busio

import adafruit_thermal_printer

# Pick which version thermal printer class to use depending on the version of
# your printer.  Hold the button on the printer as it's powered on and it will
# print a test page that displays the firmware version, like 2.64, 2.68, etc.
# Use this version in the get_printer_class function below.
ThermalPrinter = adafruit_thermal_printer.get_printer_class(2.69)

# Define RX and TX pins for the board's serial port connected to the printer.
# Only the TX pin needs to be configued, and note to take care NOT to connect
# the RX pin if your board doesn't support 5V inputs.  If RX is left unconnected
# the only loss in functionality is checking if the printer has paper--all other
# functions of the printer will work.
RX = board.RX
TX = board.TX

# Create a serial connection for the printer.  You must use the same baud rate
# as your printer is configured (print a test page by holding the button
# during power-up and it will show the baud rate).  Most printers use 19200.
uart = busio.UART(TX, RX, baudrate=19200)

# For a computer, use the pyserial library for uart access.
# import serial
# uart = serial.Serial("/dev/serial0", baudrate=19200, timeout=3000)

# Create the printer instance.
printer = ThermalPrinter(uart, auto_warm_up=False)

# Initialize the printer.  Note this will take a few seconds for the printer
# to warm up and be ready to accept commands (hence calling it explicitly vs.
# automatically in the initializer with the default auto_warm_up=True).
printer.warm_up()

# Check if the printer has paper.  This only works if the RX line is connected
# on your board (but BE CAREFUL as mentioned above this RX line is 5V!)
if printer.has_paper():
    print('Printer has paper!')
else:
    print('Printer might be out of paper, or RX is disconnected!')

# Print a test page:
printer.test_page()

# Move the paper forward two lines:
printer.feed(2)

# Print a line of text:
printer.print('Hello world!')

# Print a bold line of text:
printer.bold = True
printer.print('Bold hello world!')
printer.bold = False

# Print a normal/thin underline line of text:
printer.underline = adafruit_thermal_printer.UNDERLINE_THIN
printer.print('Thin underline!')

# Print a thick underline line of text:
printer.underline = adafruit_thermal_printer.UNDERLINE_THICK
printer.print('Thick underline!')

# Disable underlines.
printer.underline = None

# Print an inverted line.
printer.inverse = True
printer.print('Inverse hello world!')
printer.inverse = False

# Print an upside down line.
printer.upside_down = True
printer.print('Upside down hello!')
printer.upside_down = False

# Print a double height line.
printer.double_height = True
printer.print('Double height!')
printer.double_height = False

# Print a double width line.
printer.double_width = True
printer.print('Double width!')
printer.double_width = False

# Print a strike-through line.
printer.strike = True
printer.print('Strike-through hello!')
printer.strike = False

# Print medium size text.
printer.size = adafruit_thermal_printer.SIZE_MEDIUM
printer.print('Medium size text!')

# Print large size text.
printer.size = adafruit_thermal_printer.SIZE_LARGE
printer.print('Large size text!')

# Back to normal / small size text.
printer.size = adafruit_thermal_printer.SIZE_SMALL

# Print center justified text.
printer.justify = adafruit_thermal_printer.JUSTIFY_CENTER
printer.print('Center justified!')

# Print right justified text.
printer.justify = adafruit_thermal_printer.JUSTIFY_RIGHT
printer.print('Right justified!')

# Back to left justified / normal text.
printer.justify = adafruit_thermal_printer.JUSTIFY_LEFT

# Print a UPC barcode.
printer.print('UPCA barcode:')
printer.print_barcode('123456789012', printer.UPC_A)

# Feed a few lines to see everything.
printer.feed(2)
This guide was first published on Sep 02, 2012. It was last updated on Sep 02, 2012. This page (CircuitPython) was last updated on Apr 23, 2019.