SegLCDLib
Loading...
Searching...
No Matches
LCD Controllers

Detailed specifications for each supported LCD controller. For quick selection, see Supported LCDs.


Transport Headers

SegTransport.h defines the abstract transport interfaces used by drivers and LCD models.

Arduino transport implementations are declared in SegTransportArduino.h:

Arduino code using these transport classes must include SegTransportArduino.h explicitly.

Transport Build Macros

SEGLCD_DISABLE_ARDUINO_TRANSPORT disables Arduino transport declarations and implementation.

Use it in environments that provide their own SegTransportI2C or SegTransport3Wire implementation and do not have Arduino Wire.h available. Arduino builds should normally leave this undefined.


PCF85134 / PCF85176 / PCF8576 (I2C)

Driver: SegDriver_PCx85, SegDriver_PCF85134, SegDriver_PCF85176, SegDriver_PCF8576

Note: PCF85134, PCF85176, and PCF8576 share the PCx85 I2C driver model. PCF8576 is an older variant of PCF85176 with identical functionality in this library.

Physical Characteristics

Property Value
Protocol I2C (2-wire)
I2C Address 0x38 or 0x39 (SA0 pin)
Subaddresses A0-A2 (protocol subaddress, not I2C)
RAM PCF85134: 60 bytes max address range; PCF85176/PCF8576: 40 bytes (39 usable)
Max Segments Controller/display dependent
Power 3.3V or 5V (controller dependent)

I2C and Subaddressing

The I2C address is determined by the SA0 pin only:

  • SA0 = 0 → I2C address 0x38
  • SA0 = 1 → I2C address 0x39

A0, A1, A2 are NOT I2C address pins - they are subaddresses used within the communication protocol to select one of 8 devices on the same I2C address.

I2C Address (SA0 pin):
SA0 = 0 → 0x38
SA0 = 1 → 0x39
Subaddress (A0-A2, in protocol):
A2 A1 A0 → Subaddress
0 0 0 → 0 (default)
0 0 1 → 1
...
1 1 1 → 7

Finding Address: Use I2C scanner or a PCx85 raw example:

void setup() {
Wire.begin();
Serial.begin(9600);
// Try both possible I2C addresses
for (uint8_t addr : {0x38, 0x39}) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Found at: 0x");
Serial.println(addr, HEX);
}
}
}
Raw PCF85176 LCD implementation for prototyping and testing.

Communication Protocol

Initialization Sequence:

  1. I2C START condition
  2. Address byte (0x38 or 0x39 based on SA0)
  3. Subaddress + control byte (A0-A2 bits + function setting)
  4. RAM data bytes (0-39)
  5. I2C STOP condition

Command Structure:

Byte 0: 0x00 - Static mode (no multiplexing)
0x01 - 1/2 duty
0x02 - 1/3 duty
0x04 - 1/4 duty
+ 0x00-0x30 for bias/contrast (varies by device)

Functional Modes

Drive Mode (Display Refresh)

Controls how the LCD multiplexer refreshes segments:

Mode Duty Use Case
Static (1/1) 100% of segments on at once Single digit displays (rare)
1/2 Duty 2 digit rows Multi-digit displays, simpler
1/3 Duty 3 digit rows 6-digit displays (common)
1/4 Duty 4 digit rows 4-digit displays

Higher multiplexing requires more RAM but reduces pin count on LCD module.

Bias Mode

Voltage bias between LCD common and segment pins (determines contrast):

Mode Voltage Divider Typical Use
1/2 Bias VDD/2 Older LCD displays
1/3 Bias VDD/3 Modern LCD displays (typical)

Note: Only affects display when in multiplexed mode (1/2, 1/3, 1/4 duty). Static mode ignores bias.

RAM Layout

Byte Index Content Segments
─────────────────────────────────────────
0-2 Digit 1 (3 bytes) 0-23
3-5 Digit 2 (3 bytes) 24-47
...
36-38 Digit 13 (3 bytes) 288-311
Byte 39 Unused

Each byte controls 8 segments:

Byte Layout:
Bit 7 6 5 4 3 2 1 0
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
Segment a b c d e f g H (7-segment notation)

Wiring (Arduino → LCD Module)

Arduino PCF85176 Module
─────────────────────────────
SDA (A4) → SDA (pin 18)
SCL (A5) → SCL (pin 19)
3.3V/5V → VCC
GND → GND

Note: I2C pull-ups (4.7kΩ) typically already on LCD module.

Code Example

#include <Wire.h>
SegTransportI2CArduino transport(Wire);
SegLCD_PCF85176_TempHumidity lcd(transport); // Default address 0x38
void setup() {
Wire.begin();
lcd.init();
}
void loop() {
lcd.setCursor(0, 0);
lcd.print(23); // Temperature
}
PCF85176 driver for temperature/humidity LCD.
Temperature/humidity LCD with dual rows (PCF85176).
Definition SegLCD_PCF85176_TempHum.h:21
Arduino TwoWire implementation of the I2C transport.
Definition SegTransportArduino.h:38

HT1621 (3-Wire Serial)

Driver: SegDriver_HT1621

Physical Characteristics

Property Value
Protocol 3-wire serial (bit-bang GPIO)
RAM 16 bytes
Max Segments 128 (16 × 8)
Clock Speed 32 kHz (typical)
Power 3.3V typical, 5V tolerant
Integration Usually integrated into LCD module (COB)

3-Wire Protocol

Three GPIO pins control communication:

CLK (Clock) - Synchronization signal
DATA (Data) - Serial data line
CS (Select) - Chip select (active low)

Bit Timing:

CLK Cycle:
┌──────┐ ┌──────┐
│ │ │ │
────┘ └────────┘ └────
↑ ↑ ↑ ↑
Data Read Data Read
Setup at Setup at
Rising Rising

Minimum clock period: 100μs (32 kHz max)

Command Structure

Three command types:

  1. System Control Command
    9 bits: 100_0xxxxx
    └─ SYS_EN (0=disable, 1=enable)
    └─ SYS_DIS (0=display on, 1=off)
    └─ LCD_ON (1=LCD enabled)
  2. Drive/Bias Mode Command
    9 bits: 101_xxyzzz
    └─ RC (1/2 vs 1/3 bias)
    └─ Duty (1/2 to 1/4 multiplexing)
    └─ Drive frequency
  3. Data Write Command
    9 bits: 101_AAAAA (address, 32 addresses for 16 bytes)
    8 bits: Data byte

RAM Layout

Address 0-3 4-7 8-11 12-15 16-19 20-31
Content Digit1 Digit2 Digit3 Digit4 Digit5 Digit6
Bits 0-31 32-63 64-95 96-127 128-159 160-191

Each address holds 8 segments for one digit.

Write Sequence

// Example: Write 0xAA to address 0x00
CS_LOW();
WriteCommand(0x140); // Data write command (9 bits)
WriteData(0x00); // Address (5 bits)
WriteData(0xAA); // Data (8 bits)
CS_HIGH();

Wiring (Arduino → HT1621 LCD Module)

Arduino HT1621 Module
────────────────────────
Pin 5 → CLK
Pin 6 → DATA
Pin 7 → CS
3.3V → VCC
GND → GND

Note: Verify module voltage (3.3V or 5V); most are 3.3V.

Initialization Code

const int CLK = 5, DATA = 6, CS = 7;
SegTransport3WireArduino transport(DATA, CLK);
SegLCD_HT1621_4SegDegree lcd(transport, CS);
void setup() {
lcd.init(); // Initialize controller and clear display
}
4-digit 7-segment LCD with degree symbol and colon (HT1621).
Definition SegLCD_HT1621_4SegDegree.h:21
Arduino GPIO implementation of the 3-wire transport.
Definition SegTransportArduino.h:14

HT1622 (3-Wire Serial, Enhanced)

Driver: SegDriver_HT1622

Physical Characteristics

Property Value
Protocol 3-wire serial (enhanced timing)
RAM 32 bytes
Max Segments 256 (32 × 8)
Clock Speed 32 kHz (typical)
Min Pulse Width 4μs (vs 3.33μs for HT1621)
Power 3.3V typical
Integration Usually integrated into LCD module

Differences from HT1621

Feature HT1621 HT1622
RAM 16 bytes 32 bytes
Max Digits 6 (8 segments/digit) 10-16 (depends on layout)
Segment Type 7-segment 7 or 16-segment
Pulse Width 3.33μs (typical) 4μs (minimum)

Timing Requirements

HT1622 requires more precise timing:

Clock Period: ≥ 32μs (31.25 kHz max)
Low Pulse: ≥ 4μs
High Pulse: ≥ 4μs

Bit-banging code must respect 4μs minimum:

void writebit(uint8_t bit) {
digitalWrite(CLK, LOW);
digitalWrite(DATA, bit ? HIGH : LOW);
delayMicroseconds(4);
digitalWrite(CLK, HIGH);
delayMicroseconds(4);
}

RAM Layout

Address 0-7 8-15 16-23 24-31
Content Digit1 Digit2 Digit3 ...
Bits 0-63 64-127 128-191 192-255

Greater RAM supports larger segment displays (16-segment alphanumeric).

Wiring

Same as HT1621 (3 GPIO pins: CLK, DATA, CS).


VK0192 (3-Wire Serial)

Driver: SegDriver_VK0192

Physical Characteristics

Property Value
Protocol 3-wire serial, same command/address/data framing family as HT1621/HT1622
RAM 24 bytes (24 × 8 bit RAM)
Max Segments 192 (24 × 8)
Power 2.4V–5.2V
Address Mode Internal driver uses nibble-style HW write addresses over 24 × 8 bit RAM

Timing is handled by the shared SegTransport3Wire implementation — the library uses the same clock timing for HT1621, HT1622, and VK0192 (see SegTransportArduino.cpp), so there is no VK0192-specific timing requirement to account for.

Segment Mapping Is Display-Specific, Not Controller-Specific

The VK0192 controller itself addresses its 24×8 bit RAM sequentially, the same way HT1621/HT1622 do. The reference display module wired up in SegLCD_VK0192_5DigSigBattProgress happens to have its digits spread across non-adjacent RAM addresses, because of how that particular module's SEG/COM pins are wired to the glass:

Display Layout: RAM Addresses on this module
┌─────────────┐
│ Digit 1 2 3 │ Digit 1: Addresses 0, 1, 8, 9
│ Signal ●●●● │ Digit 2: Addresses 2, 3, 10, 11
│ Battery ▓▓ │ Digit 3: Addresses 4, 5, 12, 13
│ Progress ▓▓ │ Symbols: Addresses 14-47 (scattered)
└─────────────┘

This is the same kind of module-specific mapping work needed for any segment LCD (HT1621/HT1622 modules can have irregular layouts too) — it is not a property of the VK0192 controller, and other VK0192 modules may map sequentially.

4-Bit Addressing

Data Format:
Byte = [ Address High (4 bits) | Data (4 bits) ]
Example:
Address 0x12 = 0x1 << 4 | data
= 0x10 | data

RAM Layout and Addressing

Byte Address 4-bit Addresses Content
0 0, 1 Digit 1 upper, Digit 2 upper
1 (data bits)
...
12 24, 25 Signal strength segments
...
23 46, 47 Progress indicator

The table above reflects the reference SegLCD_VK0192_5DigSigBattProgress module; other VK0192-based displays may map differently.

Wiring

Same as HT1621/HT1622 (3 GPIO pins).

Segment Mapping Example

Like any segment LCD with a non-trivial physical layout, mapping logical digits/segments to RAM addresses is module-specific work done once per display class:

void _mapSegmentToAddress(uint8_t digit, uint8_t segment,
uint8_t& addr, uint8_t& bit) {
// This module: digit 0 spans addresses 0, 1, 8, 9
if (digit == 0) {
if (segment < 4) addr = 0; // Lower nibble
else addr = 8; // Upper nibble
}
// ... similar for digits 1, 2, 3, 4
}
};
VK0192 LCD segment display driver.
Definition SegDriver_VK0192.h:12
5-digit 7-segment LCD with signal/battery/progress (VK0192).
Definition SegLCD_VK0192_5DigSigBattProgress.h:22

Quick Comparison

Feature PCF85134 PCF85176/PCF8576 HT1621 HT1622 VK0192
Protocol I2C I2C 3-wire 3-wire 3-wire, same framing family as HT1621/HT1622
Pins 2 (+ power) 2 (+ power) 3 3 3
RAM 60 bytes max address range 40 bytes 16 bytes 32 bytes 24 bytes
Max Digits display-dependent 13 display-dependent display-dependent display-dependent
Controller Addressing Sequential Sequential Sequential Sequential Sequential
Integration Separate IC Separate IC Integrated Integrated Integrated
Typical Cost $$$ $$$ $$ $$ $$

Note: whether a specific module's digits/segments land on sequential or scattered RAM addresses depends on how that module's glass is wired to the controller's SEG/COM pins, not on which of these controllers it uses. All three 3-wire controllers use the same clock timing in this library's transport implementation.


Selection Guide

Choose PCF85134/PCF85176 if:

  • Need many digits (10+)
  • Want I2C (only 2 pins needed)
  • Have 3.3V/5V available for I2C pull-ups
  • Working with pre-made module

Choose HT1621 if:

  • Need 4-6 digits
  • Have GPIO pins available
  • Want simple 3-wire protocol
  • Module is integrated (no separate IC)

Choose HT1622 if:

  • Need 10+ digits
  • Want 16-segment capability
  • Module is already purchased

Choose VK0192 if:

  • Working with a specific VK0192 module
  • Display already purchased/committed

Protocol Comparison: Write Sequence

PCF85176 (I2C)

START → ADDR → CONTROL → [DATA₀-₃₉] → STOP

Single transaction, all data at once.

HT1621 (3-Wire)

CS ↓ → CMD(9b) → ADDR(5b) → DATA(8b) → CS ↑

Bit-banged protocol, address then data.

VK0192 (3-Wire)

CS ↓ → CMD(9b) → HW_ADDR → DATA(8b) → CS ↑

Same framing as HT1621, over a 24 × 8 bit RAM. SegLCDLib uses internal HW write addresses that advance in half-byte steps for compatibility with the existing driver model.


Reference