Display Data Format

Shared by both OpenDisplay Basic and OpenDisplay Flex standards

Overview

This page explains how image data is encoded into bytes for transmission to OpenDisplay devices. The encoding format depends on the color scheme configured for the display. Understanding this format is essential for implementing custom clients or debugging image transfer issues.

The image encoding format is identical for both OpenDisplay Basic and OpenDisplay Flex standards. However, the transmission protocols differ:

Pixel Order: Pixels are processed row by row, from top to bottom, left to right. Each row is encoded completely before moving to the next row.
Direct Writing: The image data format is designed to allow direct writing to the e-paper display (EPD) without requiring the full image to be stored in RAM or flash memory. Data can be written to the EPD controller as it is received, enabling efficient memory usage even for large displays.

Color Scheme 0: Monochrome (B/W)

Encoding: 1 bit per pixel, 8 pixels per byte
Colors: Black (0) or White (1)
Data Size: (width × height) ÷ 8 bytes

How It Works

Each pixel is represented by a single bit. White pixels set the bit to 1, black pixels set it to 0. Bits are packed into bytes from left to right, with the most significant bit (MSB) representing the leftmost pixel.

Example: 8 pixels in a row

W
B
W
W
B
B
W
B
Byte:
1
0
1
1
0
0
1
0
0xB6
(10110110 binary = 182 decimal = 0xB6 hex)

Color Scheme 1: B/W + Red

Encoding: Bitplanes, 1 bit per pixel per plane, 8 pixels per byte per plane
Colors: Black, White, Red
Data Size: ((width × height) ÷ 8) × 2 bytes (two planes)

How It Works

This scheme uses two bitplanes (planes). Plane 1 encodes black/white information, and Plane 2 encodes red information. The final color is determined by combining both planes:

Data is sent as: All Plane 1 bytes, then all Plane 2 bytes

Example: 8 pixels in a row

W
B
R
W
R
B
W
B
Plane 1 (B/W):
1
0
1
1
1
0
1
0
0xB6
Plane 2 (Red):
0
0
1
0
1
0
0
0
0x24

Final Data: 0xB6, 0x24 (Plane 1 first, then Plane 2)

Color Scheme 2: B/W + Yellow

Encoding: Bitplanes, 1 bit per pixel per plane, 8 pixels per byte per plane
Colors: Black, White, Yellow
Data Size: ((width × height) ÷ 8) × 2 bytes (two planes)

How It Works

Similar to Scheme 1, but Plane 2 encodes yellow instead of red:

Data is sent as: All Plane 1 bytes, then all Plane 2 bytes

Color Scheme 3: B/W + Red + Yellow

Encoding: 2 bits per pixel, 4 pixels per byte
Colors: Black (0), White (1), Yellow (2), Red (3)
Data Size: (width × height) ÷ 4 bytes

How It Works

Each pixel uses 2 bits to encode one of four colors. Pixels are packed left to right, with the leftmost pixel using bits 7-6, next pixel using bits 5-4, and so on.

Example: 4 pixels in a row

W
B
Y
R
Byte:
1
0
|
0
0
|
1
0
|
1
1
0x93
(W=01, B=00, Y=10, R=11 = 10010011 = 0x93)

Bit pairs (left to right): 01 (White), 00 (Black), 10 (Yellow), 11 (Red)

Color Scheme 4: 6-Color (B/W + Green + Blue + Red + Yellow)

Encoding: 4 bits per pixel, 2 pixels per byte
Colors: Black (0), White (1), Yellow (2), Red (3), Blue (5), Green (6)
Data Size: (width × height) ÷ 2 bytes

How It Works

Each pixel uses 4 bits (a nibble) to encode one of six colors. Two pixels fit in each byte, with the leftmost pixel in the upper nibble (bits 7-4) and the rightmost pixel in the lower nibble (bits 3-0).

Color Values

B
0
W
1
Y
2
R
3
BL
5
G
6

Visual Examples

Example 1: Black + White

B
W
Byte:
0
0
0
0
|
0
0
0
1
0x01
(B=0000 upper, W=0001 lower = 00000001 = 0x01)

Example 2: White + Red

W
R
Byte:
0
0
0
1
|
0
0
1
1
0x13
(W=0001 upper, R=0011 lower = 00010011 = 0x13)

Example 3: Yellow + Blue

Y
BL
Byte:
0
0
1
0
|
0
1
0
1
0x25
(Y=0010 upper, BL=0101 lower = 00100101 = 0x25)

Example 4: Red + Green

R
G
Byte:
0
0
1
1
|
0
1
1
0
0x36
(R=0011 upper, G=0110 lower = 00110110 = 0x36)

Example 5: All Colors (6 pixels)

B
W
Y
R
BL
G
Byte 1:
0
0
0
0
|
0
0
0
1
0x01
(B=0000, W=0001)
Byte 2:
0
0
1
0
|
0
0
1
1
0x23
(Y=0010, R=0011)
Byte 3:
0
1
0
1
|
0
1
1
0
0x56
(BL=0101, G=0110)

Complete Data: 0x01, 0x23, 0x56

Color Scheme 5: 4 Grayscale

Encoding: 2 bits per pixel, 4 pixels per byte
Colors: Black (0), Dark Gray (1), Light Gray (2), White (3)
Data Size: (width × height) ÷ 4 bytes

How It Works

Each pixel uses 2 bits to encode one of four grayscale levels. Pixels are packed left to right, similar to Scheme 3, with the leftmost pixel using bits 7-6, next pixel using bits 5-4, and so on.

Example: 4 pixels in a row

W
B
LG
DG
Byte:
1
1
|
0
0
|
1
0
|
0
1
0xE5
(W=11, B=00, LG=10, DG=01 = 11100101 = 0xE5)

Bit pairs (left to right): 11 (White), 00 (Black), 10 (Light Gray), 01 (Dark Gray)

Pixel Ordering

Pixels are always processed in row-major order: from top to bottom, left to right within each row.

Example: 4×4 Image

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Order: 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12 → 13 → 14 → 15

Byte Packing for Scheme 0 (1 bit/pixel)

Row 0: Pixel 0, Pixel 1, Pixel 2, Pixel 3 Row 1: Pixel 4, Pixel 5, Pixel 6, Pixel 7 Row 2: Pixel 8, Pixel 9, Pixel 10, Pixel 11 Row 3: Pixel 12, Pixel 13, Pixel 14, Pixel 15 Byte 0: Pixels 0-7 (Row 0: 0-3, Row 1: 4-7) Byte 1: Pixels 8-15 (Row 2: 8-11, Row 3: 12-15)

For bitplane schemes (1 and 2), all rows of Plane 1 are sent first, then all rows of Plane 2.

Implementation Notes

Transmission Protocols

While the image encoding format is identical for both standards, the transmission protocols differ. This section explains how image data is sent in each standard.

OpenDisplay Basic

In the Basic standard, image data is sent as part of the "New Image" response packet (0x82):

Packet Type: 0x82 Offset 0: packet_type (1 byte) = 0x82 Offset 1-2: image_length (2 bytes, uint16, little-endian) Offset 3 to (3+image_length-1): image_data (variable) Offset (3+image_length) to (6+image_length): poll_interval (4 bytes, uint32, little-endian)

See OpenDisplay Basic for complete packet specifications.

OpenDisplay Flex

In the Flex standard, image data is sent using the Direct Write protocol with chunking and compression support:

Start Command (0x0070)

Command: 0x00 0x70 Payload (uncompressed): - Width: 2 bytes (little-endian) - Height: 2 bytes (little-endian) - Color scheme: 1 byte - Refresh mode: 1 byte Payload (compressed): - Uncompressed size: 4 bytes (little-endian) - Compressed data: variable (up to 200 bytes in start command for BLE, up to 1000 bytes for TCP)

Data Command (0x0071)

Command: 0x00 0x71 Payload: Image data chunk - BLE: up to 230 bytes per chunk - TCP: up to 1000 bytes per chunk

End Command (0x0072)

Command: 0x00 0x72 Payload: Refresh mode flag (1 byte, optional) - 0x00: Full refresh (default) - 0x01: Fast/partial refresh

Maximum Packet Sizes

Transport Standard Maximum Chunk Size
BLE Basic ~200 bytes (wrapped in outer packet)
BLE Flex 230 bytes per chunk (0x0071 command)
TCP Basic Up to 8KB (wrapped in outer packet)
TCP Flex 1000 bytes per chunk (0x0071 command)

Compression

Both standards support zlib compression of image data:

See OpenDisplay Flex and BLE Communication Protocol for complete protocol specifications.