← Projects
raspberry-pi intermediate 3 hr ago ◯ 4 min read

Building a Raspberry Pi Powered Label Printer Automation Station with Brother QL and Python

Build time: 2-4 hours
Tools needed: Computer for initial setup/SSH, USB cable, label design/testing patience
Parts List
Raspberry PiBrother QLlabel printerbrother_qlPython automationinventory labelingCUPSthermal printerbin labeling

A maker shop generates an endless stream of things that want labels: filament spool contents and print date, bins of hardware sorted by thread size, parts drawers, cable ends, CNC bit cases, even QR codes linking a storage bin to its inventory entry. Doing this by hand with a consumer label maker is fine for a handful of labels, but it breaks down fast once you're labeling fifty bins or want labels generated automatically from a spreadsheet or inventory database. A Raspberry Pi paired with a Brother QL-series thermal label printer and the open-source brother_ql Python library turns labeling into something you script instead of something you do by hand with a tiny keypad.

Why the Brother QL Series

Brother's QL line (QL-700, QL-800, QL-820NWB, and similar) uses continuous or die-cut thermal label tape, prints at a respectable resolution without ribbons or ink to run out, and — critically for this build — has an open, well-documented raw printer protocol that the community-maintained brother_ql Python package implements directly. That means you can render a label as an image (text, barcode, QR code, whatever a Python imaging script can draw) and send it straight to the printer over USB or network without touching Brother's own driver stack or label-design software at all. This is the reason the QL series shows up in so many maker inventory projects instead of a generic label maker: the printer is a dumb, fast, well-behaved raster device once you're talking to it with the right library.

Setting Up the Pi

Any Raspberry Pi with USB and a few hundred megabytes of free storage handles this easily — a Pi Zero 2 W or Pi 4 is plenty, since rendering label bitmaps is a trivial image-processing task. Install Python 3, Pillow (for drawing text and shapes onto the label canvas), and the brother_ql package:

sudo apt update && sudo apt install python3-pip python3-pil pip3 install brother_ql

Connect the printer over USB first to get everything working reliably before attempting network printing — brother_ql supports both, but USB eliminates a whole class of networking troubleshooting while you're confirming the basic pipeline works. Identify your exact model string (e.g. QL-800) and label size (e.g. 29x90 for standard die-cut address-style labels, or a continuous width like 62 for roll tape) — both are required arguments to the brother_ql command-line tool and the Python API, and sending the wrong label-size profile is the single most common reason a first print comes out blank, shifted, or the wrong size.

Generating Labels Programmatically

The core workflow is: render a label as a Pillow image at the correct pixel dimensions for your tape width and printer DPI, then hand that image to brother_ql's raster conversion and send function. A minimal bin-label script pulls a part name and bin ID from a CSV or small SQLite inventory table, draws the text plus a QR code (using the qrcode Python package) linking back to that inventory row, and prints:

from PIL import Image, ImageDraw, ImageFont import qrcode from brother_ql.conversion import convert from brother_ql.backends.helpers import send from brother_ql.raster import BrotherQLRaster label = Image.new('L', (696, 271), 255) # 62mm continuous tape at 300dpi, example size draw = ImageDraw.Draw(label) draw.text((10, 10), "M3 Socket Cap Screws - 16mm", fill=0) qr = qrcode.make("https://inventory.local/bin/A14").resize((200, 200)) label.paste(qr, (480, 30)) qlr = BrotherQLRaster('QL-800') instructions = convert(qlr, [label], '62', cut=True) send(instructions=instructions, printer_identifier='usb://0x04f9:0x209b', backend_identifier='pyusb')

Wrap that logic in a small Flask app or a watched folder (a script that polls a CSV export or a shared directory for new label requests) and the Pi becomes a standing label station: anyone on the shop network drops a job in, and labels come out without anyone touching the Pi directly.

Batch Printing From a Spreadsheet or Inventory Tool

The most useful version of this isn't printing one label at a time — it's pointing the script at a CSV export from whatever you track inventory in (a spreadsheet, a self-hosted inventory app, a simple database) and having it iterate every row, render a label per row, and queue them all to print in sequence. Add a small delay or status check between sends on busier print runs, since the QL series buffers a reasonable number of jobs but will drop or error on a flood of near-simultaneous raw sends from a tight loop with no pacing.

Use CaseLabel ContentTrigger Filament spool IDMaterial, color, date opened, weightManual script run after opening a new spool Hardware bin labelingPart name, size, QR to inventory entryBatch run from inventory CSV export CNC/laser settings cardMaterial, speed/power/passes, bit usedPrinted alongside a cut job from G-code metadata Shipping/project labelsProject name, date, ownerWatched-folder trigger from a shared network drop

Once the pipeline is working, the Brother QL plus Pi combination quietly removes one of the more tedious parts of running an organized shop: labels stop being a chore you get behind on and become a byproduct of whatever system already tracks your inventory, printed consistently and correctly every time.