Skip to main content

7-Segment Displays

Driving numeric 7-segment displays from an ESP32 using the TM1637 (2-wire), MAX7219, and MAX7221 (SPI) driver modules for cockpit altimeters, speed tapes, and frequency readouts.

Segment Anatomy & Driver Modules

A 7-segment display has seven LED segments (a–g) plus an optional decimal point. Driving them directly from an ESP32 requires 8 pins per digit — impractical for multi-digit readouts. Driver ICs handle the multiplexing internally and communicate over a 2- or 4-wire bus.

ModuleInterfaceDigitsGPIO pins usedBest for
TM1637Custom 2-wire (CLK + DIO)4 (expandable)2Simple readouts, easy wiring
MAX7219SPI-like (MOSI + CLK + LOAD)8 per chip (daisy-chainable)3 (shared across chain)Multi-display panels, altitude, speed
MAX7221True SPI (MOSI + CLK + CS̄)8 per chip (daisy-chainable)3 (shared SPI bus)Mixed SPI bus, cockpit near radio equipment
Direct + 74HC595Shift register + GPIO mux1 per 5953 + 1 digit-select pinCustom segment control, unusual layouts

Segment map

BitSegmentPosition on digit
0 (0x01)aTop horizontal
1 (0x02)bUpper-right vertical
2 (0x04)cLower-right vertical
3 (0x08)dBottom horizontal
4 (0x10)eLower-left vertical
5 (0x20)fUpper-left vertical
6 (0x40)gMiddle horizontal
7 (0x80)dpDecimal point
TM1637 — Wiring
TM1637 4-digit module 8.8.8.8 GPIO 22 CLK GPIO 23 DIO 3.3–5 V VCC GND GND 4-digit 7-seg display
TM1637 pinConnect to
CLKGPIO 22
DIOGPIO 23
VCC3.3 V
GNDGND
TM1637 — Arduino Code

Basic number display

// Library Manager → search "TM1637Display" by Avishkar Mishra / Arduino TM1637
#include <TM1637Display.h>

const int CLK_PIN = 22;
const int DIO_PIN = 23;

TM1637Display display(CLK_PIN, DIO_PIN);

void setup() {
    display.setBrightness(5);        // 0 (dim) – 7 (bright)
    display.showNumberDec(0, true);  // show "0000" with leading zeros
}

void loop() {
    // Show current altitude from X-Plane (example: 35000 ft)
    int altitude = 35000;
    display.showNumberDec(altitude);
    delay(100);
}

Colons and custom segments

// Colons and individual segments
#include <TM1637Display.h>

TM1637Display display(22, 23);

void showTime(int hours, int minutes) {
    // showNumberDecEx: value, dots mask, leading zeros, length, position
    // dots mask 0x40 = colon on (centre dots)
    display.showNumberDecEx(hours * 100 + minutes, 0x40, true);
}

void showLabel() {
    // Custom segments for text — e.g. "AL t" (altitude label)
    const uint8_t SEG_A = 0b01110111;   // A
    const uint8_t SEG_L = 0b00111000;   // L
    const uint8_t SEG_T = 0b01111000;   // t
    uint8_t data[] = { SEG_A, SEG_L, 0, SEG_T };
    display.setSegments(data);
}
MAX7219 / MAX7221 — Wiring
MAX7219 SPI driver GPIO 23 (MOSI) DIN GPIO 18 (SCK) CLK GPIO 5 (CS) CS/LOAD 5 V / GND VCC / GND DOUT → DIN of next MAX7219 Digit 0–7 Seg a–g, DP
PinConnect to
DINGPIO 23 (MOSI) — via level shifter
CLKGPIO 18 (SCK) — via level shifter
CS / LOADGPIO 5
VCC5 V external supply
GNDCommon GND
DOUTDIN of next chip in chain

RSET — segment current resistor

Both ICs require an external resistor between ISET (pin 18) and V+ to set the peak segment current. The setIntensity() call in software then scales brightness from 0 to 15 within that ceiling.

RSET valuePeak segment currentUse when
10 kΩ~40 mAMaximum brightness (check display's absolute max)
28 kΩ~15 mAStandard 7-segment modules
33 kΩ~12 mAConservative choice, good for most cockpit panels
47 kΩ~9 mALow-power or high-efficiency LED displays
MAX7219 / MAX7221 — Arduino Code

The LedControl library works with both MAX7219 and MAX7221 without any code changes — the constructor and all method calls are identical.

// Library Manager → search "LedControl" by Eberhard Fahle
#include <LedControl.h>

// LedControl(DIN, CLK, CS, numDevices)
LedControl lc = LedControl(23, 18, 5, 1);

void setup() {
    lc.shutdown(0, false);       // wake up MAX7219 (starts in power-down mode)
    lc.setIntensity(0, 8);       // brightness 0–15
    lc.clearDisplay(0);
}

void showAltitude(int feet) {
    // Write individual digits right-to-left (position 0 = rightmost)
    for (int pos = 0; pos < 8; pos++) {
        lc.setDigit(0, pos, feet % 10, false);
        feet /= 10;
        if (feet == 0) { break; }
    }
}

void loop() {
    showAltitude(35000);
    delay(100);
}

To drive multiple chips, set numDevices to the chain length and pass the device index (0-based) to each lc.* call.

MAX7221 vs MAX7219 — Choosing the Right IC

The MAX7221 is a drop-in replacement for the MAX7219 with the same pinout, register map, and software interface. Two hardware differences matter for cockpit builds.

FeatureMAX7219MAX7221
Chip-select typeLOAD — active-high latchCS̄ — active-low, true SPI
DOUT when idleAlways driven (not tri-stated)High-impedance when CS̄ is high
Segment output slew rateFast (higher EMI)Slew-rate limited (lower EMI)
Shutdown current~150 µA~10 µA
SPI bus sharingNot possible (DOUT always active)Fully supported
LedControl librarySupportedSupported — identical API
CostLowerSlightly higher

When to choose the MAX7221

SPI bus sharing. The MAX7219's DOUT is permanently driven, which corrupts the MISO line for any other SPI device sharing the bus. The MAX7221 tri-states DOUT whenever CS̄ is high, so it coexists cleanly with other SPI peripherals (SD cards, OLED displays, accelerometers) on the same three-wire bus.

Cockpit radio-frequency environment. The MAX7221's slew-rate-limited segment drivers reduce high-frequency switching noise on the display lines. In a cockpit with COM / NAV receivers, lower EMI from display drivers lowers the risk of interference with sensitive radio equipment — a meaningful practical advantage even if the effect is small on a home simulator.

Cockpit Applications
ApplicationDriverDigits neededNotes
COM / NAV radio frequencyTM16376Two 4-digit modules; show active & standby
Altitude (MCP / FCU)MAX721955-digit altitude, leading zeros suppressed
Heading bug (HDG)TM16373000–359, padded with leading zeros
VS (vertical speed)TM16374±4 digits; use custom segment for minus sign
Transponder codeTM16374Octal display (0–7 per digit), show squawk code
Multi-panel CDU scratchpadMAX7219 chain8+Daisy-chain two MAX7219 for full alphanumeric row