You need to setup xstow in your home before following this tutorial:
Using xstow for local installations
If you don't have it, create the following directory
mkdir ~/local/src/gitlab/arcoslab -p
cd ~/local/src/gitlab/arcoslab
git clone https://gitlab.com/arcoslab/pt1230
cd pt1230
git checkout cable_labelling
sudo apt install libfreetype6-dev libfontconfig1-dev python3-numpy
cd ~/local/src/gitlab/arcoslab/pt1230
make
export PREFIX=${HOME}/local/DIR/pt1230
make install
cd ~/local/DIR/
xstow pt1230
sudo adduser _user_ lp
It is necessary to configure the permisions of the port correctly. Make sure that they are set properly so that pt1230 can access it without problems.
textlabel --font "Times New Roman" "test" | pt1230 -d /dev/usb/lp1 -b
This generates a bitmap image for “test” and it will be sent to the printer using the pt1230 command.
If you want to only get the bitmap image on screen use:
textlabel --font "Times New Roman" "test"
text-multi-line -f "Courier New:bold" -s 100 "line1
line2
line3
line4" | pt1230 -d /dev/usb/lp1 -b -c
This command generates a bitmap image with the text “line1 line2 line3 line4” separated in 4 lines and each centered. It automatically adjusts there size. The result is sent to the printer with pt1230 command.
“-c” option of pt1230 command avoids the printer to “feed” the tape. It conserves tape because for each print it normally feeds a lot of empty tape to allow to cut it correctly. Use the “-c” option as much as possible before ending printing. Then “feed” at the last print to cut correctly.
For printing in vertical orientation use:
text-multi-line -d 10 -i -f "Courier New:bold" -s 100 "line1
line2
line3
line4" | pt1230 -d /dev/usb/lp1 -b
-i is for vertical, and -d 10 is for 10 pixels of spacing between lines
You can print barcodes with this labeler using:
bincodes -e 39 -b "1" "2343452345325452345" | line2bitmap
text-cable-label -s 25 -d 2.7 "text" | pt1230 -d /dev/usb/lp0 -b -c
bmtoa -char 01 filename.xbm
bmtoa -char 01 filename.xbm | pt1230 -d /dev/usb/lp1 -b -c
-Usage example:
auto-cable -i /path/to/file/in.txt -o labelsOut
Make sure to write inside the in.txt file the cables in the following way, for example:
test: 10A, 18awg
You can also print several labels for the same cable:
test1, test2: 10A, 18awg
If you want to print for more than one cable:
test1, test2, test3: 10A, 18awg
test4: 10A, 11awg
Note: this program creats a bash executable file. For the labels to be printed you have to execute the file specifing the location of the usb port to wich the printer is conected. For example:
./labelsOut /dev/usb/lp1
pip install xrld
pip3 install pandas
pip install openpyxl
For this program the input file is a xlsx with the first column being the text that you want to print and the second column the cable. For example:

Several issues came up during real-world use that aren't covered above. These are the adjustments and checks worth keeping in mind.
/dev/usb/lp0, not lp1The examples in this tutorial use /dev/usb/lp1, but in practice the node is usually /dev/usb/lp0. Check which one you have before printing:
ls -l /dev/usb/lp*
Use whichever one actually exists. If you point at a node that doesn't exist (for example lp1 when only lp0 is present), pt1230 returns Failed to open printer device node.
lsusb | grep -i brother
The Brother device 04f9:202c (PT-1230PC) should appear. To see the kernel messages when you plug it in:
sudo dmesg | tail -15
This is the hardest problem to spot. CUPS claims the USB printer exclusively, unbinds the usblp driver, and removes the /dev/usb/lp0 node right when you try to print. In dmesg you'll see the pattern:
usblp 3-1:1.0: usblp0: USB Bidirectional printer ...
usblp0: removed
Stopping the service isn't enough if cupsd is already running. You need to kill the process and prevent it from restarting:
sudo systemctl stop cups.service cups.socket
sudo systemctl mask cups.service cups.socket
sudo pkill -9 cupsd
Confirm no process remains:
ps aux | grep cupsd | grep -v grep
(It should return nothing.) To use CUPS normally again in the future: sudo systemctl unmask cups.service cups.socket.
The sudo adduser _user_ lp step adds your user to the lp group, but the node may show up as root root, in which case group membership doesn't help. Create a udev rule so the node belongs to the lp group:
echo 'SUBSYSTEM=="usbmisc", KERNEL=="lp0", ATTRS{idVendor}=="04f9", MODE="0660", GROUP="lp"' | sudo tee /etc/udev/rules.d/99-ptouch.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
Unplug and replug the printer. The node should end up as crw-rw---- root lp:
ls -l /dev/usb/lp0
Important: after adding yourself to the lp group, your current terminal session won't pick it up until you refresh your groups. Log out and back in (or reboot), or use newgrp lp in the current terminal. Check with id that lp appears in your active groups. If id doesn't show lp, you'll still need sudo even when the node is set correctly.
To print with sudo (if you haven't refreshed your groups yet), use the full path, because pt1230 lives in ~/local/bin and isn't on root's PATH:
sudo /home/<user>/local/bin/pt1230 -d /dev/usb/lp0 -b -c -f file.bin
Exporting the PATH in a terminal only lasts that session. When you open a new terminal, textlabel / pt1230 / text-cable-label give "command not found". To make it persistent, add it to ~/.bashrc:
echo 'export PATH="$HOME/local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
The same applies to any PYTHONPATH or CMAKE_LIBRARY_PATH you need permanently.
The tools render with FontConfig. If the font name doesn't resolve, it falls back to a substitute font and may print zeros (a blank label) instead of text. "Times New Roman" is not included with Linux by default.
Check which font actually resolves:
fc-match "Times New Roman"
If it returns something other than a Times / Liberation file, it isn't installed. Two options:
--font "Liberation Serif".sudo apt install ttf-mscorefonts-installer (you have to accept the license and verify the download completes), then sudo fc-cache -f.Before printing, always confirm that fc-match "<font>" returns the expected file and not a fallback.
text-cable-label (prints zeros)The text-cable-label script has a bug: it wraps the font name in literal quotes when calling textlabel. Since subprocess passes arguments verbatim (no shell involved), FontConfig receives "Times New Roman" with the quotes included, can't resolve it, falls back to a substitute font, and the label comes out blank.
In the get_max_length function, change:
# before
bytes_result=check_output(["textlabel","--font", "\""+str(self.font)+"\"", "--width", str(self.each_line_width), line])
# after
bytes_result=check_output(["textlabel","--font", str(self.font), "--width", str(self.each_line_width), line])
Optional but recommended: change the default font in __init__ from "Times New Roman" to "Liberation Serif" so it works without installing the Microsoft fonts.
text-cable-labelWhen pt1230 fails and closes the pipe, text-cable-label raises a BrokenPipeError with a traceback. It's a symptom, not the cause (fix the reason pt1230 is failing first). If you want the script to exit cleanly instead of showing the traceback, add this after the import lines:
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)