Skip to content

LW5 Raster Protocol

The wire protocol introduced with the LabelWriter 5xx generation — LabelWriter 550, 550 Turbo, and 5XL. A clean break from the classic LabelWriter raster protocol: an explicit job header and trailer, per-label ESC D block with a 12-byte preamble in front of an unframed raster payload, and a 32-byte status reply with NFC-derived media diagnostics.

The classic LabelWriter raster predecessor it supersedes is documented separately in LW raster. The two are not wire-compatible.

USB topology

Standard USB Printer-class device on Vendor ID 0x0922 (DYMO / Sanford). Per-model PIDs are listed on the Hardware page.

Configuration 1
  Interface 0 — Printer class (bInterfaceClass 0x07)
    Endpoint OUT  Bulk    (print data + commands)
    Endpoint IN   Bulk    (32-byte status replies)

LabelWriter 550 Turbo and 5XL additionally expose a 10/100 Mbit Ethernet interface; the byte stream is identical.

Head geometry: 672 addressable dots on the 550 / 550 Turbo, 1248 on the 5XL. All chassis print at 300 dpi.

Opcode vocabulary

OpcodeBytesDescription
ESC @1B 40Restart print engine (reboot).
ESC *1B 24Restore factory settings.
ESC A1B 41 nnRequest print engine status (lock byte selects).
ESC C1B 43 nnSet print density (duty 0..200 %).
ESC D1B 44 …Start of label print data (12-byte header).
ESC e1B 65Reset print density to 100 %.
ESC E1B 45Feed to tear position (long form feed).
ESC G1B 47Feed to print head (short form feed).
ESC h1B 68Select text output mode.
ESC i1B 69Select graphics output mode.
ESC L1B 4C …Set maximum label length (continuous stock).
ESC n1B 6E N N N NSet label index (u32 LE).
ESC o1B 6F nnSet label count.
ESC Q1B 51End of print job (mandatory trailer).
ESC s1B 73 N N N NStart of print job (u32 LE Job ID).
ESC T1B 74 nnSet content type / speed mode.
ESC U1B 55Get SKU information (63-byte NFC dump).
ESC V1B 56Get engine version (34-byte HW/FW/PID block).

All multi-byte integers are little-endian.

A complete job is a single byte stream on the OUT endpoint, framed by a job header and trailer with one or more labels between them:

[print job header]
  ESC s <jobId u32>          — start of print job (mandatory)
  [ESC L]                    — set maximum label length (optional)
  ESC h | ESC i              — text vs graphics output mode
  [ESC T <speed>]            — content type / speed (optional)
  ESC C <duty>               — set print density

[per label, index 0..N-1]
  ESC n <index u32>          — label index
  ESC D <bpp> <align> <width u32> <height u32>
                             — start of label print data (12-byte header)
  <print data>               — width × ceil(height × bpp / 8) bytes
  ESC G                      — feed to print head (between labels)
  ESC E                      — feed to tear position (last label)

ESC Q                        — end of print job (mandatory)

ESC s and ESC Q are mandatory. The per-label structure (ESC n + ESC D + print data + ESC G or ESC E) repeats for every label in the job. Between labels, use ESC G; after the last label, use ESC E so the printed label reaches the tear bar. The ESC s job ID is echoed back in every status reply during the job so the host can correlate. See LabelWriter 550 Series Printers Technical Reference Manual, pp. 4–6, for the job-structure diagram.

The print data follows the ESC D header directly — no SYN prefix, no per-row framing, no length byte. Row width is fixed by the ESC D width field and head pin count.

Lock acquisition

Only one host may drive the print engine at a time. To take the lock, send ESC A 1 and read the 32-byte status reply: print-status byte 0 indicates whether the lock was granted (0..3) or whether another host holds it (5). A host that does not hold the lock can still issue ESC A 0 heartbeats but cannot send a job. The lock releases on ESC Q (Tech Ref, p. 7).

ESC @ — restart print engine

1B 40

Reboots the print engine. Any buffered data is lost. Intended for recovery when the engine is wedged; the soft path (ESC Q to release the lock) is preferred for a stuck job.

ESC * — restore factory settings

1B 24

Wipes user-tunable settings back to factory defaults.

The Tech Ref (p. 20) lists this command with mnemonic ESC * but hex 1B 24. 0x24 is ASCII $, not * (0x2A); the mnemonic-vs-byte discrepancy is a known inconsistency in the manual. The hex is authoritative on the wire.

ESC A — request print engine status

1B 41 <lock>

Three-byte form. The lock byte selects the request type:

lockPurpose
0No lock — heartbeat / status query
1Lock interface for printing (acquire before a job)
2Status query between labels in an active print job

The printer replies with 32 bytes on the IN endpoint:

OffsetFieldTypeNotes
0Print statusu8See sub-state table below.
1–4Job IDu32 LEEchoes the most recent ESC s. 0 when idle.
5–6Label indexu16 LEEchoes the current ESC n.
7Reservedu8Default 0.
8Print-head statusu80 ok · 1 overheated · 2 status unknown (default).
9Print densityu8Duty percent. 0 disables printing; 1..200 is the duty value.
10Main bay statusu8NFC media diagnostic — see table below.
11–22SKU numberchar × 1212-byte ASCII SKU of the inserted consumable. 0 = empty.
23–26Error IDu32 LE0 = no error; non-zero = error code.
27–28Label countu16 LERemaining labels on the inserted roll. 0 = empty.
29EPS statusu8Bit 0 = external power supply present. Bits 4–7 reserved.
30Print-head voltageu80 unknown · 1 ok · 2 low · 3 critically low · 4 too low for printing.
31Reservedu8Default 0xFF.
ValueMeaning
0Idle — lock held by this host.
1Printing.
2Error.
3Cancel.
4Printer just woke from standby.
5Status reply before the lock is granted to the requesting host (i.e. another host holds the lock, or the printer hasn't decided).

Values 0..3 only appear once the lock has been granted to the host receiving the reply (Tech Ref, p. 13–14). Value 5 is how the printer signals "your ESC A 1 request did not give you the lock."

Main bay status (byte 10)

NFC-derived diagnostic of the loaded roll. The 550 chassis reads an NFC tag embedded in every genuine spool; non-genuine media is detected here and printing is refused.

CodeMeaning
0Bay status unknown.
1Bay open; media presence unknown.
2No media present.
3Media not inserted properly.
4Media present — status unknown.
5Media present — empty.
6Media present — critically low.
7Media present — low.
8Media present — ok.
9Media present — jammed.
10Media present — counterfeit.

Code 10 is surfaced by firmware when the inserted spool fails NFC validation. The host cannot bypass this — the check happens during cassette insertion, independent of the wire protocol. See Label Length, Tech Ref p. 7: "Only authentic Dymo labels with a valid NFC Tag can be used for printing."

ESC C — set print density

1B 43 <duty>

duty is the strobe duty cycle as a percentage. Range 0..200, default 100. 0 disables printing; lower values produce lighter output, higher values darker. The setting persists until reset by ESC e, a power cycle, or the end of the job.

ESC D — start of label print data

1B 44 <bpp> <align> <width0..3> <height0..3> <print data>

12-byte fixed header followed immediately by the raster payload.

FieldBytesMeaning
bpp1Bits per pixel. Default 1.
align1Print alignment. 2 = bottom (the only documented value).
width4 LENumber of raster lines along the feed direction (u32).
height4 LENumber of dots per raster line, across the head (u32).
print datawidth × ceil(height × bpp / 8) bytes, contiguous.

Axis convention per the Tech Ref p. 12 diagram: width is the feed-direction line count; height is the cross-head dot count. This is the opposite of the natural "width × height" reading of a printed label.

The most significant bit of the first print-data byte is the lower pixel of the first line (dot 0 of the head is at the bottom). Bytes per line is computed as roundup(height × bpp / 8). The control electronics do not validate that height matches the installed head width — the host is responsible for sending only as many bytes per line as the head can address (84 on a 672-dot head, 156 on the 1248-dot 5XL).

ESC e — reset print density

1B 65

Resets the print density to the default 100 %.

ESC E — feed to tear position

1B 45

Advances the most recently printed label to a position where it can be torn off, placing the next label beyond the starting print position. The firmware automatically reverse-feeds when the next label begins printing. Use ESC E for the last label of a job; for inter-label feeds inside a multi-label job, use ESC G so the firmware can skip the reverse-feed step (Tech Ref, p. 7).

ESC G — feed to print head

1B 47

Short form feed: advances the next label into print position. The previously printed label may still be partially inside the printer and cannot be torn off — ESC G is for multi-label jobs where inter-label tear-off is not wanted. Use ESC E instead when the label must reach the tear bar.

ESC h / ESC i — output mode

1B 68    — select text mode (default)
1B 69    — select graphics output mode

Text mode optimises for text printing; graphics mode prints with settings tuned for graphics and barcodes, at potentially reduced print speed. Sent once per job, in the print job header.

ESC L — set maximum label length

1B 4C …

Selects the print engine mode between normal label stock and continuous label stock. Normal stock is the default and the label length is taken from the NFC tag of the inserted roll; ESC L is only needed when overriding to continuous mode.

The parameter format is not specified in the Tech Ref (p. 11). For authentic media the length comes from NFC, so ESC L is rarely needed in practice.

ESC n — set label index

1B 6E <index0..3>

4-byte little-endian label index. Sent before each label's ESC D block. The first label of a job is index 0; subsequent labels increment. The current index is echoed back in status-reply bytes 5–6 so the host can track which label is being printed.

ESC o — set label count

1B 6F <count>

Single-byte count 0..255. Overrides the on-printer remaining- labels counter. The Tech Ref (p. 20) documents the command but does not specify the use case beyond "Sets label count."

ESC Q — end of print job

1B 51

Mandatory job trailer. The print engine releases its lock and begins accepting jobs from other hosts on receipt. Every job must end with ESC Q.

ESC Q also serves as a soft-recovery primitive: sending it at any time releases the host's print lock and returns the engine to an idle state without losing power-on calibration.

ESC s — start of print job

1B 73 <jobId0..3>

Mandatory job header. 4-byte little-endian Job ID; the value is host-chosen and is echoed back in status-reply bytes 1–4 throughout the job. Any 32-bit value is acceptable.

ESC T — set content type

1B 74 <speed>
speedMode
0x10Normal speed (default)
0x20High speed

Optional. Selects the print speed mode; affects the print head duty cycle. Not all label rolls support the high-speed mode (Tech Ref, p. 8 — the LW 5XL does not support high speed at all).

ESC U — get SKU information

1B 55

Retrieves the NFC dump of the inserted consumable. The printer replies with a 63-byte structure (Tech Ref, pp. 16–19):

OffsetFieldTypeNotes
0–1Magicu16 LE0xCAB6 — validates the response.
2Versionu8Currently '0'.
3Lengthu8Payload length.
4–5CRCu16 LECRC over payload.
8–19SKU numberchar × 12ASCII SKU.
20Brand IDu80x00 = DYMO, 0x01..0xFF undefined.
21Regionu80xFF = global.
22Material typeu80x00 card · 0x01 clear · 0x02 durable · 0x03 paper · 0x04 permanent · 0x05 plastic · 0x06 removable · 0x07 time-exp.
23Label typeu80x00 continuous · 0x01 die · 0x02 card.
24Label colouru80x00 clear · 0x01 white · 0x02 pink · 0x03 yellow · 0x04 green · 0x05 blue.
25Content colouru80x00 black · 0x01 red/black.
26Marker typeu8Marker / cut-edge geometry; values 0x00..0x03.
27Reservedu8
28–29Marker pitchu16 LELength in mm.
30–31Marker 1 widthu16 LELength in mm.
32–33Marker 1 to start of labelu16 LELength in mm.
34–35Marker 2 widthu16 LELength in mm.
36–37Marker 2 offsetu16 LELength in mm.
38–39Vertical offsetu16 LELength in mm.
40–41Label lengthu16 LELength in mm. 0 / 0xFFFF for continuous stock.
42–43Label widthu16 LELength in mm.
44–45Printable area H. offsetu16 LELength in mm.
46–47Printable area V. offsetu16 LELength in mm.
48–49Liner widthu16 LELength in mm.
50–51Total label countu16 LELabels on a full roll.
52–53Total lengthu16 LERoll length in mm.
54–55Counter marginu16 LEUsed by the printer to compute labels remaining.
56Counter strategyu80x00 = count up from 0x0000; 0x01 = count down from 0xFFFF - amount - margin.
57–59Reserved
60–61Production dateASCII × 2DDYY format.
62–63Production timeASCII × 2HHMM format.

The Marker / Counter Strategy fields cover both die-cut and continuous variants; many fields are 0 / 0xFFFF on continuous stock. The byte layout for fields after byte 27 is described as inclusive ranges in the Tech Ref (e.g. "Byte 28 to Byte 29 — Marker Pitch") and the response is documented as 63 bytes total despite the table extending to offset 63 (Tech Ref, p. 16: "the following is the 63-Byte response to ESC U").

ESC V — get engine version

1B 56

Retrieves the hardware / firmware identity block. The printer replies with 34 bytes (Tech Ref, p. 20):

OffsetFieldTypeNotes
0–15Hardware versionchar × 16UTF-8 string, right-padded with 0x00.
16–19FW kindchar × 4"FWAP" = application, "FWBL" = bootloader.
20–23Major versionchar × 4ASCII version string.
24–27Minor versionchar × 4ASCII version string.
28–31Release datechar × 4MMYY format.
32–33USB PIDu16 LEThis chassis's product ID.

References

  • LabelWriter® 550 Series Printers Technical Reference Manual, for LabelWriter 550 / 550 Turbo / 5XL, Sanford L.P., 2021. The authoritative byte-level reference. Cited inline by page; not redistributed.