Draw Any Letter With LEDs
Overview
This tutorial shows how to create a reusable LedLetter component. The component
takes a capital letter, converts it into a 5 by 7 pixel font, and places one LED
for every lit pixel.
The intended usage is:
<LedLetter letter="A" power=".V5 .test" gnd=".GND .test" />
The component below supports capital A through Z, uses small SMD LEDs, and
adds one current-limiting resistor for every LED. The PCB layout is generated
from simple grid math, and the schematic is automatically spread into readable
rows so larger letters do not stack every LED and resistor in one place.
How the layout works
The font is a small Record<string, string[]> where each letter is seven rows
tall and five columns wide. Each 1 becomes an LED. Each 0 is left empty.
For every lit pixel, the component calculates the PCB position like this:
const ledPcbX = pcbX + (col - (columns - 1) / 2) * pitch
const ledPcbY = pcbY + ((rows - 1) / 2 - row) * pitch
That keeps the letter centered around pcbX and pcbY, regardless of which
letter is selected. Increasing pitch makes the letter larger. Decreasing it
makes the LEDs tighter.
Current limiting
Every LED gets its own resistor:
<trace from={power} to={"." + resistorName + " .pos"} />
<trace from={"." + resistorName + " .neg"} to={"." + ledName + " .pos"} />
<trace from={"." + ledName + " .neg"} to={gnd} />
This makes the electrical path:
power -> resistor -> LED -> ground
The default is a 1k resistor and 0603 footprints for both the LED and the
resistor. You can switch to 0402 parts when you want a smaller, denser letter:
<LedLetter
letter="K"
power=".V5 .test"
gnd=".GND .test"
ledFootprint="0402"
resistorFootprint="0402"
pitch={2.2}
/>
Reusing the component
Use a different name for every instance so the generated component names stay
unique:
<LedLetter name="LEFT_A" letter="A" power=".V5 .test" gnd=".GND .test" pcbX={-12} />
<LedLetter name="RIGHT_Z" letter="Z" power=".V5 .test" gnd=".GND .test" pcbX={12} />
The same font map can be adjusted later if you want a more rounded or condensed style. The placement math does not need to change because it only depends on the row and column of each lit pixel.