

Elo 112
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
5CH340G
SOP-16-40℃~+85℃ 2Mbps 3.3V、5V USB 2.0 USB to UART SOP-16 USB Converters ROHSWCH (Nanjing Qinheng Microelectronics)USB ConvertersLM1117MP-ADJ
SOT-2230.003%Vout 0℃~+125℃@(Tj) 1 1.25V~13.8V 1.3V@(800mA) 10mA 15V 75dB@(120Hz) 800mA Adjustable Over Current Protection、Thermal Shutdown Positive SOT-223 Voltage Regulators - Linear, Low Drop Out (LDO) Regulators ROHSTexas InstrumentsVoltage Regulators - Linear, Low Drop Out (LDO) RegulatorsUSBLC6-4SC6
SOT-23-6-55℃~+125℃ 0.3pF 15V 300W@8/20us 4.7A@8/20us 5V 6V 80nA ESD Four channels IEC 61000-4-2、IEC 61000-4-5、IEC 61000-4-4 Unidirectional SOT-23-6 ESD and Surge Protection (TVS/ESD) ROHSTECH PUBLICESD And Surge Protection (TVS/ESD)MMBT2222A
SOT-23-55℃~+150℃ 1 NPN 100 100nA 1V 300MHz 300mW 40V 600mA 6V NPN Standalone SOT-23 Bipolar (BJT) ROHShongjiachengBipolar (BJT)BLM21PG220SN1
08051 22Ω@100MHz 6A 9mΩ ±25% 0805 Ferrite Beads ROHSMurataFerrite Beads
README
Readme.mdSTM32 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
| Module | Component |
|---|---|
| MCU | STM32F103C8T6 |
| Column drivers (high-side) | 8 × MMBT2907A (PNP, SOT-23) |
| Row drivers (low-side) | 8 × MMBT2222A (NPN, SOT-23) |
| LED current limiting | R13–R20 (per-column resistors) |
| USB-UART bridge | CH340G + 12 MHz crystal |
| Regulator | LM1117MP-ADJ |
| System oscillator | 8 MHz crystal |
| USB connector | USB-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
├── 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| Qty | Value | Footprint | References |
|---|---|---|---|
| 64 | LED | LED_SMD:LED_0402_1005Metric | D1, D2, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23 +48 |
| 16 | R_Small | Resistor_SMD:R_0402_1005Metric | R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20 |
| 8 | MMBT2222A | Package_TO_SOT_SMD:SOT-23 | Q9, Q10, Q11, Q12, Q13, Q14, Q15, Q16 |
| 8 | PNP | Package_TO_SOT_SMD:SOT-23 | Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8 |
| 6 | 100nF | Capacitor_SMD:C_0402_1005Metric | C1, C2, C3, C4, C11, C18 |
| 3 | 4.7uF | Capacitor_SMD:C_0402_1005Metric | C5, C8, C9 |
| 2 | 100 Ohm | Resistor_SMD:R_0402_1005Metric | R21, R22 |
| 2 | 15pF | Capacitor_SMD:C_0402_1005Metric | C12, C16 |
| 2 | 22u | Capacitor_SMD:C_0402_1005Metric | C22, C23 |
| 2 | 33pF | Capacitor_SMD:C_0402_1005Metric | C14, C15 |
| 2 | 5.1k | Resistor_SMD:R_0402_1005Metric | R1, R2 |
| 2 | ESD3.3 | Diode_SMD:SODFL1006X40N | D66, D68 |
| 2 | RESET | Button_Switch_SMD:SW_CS1213AGF260_CRS | SW1, SW2 |
| 1 | 1 uF | Capacitor_SMD:C_0402_1005Metric | C6 |
| 1 | 100Ohm | Resistor_SMD:R_0402_1005Metric | R3 |
| 1 | 100n | Capacitor_SMD:C_0402_1005Metric | C41 |
| 1 | 10nF | Capacitor_SMD:C_0402_1005Metric | C7 |
| 1 | 12MHz | Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mm | Y1 |
| 1 | 1N5817 | Diode_SMD:D_SOD-123 | D65 |
| 1 | 1k | Resistor_SMD:R_0402_1005Metric | R23 |
| 1 | 4.7nF | Capacitor_SMD:C_0402_1005Metric | C10 |
| 1 | 5.1KOhm | Resistor_SMD:R_0402_1005Metric | R4 |
| 1 | 8MHz | Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mm | Y2 |
| 1 | BLM21PG220 | Diode_SMD:IND_BLM21_MUR-L | FB1 |
| 1 | CH340G | Package_SO:SOIC-16_3.9x9.9mm_P1.27mm | U2 |
| 1 | Green | LED_SMD:LED_0805_2012Metric | D67 |
| 1 | LM1117MP-ADJ | Regulator:DCY0004A_L | U4 |
| 1 | Polyfuse 1A | Fuse:FUSC1608X100N | F1 |
| 1 | STM32F103C8Tx | Package_QFP:LQFP-48_7x7mm_P0.5mm | U1 |
| 1 | USBLC6-4SC6 | Package_TO_SOT_SMD:SOT-23-6 | U6 |
| 1 | USB_C_Receptacle_USB2.0_16P | Connector_USB:USB_C_Receptacle_HCTL_HC-TYPE-C-16P-01A | J1 |
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 mm

- 4 layers50 × 75 mm

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 mm

- 4 layers84 × 67.2 mm

Tiny4xPoweredStereoMixer
cracked-machine/Tiny4xPoweredStereoMixer
A 9V Stereo Splitter for 4 channels
55 parts1MIT - 2 layers142.6 × 85.1 mm

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 mm

- 2 layers55.2 × 25.7 mm

- 2 layers
