Overview
This 5x5 matrix packs 25 WS2812B addressable RGB LEDs onto one compact board — a tiny full-color display driven by a single GPIO pin. Every pixel has its own controller chip, so each of the 25 LEDs takes any 24-bit color independently: icons, digits, sprites, spectrum bars, dice faces, emoji-style expressions, game-of-life animations, or simply a very bright, very colorful status panel.
Electrically it's a standard WS2812B chain folded into a grid: DIN in, DOUT out, 5V and GND for power. Your library sees it as a 25-pixel strip; a tiny x/y helper function turns "row 2, column 3" into the right strip index, and from there it behaves like a miniature screen. DOUT lets you chain matrices side by side into wider panels, or chain into rings and strips — it's all one protocol.
Like all WS2812Bs, it wants a 5V supply sized for the worst case (25 LEDs x 60 mA ≈ 1.5 A at full white — though real animations at sane brightness draw a small fraction of that), a 330-470 ohm resistor in the data line, and a fat capacitor across power. Libraries: Adafruit NeoPixel or FastLED on Arduino/ESP32, MicroPython's built-in neopixel on ESP32/Pico, rpi_ws281x on the Pi.
At a Glance
Specifications
| Parameter | Value |
| LED Type | WS2812B integrated RGB + driver, 5050 package |
| Layout | 5 columns x 5 rows = 25 pixels |
| Supply Voltage | 5V DC (4.5 - 5.5V) |
| Current Draw | ~1 mA/LED idle; up to ~60 mA/LED full white (~1.5 A total) |
| Data Protocol | Single-wire 800 kHz, GRB byte order |
| Pads | DIN, DOUT, VCC/5V, GND |
| Pixel Order | Sequential from DIN — run the index test below to map your board |
| Recommended Extras | 330-470 ohm on DIN; 470-1000 uF across 5V/GND |
| Logic Level | 5V nominal; 3.3V data usually fine (shift if flickery) |
| Refresh | Hundreds of full-frame updates per second at 25 pixels |
Wiring Guide
Wire DIN to your GPIO through a 330-470 ohm resistor, 5V and GND to power (capacitor across them), and leave DOUT free unless you're chaining to another matrix. Grounds must be common between the LED supply and the controller.
Arduino Wiring
| Matrix Pad | Arduino Pin | Details |
|---|---|---|
| DIN | D6 via 330 ohm | |
| VCC | 5V (demos) / external 5V 2A (full) | Cap across supply |
| GND | GND |
ESP32 Wiring
| Matrix Pad | ESP32 Pin | Details |
|---|---|---|
| DIN | GPIO 13 via 330 ohm | Any output GPIO |
| VCC | VIN (USB 5V) | LEDs need 5V power, not 3V3 |
| GND | GND |
Raspberry Pi Wiring
| Matrix Pad | Pi Pin | Details |
|---|---|---|
| DIN | Pin 12 (GPIO 18) via 330 ohm | PWM0, required by rpi_ws281x |
| VCC | Pin 2 (5V) / external 5V | |
| GND | Pin 6 (GND) |
Raspberry Pi Pico Wiring
| Matrix Pad | Pico Pin | Details |
|---|---|---|
| DIN | GP0 (pin 1) via 330 ohm | |
| VCC | VBUS (pin 40, 5V) | |
| GND | GND (pin 38) |
Code Examples
Each example includes the xy() mapping helper plus a demo: an index test, a color-cycling heart icon, and a bouncing pixel. Set SERPENTINE to match what the index test shows on your board.
Arduino
// WS2812B 5x5 Matrix - Arduino Example
// DIN->D6 via 330 ohm, VCC->5V, GND->GND
// Library: "Adafruit NeoPixel"
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define W 5
#define H 5
#define NUM (W * H)
bool SERPENTINE = false; // set true if the index test zigzags
Adafruit_NeoPixel px(NUM, PIN, NEO_GRB + NEO_KHZ800);
int xy(int x, int y) { // (0,0) = first pixel at DIN
if (SERPENTINE && (y % 2 == 1)) return y * W + (W - 1 - x);
return y * W + x;
}
// 5x5 heart bitmap
const uint8_t HEART[5] = {0b01010, 0b11111, 0b11111, 0b01110, 0b00100};
void indexTest() {
for (int i = 0; i < NUM; i++) {
px.clear();
px.setPixelColor(i, 0, 150, 255);
px.show();
delay(150);
}
}
void drawHeart(uint32_t color) {
px.clear();
for (int y = 0; y < H; y++)
for (int x = 0; x < W; x++)
if (HEART[y] & (1 << (W - 1 - x)))
px.setPixelColor(xy(x, y), color);
px.show();
}
void setup() {
px.begin();
px.setBrightness(50);
indexTest(); // watch the order once at startup
}
void loop() {
drawHeart(px.Color(255, 0, 40)); delay(500);
drawHeart(px.Color(255, 80, 0)); delay(500);
drawHeart(px.Color(150, 0, 255)); delay(500);
}
ESP32 (MicroPython)
# WS2812B 5x5 Matrix - ESP32 MicroPython Example
# DIN->GPIO 13 via 330 ohm, VCC->VIN(5V), GND->GND
from machine import Pin
import neopixel, time
W = H = 5
SERPENTINE = False
px = neopixel.NeoPixel(Pin(13), W * H)
BRIGHT = 0.2
def xy(x, y):
if SERPENTINE and y % 2 == 1:
return y * W + (W - 1 - x)
return y * W + x
def scale(c):
return tuple(int(v * BRIGHT) for v in c)
HEART = [0b01010, 0b11111, 0b11111, 0b01110, 0b00100]
SMILE = [0b01010, 0b01010, 0b00000, 0b10001, 0b01110]
def draw(bitmap, color):
px.fill((0, 0, 0))
for y in range(H):
for x in range(W):
if bitmap[y] & (1 << (W - 1 - x)):
px[xy(x, y)] = scale(color)
px.write()
def bounce(loops=3):
x, y, dx, dy = 0, 0, 1, 1
for _ in range(loops * 20):
px.fill((0, 0, 0))
px[xy(x, y)] = scale((0, 255, 120))
px.write()
x += dx; y += dy
if x in (0, W - 1): dx = -dx
if y in (0, H - 1): dy = -dy
time.sleep_ms(100)
while True:
draw(HEART, (255, 0, 40)); time.sleep(0.6)
draw(SMILE, (255, 160, 0)); time.sleep(0.6)
bounce()
Raspberry Pi (Python)
#!/usr/bin/env python3
# WS2812B 5x5 Matrix - Raspberry Pi Example (rpi_ws281x)
# DIN->GPIO18 (pin 12) via 330 ohm; run with sudo
# Install: sudo pip3 install rpi_ws281x
import time
from rpi_ws281x import PixelStrip, Color
W = H = 5
SERPENTINE = False
strip = PixelStrip(W * H, 18, brightness=50)
strip.begin()
def xy(x, y):
if SERPENTINE and y % 2 == 1:
return y * W + (W - 1 - x)
return y * W + x
HEART = [0b01010, 0b11111, 0b11111, 0b01110, 0b00100]
def clear():
for i in range(W * H):
strip.setPixelColor(i, 0)
def draw(bitmap, color):
clear()
for y in range(H):
for x in range(W):
if bitmap[y] & (1 << (W - 1 - x)):
strip.setPixelColor(xy(x, y), color)
strip.show()
def column_sweep(color, loops=3):
for _ in range(loops):
for x in range(W):
clear()
for y in range(H):
strip.setPixelColor(xy(x, y), color)
strip.show()
time.sleep(0.12)
try:
while True:
draw(HEART, Color(255, 0, 40))
time.sleep(0.8)
column_sweep(Color(0, 120, 255))
except KeyboardInterrupt:
clear(); strip.show()
print("Stopped by user")
Raspberry Pi Pico (MicroPython)
# WS2812B 5x5 Matrix - Pico MicroPython Example
# DIN->GP0 via 330 ohm, VCC->VBUS(5V), GND->GND
from machine import Pin
import neopixel, time
W = H = 5
SERPENTINE = False
px = neopixel.NeoPixel(Pin(0), W * H)
BRIGHT = 0.2
def xy(x, y):
if SERPENTINE and y % 2 == 1:
return y * W + (W - 1 - x)
return y * W + x
def scale(c):
return tuple(int(v * BRIGHT) for v in c)
DIGITS = { # tiny 5x5 digits 0-3 (add more!)
0: [0b01110, 0b10001, 0b10001, 0b10001, 0b01110],
1: [0b00100, 0b01100, 0b00100, 0b00100, 0b01110],
2: [0b01110, 0b10001, 0b00110, 0b01000, 0b11111],
3: [0b11110, 0b00001, 0b00110, 0b00001, 0b11110],
}
def draw(bitmap, color):
px.fill((0, 0, 0))
for y in range(H):
for x in range(W):
if bitmap[y] & (1 << (W - 1 - x)):
px[xy(x, y)] = scale(color)
px.write()
count = 0
while True:
draw(DIGITS[count % 4], (0, 200, 255))
count += 1
time.sleep(1)