Skip to the content
PCBKitNew board
4 layers35 × 35 mmElo 112, the printed circuit board in 3D

design of custom PCB that drives an 8×8 LED matrix (64 LEDs) using an STM32F103C8T6

Size
35 × 35 mm
Copper layers
4
Thickness
1.6 mm
Parts
137
Nets
100
Pads
380
Tracks, vias
973, 175
Pours
2
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
23 Jun 2026
Updated
30 Jun 2026

Overview

Elo 112 is an open-source printed circuit board by irocobble, from the irocobble/LED_Matrix repository on GitHub. It is a 4-layer board of 35 × 35 mm with 137 parts on 100 nets, routed with 973 tracks and 175 vias.

It is built around the CH340G, LM1117MP-ADJ and USBLC6-4SC6, with the MMBT2222A and BLM21PG220SN1 among its other parts. Its parts include 68 diodes, 23 resistors, 19 capacitors, 16 transistors and 4 ICs. It belongs with the lEDs and displays boards and the STM32 boards of this library.

Main components

5

README

Readme.md

STM32 8×8 LED Matrix Driver

Team Name: ?

AIM

To design a custom PCB that drives an 8×8 LED matrix (64 LEDs) using an STM32F103C8T6 microcontroller, using transistor-based multiplexing instead of a dedicated LED driver IC — and to use it as a stepping stone for learning custom STM32 PCB design end-to-end (schematic, layout, fab, bring-up).


Design Path — What We Tried First

The first version of the schematic used MMBT2222A (NPN) transistors for both the row and column drivers. This works fine for the rows, which sink current to GND — a standard common-emitter low-side switch. It does not work cleanly for the columns, which are high-side switches: the transistor emitter sits at +3.3V, and the GPIO has to pull the base above the emitter to turn an NPN on, which it can't do from the same 3.3V rail. Fixed by switching the column drivers to MMBT2907A (PNP), where the GPIO pulls the base low relative to the 3.3V emitter instead.

The 3.3V regulator (LM1117MP-ADJ) needs a feedback resistor divider on the ADJ pin to set its output voltage — this should be confirmed present in the final schematic, or the part swapped for the fixed-output LM1117-3.3.

Both crystals (Y1: 12MHz for CH340G, Y2: 8MHz for STM32) are passive, with load capacitors and series resistors on each. Load cap values were recalculated based on the actual crystal's datasheet rated load capacitance (12pF for the YXC YSX321SL used on the CH340G side) rather than left at a generic default.


How It Works — The Big Picture

USB-C (5V) → LM1117 regulator → STM32F103C8T6 → GPIO row/column scan → BJT drivers → 8×8 LED matrix

The MCU drives one row low and one column high at a time, cycling through all 8×8 = 64 LEDs fast enough that persistence of vision makes the whole matrix appear continuously lit. Only one LED is physically on at any instant.

Separately, USB-C → CH340G → UART (PA9/PA10) lets the board be programmed and debugged over the same USB-C connector, using the STM32's built-in UART bootloader — no ST-Link required.


Key Definitions

  • Row/Column Multiplexing: Driving a 2D LED grid with only 16 GPIO (8 rows + 8 columns) instead of 64, by lighting one row/column intersection at a time and relying on persistence of vision.
  • High-side / Low-side Switching: A low-side switch sits between the load and GND (sinks current); a high-side switch sits between the supply and the load (sources current). NPN BJTs suit low-side switching off the same rail as the GPIO; PNP BJTs suit high-side switching, for the same reason in reverse.
  • Load Capacitor (Crystal): A capacitor placed on each leg of a passive crystal to bring the circuit's effective capacitance to the value the crystal was designed to oscillate at (its rated load capacitance).
  • Ground/Power Plane: A dedicated PCB layer filled with copper tied to GND or a supply rail, used for low-impedance return paths and easier routing on a multi-layer board.
  • Via Stitching: Vias placed to connect copper pours on different layers (e.g. multiple GND fills), improving return-current paths and thermal spreading.
  • UART Bootloader: A factory-programmed ROM bootloader on STM32 parts that allows flashing firmware over UART (instead of SWD/JTAG) when BOOT0 is pulled high at reset.
  • ESD Protection Diode: A component that clamps voltage transients on a signal line (e.g. USB D+/D-) to protect downstream ICs from static discharge.
  • Polyfuse: A resettable fuse that increases resistance under overcurrent and resets automatically once the fault clears, unlike a one-time fuse.

Hardware

  • MCU: STM32F103C8T6 — ARM Cortex-M3, 72 MHz, 64 KB Flash, 20 KB SRAM
  • Display: 8×8 LED matrix (64 LEDs), each column gated through its own current-limiting resistor (R13–R20)
  • Matrix Drivers: 16 × SOT-23 BJTs — 8× MMBT2907A (PNP, column high-side), 8× MMBT2222A (NPN, row low-side)
  • Power Input: USB-C, 5V
  • Regulation: LM1117MP-ADJ — feedback divider to be confirmed before fab
  • USB-UART Bridge: CH340G with 12 MHz passive crystal (YXC YSX321SL, 12pF load cap)
  • System Clock: 8 MHz passive crystal on STM32
  • Programming: UART bootloader via BOOT0 selection, no ST-Link required
  • Protection: USB-C CC resistors, polyfuse, ESD diodes, ferrite bead on VBUS
  • Controls: Reset and BOOT0 push buttons
ModuleComponent
MCUSTM32F103C8T6
Column drivers (high-side)8 × MMBT2907A (PNP, SOT-23)
Row drivers (low-side)8 × MMBT2222A (NPN, SOT-23)
LED current limitingR13–R20 (per-column resistors)
USB-UART bridgeCH340G + 12 MHz crystal
RegulatorLM1117MP-ADJ
System oscillator8 MHz crystal
USB connectorUSB-C receptacle

Design tool: KiCad 9.0.3

Source files: [link to your repo]


PCB Layout

  • Board size: 35×35mm
  • Layer count: 4 layers
    • L1 (top): Signal routing
    • L2: GND plane
    • L3: 3.3V plane
    • L4 (bottom): Signal routing
  • Power and ground as solid internal planes gives low-impedance return paths for the digital signals on the outer layers and simplifies routing density around the STM32 and LED matrix.

Firmware — Planned Approach

  • MCU scans rows/columns using a timer interrupt for consistent refresh rate
  • Frame buffer in SRAM holds the current 8×8 bitmap; the scan routine only reads from it, so updating the display is just writing to the buffer
  • Brightness control planned via Bit Angle Modulation (BAM) for per-LED grayscale, layered on top of the row/column scan — no hardware change required, this is a firmware-only addition
  • UART bootloader flow: pull BOOT0 high, reset, flash via STM32CubeProgrammer, pull BOOT0 low, reset again to run

Repository Structure

text
├── Hardware/
│   ├── Schematic
│   ├── PCB Layout
│   └── Manufacturing Files
├── Firmware/
│   ├── Source Code
│   └── Build Files
└── Documentation/

Current Status

  • Schematic — PNP columns, per-LED current-limiting resistors, passive crystals
  • Confirm LM1117MP-ADJ feedback divider is present and correctly valued
  • PCB routing — first pass complete, 4-layer stackup
  • Run DRC and confirm zero unrouted nets / clearance violations
  • Prototype fabrication
  • Hardware validation
  • Firmware development
  • Display animation library (brightness/BAM, frame buffer, basic patterns)

Limitations and Future Work

The LM1117MP-ADJ regulator's feedback divider needs to be confirmed on the final schematic before fabrication. A few possible unrouted nets/airwires were visible on the top copper layer near the crystal and BJT driver area during review — DRC should be run to confirm full routing before sending to fab. No explicit ground-stitching vias were added near the row-driver BJT cluster, which sinks up to ~160mA when a full row is lit; this is not a blocker but could improve return-current path and thermal performance. The design uses discrete BJTs for all 16 drivers instead of a dedicated LED matrix driver IC (e.g. MAX7219), which is simpler to wire but uses more board space and GPIO pins than a driver-IC approach. Brightness control (PWM/BAM dimming) is planned but not yet implemented in firmware.

License

Parts

137
QtyValueFootprintReferences
64LEDLED_SMD:LED_0402_1005MetricD1, D2, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23 +48
16R_SmallResistor_SMD:R_0402_1005MetricR5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20
8MMBT2222APackage_TO_SOT_SMD:SOT-23Q9, Q10, Q11, Q12, Q13, Q14, Q15, Q16
8PNPPackage_TO_SOT_SMD:SOT-23Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8
6100nFCapacitor_SMD:C_0402_1005MetricC1, C2, C3, C4, C11, C18
34.7uFCapacitor_SMD:C_0402_1005MetricC5, C8, C9
2100 OhmResistor_SMD:R_0402_1005MetricR21, R22
215pFCapacitor_SMD:C_0402_1005MetricC12, C16
222uCapacitor_SMD:C_0402_1005MetricC22, C23
233pFCapacitor_SMD:C_0402_1005MetricC14, C15
25.1kResistor_SMD:R_0402_1005MetricR1, R2
2ESD3.3Diode_SMD:SODFL1006X40ND66, D68
2RESETButton_Switch_SMD:SW_CS1213AGF260_CRSSW1, SW2
11 uFCapacitor_SMD:C_0402_1005MetricC6
1100OhmResistor_SMD:R_0402_1005MetricR3
1100nCapacitor_SMD:C_0402_1005MetricC41
110nFCapacitor_SMD:C_0402_1005MetricC7
112MHzCrystal:Crystal_SMD_3225-4Pin_3.2x2.5mmY1
11N5817Diode_SMD:D_SOD-123D65
11kResistor_SMD:R_0402_1005MetricR23
14.7nFCapacitor_SMD:C_0402_1005MetricC10
15.1KOhmResistor_SMD:R_0402_1005MetricR4
18MHzCrystal:Crystal_SMD_3225-4Pin_3.2x2.5mmY2
1BLM21PG220Diode_SMD:IND_BLM21_MUR-LFB1
1CH340GPackage_SO:SOIC-16_3.9x9.9mm_P1.27mmU2
1GreenLED_SMD:LED_0805_2012MetricD67
1LM1117MP-ADJRegulator:DCY0004A_LU4
1Polyfuse 1AFuse:FUSC1608X100NF1
1STM32F103C8TxPackage_QFP:LQFP-48_7x7mm_P0.5mmU1
1USBLC6-4SC6Package_TO_SOT_SMD:SOT-23-6U6
1USB_C_Receptacle_USB2.0_16PConnector_USB:USB_C_Receptacle_HCTL_HC-TYPE-C-16P-01AJ1

Questions

How big is the Elo 112 PCB?

It measures 35 × 35 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Elo 112 use?

137 parts, built around the CH340G, LM1117MP-ADJ, USBLC6-4SC6 and MMBT2222A. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Elo 112 KiCad files?

From the irocobble/LED_Matrix repository on GitHub, at the commit this page was made from: the board is Hardware/PCB/Elo_112.kicad_pcb and its schematic Hardware/PCB/Elo_112.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Elo 112 design in my own project?

Its repository states no licence, so its author keeps all rights: ask irocobble before reusing the design.

Similar boards

  • 4 layers35 × 25 mmNew', the printed circuit board in 3D

    New'

    irocobble/CSI_collection

    capturing & Analyzing CSI data using ESP_32_S3

    29 parts
  • 4 layers50 × 75 mmAccoustic Sensing Node, the printed circuit board in 3D

    Accoustic Sensing Node

    irocobble/CA_LR_ES

    Open-source ESP32-S3 edge computing module with LoRa, GPS, external flash, MicroSD, and expansion support for long-range IoT applications.

    129 parts
  • 4 layers89.1 × 92.1 mmGnss module, the printed circuit board in 3D

    Gnss module

    spacelab-ufsc/gnss-module

    21 parts3
  • 4 layers84 × 67.2 mmTiny4xPoweredStereoMixer, the printed circuit board in 3D

    Tiny4xPoweredStereoMixer

    cracked-machine/Tiny4xPoweredStereoMixer

    A 9V Stereo Splitter for 4 channels

    55 parts1MIT
  • 2 layers142.6 × 85.1 mmLineFollower Speedy-, the printed circuit board in 3D

    LineFollower Speedy-

    Club-robotica-UDLSB/LineFollower-Speedy-

    Documentación del desarrollo del Seguidor de línea (El speedy)

    89 partsGPL-3.0
  • 2 layers26.5 × 26.8 mmRcj25, the printed circuit board in 3D

    Rcj25

    hu-more-bot/RCJ2025

    Software & Hardware for RCJ2025

    39 partsMIT
  • 2 layers55.2 × 25.7 mmBlinker v1 0, the printed circuit board in 3D

    Blinker v1 0

    poradam/NE555_blinker

    23 parts
  • 2 layersStm, the printed circuit board in 3D

    Stm

    Purdue-Space-Program/PSPL_R4_Avionics_Hardware

    Boards and other components for R4

    69 parts2