Skip to the content
PCBKitNew board
2 layers208 × 110 mmButton grid, the printed circuit board in 3D

An ESP32-S3 controller board for an 8×8 button matrix with 64 individually switched 12 V LEDs. It's designed in KiCad 9 and made to be ordered from JLCPCB.

Size
208 × 110 mm
Copper layers
2
Thickness
1.6 mm
Parts
108
Nets
204
Pads
606
Tracks, vias
2,031, 545
Pours
2
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
14 Oct 2026
Updated
14 Oct 2026

Overview

Button grid is an open-source printed circuit board by paulsonnentag, from the paulsonnentag/button-grid repository on GitHub. It is a 2-layer board of 208 × 110 mm with 108 parts on 204 nets, routed with 2,031 tracks and 545 vias.

It is built around the ESP32-S3-WROOM-1-N8, 74HC595 and ULN2803A, with the TPS54202HDDC, SS34 and SS54 among its other parts. Its parts include 40 resistors, 26 capacitors, 18 ICs, 13 connectors and 4 diodes. It belongs with the ESP32 boards of this library.

Main components

6

README

README.md

button-grid

An ESP32-S3 controller board for an 8×8 button matrix with 64 individually switched 12 V LEDs. It's designed in KiCad 9 and made to be ordered from JLCPCB.

Site with the design viewer, test results and JLCPCB downloads: GitHub Pages for this repo, built by .github/workflows/pages.yml.

What's on the board

FunctionImplementation
MCUESP32-S3-WROOM-1-N8, native USB-C for flashing and serial
LEDs (64, not multiplexed)8× 74HC595 in one chain → 8× ULN2803A low-side drivers → screw terminals
Buttons (your diode matrix)8 rows + 8 columns directly on GPIOs, 100 Ω series resistors, 22 kΩ pull-ups
Power12 V wall adapter (5.5×2.1 mm, centre +, ≥ 2 A) → SS54 reverse-polarity diode → LED supply; TPS54202 buck converter → 3.3 V
Size208 × 110 mm, 2 layers

Wiring

  • LED terminals J11–J18 (10-pole, 3.5 mm pitch, along the top and bottom edges). Pins 1–8 take the cathode (−) wire of 8 LEDs. Pins 9–10 are +12 V for the anode (+) wires. Each LED must keep its own series resistor. Twist or daisy-chain the + wires of a bank so that at most 2 wires go into one screw. Bank 1 (J11) is LEDs 0–7, bank 2 is LEDs 8–15, and so on.
  • ROWS J3 / COLS J4 (8-pole, left edge): connect the 8 row wires and 8 column wires of your matrix. Which way the diodes point is set in firmware, so either orientation works.
  • 12 V goes into the barrel jack. USB-C alone powers only the logic (enough to flash firmware). The LEDs need 12 V.

ESP32 pin map (for the firmware)

SignalGPIO
ROW0…ROW74, 5, 6, 7, 15, 16, 17, 18
COL0…COL78, 9, 10, 11, 12, 13, 14, 21
74HC595 SER (data in) / SRCLK / RCLK (latch) / OE (active low, pulled high)38 / 39 / 40 / 41
Chain return (last 74HC595 QH′), used to self-test the chain42
Status LED2
USB D− / D+19 / 20

To set LEDs, shift out 64 bits, with the bits for bank 8 first, then pulse RCLK. A 1 turns the LED on. Drive OE low to enable the outputs. PWM on OE dims all LEDs.

Repository layout

text
hardware/
  button-grid.kicad_pro/.kicad_sch/.kicad_pcb, led_bank.kicad_sch   <- open these in KiCad 9
  gen/        generators: build_schematic.py, build_pcb.py (placement), finish_pcb.py (pours)
  scripts/    build.sh, route.sh, check.sh, export.sh, check_netlist.py, jlc_bom_cpl.py
site/         build_site.py -> static GitHub Pages site

The design was generated from Python. It uses one "LED bank" sheet that is reused 8 times as a KiCad hierarchical sheet, so a change to that sheet applies to all 64 channels. The output is an ordinary KiCad project:

  • Editing by hand in KiCad: just do it, then run hardware/scripts/check.sh. Once you've edited by hand, don't re-run the generators, because they overwrite the files.
  • Editing through the generators: change hardware/gen/*.py, then run build.sh → route.sh → check.sh.

Every script runs KiCad from the official kicad/kicad:9.0 Docker image when KiCad isn't installed locally. route.sh also needs Java 25 and the Freerouting jar.

How the design is checked

hardware/scripts/check.sh runs on every push, and the results are shown on the site:

  1. ERC. KiCad's electrical rules check on the schematic.
  2. Connectivity assertions (check_netlist.py). These check the intended circuit pin by pin: all 64 LED channels, the 74HC595 chain order, the clock/latch/enable fan-out, every matrix line, USB-C CC resistors, the buck converter's feedback voltage, strapping pins, and LCSC numbers on every assembled part. The checker was tested by feeding it deliberately broken netlists (swapped LED wires, a broken chain), and it catches them.
  3. DRC with schematic parity. Manufacturing limits that are safe for JLCPCB, a check that every net is routed, and a check that the PCB matches the schematic.

Recommended before ordering:

  • Breadboard test of one channel: an ESP32 dev board, a 74HC595, a ULN2803 and one of your LEDs at 12 V.
  • First power-up: connect 12 V with no LEDs attached and measure 3.3 V. Then flash a test firmware that walks one LED at a time, checks the chain through GPIO42, and prints matrix presses over USB.

Ordering (see the site for the files)

Upload the gerber zip, then turn on PCB Assembly with the BOM and CPL files, 2 boards assembled. The screw terminals, barrel jack, buttons and header are through-hole parts that you solder yourself (hand-solder-parts.csv). On JLCPCB's placement preview, check that the chips and the USB-C connector are rotated correctly.

Part numbers: the LCSC numbers were picked from JLCPCB's catalogue but couldn't be checked against live stock while building. Check them when you upload the BOM. Any part flagged as out of stock can be swapped for one with the same footprint.

Parts

108
QtyValueFootprintReferences
19100nFCapacitor_SMD:C_0603_1608MetricC10, C11, C12, C13, C14, C15, C16, C17, C18, C21, C22, C23, C24, C25, C26, C27 +3
1722kResistor_SMD:R_0603_1608MetricR2, R30, R31, R32, R33, R34, R35, R36, R37, R40, R41, R42, R43, R44, R45, R46 +1
16100Resistor_SMD:R_0603_1608MetricR10, R11, R12, R13, R14, R15, R16, R17, R20, R21, R22, R23, R24, R25, R26, R27
874HC595Package_SO:SOIC-16_3.9x9.9mm_P1.27mmU11, U12, U13, U14, U15, U16, U17, U18
8LEDsTerminalBlock_Phoenix:TerminalBlock_Phoenix_PT-1,5-10-3.5-H_1x10_P3.50mm_HorizontalJ11, J12, J13, J14, J15, J16, J17, J18
8ULN2803APackage_SO:SOIC-18W_7.5x11.6mm_P1.27mmU21, U22, U23, U24, U25, U26, U27, U28
410uF 25VCapacitor_SMD:C_0805_2012MetricC1, C2, C3, C9
4M3MountingHole:MountingHole_3.2mm_M3H1, H2, H3, H4
310kResistor_SMD:R_0603_1608MetricR3, R4, R5
222uFCapacitor_SMD:C_0805_2012MetricC6, C7
25.1kResistor_SMD:R_0603_1608MetricR7, R8
2SS34Diode_SMD:D_SMAD2, D3
1100kResistor_SMD:R_0603_1608MetricR1
110uHInductor_SMD:L_Sunlord_SWPA4030SL1
112V DCConnector_BarrelJack:BarrelJack_HorizontalJ1
11kResistor_SMD:R_0603_1608MetricR6
11uFCapacitor_SMD:C_0603_1608MetricC8
1BOOTButton_Switch_THT:SW_PUSH_6mmSW2
1COLSTerminalBlock_Phoenix:TerminalBlock_Phoenix_PT-1,5-8-3.5-H_1x08_P3.50mm_HorizontalJ4
1ESP32-S3-WROOM-1-N8RF_Module:ESP32-S3-WROOM-1U1
1RESETButton_Switch_THT:SW_PUSH_6mmSW1
1ROWSTerminalBlock_Phoenix:TerminalBlock_Phoenix_PT-1,5-8-3.5-H_1x08_P3.50mm_HorizontalJ3
1SS54Diode_SMD:D_SMAD1
1TPS54202HPackage_TO_SOT_SMD:TSOT-23-6U2
1UARTConnector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalJ5
1USB-CConnector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12J2
1statusLED_SMD:LED_0603_1608MetricD4

Questions

How big is the Button grid PCB?

It measures 208 × 110 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Button grid use?

108 parts, built around the ESP32-S3-WROOM-1-N8, 74HC595, ULN2803A and TPS54202HDDC. 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 Button grid KiCad files?

From the paulsonnentag/button-grid repository on GitHub, at the commit this page was made from: the board is hardware/button-grid.kicad_pcb and its schematic hardware/button-grid.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Button grid design in my own project?

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

Similar boards

  • 2 layers210 × 120 mmRelay24 ESP32, the printed circuit board in 3D

    Relay24 ESP32

    renatorgr/Boards

    Hardware and firmware for the AgOpenGPS AiO v4.5 autosteer boards: Teensy 4.1 firmware with its own web page (GPS, IMU, autosteer), a XIAO ESP32 Wi-Fi status page, XIAO adapter boards, and an Arduino Nano sprayer…

    164 parts2GPL-3.0
  • 2 layers100 × 89.5 mmLed processor board, the printed circuit board in 3D

    Led processor board

    eelstretching/led-processor-board

    A board with a processor and a couple of other things that can talk to an LED output board.

    128 parts
  • 2 layers50 × 62 mmIotDisplay, the printed circuit board in 3D

    IotDisplay

    BerkeleyHCI/PolymorphicBlocks

    A Python-based hardware description language for PCBs for higher-level (block-diagram / system-architecture level) PCB design through libraries of directly reusable subcircuit generators.

    78 parts94BSD-3-Clause
  • 2 layers90 × 90 mmTas5805m, the printed circuit board in 3D

    Tas5805m

    bybzmt/practise

    110 parts
  • 2 layers125 × 100 mmRTC RELAY, the printed circuit board in 3D

    RTC RELAY

    zen451019/EMASA_drivers

    Compendium of codes, schematics, and controller boards designed for use by EMASA

    56 parts
  • 2 layers121 × 75.5 mmJlctest, the printed circuit board in 3D

    Jlctest

    cjheath/jlcbasic

    JLC Basic parts library for Kicad fetched and converted from EasyEDA

    46 parts5
  • 4 layers65 × 73.9 mmBarn blinds controller, the printed circuit board in 3D

    Barn blinds controller

    irvintim/barn-blinds-controller

    Open barn-blinds-controller.kicadpro. Everything the project needs is under this folder: lib/NewLibrary.kicadsym (U1, J4, TMP235), lib/barnshadecontroller.pretty/, and lib/3dmodels/ (referenced as…

    118 parts