From ddede6f996fbc6f5822562edf38efacefdd8e682 Mon Sep 17 00:00:00 2001 From: kebanks2 <109536664+kebanks2@users.noreply.github.com> Date: Wed, 20 May 2026 06:44:12 +0300 Subject: [PATCH] Create drawing-led-letters.mdx --- docs/tutorials/drawing-led-letters.mdx | 175 +++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 docs/tutorials/drawing-led-letters.mdx diff --git a/docs/tutorials/drawing-led-letters.mdx b/docs/tutorials/drawing-led-letters.mdx new file mode 100644 index 0000000..ff7278a --- /dev/null +++ b/docs/tutorials/drawing-led-letters.mdx @@ -0,0 +1,175 @@ +--- +title: Drawing Letters with LEDs +description: Build a reusable LedLetter component that lays out A-Z LED glyphs with current-limiting resistors in tscircuit. +--- + +import CircuitPreview from "@site/src/components/CircuitPreview" + +## Overview + +This tutorial builds a reusable `LedLetter` component. The component accepts a +capital letter from A to Z, looks up a 5 by 7 bitmap glyph, and uses math to +place an LED and current-limiting resistor for every lit pixel. + +Each LED string is wired from `power` through its own resistor and LED to `gnd`. +That keeps the example simple, predictable, and easy to copy into a larger sign, +badge, or indicator board. + +## Final example + + = { + A: ["01110", "10001", "10001", "11111", "10001", "10001", "10001"], + B: ["11110", "10001", "10001", "11110", "10001", "10001", "11110"], + C: ["01111", "10000", "10000", "10000", "10000", "10000", "01111"], + D: ["11110", "10001", "10001", "10001", "10001", "10001", "11110"], + E: ["11111", "10000", "10000", "11110", "10000", "10000", "11111"], + F: ["11111", "10000", "10000", "11110", "10000", "10000", "10000"], + G: ["01111", "10000", "10000", "10111", "10001", "10001", "01110"], + H: ["10001", "10001", "10001", "11111", "10001", "10001", "10001"], + I: ["11111", "00100", "00100", "00100", "00100", "00100", "11111"], + J: ["00111", "00010", "00010", "00010", "00010", "10010", "01100"], + K: ["10001", "10010", "10100", "11000", "10100", "10010", "10001"], + L: ["10000", "10000", "10000", "10000", "10000", "10000", "11111"], + M: ["10001", "11011", "10101", "10101", "10001", "10001", "10001"], + N: ["10001", "11001", "10101", "10011", "10001", "10001", "10001"], + O: ["01110", "10001", "10001", "10001", "10001", "10001", "01110"], + P: ["11110", "10001", "10001", "11110", "10000", "10000", "10000"], + Q: ["01110", "10001", "10001", "10001", "10101", "10010", "01101"], + R: ["11110", "10001", "10001", "11110", "10100", "10010", "10001"], + S: ["01111", "10000", "10000", "01110", "00001", "00001", "11110"], + T: ["11111", "00100", "00100", "00100", "00100", "00100", "00100"], + U: ["10001", "10001", "10001", "10001", "10001", "10001", "01110"], + V: ["10001", "10001", "10001", "10001", "10001", "01010", "00100"], + W: ["10001", "10001", "10001", "10101", "10101", "10101", "01010"], + X: ["10001", "10001", "01010", "00100", "01010", "10001", "10001"], + Y: ["10001", "10001", "01010", "00100", "00100", "00100", "00100"], + Z: ["11111", "00001", "00010", "00100", "01000", "10000", "11111"], +} + +const litPixelsFor = (letter: string) => { + const rows = glyphs[letter.toUpperCase()] + if (!rows) { + throw new Error(\`LedLetter only supports capital A-Z, got "\${letter}"\`) + } + + return rows.flatMap((row, rowIndex) => + [...row].flatMap((pixel, columnIndex) => + pixel === "1" ? [{ row: rowIndex, column: columnIndex }] : [], + ), + ) +} + +export const LedLetter = ({ + letter, + power, + gnd, + x = 0, + y = 0, + pitch = 2.5, + ledFootprint = "0603", + resistorFootprint = "0402", + resistance = "1k", +}: LedLetterProps) => { + const pixels = litPixelsFor(letter) + const startX = x - ((5 - 1) * pitch) / 2 + const startY = y + ((7 - 1) * pitch) / 2 + + return ( + + {pixels.map(({ row, column }, index) => { + const ledName = \`LED_\${letter}_\${index + 1}\` + const resistorName = \`R_\${letter}_\${index + 1}\` + const pcbX = startX + column * pitch + const pcbY = startY - row * pitch + const schX = column * 2 + const schY = -row * 1.6 + + return ( + + + + .pin1\`} /> + .pin2\`} to={\`.\${ledName} > .pos\`} /> + .neg\`} to={gnd} /> + + ) + })} + + ) +} + +export default () => ( + + + + + +) +`} +/> + +## Usage + +Use `LedLetter` inside any board and pass the nets that should power each LED +string: + +```tsx + +``` + +The example uses one resistor for each LED. That is conservative for a small +display because every pixel has its own current limiter. If you decide to wire +LEDs in series or multiplex a larger display, calculate the resistor values and +drive circuitry for the selected LED forward voltage, supply voltage, duty +cycle, and desired current. + +## How the layout works + +Each glyph is stored as seven strings with five characters per row. A `1` means +that pixel is lit; a `0` means it is empty. `litPixelsFor()` converts the glyph +into `{ row, column }` coordinates, and `LedLetter` turns those coordinates into +component positions: + +- `pcbX` and `pcbY` use `pitch` to form the physical LED grid. +- `schX` and `schY` spread the LED-resistor strings into a readable schematic. +- Component names include the selected letter and pixel index so every LED and + resistor has a stable, unique name. +- `ledFootprint`, `resistorFootprint`, and `resistance` are props, so the same + component can switch between 0402 and 0603 assemblies. + +## Try another letter + +Change the prop from `letter="A"` to any capital letter through `letter="Z"`. +The glyph table above includes all A-Z letters, so the same component can render +letters for names, badges, indicators, or simple LED art.