Controlling the Brother P-Touch Cube label maker from a computer

The Brother PTP300BT label maker is intended to be controlled using the official Brother P-Touch Design & Print iOS/Android app. The app has arbitrary limits on what you can print (1 text object and up to 3 preset icons), so I thought it would be a fun challenge to reverse engineer the protocol to print whatever I wanted.

Python code at the bottom if you want to skip the fine details.


Intitially I had a quick peek at the Android APK to see if there was any useful information inside. The code that handles the communication with the printer in Print&Design turned out to be a native library, but the app clearly prepares a bitmap image and passes it to this native library for printing. Bitmaps are definitely something we can work with.

View Makefile
# This makefile is set up to work with the Arduino bootloader
# Depending on your device, you may need to adjust the PROGRAMMER
# line to point to the right serial port.
# To use, just run "make flash" with an arduino connected
DEVICE = atmega328p
CLOCK = 8000000
PROGRAMMER = -c arduino -P /dev/ttyUSB0 -b57600
SOURCES = $(shell find -name '*.c' -or -name '*.cpp' -or -name '*.S')
View GDEPaper.h
#pragma once
// AVR
extern "C" {
#include <avr/io.h>
#define GD_PSR 0x00 // Panel settings
#define GD_PWR 0x01 // Power setting
#define GD_BTST 0x06 // Booster soft start
View Makefile
DEVICE = attiny13a
CLOCK = 1200000
PROGRAMMER = -c dragon_isp
SOURCES = $(shell find . -name '*.c' -or -name '*.cpp' -or -name '*.S')
AVRDUDE = avrdude $(PROGRAMMER) -p t13
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
COMPILE += -I -I. -I./lib/
COMPILE += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums



Allowing control without root privileges

# Create rule so the device can be controlled by any user
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="f055", ATTR{idProduct}=="05df", MODE="0666"' \
  | tee /etc/udev/rules.d/99-status-light.rules
View TimerModule.h
#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"
@interface TimerModule : NSObject <RCTBridgeModule>
#!/usr/bin/env python3
# Experiment: Replacing the LED in an infrared remote with a wired connection
# Details of the hardware/software implementation:
# I've hard-wired the crappy IR remote that came with a DVB-T RTL-SDR
# dongle into a GPIO pin on the Raspberry Pi. The infrared LED in the
# remote has been removed and replaced with a wire going to GPIO 3.
View How to

Note: this is an extract from Heyday's internal docs, written by me. Published as a Gist to share the love.

Authoring commits

We like sensible commit messages. There're a lot of good articles about writing great, useful commit messages, but here's the gist of what we like:

  • The single most important thing is: commit messages should explain why you are making the change.
  • Think, "what would future me want to know about this change?"
  • Avoid committing multiple sets of ideas/changes in the same commit: split them up.
  • Don't assume the reader understands what the original problem was.
View GridFieldStreamExportButton.php
* Improved GridFieldExportButton that streams CSV data to the client instead of building
* the entire CSV in memory and sending that (which doesn't work for large data sets).
class GridFieldStreamExportButton extends GridFieldExportButton