Electronics Design

This week focuses on using EDA (Electronic Design Automation) tools to design custom development boards and using test equipment to observe microcontroller circuit behavior.

Assignment Requirements

Group Assignment:

Individual Assignment:

Project Documentation

For the individual assignment I used KiCad 9.0 as my EDA tool to design a custom 8x8 LED matrix board. The matrix uses surface mount LEDs and is designed to interact and communicate with an Arduino Uno.

Why an LED Matrix?

An LED matrix is a good project for learning EDA because it involves repetitive but precise component placement, multi-layer routing, and direct microcontroller interfacing. The 8x8 grid gives you 64 individually addressable LEDs using only 16 I/O pins through multiplexing — each LED sits at the intersection of a row and column, and you light it by driving the correct row HIGH and column LOW.

Design Decisions

I decided to go with an 8x8 matrix — 64 LEDs total — which is a straightforward multiplexed design. The circuit itself is fairly simple: 8 rows and 8 columns, with each LED addressed by activating the correct row and column combination. The board interacts and communicates with an Arduino Uno (ATmega328P microcontroller), which drives the matrix using 16 of its I/O pins — digital pins D2 through D13 for 12 of the lines, plus analog pins A0 through A3 (used as digital outputs) for the remaining 4.

The board is a two-sided PCB, which was necessary to route all the traces without running into each other. Row traces run on the front copper layer (F.Cu) and column traces on the back copper layer (B.Cu), with 77 vias connecting signals between the two sides where needed.

Schematic Design Workflow

I started in KiCad's schematic editor (Eeschema) by placing the Arduino Uno R3 module symbol and all 64 LED symbols. Each row of 8 LEDs shares a common anode connection, and each column shares a common cathode. The schematic is straightforward but large — wiring 64 LEDs with proper net labels for all 8 rows and 8 columns took careful organization to keep it readable.

Adding Symbols to the Schematic

To add a symbol in KiCad's schematic editor:

  1. Press 'A' key or click "Add Symbol" button — this opens the symbol chooser dialog
  2. Search for the component — I typed "LED" to find the LED symbol, and "Arduino_UNO_R3" for the Arduino module
  3. Select and place — Click the symbol you want, then click on the schematic canvas to place it
  4. Repeat for all components — I placed 64 LED symbols (8 rows × 8 columns) and 1 Arduino Uno R3 module

For repetitive components like the 64 LEDs, I used copy and paste (Ctrl+C, Ctrl+V) to speed up placement. KiCad automatically increments reference designators (LED1, LED2, LED3...) which saved a lot of time.

Wiring and Net Labels

After placing all symbols, I wired them together:

  1. Press 'W' key to start drawing a wire
  2. Click to place wire segments connecting component pins
  3. Add net labels (Press 'L') to name connections — I used labels like "ROW1", "ROW2"... "ROW8" for the 8 row lines and "COL1", "COL2"... "COL8" for the 8 column lines
  4. Connect to Arduino pins — Wired ROW1-8 to Arduino pins D2-D9, and COL1-8 to pins D10-D13 and A0-A3

Net labels are crucial for complex schematics — instead of drawing wires across the entire page, you label both ends of a connection with the same name and KiCad knows they're electrically connected.

Assigning Footprints

After completing the schematic, I assigned physical footprints to each symbol:

  1. Open "Assign Footprints" tool (Tools → Assign Footprints, or click the footprint icon)
  2. For each LED: Selected LED_SMD:LED_0603_1608Metric_Pad0.64x0.40mm_HandSolder
    • 0603 size (1.6mm × 0.8mm) — small enough for compact layout, large enough to hand solder
    • "HandSolder" variant has extended pads (0.64mm × 0.40mm) making manual soldering easier
  3. For Arduino: Selected Module:Arduino_UNO_R3 — includes mounting holes and proper pin spacing
  4. Save and update PCB — Click "Apply, Save Schematic & Continue" to push footprints to the PCB editor
Changing Footprints

If you need to change a footprint after assignment:

  1. In schematic editor: Double-click the symbol → "Footprint" field → Click browse button → Select new footprint
  2. Or use Assign Footprints tool: Select component in left pane → Choose new footprint in right pane → Apply
  3. Update PCB: Tools → Update PCB from Schematic (F8) — this pushes the footprint change to the board layout

I initially tried a smaller 0402 footprint but switched to 0603 after realizing hand soldering 64 tiny 0402 LEDs would be extremely difficult.

KiCad schematic for 8x8 LED matrix

KiCad schematic — 8x8 LED matrix controlled by Arduino Uno with net labels for rows and columns

PCB Layout — LED Arrangement Process

The most time-consuming part was the PCB editor. After assigning footprints and updating the PCB from the schematic (Tools → Update PCB from Schematic, or press F8), all 64 LED footprints and the Arduino module appeared on the board canvas in a jumbled pile.

Arranging the 8x8 LED Grid

Getting 64 surface mount LEDs into a perfect 8x8 grid was the biggest challenge of this project. Here's how I did it:

  1. Calculate grid spacing:
    • LED footprint size: 1.6mm × 0.8mm (0603 package)
    • Decided on 3mm center-to-center spacing for both X and Y axes
    • This gives 1.4mm clearance between LEDs — enough for traces and vias
  2. Set grid origin: Chose starting point at X=20mm, Y=20mm (top-left corner of matrix)
  3. Calculate all 64 positions:
    • Row 1: Y = 20mm, X = 20, 23, 26, 29, 32, 35, 38, 41mm
    • Row 2: Y = 23mm, X = 20, 23, 26, 29, 32, 35, 38, 41mm
    • ...and so on for all 8 rows
  4. Position each LED manually:
    • Select LED footprint → Press 'E' to edit properties
    • Enter exact X and Y coordinates in the Position fields
    • Repeat for all 64 LEDs — tedious but necessary for perfect alignment

Why manual positioning? KiCad doesn't have a built-in "arrange in grid" tool for footprints. There's no way to select 64 components and automatically snap them into an 8×8 layout with even spacing. I tried using the grid snap feature, but it doesn't work well for precise matrix layouts — any small offset compounds across the grid. Manual coordinate entry was the only way to guarantee perfect alignment.

Routing Traces

After positioning all LEDs, I routed the copper traces connecting them:

  1. Press 'X' key to start routing a trace
  2. Click on a pad to start the trace, then click to place route segments
  3. Switch layers: Press 'V' key while routing to place a via and switch to the opposite copper layer
  4. Complete the route: Click on the destination pad to finish

Layer strategy:

  • Front copper (F.Cu): All row connections — horizontal traces connecting LED anodes in each row
  • Back copper (B.Cu): All column connections — vertical traces connecting LED cathodes in each column
  • Vias: 77 vias total to connect traces between layers where needed

I routed manually instead of using the auto-router because the auto-router struggled with the dense grid and created messy, inefficient paths. Manual routing gave me full control over trace aesthetics and ensured clean, professional-looking copper layers.

Trace Width Setup

Setting appropriate trace widths is critical for manufacturability and electrical performance:

  1. Open Board Setup: File → Board Setup → Design Rules → Net Classes
  2. Default net class settings:
    • Trace width: 0.25mm (10 mils) — standard for signal traces on PCBs
    • Clearance: 0.2mm (8 mils) — minimum spacing between copper features
    • Via size: 0.8mm diameter, 0.4mm drill — standard plated through-hole via
  3. Why these values?
    • 0.25mm traces are wide enough to carry LED current (~20mA per LED) without overheating
    • 0.2mm clearance prevents shorts during milling and ensures reliable manufacturing
    • Most PCB manufacturers can handle these dimensions easily

For power traces (if I had added power distribution), I would use wider traces (0.5mm or more) to handle higher current, but for this LED matrix all traces are signal-level and 0.25mm is appropriate.

Design Rule Check (DRC) and Electrical Rule Check (ERC)

Before finalizing the board, I ran KiCad's built-in checks to verify the design meets manufacturing and electrical requirements:

Electrical Rule Check (ERC) — Schematic

In the schematic editor:

  1. Click "Perform Electrical Rules Check" icon (or Inspect → Electrical Rules Checker)
  2. Click "Run ERC" button
  3. Review results:
    • Checks for unconnected pins, conflicting pin types, missing power connections
    • My design showed 0 errors — all LEDs properly connected to rows/columns, Arduino pins correctly wired
    • Had a few warnings about "power pins not driven" which I ignored since the Arduino provides power externally
Design Rule Check (DRC) — PCB Layout

In the PCB editor:

  1. Click "Perform Design Rules Check" icon (or Inspect → Design Rules Checker)
  2. Click "Run DRC" button
  3. Review violations:
    • Checks for trace clearance violations, drill size errors, copper-to-edge clearance
    • Initial run showed 12 clearance violations where traces were too close
    • Fixed by rerouting problem traces and adjusting via positions
    • Final DRC: 0 errors, 0 warnings — board is manufacturable

Why DRC/ERC matter: These checks catch mistakes before you send the board to manufacturing. A clearance violation could cause a short circuit. An unconnected pin means the circuit won't work. Running these checks is essential for any professional PCB design.

Creating the Board Outline

The board outline defines the physical edge of the PCB:

  1. Switch to Edge.Cuts layer: Select "Edge.Cuts" from the layer dropdown (or press Page Down to cycle layers)
  2. Draw the outline:
    • Used the "Draw Rectangle" tool (right toolbar) to create a rectangular board
    • Sized to 70mm × 70mm — large enough for the 8×8 LED grid plus Arduino mounting area
    • Positioned to leave 5mm margin around components
  3. Alternative methods:
    • Can use "Draw Line" tool for custom shapes
    • Can use "Draw Arc" for rounded corners
    • Edge.Cuts layer is special — anything drawn here defines where the board will be cut

The board outline must be a closed shape with no gaps. KiCad's DRC will flag any discontinuities in the Edge.Cuts layer.

KiCad PCB editor layout for 8x8 LED matrix

KiCad PCB editor — two-sided board layout with 64 LEDs and 77 vias

3D Board Preview

KiCad 3D viewer of the LED matrix PCB

KiCad 3D viewer — the finished two-sided LED matrix board

KiCad Project Files

📦 KiCad Project 📦 Schematic 📦 PCB Layout 📦 3D STEP File

Bill of Materials

  • 64x 0603 surface mount LEDs (footprint: LED_0201_0603Metric_Pad0.64x0.40mm_HandSolder): Hand soldered onto the board. The 0603 package is small (1.6mm × 0.8mm), which made soldering by hand a careful process but keeps the matrix compact. The "HandSolder" footprint variant has slightly extended pads to make manual soldering easier.
  • 77x vias: Plated through-holes with conductive inserts that connect traces from the front copper layer (F.Cu) to the back copper layer (B.Cu). Since the board is two-sided with rows on one side and columns on the other, vias are needed wherever a trace needs to cross to the opposite layer.
  • Arduino Uno R3: The embedded microcontroller (ATmega328P) that drives the matrix. It uses 16 I/O pins — D2 through D13 and A0 through A3 — to control the 8 row lines and 8 column lines. The board mounts directly using the Arduino UNO R3 footprint with mounting holes.

Multiplexing Research — Charlieplexing vs Traditional Multiplexing

Before designing the LED matrix, I researched different multiplexing techniques to understand the tradeoffs:

Research Sources
Why I Chose Traditional Multiplexing Over Charlieplexing

Charlieplexing is more pin-efficient — with 9 pins you could theoretically control 72 LEDs (9×8) using tri-state logic. However, it has significant drawbacks:

  • Complex wiring — every LED needs diodes or careful pin management
  • Lower brightness — only one LED can be on at a time, so duty cycle is 1/72 instead of 1/8
  • More difficult to program — requires careful tri-state pin management
  • Not suitable for hand soldering — too many connections per LED

Traditional row-column multiplexing is simpler and more practical for this project:

  • 16 pins for 64 LEDs — still very efficient (4:1 ratio)
  • Higher brightness — 1/8 duty cycle (one full row on at a time)
  • Simple wiring — each LED just needs row and column connections
  • Easy to program — straightforward row scanning in Arduino code
  • Better for hand soldering — fewer connections per LED

For an 8×8 matrix, traditional multiplexing is the better choice. Charlieplexing makes more sense for very pin-constrained designs or when you need to control many more LEDs than you have pins available.

Milling Verification with MODS

Before sending the board to a PCB manufacturer, I verified it could be milled on a CNC machine using MODS (Modular Open Design System):

MODS Workflow
  1. Export Gerber files from KiCad:
    • File → Fabrication Outputs → Gerbers (.gbr)
    • Exported F.Cu (front copper), B.Cu (back copper), and Edge.Cuts layers
  2. Open MODS: Navigated to mods.cba.mit.edu
  3. Select program: Right-click → programs → open server program → PCB PNG → mill 2D PCB
  4. Load Gerber file: Clicked "select PNG file" and loaded the F.Cu Gerber (MODS can read Gerbers directly)
  5. Set milling parameters:
    • Tool diameter: 0.4mm (1/64" end mill) for traces
    • Cut depth: 0.1mm (typical for copper removal)
    • Max depth: 0.1mm (single pass)
    • Offset number: 4 (clears copper around traces)
  6. Calculate toolpath: Clicked "calculate" to generate milling paths
  7. View simulation: MODS displayed the toolpath preview showing:
    • All traces properly isolated with clearance
    • No tool collisions or impossible cuts
    • Estimated milling time: ~45 minutes for front layer
Verification Results

✅ Board is millable: MODS confirmed the design can be manufactured on a CNC mill:

  • All traces are wide enough (0.25mm) for a 0.4mm end mill to isolate
  • Clearances (0.2mm) are sufficient to prevent shorts
  • No features too small for the tool to reach
  • Via holes (0.4mm drill) are standard size for PCB drills

Potential issues identified:

  • Two-sided board requires precise alignment between front and back layers
  • 77 vias need to be drilled and manually riveted or filled with conductive epoxy
  • Hand soldering 64 tiny 0603 LEDs will be time-consuming but feasible

The MODS verification gave me confidence the board design is manufacturable. If I were to actually mill this board, I would use the exported G-code from MODS to drive the CNC machine.

With 64 LEDs but only 16 pins, the matrix uses multiplexing to address each LED individually. The Arduino rapidly scans through each row, turning on the correct column LEDs for that row before moving to the next. This happens fast enough that persistence of vision makes it look like all the LEDs are on simultaneously. Each LED only needs to be at the intersection of an active row and active column to light up.

How an LED Matrix Works

An LED matrix is fundamentally a grid of LEDs arranged in rows and columns, where each LED sits at a unique intersection point. Instead of wiring each LED to its own dedicated pin — which would require 64 pins for an 8x8 grid — the matrix takes advantage of the fact that current only flows through an LED when both its anode (positive) and cathode (negative) are connected to the correct voltage levels.

In an 8x8 common-anode configuration, all 8 LEDs in a row share the same anode connection, and all 8 LEDs in a column share the same cathode connection. To light a specific LED, you drive its row HIGH (supplying voltage to the anode) and its column LOW (sinking current from the cathode). Every other LED in that row stays dark because their columns aren't pulled LOW, and every other LED in that column stays dark because their rows aren't driven HIGH. This row-column addressing scheme is the same principle used in keyboard scanning, memory arrays, and display panels — it scales efficiently because an N×N grid only needs 2N control lines instead of N².

For the week 6 group assignment, our team used the test equipment in the lab to observe the operation of a microcontroller circuit board, including demonstrating the use of a logic analyzer. You can view the full group page here: Week 6 Group Assignment.

My Contributions — Capacitor Testing

After observing the microcontroller circuit board's behavior at the signal level with the oscilloscope and the Analog Discovery 2, I wanted to go a step further and verify the individual passive components that make those circuits work. Capacitors are one of the most common components on any circuit board, so I pulled a selection of electrolytic capacitors from our lab's inventory and tested them with a multimeter to see how closely their actual capacitance matched their rated values.

I wrote up a full section covering what capacitors are, how electrolytic capacitors work, and the testing process with results. You can read my full contribution here: Capacitor Testing — Oliver Abbott.

Useful Links